xref: /aosp_15_r20/external/capstone/arch/X86/X86DisassemblerDecoder.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi /*===-- X86DisassemblerDecoder.c - Disassembler decoder ------------*- C -*-===*
2*9a0e4156SSadaf Ebrahimi  *
3*9a0e4156SSadaf Ebrahimi  *                     The LLVM Compiler Infrastructure
4*9a0e4156SSadaf Ebrahimi  *
5*9a0e4156SSadaf Ebrahimi  * This file is distributed under the University of Illinois Open Source
6*9a0e4156SSadaf Ebrahimi  * License. See LICENSE.TXT for details.
7*9a0e4156SSadaf Ebrahimi  *
8*9a0e4156SSadaf Ebrahimi  *===----------------------------------------------------------------------===*
9*9a0e4156SSadaf Ebrahimi  *
10*9a0e4156SSadaf Ebrahimi  * This file is part of the X86 Disassembler.
11*9a0e4156SSadaf Ebrahimi  * It contains the implementation of the instruction decoder.
12*9a0e4156SSadaf Ebrahimi  * Documentation for the disassembler can be found in X86Disassembler.h.
13*9a0e4156SSadaf Ebrahimi  *
14*9a0e4156SSadaf Ebrahimi  *===----------------------------------------------------------------------===*/
15*9a0e4156SSadaf Ebrahimi 
16*9a0e4156SSadaf Ebrahimi /* Capstone Disassembly Engine */
17*9a0e4156SSadaf Ebrahimi /* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */
18*9a0e4156SSadaf Ebrahimi 
19*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_HAS_X86
20*9a0e4156SSadaf Ebrahimi 
21*9a0e4156SSadaf Ebrahimi #include <stdarg.h>   /* for va_*()       */
22*9a0e4156SSadaf Ebrahimi #if defined(CAPSTONE_HAS_OSXKERNEL)
23*9a0e4156SSadaf Ebrahimi #include <libkern/libkern.h>
24*9a0e4156SSadaf Ebrahimi #else
25*9a0e4156SSadaf Ebrahimi #include <stdlib.h>   /* for exit()       */
26*9a0e4156SSadaf Ebrahimi #endif
27*9a0e4156SSadaf Ebrahimi 
28*9a0e4156SSadaf Ebrahimi #include "../../cs_priv.h"
29*9a0e4156SSadaf Ebrahimi #include "../../utils.h"
30*9a0e4156SSadaf Ebrahimi 
31*9a0e4156SSadaf Ebrahimi #include "X86DisassemblerDecoder.h"
32*9a0e4156SSadaf Ebrahimi 
33*9a0e4156SSadaf Ebrahimi /// Specifies whether a ModR/M byte is needed and (if so) which
34*9a0e4156SSadaf Ebrahimi /// instruction each possible value of the ModR/M byte corresponds to.  Once
35*9a0e4156SSadaf Ebrahimi /// this information is known, we have narrowed down to a single instruction.
36*9a0e4156SSadaf Ebrahimi struct ModRMDecision {
37*9a0e4156SSadaf Ebrahimi 	uint8_t modrm_type;
38*9a0e4156SSadaf Ebrahimi 	uint16_t instructionIDs;
39*9a0e4156SSadaf Ebrahimi };
40*9a0e4156SSadaf Ebrahimi 
41*9a0e4156SSadaf Ebrahimi /// Specifies which set of ModR/M->instruction tables to look at
42*9a0e4156SSadaf Ebrahimi /// given a particular opcode.
43*9a0e4156SSadaf Ebrahimi struct OpcodeDecision {
44*9a0e4156SSadaf Ebrahimi 	struct ModRMDecision modRMDecisions[256];
45*9a0e4156SSadaf Ebrahimi };
46*9a0e4156SSadaf Ebrahimi 
47*9a0e4156SSadaf Ebrahimi /// Specifies which opcode->instruction tables to look at given
48*9a0e4156SSadaf Ebrahimi /// a particular context (set of attributes).  Since there are many possible
49*9a0e4156SSadaf Ebrahimi /// contexts, the decoder first uses CONTEXTS_SYM to determine which context
50*9a0e4156SSadaf Ebrahimi /// applies given a specific set of attributes.  Hence there are only IC_max
51*9a0e4156SSadaf Ebrahimi /// entries in this table, rather than 2^(ATTR_max).
52*9a0e4156SSadaf Ebrahimi struct ContextDecision {
53*9a0e4156SSadaf Ebrahimi 	struct OpcodeDecision opcodeDecisions[IC_max];
54*9a0e4156SSadaf Ebrahimi };
55*9a0e4156SSadaf Ebrahimi 
56*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_X86_REDUCE
57*9a0e4156SSadaf Ebrahimi #include "X86GenDisassemblerTables_reduce.inc"
58*9a0e4156SSadaf Ebrahimi #else
59*9a0e4156SSadaf Ebrahimi #include "X86GenDisassemblerTables.inc"
60*9a0e4156SSadaf Ebrahimi #endif
61*9a0e4156SSadaf Ebrahimi 
62*9a0e4156SSadaf Ebrahimi //#define GET_INSTRINFO_ENUM
63*9a0e4156SSadaf Ebrahimi #define GET_INSTRINFO_MC_DESC
64*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_X86_REDUCE
65*9a0e4156SSadaf Ebrahimi #include "X86GenInstrInfo_reduce.inc"
66*9a0e4156SSadaf Ebrahimi #else
67*9a0e4156SSadaf Ebrahimi #include "X86GenInstrInfo.inc"
68*9a0e4156SSadaf Ebrahimi #endif
69*9a0e4156SSadaf Ebrahimi 
70*9a0e4156SSadaf Ebrahimi /*
71*9a0e4156SSadaf Ebrahimi  * contextForAttrs - Client for the instruction context table.  Takes a set of
72*9a0e4156SSadaf Ebrahimi  *   attributes and returns the appropriate decode context.
73*9a0e4156SSadaf Ebrahimi  *
74*9a0e4156SSadaf Ebrahimi  * @param attrMask  - Attributes, from the enumeration attributeBits.
75*9a0e4156SSadaf Ebrahimi  * @return          - The InstructionContext to use when looking up an
76*9a0e4156SSadaf Ebrahimi  *                    an instruction with these attributes.
77*9a0e4156SSadaf Ebrahimi  */
contextForAttrs(uint16_t attrMask)78*9a0e4156SSadaf Ebrahimi static InstructionContext contextForAttrs(uint16_t attrMask)
79*9a0e4156SSadaf Ebrahimi {
80*9a0e4156SSadaf Ebrahimi 	return CONTEXTS_SYM[attrMask];
81*9a0e4156SSadaf Ebrahimi }
82*9a0e4156SSadaf Ebrahimi 
83*9a0e4156SSadaf Ebrahimi /*
84*9a0e4156SSadaf Ebrahimi  * modRMRequired - Reads the appropriate instruction table to determine whether
85*9a0e4156SSadaf Ebrahimi  *   the ModR/M byte is required to decode a particular instruction.
86*9a0e4156SSadaf Ebrahimi  *
87*9a0e4156SSadaf Ebrahimi  * @param type        - The opcode type (i.e., how many bytes it has).
88*9a0e4156SSadaf Ebrahimi  * @param insnContext - The context for the instruction, as returned by
89*9a0e4156SSadaf Ebrahimi  *                      contextForAttrs.
90*9a0e4156SSadaf Ebrahimi  * @param opcode      - The last byte of the instruction's opcode, not counting
91*9a0e4156SSadaf Ebrahimi  *                      ModR/M extensions and escapes.
92*9a0e4156SSadaf Ebrahimi  * @return            - true if the ModR/M byte is required, false otherwise.
93*9a0e4156SSadaf Ebrahimi  */
modRMRequired(OpcodeType type,InstructionContext insnContext,uint16_t opcode)94*9a0e4156SSadaf Ebrahimi static int modRMRequired(OpcodeType type,
95*9a0e4156SSadaf Ebrahimi 		InstructionContext insnContext,
96*9a0e4156SSadaf Ebrahimi 		uint16_t opcode)
97*9a0e4156SSadaf Ebrahimi {
98*9a0e4156SSadaf Ebrahimi 	const struct OpcodeDecision *decision = NULL;
99*9a0e4156SSadaf Ebrahimi 	const uint8_t *indextable = NULL;
100*9a0e4156SSadaf Ebrahimi 	uint8_t index;
101*9a0e4156SSadaf Ebrahimi 
102*9a0e4156SSadaf Ebrahimi 	switch (type) {
103*9a0e4156SSadaf Ebrahimi 		default:
104*9a0e4156SSadaf Ebrahimi 		case ONEBYTE:
105*9a0e4156SSadaf Ebrahimi 			decision = ONEBYTE_SYM;
106*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerOneByteOpcodes;
107*9a0e4156SSadaf Ebrahimi 			break;
108*9a0e4156SSadaf Ebrahimi 		case TWOBYTE:
109*9a0e4156SSadaf Ebrahimi 			decision = TWOBYTE_SYM;
110*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerTwoByteOpcodes;
111*9a0e4156SSadaf Ebrahimi 			break;
112*9a0e4156SSadaf Ebrahimi 		case THREEBYTE_38:
113*9a0e4156SSadaf Ebrahimi 			decision = THREEBYTE38_SYM;
114*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerThreeByte38Opcodes;
115*9a0e4156SSadaf Ebrahimi 			break;
116*9a0e4156SSadaf Ebrahimi 		case THREEBYTE_3A:
117*9a0e4156SSadaf Ebrahimi 			decision = THREEBYTE3A_SYM;
118*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerThreeByte3AOpcodes;
119*9a0e4156SSadaf Ebrahimi 			break;
120*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_X86_REDUCE
121*9a0e4156SSadaf Ebrahimi 		case XOP8_MAP:
122*9a0e4156SSadaf Ebrahimi 			decision = XOP8_MAP_SYM;
123*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOP8Opcodes;
124*9a0e4156SSadaf Ebrahimi 			break;
125*9a0e4156SSadaf Ebrahimi 		case XOP9_MAP:
126*9a0e4156SSadaf Ebrahimi 			decision = XOP9_MAP_SYM;
127*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOP9Opcodes;
128*9a0e4156SSadaf Ebrahimi 			break;
129*9a0e4156SSadaf Ebrahimi 		case XOPA_MAP:
130*9a0e4156SSadaf Ebrahimi 			decision = XOPA_MAP_SYM;
131*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOPAOpcodes;
132*9a0e4156SSadaf Ebrahimi 			break;
133*9a0e4156SSadaf Ebrahimi 		case T3DNOW_MAP:
134*9a0e4156SSadaf Ebrahimi 			// 3DNow instructions always have ModRM byte
135*9a0e4156SSadaf Ebrahimi 			return true;
136*9a0e4156SSadaf Ebrahimi #endif
137*9a0e4156SSadaf Ebrahimi 	}
138*9a0e4156SSadaf Ebrahimi 
139*9a0e4156SSadaf Ebrahimi 	index = indextable[insnContext];
140*9a0e4156SSadaf Ebrahimi 	if (index)
141*9a0e4156SSadaf Ebrahimi 		return decision[index - 1].modRMDecisions[opcode].modrm_type != MODRM_ONEENTRY;
142*9a0e4156SSadaf Ebrahimi 	else
143*9a0e4156SSadaf Ebrahimi 		return false;
144*9a0e4156SSadaf Ebrahimi }
145*9a0e4156SSadaf Ebrahimi 
146*9a0e4156SSadaf Ebrahimi /*
147*9a0e4156SSadaf Ebrahimi  * decode - Reads the appropriate instruction table to obtain the unique ID of
148*9a0e4156SSadaf Ebrahimi  *   an instruction.
149*9a0e4156SSadaf Ebrahimi  *
150*9a0e4156SSadaf Ebrahimi  * @param type        - See modRMRequired().
151*9a0e4156SSadaf Ebrahimi  * @param insnContext - See modRMRequired().
152*9a0e4156SSadaf Ebrahimi  * @param opcode      - See modRMRequired().
153*9a0e4156SSadaf Ebrahimi  * @param modRM       - The ModR/M byte if required, or any value if not.
154*9a0e4156SSadaf Ebrahimi  * @return            - The UID of the instruction, or 0 on failure.
155*9a0e4156SSadaf Ebrahimi  */
decode(OpcodeType type,InstructionContext insnContext,uint8_t opcode,uint8_t modRM)156*9a0e4156SSadaf Ebrahimi static InstrUID decode(OpcodeType type,
157*9a0e4156SSadaf Ebrahimi 		InstructionContext insnContext,
158*9a0e4156SSadaf Ebrahimi 		uint8_t opcode,
159*9a0e4156SSadaf Ebrahimi 		uint8_t modRM)
160*9a0e4156SSadaf Ebrahimi {
161*9a0e4156SSadaf Ebrahimi 	const struct ModRMDecision *dec = NULL;
162*9a0e4156SSadaf Ebrahimi 	const uint8_t *indextable = NULL;
163*9a0e4156SSadaf Ebrahimi 	uint8_t index;
164*9a0e4156SSadaf Ebrahimi 
165*9a0e4156SSadaf Ebrahimi 	switch (type) {
166*9a0e4156SSadaf Ebrahimi 		default:
167*9a0e4156SSadaf Ebrahimi 		case ONEBYTE:
168*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerOneByteOpcodes;
169*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
170*9a0e4156SSadaf Ebrahimi 			if (index)
171*9a0e4156SSadaf Ebrahimi 				dec = &ONEBYTE_SYM[index - 1].modRMDecisions[opcode];
172*9a0e4156SSadaf Ebrahimi 			else
173*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
174*9a0e4156SSadaf Ebrahimi 			break;
175*9a0e4156SSadaf Ebrahimi 		case TWOBYTE:
176*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerTwoByteOpcodes;
177*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
178*9a0e4156SSadaf Ebrahimi 			if (index)
179*9a0e4156SSadaf Ebrahimi 				dec = &TWOBYTE_SYM[index - 1].modRMDecisions[opcode];
180*9a0e4156SSadaf Ebrahimi 			else
181*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
182*9a0e4156SSadaf Ebrahimi 			break;
183*9a0e4156SSadaf Ebrahimi 		case THREEBYTE_38:
184*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerThreeByte38Opcodes;
185*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
186*9a0e4156SSadaf Ebrahimi 			if (index)
187*9a0e4156SSadaf Ebrahimi 				dec = &THREEBYTE38_SYM[index - 1].modRMDecisions[opcode];
188*9a0e4156SSadaf Ebrahimi 			else
189*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
190*9a0e4156SSadaf Ebrahimi 			break;
191*9a0e4156SSadaf Ebrahimi 		case THREEBYTE_3A:
192*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerThreeByte3AOpcodes;
193*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
194*9a0e4156SSadaf Ebrahimi 			if (index)
195*9a0e4156SSadaf Ebrahimi 				dec = &THREEBYTE3A_SYM[index - 1].modRMDecisions[opcode];
196*9a0e4156SSadaf Ebrahimi 			else
197*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
198*9a0e4156SSadaf Ebrahimi 			break;
199*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_X86_REDUCE
200*9a0e4156SSadaf Ebrahimi 		case XOP8_MAP:
201*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOP8Opcodes;
202*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
203*9a0e4156SSadaf Ebrahimi 			if (index)
204*9a0e4156SSadaf Ebrahimi 				dec = &XOP8_MAP_SYM[index - 1].modRMDecisions[opcode];
205*9a0e4156SSadaf Ebrahimi 			else
206*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
207*9a0e4156SSadaf Ebrahimi 			break;
208*9a0e4156SSadaf Ebrahimi 		case XOP9_MAP:
209*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOP9Opcodes;
210*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
211*9a0e4156SSadaf Ebrahimi 			if (index)
212*9a0e4156SSadaf Ebrahimi 				dec = &XOP9_MAP_SYM[index - 1].modRMDecisions[opcode];
213*9a0e4156SSadaf Ebrahimi 			else
214*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
215*9a0e4156SSadaf Ebrahimi 			break;
216*9a0e4156SSadaf Ebrahimi 		case XOPA_MAP:
217*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerXOPAOpcodes;
218*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
219*9a0e4156SSadaf Ebrahimi 			if (index)
220*9a0e4156SSadaf Ebrahimi 				dec = &XOPA_MAP_SYM[index - 1].modRMDecisions[opcode];
221*9a0e4156SSadaf Ebrahimi 			else
222*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
223*9a0e4156SSadaf Ebrahimi 			break;
224*9a0e4156SSadaf Ebrahimi 		case T3DNOW_MAP:
225*9a0e4156SSadaf Ebrahimi 			indextable = index_x86DisassemblerT3DNOWOpcodes;
226*9a0e4156SSadaf Ebrahimi 			index = indextable[insnContext];
227*9a0e4156SSadaf Ebrahimi 			if (index)
228*9a0e4156SSadaf Ebrahimi 				dec = &T3DNOW_MAP_SYM[index - 1].modRMDecisions[opcode];
229*9a0e4156SSadaf Ebrahimi 			else
230*9a0e4156SSadaf Ebrahimi 				dec = &emptyTable.modRMDecisions[opcode];
231*9a0e4156SSadaf Ebrahimi 			break;
232*9a0e4156SSadaf Ebrahimi #endif
233*9a0e4156SSadaf Ebrahimi 	}
234*9a0e4156SSadaf Ebrahimi 
235*9a0e4156SSadaf Ebrahimi 	switch (dec->modrm_type) {
236*9a0e4156SSadaf Ebrahimi 		default:
237*9a0e4156SSadaf Ebrahimi 			//debug("Corrupt table!  Unknown modrm_type");
238*9a0e4156SSadaf Ebrahimi 			return 0;
239*9a0e4156SSadaf Ebrahimi 		case MODRM_ONEENTRY:
240*9a0e4156SSadaf Ebrahimi 			return modRMTable[dec->instructionIDs];
241*9a0e4156SSadaf Ebrahimi 		case MODRM_SPLITRM:
242*9a0e4156SSadaf Ebrahimi 			if (modFromModRM(modRM) == 0x3)
243*9a0e4156SSadaf Ebrahimi 				return modRMTable[dec->instructionIDs+1];
244*9a0e4156SSadaf Ebrahimi 			return modRMTable[dec->instructionIDs];
245*9a0e4156SSadaf Ebrahimi 		case MODRM_SPLITREG:
246*9a0e4156SSadaf Ebrahimi 			if (modFromModRM(modRM) == 0x3)
247*9a0e4156SSadaf Ebrahimi 				return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8];
248*9a0e4156SSadaf Ebrahimi 			return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
249*9a0e4156SSadaf Ebrahimi 		case MODRM_SPLITMISC:
250*9a0e4156SSadaf Ebrahimi 			if (modFromModRM(modRM) == 0x3)
251*9a0e4156SSadaf Ebrahimi 				return modRMTable[dec->instructionIDs+(modRM & 0x3f)+8];
252*9a0e4156SSadaf Ebrahimi 			return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
253*9a0e4156SSadaf Ebrahimi 		case MODRM_FULL:
254*9a0e4156SSadaf Ebrahimi 			return modRMTable[dec->instructionIDs+modRM];
255*9a0e4156SSadaf Ebrahimi 	}
256*9a0e4156SSadaf Ebrahimi }
257*9a0e4156SSadaf Ebrahimi 
258*9a0e4156SSadaf Ebrahimi /*
259*9a0e4156SSadaf Ebrahimi  * specifierForUID - Given a UID, returns the name and operand specification for
260*9a0e4156SSadaf Ebrahimi  *   that instruction.
261*9a0e4156SSadaf Ebrahimi  *
262*9a0e4156SSadaf Ebrahimi  * @param uid - The unique ID for the instruction.  This should be returned by
263*9a0e4156SSadaf Ebrahimi  *              decode(); specifierForUID will not check bounds.
264*9a0e4156SSadaf Ebrahimi  * @return    - A pointer to the specification for that instruction.
265*9a0e4156SSadaf Ebrahimi  */
specifierForUID(InstrUID uid)266*9a0e4156SSadaf Ebrahimi static const struct InstructionSpecifier *specifierForUID(InstrUID uid)
267*9a0e4156SSadaf Ebrahimi {
268*9a0e4156SSadaf Ebrahimi 	return &INSTRUCTIONS_SYM[uid];
269*9a0e4156SSadaf Ebrahimi }
270*9a0e4156SSadaf Ebrahimi 
271*9a0e4156SSadaf Ebrahimi /*
272*9a0e4156SSadaf Ebrahimi  * consumeByte - Uses the reader function provided by the user to consume one
273*9a0e4156SSadaf Ebrahimi  *   byte from the instruction's memory and advance the cursor.
274*9a0e4156SSadaf Ebrahimi  *
275*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction with the reader function to use.  The cursor
276*9a0e4156SSadaf Ebrahimi  *                for this instruction is advanced.
277*9a0e4156SSadaf Ebrahimi  * @param byte  - A pointer to a pre-allocated memory buffer to be populated
278*9a0e4156SSadaf Ebrahimi  *                with the data read.
279*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the read was successful; nonzero otherwise.
280*9a0e4156SSadaf Ebrahimi  */
consumeByte(struct InternalInstruction * insn,uint8_t * byte)281*9a0e4156SSadaf Ebrahimi static int consumeByte(struct InternalInstruction *insn, uint8_t *byte)
282*9a0e4156SSadaf Ebrahimi {
283*9a0e4156SSadaf Ebrahimi 	int ret = insn->reader(insn->readerArg, byte, insn->readerCursor);
284*9a0e4156SSadaf Ebrahimi 
285*9a0e4156SSadaf Ebrahimi 	if (!ret)
286*9a0e4156SSadaf Ebrahimi 		++(insn->readerCursor);
287*9a0e4156SSadaf Ebrahimi 
288*9a0e4156SSadaf Ebrahimi 	return ret;
289*9a0e4156SSadaf Ebrahimi }
290*9a0e4156SSadaf Ebrahimi 
291*9a0e4156SSadaf Ebrahimi /*
292*9a0e4156SSadaf Ebrahimi  * lookAtByte - Like consumeByte, but does not advance the cursor.
293*9a0e4156SSadaf Ebrahimi  *
294*9a0e4156SSadaf Ebrahimi  * @param insn  - See consumeByte().
295*9a0e4156SSadaf Ebrahimi  * @param byte  - See consumeByte().
296*9a0e4156SSadaf Ebrahimi  * @return      - See consumeByte().
297*9a0e4156SSadaf Ebrahimi  */
lookAtByte(struct InternalInstruction * insn,uint8_t * byte)298*9a0e4156SSadaf Ebrahimi static int lookAtByte(struct InternalInstruction *insn, uint8_t *byte)
299*9a0e4156SSadaf Ebrahimi {
300*9a0e4156SSadaf Ebrahimi 	return insn->reader(insn->readerArg, byte, insn->readerCursor);
301*9a0e4156SSadaf Ebrahimi }
302*9a0e4156SSadaf Ebrahimi 
unconsumeByte(struct InternalInstruction * insn)303*9a0e4156SSadaf Ebrahimi static void unconsumeByte(struct InternalInstruction *insn)
304*9a0e4156SSadaf Ebrahimi {
305*9a0e4156SSadaf Ebrahimi 	insn->readerCursor--;
306*9a0e4156SSadaf Ebrahimi }
307*9a0e4156SSadaf Ebrahimi 
308*9a0e4156SSadaf Ebrahimi #define CONSUME_FUNC(name, type)                                  \
309*9a0e4156SSadaf Ebrahimi 	static int name(struct InternalInstruction *insn, type *ptr) {  \
310*9a0e4156SSadaf Ebrahimi 		type combined = 0;                                            \
311*9a0e4156SSadaf Ebrahimi 		unsigned offset;                                              \
312*9a0e4156SSadaf Ebrahimi 		for (offset = 0; offset < sizeof(type); ++offset) {           \
313*9a0e4156SSadaf Ebrahimi 			uint8_t byte;                                               \
314*9a0e4156SSadaf Ebrahimi 			int ret = insn->reader(insn->readerArg,                     \
315*9a0e4156SSadaf Ebrahimi 					&byte,                               \
316*9a0e4156SSadaf Ebrahimi 					insn->readerCursor + offset);        \
317*9a0e4156SSadaf Ebrahimi 			if (ret)                                                    \
318*9a0e4156SSadaf Ebrahimi 			return ret;                                               \
319*9a0e4156SSadaf Ebrahimi 			combined = combined | (type)((uint64_t)byte << (offset * 8));     \
320*9a0e4156SSadaf Ebrahimi 		}                                                             \
321*9a0e4156SSadaf Ebrahimi 		*ptr = combined;                                              \
322*9a0e4156SSadaf Ebrahimi 		insn->readerCursor += sizeof(type);                           \
323*9a0e4156SSadaf Ebrahimi 		return 0;                                                     \
324*9a0e4156SSadaf Ebrahimi 	}
325*9a0e4156SSadaf Ebrahimi 
326*9a0e4156SSadaf Ebrahimi /*
327*9a0e4156SSadaf Ebrahimi  * consume* - Use the reader function provided by the user to consume data
328*9a0e4156SSadaf Ebrahimi  *   values of various sizes from the instruction's memory and advance the
329*9a0e4156SSadaf Ebrahimi  *   cursor appropriately.  These readers perform endian conversion.
330*9a0e4156SSadaf Ebrahimi  *
331*9a0e4156SSadaf Ebrahimi  * @param insn    - See consumeByte().
332*9a0e4156SSadaf Ebrahimi  * @param ptr     - A pointer to a pre-allocated memory of appropriate size to
333*9a0e4156SSadaf Ebrahimi  *                  be populated with the data read.
334*9a0e4156SSadaf Ebrahimi  * @return        - See consumeByte().
335*9a0e4156SSadaf Ebrahimi  */
CONSUME_FUNC(consumeInt8,int8_t)336*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeInt8, int8_t)
337*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeInt16, int16_t)
338*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeInt32, int32_t)
339*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeUInt16, uint16_t)
340*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeUInt32, uint32_t)
341*9a0e4156SSadaf Ebrahimi CONSUME_FUNC(consumeUInt64, uint64_t)
342*9a0e4156SSadaf Ebrahimi 
343*9a0e4156SSadaf Ebrahimi /*
344*9a0e4156SSadaf Ebrahimi  * setPrefixPresent - Marks that a particular prefix is present at a particular
345*9a0e4156SSadaf Ebrahimi  *   location.
346*9a0e4156SSadaf Ebrahimi  *
347*9a0e4156SSadaf Ebrahimi  * @param insn      - The instruction to be marked as having the prefix.
348*9a0e4156SSadaf Ebrahimi  * @param prefix    - The prefix that is present.
349*9a0e4156SSadaf Ebrahimi  * @param location  - The location where the prefix is located (in the address
350*9a0e4156SSadaf Ebrahimi  *                    space of the instruction's reader).
351*9a0e4156SSadaf Ebrahimi  */
352*9a0e4156SSadaf Ebrahimi static void setPrefixPresent(struct InternalInstruction *insn, uint8_t prefix, uint64_t location)
353*9a0e4156SSadaf Ebrahimi {
354*9a0e4156SSadaf Ebrahimi 	switch (prefix) {
355*9a0e4156SSadaf Ebrahimi 	case 0x26:
356*9a0e4156SSadaf Ebrahimi 		insn->isPrefix26 = true;
357*9a0e4156SSadaf Ebrahimi 		insn->prefix26 = location;
358*9a0e4156SSadaf Ebrahimi 		break;
359*9a0e4156SSadaf Ebrahimi 	case 0x2e:
360*9a0e4156SSadaf Ebrahimi 		insn->isPrefix2e = true;
361*9a0e4156SSadaf Ebrahimi 		insn->prefix2e = location;
362*9a0e4156SSadaf Ebrahimi 		break;
363*9a0e4156SSadaf Ebrahimi 	case 0x36:
364*9a0e4156SSadaf Ebrahimi 		insn->isPrefix36 = true;
365*9a0e4156SSadaf Ebrahimi 		insn->prefix36 = location;
366*9a0e4156SSadaf Ebrahimi 		break;
367*9a0e4156SSadaf Ebrahimi 	case 0x3e:
368*9a0e4156SSadaf Ebrahimi 		insn->isPrefix3e = true;
369*9a0e4156SSadaf Ebrahimi 		insn->prefix3e = location;
370*9a0e4156SSadaf Ebrahimi 		break;
371*9a0e4156SSadaf Ebrahimi 	case 0x64:
372*9a0e4156SSadaf Ebrahimi 		insn->isPrefix64 = true;
373*9a0e4156SSadaf Ebrahimi 		insn->prefix64 = location;
374*9a0e4156SSadaf Ebrahimi 		break;
375*9a0e4156SSadaf Ebrahimi 	case 0x65:
376*9a0e4156SSadaf Ebrahimi 		insn->isPrefix65 = true;
377*9a0e4156SSadaf Ebrahimi 		insn->prefix65 = location;
378*9a0e4156SSadaf Ebrahimi 		break;
379*9a0e4156SSadaf Ebrahimi 	case 0x66:
380*9a0e4156SSadaf Ebrahimi 		insn->isPrefix66 = true;
381*9a0e4156SSadaf Ebrahimi 		insn->prefix66 = location;
382*9a0e4156SSadaf Ebrahimi 		break;
383*9a0e4156SSadaf Ebrahimi 	case 0x67:
384*9a0e4156SSadaf Ebrahimi 		insn->isPrefix67 = true;
385*9a0e4156SSadaf Ebrahimi 		insn->prefix67 = location;
386*9a0e4156SSadaf Ebrahimi 		break;
387*9a0e4156SSadaf Ebrahimi 	case 0xf0:
388*9a0e4156SSadaf Ebrahimi 		insn->isPrefixf0 = true;
389*9a0e4156SSadaf Ebrahimi 		insn->prefixf0 = location;
390*9a0e4156SSadaf Ebrahimi 		break;
391*9a0e4156SSadaf Ebrahimi 	case 0xf2:
392*9a0e4156SSadaf Ebrahimi 		insn->isPrefixf2 = true;
393*9a0e4156SSadaf Ebrahimi 		insn->prefixf2 = location;
394*9a0e4156SSadaf Ebrahimi 		break;
395*9a0e4156SSadaf Ebrahimi 	case 0xf3:
396*9a0e4156SSadaf Ebrahimi 		insn->isPrefixf3 = true;
397*9a0e4156SSadaf Ebrahimi 		insn->prefixf3 = location;
398*9a0e4156SSadaf Ebrahimi 		break;
399*9a0e4156SSadaf Ebrahimi 	default:
400*9a0e4156SSadaf Ebrahimi 		break;
401*9a0e4156SSadaf Ebrahimi 	}
402*9a0e4156SSadaf Ebrahimi }
403*9a0e4156SSadaf Ebrahimi 
404*9a0e4156SSadaf Ebrahimi /*
405*9a0e4156SSadaf Ebrahimi  * isPrefixAtLocation - Queries an instruction to determine whether a prefix is
406*9a0e4156SSadaf Ebrahimi  *   present at a given location.
407*9a0e4156SSadaf Ebrahimi  *
408*9a0e4156SSadaf Ebrahimi  * @param insn      - The instruction to be queried.
409*9a0e4156SSadaf Ebrahimi  * @param prefix    - The prefix.
410*9a0e4156SSadaf Ebrahimi  * @param location  - The location to query.
411*9a0e4156SSadaf Ebrahimi  * @return          - Whether the prefix is at that location.
412*9a0e4156SSadaf Ebrahimi  */
isPrefixAtLocation(struct InternalInstruction * insn,uint8_t prefix,uint64_t location)413*9a0e4156SSadaf Ebrahimi static bool isPrefixAtLocation(struct InternalInstruction *insn, uint8_t prefix,
414*9a0e4156SSadaf Ebrahimi 		uint64_t location)
415*9a0e4156SSadaf Ebrahimi {
416*9a0e4156SSadaf Ebrahimi 	switch (prefix) {
417*9a0e4156SSadaf Ebrahimi 	case 0x26:
418*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix26 && insn->prefix26 == location)
419*9a0e4156SSadaf Ebrahimi 			return true;
420*9a0e4156SSadaf Ebrahimi 		break;
421*9a0e4156SSadaf Ebrahimi 	case 0x2e:
422*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix2e && insn->prefix2e == location)
423*9a0e4156SSadaf Ebrahimi 			return true;
424*9a0e4156SSadaf Ebrahimi 		break;
425*9a0e4156SSadaf Ebrahimi 	case 0x36:
426*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix36 && insn->prefix36 == location)
427*9a0e4156SSadaf Ebrahimi 			return true;
428*9a0e4156SSadaf Ebrahimi 		break;
429*9a0e4156SSadaf Ebrahimi 	case 0x3e:
430*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix3e && insn->prefix3e == location)
431*9a0e4156SSadaf Ebrahimi 			return true;
432*9a0e4156SSadaf Ebrahimi 		break;
433*9a0e4156SSadaf Ebrahimi 	case 0x64:
434*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix64 && insn->prefix64 == location)
435*9a0e4156SSadaf Ebrahimi 			return true;
436*9a0e4156SSadaf Ebrahimi 		break;
437*9a0e4156SSadaf Ebrahimi 	case 0x65:
438*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix65 && insn->prefix65 == location)
439*9a0e4156SSadaf Ebrahimi 			return true;
440*9a0e4156SSadaf Ebrahimi 		break;
441*9a0e4156SSadaf Ebrahimi 	case 0x66:
442*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix66 && insn->prefix66 == location)
443*9a0e4156SSadaf Ebrahimi 			return true;
444*9a0e4156SSadaf Ebrahimi 		break;
445*9a0e4156SSadaf Ebrahimi 	case 0x67:
446*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix67 && insn->prefix67 == location)
447*9a0e4156SSadaf Ebrahimi 			return true;
448*9a0e4156SSadaf Ebrahimi 		break;
449*9a0e4156SSadaf Ebrahimi 	case 0xf0:
450*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefixf0 && insn->prefixf0 == location)
451*9a0e4156SSadaf Ebrahimi 			return true;
452*9a0e4156SSadaf Ebrahimi 		break;
453*9a0e4156SSadaf Ebrahimi 	case 0xf2:
454*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefixf2 && insn->prefixf2 == location)
455*9a0e4156SSadaf Ebrahimi 			return true;
456*9a0e4156SSadaf Ebrahimi 		break;
457*9a0e4156SSadaf Ebrahimi 	case 0xf3:
458*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefixf3 && insn->prefixf3 == location)
459*9a0e4156SSadaf Ebrahimi 			return true;
460*9a0e4156SSadaf Ebrahimi 		break;
461*9a0e4156SSadaf Ebrahimi 	default:
462*9a0e4156SSadaf Ebrahimi 		break;
463*9a0e4156SSadaf Ebrahimi 	}
464*9a0e4156SSadaf Ebrahimi 	return false;
465*9a0e4156SSadaf Ebrahimi }
466*9a0e4156SSadaf Ebrahimi 
467*9a0e4156SSadaf Ebrahimi /*
468*9a0e4156SSadaf Ebrahimi  * readPrefixes - Consumes all of an instruction's prefix bytes, and marks the
469*9a0e4156SSadaf Ebrahimi  *   instruction as having them.  Also sets the instruction's default operand,
470*9a0e4156SSadaf Ebrahimi  *   address, and other relevant data sizes to report operands correctly.
471*9a0e4156SSadaf Ebrahimi  *
472*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose prefixes are to be read.
473*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the instruction could be read until the end of the prefix
474*9a0e4156SSadaf Ebrahimi  *                bytes, and no prefixes conflicted; nonzero otherwise.
475*9a0e4156SSadaf Ebrahimi  */
readPrefixes(struct InternalInstruction * insn)476*9a0e4156SSadaf Ebrahimi static int readPrefixes(struct InternalInstruction *insn)
477*9a0e4156SSadaf Ebrahimi {
478*9a0e4156SSadaf Ebrahimi 	bool isPrefix = true;
479*9a0e4156SSadaf Ebrahimi 	uint64_t prefixLocation;
480*9a0e4156SSadaf Ebrahimi 	uint8_t byte = 0, nextByte;
481*9a0e4156SSadaf Ebrahimi 
482*9a0e4156SSadaf Ebrahimi 	bool hasAdSize = false;
483*9a0e4156SSadaf Ebrahimi 	bool hasOpSize = false;
484*9a0e4156SSadaf Ebrahimi 
485*9a0e4156SSadaf Ebrahimi 	//initialize to an impossible value
486*9a0e4156SSadaf Ebrahimi 	insn->necessaryPrefixLocation = insn->readerCursor - 1;
487*9a0e4156SSadaf Ebrahimi 	while (isPrefix) {
488*9a0e4156SSadaf Ebrahimi 		if (insn->mode == MODE_64BIT) {
489*9a0e4156SSadaf Ebrahimi 			// eliminate consecutive redundant REX bytes in front
490*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &byte))
491*9a0e4156SSadaf Ebrahimi 				return -1;
492*9a0e4156SSadaf Ebrahimi 
493*9a0e4156SSadaf Ebrahimi 			if ((byte & 0xf0) == 0x40) {
494*9a0e4156SSadaf Ebrahimi 				while(true) {
495*9a0e4156SSadaf Ebrahimi 					if (lookAtByte(insn, &byte))	// out of input code
496*9a0e4156SSadaf Ebrahimi 						return -1;
497*9a0e4156SSadaf Ebrahimi 					if ((byte & 0xf0) == 0x40) {
498*9a0e4156SSadaf Ebrahimi 						// another REX prefix, but we only remember the last one
499*9a0e4156SSadaf Ebrahimi 						if (consumeByte(insn, &byte))
500*9a0e4156SSadaf Ebrahimi 							return -1;
501*9a0e4156SSadaf Ebrahimi 					} else
502*9a0e4156SSadaf Ebrahimi 						break;
503*9a0e4156SSadaf Ebrahimi 				}
504*9a0e4156SSadaf Ebrahimi 
505*9a0e4156SSadaf Ebrahimi 				// recover the last REX byte if next byte is not a legacy prefix
506*9a0e4156SSadaf Ebrahimi 				switch (byte) {
507*9a0e4156SSadaf Ebrahimi 					case 0xf2:  /* REPNE/REPNZ */
508*9a0e4156SSadaf Ebrahimi 					case 0xf3:  /* REP or REPE/REPZ */
509*9a0e4156SSadaf Ebrahimi 					case 0xf0:  /* LOCK */
510*9a0e4156SSadaf Ebrahimi 					case 0x2e:  /* CS segment override -OR- Branch not taken */
511*9a0e4156SSadaf Ebrahimi 					case 0x36:  /* SS segment override -OR- Branch taken */
512*9a0e4156SSadaf Ebrahimi 					case 0x3e:  /* DS segment override */
513*9a0e4156SSadaf Ebrahimi 					case 0x26:  /* ES segment override */
514*9a0e4156SSadaf Ebrahimi 					case 0x64:  /* FS segment override */
515*9a0e4156SSadaf Ebrahimi 					case 0x65:  /* GS segment override */
516*9a0e4156SSadaf Ebrahimi 					case 0x66:  /* Operand-size override */
517*9a0e4156SSadaf Ebrahimi 					case 0x67:  /* Address-size override */
518*9a0e4156SSadaf Ebrahimi 						break;
519*9a0e4156SSadaf Ebrahimi 					default:    /* Not a prefix byte */
520*9a0e4156SSadaf Ebrahimi 						unconsumeByte(insn);
521*9a0e4156SSadaf Ebrahimi 						break;
522*9a0e4156SSadaf Ebrahimi 				}
523*9a0e4156SSadaf Ebrahimi 			} else {
524*9a0e4156SSadaf Ebrahimi 				unconsumeByte(insn);
525*9a0e4156SSadaf Ebrahimi 			}
526*9a0e4156SSadaf Ebrahimi 		}
527*9a0e4156SSadaf Ebrahimi 
528*9a0e4156SSadaf Ebrahimi 		prefixLocation = insn->readerCursor;
529*9a0e4156SSadaf Ebrahimi 
530*9a0e4156SSadaf Ebrahimi 		/* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
531*9a0e4156SSadaf Ebrahimi 		if (consumeByte(insn, &byte))
532*9a0e4156SSadaf Ebrahimi 			return -1;
533*9a0e4156SSadaf Ebrahimi 
534*9a0e4156SSadaf Ebrahimi 		if (insn->readerCursor - 1 == insn->startLocation
535*9a0e4156SSadaf Ebrahimi 				&& (byte == 0xf2 || byte == 0xf3)) {
536*9a0e4156SSadaf Ebrahimi 
537*9a0e4156SSadaf Ebrahimi 			if (lookAtByte(insn, &nextByte))
538*9a0e4156SSadaf Ebrahimi 				return -1;
539*9a0e4156SSadaf Ebrahimi 
540*9a0e4156SSadaf Ebrahimi 			/*
541*9a0e4156SSadaf Ebrahimi 			 * If the byte is 0xf2 or 0xf3, and any of the following conditions are
542*9a0e4156SSadaf Ebrahimi 			 * met:
543*9a0e4156SSadaf Ebrahimi 			 * - it is followed by a LOCK (0xf0) prefix
544*9a0e4156SSadaf Ebrahimi 			 * - it is followed by an xchg instruction
545*9a0e4156SSadaf Ebrahimi 			 * then it should be disassembled as a xacquire/xrelease not repne/rep.
546*9a0e4156SSadaf Ebrahimi 			 */
547*9a0e4156SSadaf Ebrahimi 			if (((nextByte == 0xf0) ||
548*9a0e4156SSadaf Ebrahimi 				((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90)))
549*9a0e4156SSadaf Ebrahimi 				insn->xAcquireRelease = true;
550*9a0e4156SSadaf Ebrahimi 			/*
551*9a0e4156SSadaf Ebrahimi 			 * Also if the byte is 0xf3, and the following condition is met:
552*9a0e4156SSadaf Ebrahimi 			 * - it is followed by a "mov mem, reg" (opcode 0x88/0x89) or
553*9a0e4156SSadaf Ebrahimi 			 *                       "mov mem, imm" (opcode 0xc6/0xc7) instructions.
554*9a0e4156SSadaf Ebrahimi 			 * then it should be disassembled as an xrelease not rep.
555*9a0e4156SSadaf Ebrahimi 			 */
556*9a0e4156SSadaf Ebrahimi 			if (byte == 0xf3 &&
557*9a0e4156SSadaf Ebrahimi 					(nextByte == 0x88 || nextByte == 0x89 ||
558*9a0e4156SSadaf Ebrahimi 					 nextByte == 0xc6 || nextByte == 0xc7))
559*9a0e4156SSadaf Ebrahimi 				insn->xAcquireRelease = true;
560*9a0e4156SSadaf Ebrahimi 
561*9a0e4156SSadaf Ebrahimi 			if (insn->mode == MODE_64BIT && (nextByte & 0xf0) == 0x40) {
562*9a0e4156SSadaf Ebrahimi 				if (consumeByte(insn, &nextByte))
563*9a0e4156SSadaf Ebrahimi 					return -1;
564*9a0e4156SSadaf Ebrahimi 				if (lookAtByte(insn, &nextByte))
565*9a0e4156SSadaf Ebrahimi 					return -1;
566*9a0e4156SSadaf Ebrahimi 				unconsumeByte(insn);
567*9a0e4156SSadaf Ebrahimi 			}
568*9a0e4156SSadaf Ebrahimi 		}
569*9a0e4156SSadaf Ebrahimi 
570*9a0e4156SSadaf Ebrahimi 		switch (byte) {
571*9a0e4156SSadaf Ebrahimi 			case 0xf2:  /* REPNE/REPNZ */
572*9a0e4156SSadaf Ebrahimi 			case 0xf3:  /* REP or REPE/REPZ */
573*9a0e4156SSadaf Ebrahimi 			case 0xf0:  /* LOCK */
574*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
575*9a0e4156SSadaf Ebrahimi 				insn->isPrefixf2 = false;
576*9a0e4156SSadaf Ebrahimi 				insn->isPrefixf3 = false;
577*9a0e4156SSadaf Ebrahimi 				insn->isPrefixf0 = false;
578*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
579*9a0e4156SSadaf Ebrahimi 				insn->prefix0 = byte;
580*9a0e4156SSadaf Ebrahimi 				break;
581*9a0e4156SSadaf Ebrahimi 			case 0x2e:  /* CS segment override -OR- Branch not taken */
582*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_CS;
583*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
584*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
585*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
586*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
587*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
588*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
589*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
590*9a0e4156SSadaf Ebrahimi 
591*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
592*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
593*9a0e4156SSadaf Ebrahimi 				break;
594*9a0e4156SSadaf Ebrahimi 			case 0x36:  /* SS segment override -OR- Branch taken */
595*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_SS;
596*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
597*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
598*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
599*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
600*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
601*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
602*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
603*9a0e4156SSadaf Ebrahimi 
604*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
605*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
606*9a0e4156SSadaf Ebrahimi 				break;
607*9a0e4156SSadaf Ebrahimi 			case 0x3e:  /* DS segment override */
608*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_DS;
609*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
610*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
611*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
612*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
613*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
614*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
615*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
616*9a0e4156SSadaf Ebrahimi 
617*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
618*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
619*9a0e4156SSadaf Ebrahimi 				break;
620*9a0e4156SSadaf Ebrahimi 			case 0x26:  /* ES segment override */
621*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_ES;
622*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
623*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
624*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
625*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
626*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
627*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
628*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
629*9a0e4156SSadaf Ebrahimi 
630*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
631*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
632*9a0e4156SSadaf Ebrahimi 				break;
633*9a0e4156SSadaf Ebrahimi 			case 0x64:  /* FS segment override */
634*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_FS;
635*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
636*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
637*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
638*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
639*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
640*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
641*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
642*9a0e4156SSadaf Ebrahimi 
643*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
644*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
645*9a0e4156SSadaf Ebrahimi 				break;
646*9a0e4156SSadaf Ebrahimi 			case 0x65:  /* GS segment override */
647*9a0e4156SSadaf Ebrahimi 				insn->segmentOverride = SEG_OVERRIDE_GS;
648*9a0e4156SSadaf Ebrahimi 				// only accept the last prefix
649*9a0e4156SSadaf Ebrahimi 				insn->isPrefix2e = false;
650*9a0e4156SSadaf Ebrahimi 				insn->isPrefix36 = false;
651*9a0e4156SSadaf Ebrahimi 				insn->isPrefix3e = false;
652*9a0e4156SSadaf Ebrahimi 				insn->isPrefix26 = false;
653*9a0e4156SSadaf Ebrahimi 				insn->isPrefix64 = false;
654*9a0e4156SSadaf Ebrahimi 				insn->isPrefix65 = false;
655*9a0e4156SSadaf Ebrahimi 
656*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
657*9a0e4156SSadaf Ebrahimi 				insn->prefix1 = byte;
658*9a0e4156SSadaf Ebrahimi 				break;
659*9a0e4156SSadaf Ebrahimi 			case 0x66:  /* Operand-size override */
660*9a0e4156SSadaf Ebrahimi 				hasOpSize = true;
661*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
662*9a0e4156SSadaf Ebrahimi 				insn->prefix2 = byte;
663*9a0e4156SSadaf Ebrahimi 				break;
664*9a0e4156SSadaf Ebrahimi 			case 0x67:  /* Address-size override */
665*9a0e4156SSadaf Ebrahimi 				hasAdSize = true;
666*9a0e4156SSadaf Ebrahimi 				setPrefixPresent(insn, byte, prefixLocation);
667*9a0e4156SSadaf Ebrahimi 				insn->prefix3 = byte;
668*9a0e4156SSadaf Ebrahimi 				break;
669*9a0e4156SSadaf Ebrahimi 			default:    /* Not a prefix byte */
670*9a0e4156SSadaf Ebrahimi 				isPrefix = false;
671*9a0e4156SSadaf Ebrahimi 				break;
672*9a0e4156SSadaf Ebrahimi 		}
673*9a0e4156SSadaf Ebrahimi 
674*9a0e4156SSadaf Ebrahimi 		//if (isPrefix)
675*9a0e4156SSadaf Ebrahimi 		//	dbgprintf(insn, "Found prefix 0x%hhx", byte);
676*9a0e4156SSadaf Ebrahimi 	}
677*9a0e4156SSadaf Ebrahimi 
678*9a0e4156SSadaf Ebrahimi 	insn->vectorExtensionType = TYPE_NO_VEX_XOP;
679*9a0e4156SSadaf Ebrahimi 
680*9a0e4156SSadaf Ebrahimi 
681*9a0e4156SSadaf Ebrahimi 	if (byte == 0x62) {
682*9a0e4156SSadaf Ebrahimi 		uint8_t byte1, byte2;
683*9a0e4156SSadaf Ebrahimi 
684*9a0e4156SSadaf Ebrahimi 		if (consumeByte(insn, &byte1)) {
685*9a0e4156SSadaf Ebrahimi 			//dbgprintf(insn, "Couldn't read second byte of EVEX prefix");
686*9a0e4156SSadaf Ebrahimi 			return -1;
687*9a0e4156SSadaf Ebrahimi 		}
688*9a0e4156SSadaf Ebrahimi 
689*9a0e4156SSadaf Ebrahimi 		if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
690*9a0e4156SSadaf Ebrahimi 				((~byte1 & 0xc) == 0xc)) {
691*9a0e4156SSadaf Ebrahimi 			if (lookAtByte(insn, &byte2)) {
692*9a0e4156SSadaf Ebrahimi 				//dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
693*9a0e4156SSadaf Ebrahimi 				return -1;
694*9a0e4156SSadaf Ebrahimi 			}
695*9a0e4156SSadaf Ebrahimi 
696*9a0e4156SSadaf Ebrahimi 			if ((byte2 & 0x4) == 0x4) {
697*9a0e4156SSadaf Ebrahimi 				insn->vectorExtensionType = TYPE_EVEX;
698*9a0e4156SSadaf Ebrahimi 			} else {
699*9a0e4156SSadaf Ebrahimi 				unconsumeByte(insn); /* unconsume byte1 */
700*9a0e4156SSadaf Ebrahimi 				unconsumeByte(insn); /* unconsume byte  */
701*9a0e4156SSadaf Ebrahimi 				insn->necessaryPrefixLocation = insn->readerCursor - 2;
702*9a0e4156SSadaf Ebrahimi 			}
703*9a0e4156SSadaf Ebrahimi 
704*9a0e4156SSadaf Ebrahimi 			if (insn->vectorExtensionType == TYPE_EVEX) {
705*9a0e4156SSadaf Ebrahimi 				insn->vectorExtensionPrefix[0] = byte;
706*9a0e4156SSadaf Ebrahimi 				insn->vectorExtensionPrefix[1] = byte1;
707*9a0e4156SSadaf Ebrahimi 
708*9a0e4156SSadaf Ebrahimi 				if (consumeByte(insn, &insn->vectorExtensionPrefix[2])) {
709*9a0e4156SSadaf Ebrahimi 					//dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
710*9a0e4156SSadaf Ebrahimi 					return -1;
711*9a0e4156SSadaf Ebrahimi 				}
712*9a0e4156SSadaf Ebrahimi 
713*9a0e4156SSadaf Ebrahimi 				if (consumeByte(insn, &insn->vectorExtensionPrefix[3])) {
714*9a0e4156SSadaf Ebrahimi 					//dbgprintf(insn, "Couldn't read fourth byte of EVEX prefix");
715*9a0e4156SSadaf Ebrahimi 					return -1;
716*9a0e4156SSadaf Ebrahimi 				}
717*9a0e4156SSadaf Ebrahimi 
718*9a0e4156SSadaf Ebrahimi 				/* We simulate the REX prefix for simplicity's sake */
719*9a0e4156SSadaf Ebrahimi 				if (insn->mode == MODE_64BIT) {
720*9a0e4156SSadaf Ebrahimi 					insn->rexPrefix = 0x40
721*9a0e4156SSadaf Ebrahimi 						| (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3)
722*9a0e4156SSadaf Ebrahimi 						| (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2)
723*9a0e4156SSadaf Ebrahimi 						| (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1)
724*9a0e4156SSadaf Ebrahimi 						| (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0);
725*9a0e4156SSadaf Ebrahimi 				}
726*9a0e4156SSadaf Ebrahimi 				switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
727*9a0e4156SSadaf Ebrahimi 					default:
728*9a0e4156SSadaf Ebrahimi 						break;
729*9a0e4156SSadaf Ebrahimi 					case VEX_PREFIX_66:
730*9a0e4156SSadaf Ebrahimi 						hasOpSize = true;
731*9a0e4156SSadaf Ebrahimi 						break;
732*9a0e4156SSadaf Ebrahimi 				}
733*9a0e4156SSadaf Ebrahimi 				//dbgprintf(insn, "Found EVEX prefix 0x%hhx 0x%hhx 0x%hhx 0x%hhx",
734*9a0e4156SSadaf Ebrahimi 				//		insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
735*9a0e4156SSadaf Ebrahimi 				//		insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]);
736*9a0e4156SSadaf Ebrahimi 			}
737*9a0e4156SSadaf Ebrahimi 		} else {
738*9a0e4156SSadaf Ebrahimi 			// BOUND instruction
739*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn); /* unconsume byte1 */
740*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn); /* unconsume byte */
741*9a0e4156SSadaf Ebrahimi 		}
742*9a0e4156SSadaf Ebrahimi 	} else if (byte == 0xc4) {
743*9a0e4156SSadaf Ebrahimi 		uint8_t byte1;
744*9a0e4156SSadaf Ebrahimi 
745*9a0e4156SSadaf Ebrahimi 		if (lookAtByte(insn, &byte1)) {
746*9a0e4156SSadaf Ebrahimi 			//dbgprintf(insn, "Couldn't read second byte of VEX");
747*9a0e4156SSadaf Ebrahimi 			return -1;
748*9a0e4156SSadaf Ebrahimi 		}
749*9a0e4156SSadaf Ebrahimi 
750*9a0e4156SSadaf Ebrahimi 		if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
751*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionType = TYPE_VEX_3B;
752*9a0e4156SSadaf Ebrahimi 			insn->necessaryPrefixLocation = insn->readerCursor - 1;
753*9a0e4156SSadaf Ebrahimi 		} else {
754*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn);
755*9a0e4156SSadaf Ebrahimi 			insn->necessaryPrefixLocation = insn->readerCursor - 1;
756*9a0e4156SSadaf Ebrahimi 		}
757*9a0e4156SSadaf Ebrahimi 
758*9a0e4156SSadaf Ebrahimi 		if (insn->vectorExtensionType == TYPE_VEX_3B) {
759*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionPrefix[0] = byte;
760*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
761*9a0e4156SSadaf Ebrahimi 				return -1;
762*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
763*9a0e4156SSadaf Ebrahimi 				return -1;
764*9a0e4156SSadaf Ebrahimi 
765*9a0e4156SSadaf Ebrahimi 			/* We simulate the REX prefix for simplicity's sake */
766*9a0e4156SSadaf Ebrahimi 			if (insn->mode == MODE_64BIT) {
767*9a0e4156SSadaf Ebrahimi 				insn->rexPrefix = 0x40
768*9a0e4156SSadaf Ebrahimi 					| (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3)
769*9a0e4156SSadaf Ebrahimi 					| (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2)
770*9a0e4156SSadaf Ebrahimi 					| (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1)
771*9a0e4156SSadaf Ebrahimi 					| (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);
772*9a0e4156SSadaf Ebrahimi 
773*9a0e4156SSadaf Ebrahimi 			}
774*9a0e4156SSadaf Ebrahimi 			switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
775*9a0e4156SSadaf Ebrahimi 				default:
776*9a0e4156SSadaf Ebrahimi 					break;
777*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
778*9a0e4156SSadaf Ebrahimi 					hasOpSize = true;
779*9a0e4156SSadaf Ebrahimi 					break;
780*9a0e4156SSadaf Ebrahimi 			}
781*9a0e4156SSadaf Ebrahimi 		}
782*9a0e4156SSadaf Ebrahimi 	} else if (byte == 0xc5) {
783*9a0e4156SSadaf Ebrahimi 		uint8_t byte1;
784*9a0e4156SSadaf Ebrahimi 
785*9a0e4156SSadaf Ebrahimi 		if (lookAtByte(insn, &byte1)) {
786*9a0e4156SSadaf Ebrahimi 			//dbgprintf(insn, "Couldn't read second byte of VEX");
787*9a0e4156SSadaf Ebrahimi 			return -1;
788*9a0e4156SSadaf Ebrahimi 		}
789*9a0e4156SSadaf Ebrahimi 
790*9a0e4156SSadaf Ebrahimi 		if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
791*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionType = TYPE_VEX_2B;
792*9a0e4156SSadaf Ebrahimi 		} else {
793*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn);
794*9a0e4156SSadaf Ebrahimi 		}
795*9a0e4156SSadaf Ebrahimi 
796*9a0e4156SSadaf Ebrahimi 		if (insn->vectorExtensionType == TYPE_VEX_2B) {
797*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionPrefix[0] = byte;
798*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
799*9a0e4156SSadaf Ebrahimi 				return -1;
800*9a0e4156SSadaf Ebrahimi 
801*9a0e4156SSadaf Ebrahimi 			if (insn->mode == MODE_64BIT) {
802*9a0e4156SSadaf Ebrahimi 				insn->rexPrefix = 0x40
803*9a0e4156SSadaf Ebrahimi 					| (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
804*9a0e4156SSadaf Ebrahimi 			}
805*9a0e4156SSadaf Ebrahimi 
806*9a0e4156SSadaf Ebrahimi 			switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
807*9a0e4156SSadaf Ebrahimi 				default:
808*9a0e4156SSadaf Ebrahimi 					break;
809*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
810*9a0e4156SSadaf Ebrahimi 					hasOpSize = true;
811*9a0e4156SSadaf Ebrahimi 					break;
812*9a0e4156SSadaf Ebrahimi 			}
813*9a0e4156SSadaf Ebrahimi 		}
814*9a0e4156SSadaf Ebrahimi 	} else if (byte == 0x8f) {
815*9a0e4156SSadaf Ebrahimi 		uint8_t byte1;
816*9a0e4156SSadaf Ebrahimi 
817*9a0e4156SSadaf Ebrahimi 		if (lookAtByte(insn, &byte1)) {
818*9a0e4156SSadaf Ebrahimi 			// dbgprintf(insn, "Couldn't read second byte of XOP");
819*9a0e4156SSadaf Ebrahimi 			return -1;
820*9a0e4156SSadaf Ebrahimi 		}
821*9a0e4156SSadaf Ebrahimi 
822*9a0e4156SSadaf Ebrahimi 		if ((byte1 & 0x38) != 0x0) { /* 0 in these 3 bits is a POP instruction. */
823*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionType = TYPE_XOP;
824*9a0e4156SSadaf Ebrahimi 			insn->necessaryPrefixLocation = insn->readerCursor - 1;
825*9a0e4156SSadaf Ebrahimi 		} else {
826*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn);
827*9a0e4156SSadaf Ebrahimi 			insn->necessaryPrefixLocation = insn->readerCursor - 1;
828*9a0e4156SSadaf Ebrahimi 		}
829*9a0e4156SSadaf Ebrahimi 
830*9a0e4156SSadaf Ebrahimi 		if (insn->vectorExtensionType == TYPE_XOP) {
831*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionPrefix[0] = byte;
832*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
833*9a0e4156SSadaf Ebrahimi 				return -1;
834*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
835*9a0e4156SSadaf Ebrahimi 				return -1;
836*9a0e4156SSadaf Ebrahimi 
837*9a0e4156SSadaf Ebrahimi 			/* We simulate the REX prefix for simplicity's sake */
838*9a0e4156SSadaf Ebrahimi 			if (insn->mode == MODE_64BIT) {
839*9a0e4156SSadaf Ebrahimi 				insn->rexPrefix = 0x40
840*9a0e4156SSadaf Ebrahimi 					| (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3)
841*9a0e4156SSadaf Ebrahimi 					| (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2)
842*9a0e4156SSadaf Ebrahimi 					| (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1)
843*9a0e4156SSadaf Ebrahimi 					| (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
844*9a0e4156SSadaf Ebrahimi 			}
845*9a0e4156SSadaf Ebrahimi 
846*9a0e4156SSadaf Ebrahimi 			switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
847*9a0e4156SSadaf Ebrahimi 				default:
848*9a0e4156SSadaf Ebrahimi 					break;
849*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
850*9a0e4156SSadaf Ebrahimi 					hasOpSize = true;
851*9a0e4156SSadaf Ebrahimi 					break;
852*9a0e4156SSadaf Ebrahimi 			}
853*9a0e4156SSadaf Ebrahimi 		}
854*9a0e4156SSadaf Ebrahimi 	} else {
855*9a0e4156SSadaf Ebrahimi 		if (insn->mode == MODE_64BIT) {
856*9a0e4156SSadaf Ebrahimi 			if ((byte & 0xf0) == 0x40) {
857*9a0e4156SSadaf Ebrahimi 				uint8_t opcodeByte;
858*9a0e4156SSadaf Ebrahimi 
859*9a0e4156SSadaf Ebrahimi 				while(true) {
860*9a0e4156SSadaf Ebrahimi 					if (lookAtByte(insn, &opcodeByte))	// out of input code
861*9a0e4156SSadaf Ebrahimi 						return -1;
862*9a0e4156SSadaf Ebrahimi 					if ((opcodeByte & 0xf0) == 0x40) {
863*9a0e4156SSadaf Ebrahimi 						// another REX prefix, but we only remember the last one
864*9a0e4156SSadaf Ebrahimi 						if (consumeByte(insn, &byte))
865*9a0e4156SSadaf Ebrahimi 							return -1;
866*9a0e4156SSadaf Ebrahimi 					} else
867*9a0e4156SSadaf Ebrahimi 						break;
868*9a0e4156SSadaf Ebrahimi 				}
869*9a0e4156SSadaf Ebrahimi 
870*9a0e4156SSadaf Ebrahimi 				insn->rexPrefix = byte;
871*9a0e4156SSadaf Ebrahimi 				insn->necessaryPrefixLocation = insn->readerCursor - 2;
872*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
873*9a0e4156SSadaf Ebrahimi 			} else {
874*9a0e4156SSadaf Ebrahimi 				unconsumeByte(insn);
875*9a0e4156SSadaf Ebrahimi 				insn->necessaryPrefixLocation = insn->readerCursor - 1;
876*9a0e4156SSadaf Ebrahimi 			}
877*9a0e4156SSadaf Ebrahimi 		} else {
878*9a0e4156SSadaf Ebrahimi 			unconsumeByte(insn);
879*9a0e4156SSadaf Ebrahimi 			insn->necessaryPrefixLocation = insn->readerCursor - 1;
880*9a0e4156SSadaf Ebrahimi 		}
881*9a0e4156SSadaf Ebrahimi 	}
882*9a0e4156SSadaf Ebrahimi 
883*9a0e4156SSadaf Ebrahimi 	if (insn->mode == MODE_16BIT) {
884*9a0e4156SSadaf Ebrahimi 		insn->registerSize       = (hasOpSize ? 4 : 2);
885*9a0e4156SSadaf Ebrahimi 		insn->addressSize        = (hasAdSize ? 4 : 2);
886*9a0e4156SSadaf Ebrahimi 		insn->displacementSize   = (hasAdSize ? 4 : 2);
887*9a0e4156SSadaf Ebrahimi 		insn->immediateSize      = (hasOpSize ? 4 : 2);
888*9a0e4156SSadaf Ebrahimi 		insn->immSize = (hasOpSize ? 4 : 2);
889*9a0e4156SSadaf Ebrahimi 	} else if (insn->mode == MODE_32BIT) {
890*9a0e4156SSadaf Ebrahimi 		insn->registerSize       = (hasOpSize ? 2 : 4);
891*9a0e4156SSadaf Ebrahimi 		insn->addressSize        = (hasAdSize ? 2 : 4);
892*9a0e4156SSadaf Ebrahimi 		insn->displacementSize   = (hasAdSize ? 2 : 4);
893*9a0e4156SSadaf Ebrahimi 		insn->immediateSize      = (hasOpSize ? 2 : 4);
894*9a0e4156SSadaf Ebrahimi 		insn->immSize = (hasOpSize ? 2 : 4);
895*9a0e4156SSadaf Ebrahimi 	} else if (insn->mode == MODE_64BIT) {
896*9a0e4156SSadaf Ebrahimi 		if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
897*9a0e4156SSadaf Ebrahimi 			insn->registerSize       = 8;
898*9a0e4156SSadaf Ebrahimi 			insn->addressSize        = (hasAdSize ? 4 : 8);
899*9a0e4156SSadaf Ebrahimi 			insn->displacementSize   = 4;
900*9a0e4156SSadaf Ebrahimi 			insn->immediateSize      = 4;
901*9a0e4156SSadaf Ebrahimi 			insn->immSize      = 4;
902*9a0e4156SSadaf Ebrahimi 		} else if (insn->rexPrefix) {
903*9a0e4156SSadaf Ebrahimi 			insn->registerSize       = (hasOpSize ? 2 : 4);
904*9a0e4156SSadaf Ebrahimi 			insn->addressSize        = (hasAdSize ? 4 : 8);
905*9a0e4156SSadaf Ebrahimi 			insn->displacementSize   = (hasOpSize ? 2 : 4);
906*9a0e4156SSadaf Ebrahimi 			insn->immediateSize      = (hasOpSize ? 2 : 4);
907*9a0e4156SSadaf Ebrahimi 			insn->immSize      = (hasOpSize ? 2 : 4);
908*9a0e4156SSadaf Ebrahimi 		} else {
909*9a0e4156SSadaf Ebrahimi 			insn->registerSize       = (hasOpSize ? 2 : 4);
910*9a0e4156SSadaf Ebrahimi 			insn->addressSize        = (hasAdSize ? 4 : 8);
911*9a0e4156SSadaf Ebrahimi 			insn->displacementSize   = (hasOpSize ? 2 : 4);
912*9a0e4156SSadaf Ebrahimi 			insn->immediateSize      = (hasOpSize ? 2 : 4);
913*9a0e4156SSadaf Ebrahimi 			insn->immSize      = (hasOpSize ? 4 : 8);
914*9a0e4156SSadaf Ebrahimi 		}
915*9a0e4156SSadaf Ebrahimi 	}
916*9a0e4156SSadaf Ebrahimi 
917*9a0e4156SSadaf Ebrahimi 	return 0;
918*9a0e4156SSadaf Ebrahimi }
919*9a0e4156SSadaf Ebrahimi 
920*9a0e4156SSadaf Ebrahimi static int readModRM(struct InternalInstruction *insn);
921*9a0e4156SSadaf Ebrahimi 
922*9a0e4156SSadaf Ebrahimi /*
923*9a0e4156SSadaf Ebrahimi  * readOpcode - Reads the opcode (excepting the ModR/M byte in the case of
924*9a0e4156SSadaf Ebrahimi  *   extended or escape opcodes).
925*9a0e4156SSadaf Ebrahimi  *
926*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose opcode is to be read.
927*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the opcode could be read successfully; nonzero otherwise.
928*9a0e4156SSadaf Ebrahimi  */
readOpcode(struct InternalInstruction * insn)929*9a0e4156SSadaf Ebrahimi static int readOpcode(struct InternalInstruction *insn)
930*9a0e4156SSadaf Ebrahimi {
931*9a0e4156SSadaf Ebrahimi 	/* Determine the length of the primary opcode */
932*9a0e4156SSadaf Ebrahimi 	uint8_t current;
933*9a0e4156SSadaf Ebrahimi 
934*9a0e4156SSadaf Ebrahimi 	// printf(">>> readOpcode() = %x\n", insn->readerCursor);
935*9a0e4156SSadaf Ebrahimi 
936*9a0e4156SSadaf Ebrahimi 	insn->opcodeType = ONEBYTE;
937*9a0e4156SSadaf Ebrahimi 	insn->firstByte = 0x00;
938*9a0e4156SSadaf Ebrahimi 
939*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType == TYPE_EVEX) {
940*9a0e4156SSadaf Ebrahimi 		switch (mmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
941*9a0e4156SSadaf Ebrahimi 			default:
942*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "Unhandled mm field for instruction (0x%hhx)",
943*9a0e4156SSadaf Ebrahimi 				// 		mmFromEVEX2of4(insn->vectorExtensionPrefix[1]));
944*9a0e4156SSadaf Ebrahimi 				return -1;
945*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F:
946*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = TWOBYTE;
947*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
948*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F38:
949*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = THREEBYTE_38;
950*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
951*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F3A:
952*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = THREEBYTE_3A;
953*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
954*9a0e4156SSadaf Ebrahimi 		}
955*9a0e4156SSadaf Ebrahimi 	} else if (insn->vectorExtensionType == TYPE_VEX_3B) {
956*9a0e4156SSadaf Ebrahimi 		switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
957*9a0e4156SSadaf Ebrahimi 			default:
958*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
959*9a0e4156SSadaf Ebrahimi 				//		mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
960*9a0e4156SSadaf Ebrahimi 				return -1;
961*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F:
962*9a0e4156SSadaf Ebrahimi 				insn->twoByteEscape = 0x0f;
963*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = TWOBYTE;
964*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
965*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F38:
966*9a0e4156SSadaf Ebrahimi 				insn->twoByteEscape = 0x0f;
967*9a0e4156SSadaf Ebrahimi 				insn->threeByteEscape = 0x38;
968*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = THREEBYTE_38;
969*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
970*9a0e4156SSadaf Ebrahimi 			case VEX_LOB_0F3A:
971*9a0e4156SSadaf Ebrahimi 				insn->twoByteEscape = 0x0f;
972*9a0e4156SSadaf Ebrahimi 				insn->threeByteEscape = 0x3a;
973*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = THREEBYTE_3A;
974*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
975*9a0e4156SSadaf Ebrahimi 		}
976*9a0e4156SSadaf Ebrahimi 	} else if (insn->vectorExtensionType == TYPE_VEX_2B) {
977*9a0e4156SSadaf Ebrahimi 		insn->twoByteEscape = 0x0f;
978*9a0e4156SSadaf Ebrahimi 		insn->opcodeType = TWOBYTE;
979*9a0e4156SSadaf Ebrahimi 		return consumeByte(insn, &insn->opcode);
980*9a0e4156SSadaf Ebrahimi 	} else if (insn->vectorExtensionType == TYPE_XOP) {
981*9a0e4156SSadaf Ebrahimi 		switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
982*9a0e4156SSadaf Ebrahimi 			default:
983*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
984*9a0e4156SSadaf Ebrahimi 				// 		mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
985*9a0e4156SSadaf Ebrahimi 				return -1;
986*9a0e4156SSadaf Ebrahimi 			case XOP_MAP_SELECT_8:
987*9a0e4156SSadaf Ebrahimi 				// FIXME: twoByteEscape?
988*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = XOP8_MAP;
989*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
990*9a0e4156SSadaf Ebrahimi 			case XOP_MAP_SELECT_9:
991*9a0e4156SSadaf Ebrahimi 				// FIXME: twoByteEscape?
992*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = XOP9_MAP;
993*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
994*9a0e4156SSadaf Ebrahimi 			case XOP_MAP_SELECT_A:
995*9a0e4156SSadaf Ebrahimi 				// FIXME: twoByteEscape?
996*9a0e4156SSadaf Ebrahimi 				insn->opcodeType = XOPA_MAP;
997*9a0e4156SSadaf Ebrahimi 				return consumeByte(insn, &insn->opcode);
998*9a0e4156SSadaf Ebrahimi 		}
999*9a0e4156SSadaf Ebrahimi 	}
1000*9a0e4156SSadaf Ebrahimi 
1001*9a0e4156SSadaf Ebrahimi 	if (consumeByte(insn, &current))
1002*9a0e4156SSadaf Ebrahimi 		return -1;
1003*9a0e4156SSadaf Ebrahimi 
1004*9a0e4156SSadaf Ebrahimi 	// save this first byte for MOVcr, MOVdr, MOVrc, MOVrd
1005*9a0e4156SSadaf Ebrahimi 	insn->firstByte = current;
1006*9a0e4156SSadaf Ebrahimi 
1007*9a0e4156SSadaf Ebrahimi 	if (current == 0x0f) {
1008*9a0e4156SSadaf Ebrahimi 		// dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current);
1009*9a0e4156SSadaf Ebrahimi 
1010*9a0e4156SSadaf Ebrahimi 		insn->twoByteEscape = current;
1011*9a0e4156SSadaf Ebrahimi 
1012*9a0e4156SSadaf Ebrahimi 		if (consumeByte(insn, &current))
1013*9a0e4156SSadaf Ebrahimi 			return -1;
1014*9a0e4156SSadaf Ebrahimi 
1015*9a0e4156SSadaf Ebrahimi 		if (current == 0x38) {
1016*9a0e4156SSadaf Ebrahimi 			// dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
1017*9a0e4156SSadaf Ebrahimi 
1018*9a0e4156SSadaf Ebrahimi 			insn->threeByteEscape = current;
1019*9a0e4156SSadaf Ebrahimi 
1020*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &current))
1021*9a0e4156SSadaf Ebrahimi 				return -1;
1022*9a0e4156SSadaf Ebrahimi 
1023*9a0e4156SSadaf Ebrahimi 			insn->opcodeType = THREEBYTE_38;
1024*9a0e4156SSadaf Ebrahimi 		} else if (current == 0x3a) {
1025*9a0e4156SSadaf Ebrahimi 			// dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
1026*9a0e4156SSadaf Ebrahimi 
1027*9a0e4156SSadaf Ebrahimi 			insn->threeByteEscape = current;
1028*9a0e4156SSadaf Ebrahimi 
1029*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &current))
1030*9a0e4156SSadaf Ebrahimi 				return -1;
1031*9a0e4156SSadaf Ebrahimi 
1032*9a0e4156SSadaf Ebrahimi 			insn->opcodeType = THREEBYTE_3A;
1033*9a0e4156SSadaf Ebrahimi 		} else {
1034*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_X86_REDUCE
1035*9a0e4156SSadaf Ebrahimi 			switch(current) {
1036*9a0e4156SSadaf Ebrahimi 				default:
1037*9a0e4156SSadaf Ebrahimi 					// dbgprintf(insn, "Didn't find a three-byte escape prefix");
1038*9a0e4156SSadaf Ebrahimi 					insn->opcodeType = TWOBYTE;
1039*9a0e4156SSadaf Ebrahimi 					break;
1040*9a0e4156SSadaf Ebrahimi 				case 0x0e:	// HACK for femms. to be handled properly in next version 3.x
1041*9a0e4156SSadaf Ebrahimi 					insn->opcodeType = T3DNOW_MAP;
1042*9a0e4156SSadaf Ebrahimi 					// this encode does not have ModRM
1043*9a0e4156SSadaf Ebrahimi 					insn->consumedModRM = true;
1044*9a0e4156SSadaf Ebrahimi 					break;
1045*9a0e4156SSadaf Ebrahimi 				case 0x0f:
1046*9a0e4156SSadaf Ebrahimi 					// 3DNow instruction has weird format: ModRM/SIB/displacement + opcode
1047*9a0e4156SSadaf Ebrahimi 					if (readModRM(insn))
1048*9a0e4156SSadaf Ebrahimi 						return -1;
1049*9a0e4156SSadaf Ebrahimi 					// next is 3DNow opcode
1050*9a0e4156SSadaf Ebrahimi 					if (consumeByte(insn, &current))
1051*9a0e4156SSadaf Ebrahimi 						return -1;
1052*9a0e4156SSadaf Ebrahimi 					insn->opcodeType = T3DNOW_MAP;
1053*9a0e4156SSadaf Ebrahimi 					break;
1054*9a0e4156SSadaf Ebrahimi 			}
1055*9a0e4156SSadaf Ebrahimi #endif
1056*9a0e4156SSadaf Ebrahimi 		}
1057*9a0e4156SSadaf Ebrahimi 	}
1058*9a0e4156SSadaf Ebrahimi 
1059*9a0e4156SSadaf Ebrahimi 	/*
1060*9a0e4156SSadaf Ebrahimi 	 * At this point we have consumed the full opcode.
1061*9a0e4156SSadaf Ebrahimi 	 * Anything we consume from here on must be unconsumed.
1062*9a0e4156SSadaf Ebrahimi 	 */
1063*9a0e4156SSadaf Ebrahimi 
1064*9a0e4156SSadaf Ebrahimi 	insn->opcode = current;
1065*9a0e4156SSadaf Ebrahimi 
1066*9a0e4156SSadaf Ebrahimi 	return 0;
1067*9a0e4156SSadaf Ebrahimi }
1068*9a0e4156SSadaf Ebrahimi 
1069*9a0e4156SSadaf Ebrahimi // Hacky for FEMMS
1070*9a0e4156SSadaf Ebrahimi #define GET_INSTRINFO_ENUM
1071*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_X86_REDUCE
1072*9a0e4156SSadaf Ebrahimi #include "X86GenInstrInfo.inc"
1073*9a0e4156SSadaf Ebrahimi #else
1074*9a0e4156SSadaf Ebrahimi #include "X86GenInstrInfo_reduce.inc"
1075*9a0e4156SSadaf Ebrahimi #endif
1076*9a0e4156SSadaf Ebrahimi 
1077*9a0e4156SSadaf Ebrahimi /*
1078*9a0e4156SSadaf Ebrahimi  * getIDWithAttrMask - Determines the ID of an instruction, consuming
1079*9a0e4156SSadaf Ebrahimi  *   the ModR/M byte as appropriate for extended and escape opcodes,
1080*9a0e4156SSadaf Ebrahimi  *   and using a supplied attribute mask.
1081*9a0e4156SSadaf Ebrahimi  *
1082*9a0e4156SSadaf Ebrahimi  * @param instructionID - A pointer whose target is filled in with the ID of the
1083*9a0e4156SSadaf Ebrahimi  *                        instruction.
1084*9a0e4156SSadaf Ebrahimi  * @param insn          - The instruction whose ID is to be determined.
1085*9a0e4156SSadaf Ebrahimi  * @param attrMask      - The attribute mask to search.
1086*9a0e4156SSadaf Ebrahimi  * @return              - 0 if the ModR/M could be read when needed or was not
1087*9a0e4156SSadaf Ebrahimi  *                        needed; nonzero otherwise.
1088*9a0e4156SSadaf Ebrahimi  */
getIDWithAttrMask(uint16_t * instructionID,struct InternalInstruction * insn,uint16_t attrMask)1089*9a0e4156SSadaf Ebrahimi static int getIDWithAttrMask(uint16_t *instructionID,
1090*9a0e4156SSadaf Ebrahimi 		struct InternalInstruction *insn,
1091*9a0e4156SSadaf Ebrahimi 		uint16_t attrMask)
1092*9a0e4156SSadaf Ebrahimi {
1093*9a0e4156SSadaf Ebrahimi 	bool hasModRMExtension;
1094*9a0e4156SSadaf Ebrahimi 
1095*9a0e4156SSadaf Ebrahimi 	InstructionContext instructionClass;
1096*9a0e4156SSadaf Ebrahimi 
1097*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_X86_REDUCE
1098*9a0e4156SSadaf Ebrahimi 	// HACK for femms. to be handled properly in next version 3.x
1099*9a0e4156SSadaf Ebrahimi 	if (insn->opcode == 0x0e && insn->opcodeType == T3DNOW_MAP) {
1100*9a0e4156SSadaf Ebrahimi 		*instructionID = X86_FEMMS;
1101*9a0e4156SSadaf Ebrahimi 		return 0;
1102*9a0e4156SSadaf Ebrahimi 	}
1103*9a0e4156SSadaf Ebrahimi #endif
1104*9a0e4156SSadaf Ebrahimi 
1105*9a0e4156SSadaf Ebrahimi 	if (insn->opcodeType == T3DNOW_MAP)
1106*9a0e4156SSadaf Ebrahimi 		instructionClass = IC_OF;
1107*9a0e4156SSadaf Ebrahimi 	else
1108*9a0e4156SSadaf Ebrahimi 		instructionClass = contextForAttrs(attrMask);
1109*9a0e4156SSadaf Ebrahimi 
1110*9a0e4156SSadaf Ebrahimi 	hasModRMExtension = modRMRequired(insn->opcodeType,
1111*9a0e4156SSadaf Ebrahimi 			instructionClass,
1112*9a0e4156SSadaf Ebrahimi 			insn->opcode) != 0;
1113*9a0e4156SSadaf Ebrahimi 
1114*9a0e4156SSadaf Ebrahimi 	if (hasModRMExtension) {
1115*9a0e4156SSadaf Ebrahimi 		if (readModRM(insn))
1116*9a0e4156SSadaf Ebrahimi 			return -1;
1117*9a0e4156SSadaf Ebrahimi 
1118*9a0e4156SSadaf Ebrahimi 		*instructionID = decode(insn->opcodeType,
1119*9a0e4156SSadaf Ebrahimi 				instructionClass,
1120*9a0e4156SSadaf Ebrahimi 				insn->opcode,
1121*9a0e4156SSadaf Ebrahimi 				insn->modRM);
1122*9a0e4156SSadaf Ebrahimi 	} else {
1123*9a0e4156SSadaf Ebrahimi 		*instructionID = decode(insn->opcodeType,
1124*9a0e4156SSadaf Ebrahimi 				instructionClass,
1125*9a0e4156SSadaf Ebrahimi 				insn->opcode,
1126*9a0e4156SSadaf Ebrahimi 				0);
1127*9a0e4156SSadaf Ebrahimi 	}
1128*9a0e4156SSadaf Ebrahimi 
1129*9a0e4156SSadaf Ebrahimi 	return 0;
1130*9a0e4156SSadaf Ebrahimi }
1131*9a0e4156SSadaf Ebrahimi 
1132*9a0e4156SSadaf Ebrahimi /*
1133*9a0e4156SSadaf Ebrahimi  * is16BitEquivalent - Determines whether two instruction names refer to
1134*9a0e4156SSadaf Ebrahimi  * equivalent instructions but one is 16-bit whereas the other is not.
1135*9a0e4156SSadaf Ebrahimi  *
1136*9a0e4156SSadaf Ebrahimi  * @param orig  - The instruction ID that is not 16-bit
1137*9a0e4156SSadaf Ebrahimi  * @param equiv - The instruction ID that is 16-bit
1138*9a0e4156SSadaf Ebrahimi  */
is16BitEquivalent(unsigned orig,unsigned equiv)1139*9a0e4156SSadaf Ebrahimi static bool is16BitEquivalent(unsigned orig, unsigned equiv)
1140*9a0e4156SSadaf Ebrahimi {
1141*9a0e4156SSadaf Ebrahimi 	size_t i;
1142*9a0e4156SSadaf Ebrahimi 	uint16_t idx;
1143*9a0e4156SSadaf Ebrahimi 
1144*9a0e4156SSadaf Ebrahimi 	if ((idx = x86_16_bit_eq_lookup[orig]) != 0) {
1145*9a0e4156SSadaf Ebrahimi 		for (i = idx - 1; i < ARR_SIZE(x86_16_bit_eq_tbl) && x86_16_bit_eq_tbl[i].first == orig; i++) {
1146*9a0e4156SSadaf Ebrahimi 			if (x86_16_bit_eq_tbl[i].second == equiv)
1147*9a0e4156SSadaf Ebrahimi 				return true;
1148*9a0e4156SSadaf Ebrahimi 		}
1149*9a0e4156SSadaf Ebrahimi 	}
1150*9a0e4156SSadaf Ebrahimi 
1151*9a0e4156SSadaf Ebrahimi 	return false;
1152*9a0e4156SSadaf Ebrahimi }
1153*9a0e4156SSadaf Ebrahimi 
1154*9a0e4156SSadaf Ebrahimi /*
1155*9a0e4156SSadaf Ebrahimi  * is64Bit - Determines whether this instruction is a 64-bit instruction.
1156*9a0e4156SSadaf Ebrahimi  *
1157*9a0e4156SSadaf Ebrahimi  * @param name - The instruction that is not 16-bit
1158*9a0e4156SSadaf Ebrahimi  */
is64Bit(uint16_t id)1159*9a0e4156SSadaf Ebrahimi static bool is64Bit(uint16_t id)
1160*9a0e4156SSadaf Ebrahimi {
1161*9a0e4156SSadaf Ebrahimi 	return is_64bit_insn[id];
1162*9a0e4156SSadaf Ebrahimi }
1163*9a0e4156SSadaf Ebrahimi 
1164*9a0e4156SSadaf Ebrahimi /*
1165*9a0e4156SSadaf Ebrahimi  * getID - Determines the ID of an instruction, consuming the ModR/M byte as
1166*9a0e4156SSadaf Ebrahimi  *   appropriate for extended and escape opcodes.  Determines the attributes and
1167*9a0e4156SSadaf Ebrahimi  *   context for the instruction before doing so.
1168*9a0e4156SSadaf Ebrahimi  *
1169*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose ID is to be determined.
1170*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the ModR/M could be read when needed or was not needed;
1171*9a0e4156SSadaf Ebrahimi  *                nonzero otherwise.
1172*9a0e4156SSadaf Ebrahimi  */
getID(struct InternalInstruction * insn)1173*9a0e4156SSadaf Ebrahimi static int getID(struct InternalInstruction *insn)
1174*9a0e4156SSadaf Ebrahimi {
1175*9a0e4156SSadaf Ebrahimi 	uint16_t attrMask;
1176*9a0e4156SSadaf Ebrahimi 	uint16_t instructionID;
1177*9a0e4156SSadaf Ebrahimi 
1178*9a0e4156SSadaf Ebrahimi 	// printf(">>> getID()\n");
1179*9a0e4156SSadaf Ebrahimi 	attrMask = ATTR_NONE;
1180*9a0e4156SSadaf Ebrahimi 
1181*9a0e4156SSadaf Ebrahimi 	if (insn->mode == MODE_64BIT)
1182*9a0e4156SSadaf Ebrahimi 		attrMask |= ATTR_64BIT;
1183*9a0e4156SSadaf Ebrahimi 
1184*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
1185*9a0e4156SSadaf Ebrahimi 		attrMask |= (insn->vectorExtensionType == TYPE_EVEX) ? ATTR_EVEX : ATTR_VEX;
1186*9a0e4156SSadaf Ebrahimi 
1187*9a0e4156SSadaf Ebrahimi 		if (insn->vectorExtensionType == TYPE_EVEX) {
1188*9a0e4156SSadaf Ebrahimi 			switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
1189*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
1190*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_OPSIZE;
1191*9a0e4156SSadaf Ebrahimi 					break;
1192*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F3:
1193*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XS;
1194*9a0e4156SSadaf Ebrahimi 					break;
1195*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F2:
1196*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XD;
1197*9a0e4156SSadaf Ebrahimi 					break;
1198*9a0e4156SSadaf Ebrahimi 			}
1199*9a0e4156SSadaf Ebrahimi 
1200*9a0e4156SSadaf Ebrahimi 			if (zFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1201*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_EVEXKZ;
1202*9a0e4156SSadaf Ebrahimi 			if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1203*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_EVEXB;
1204*9a0e4156SSadaf Ebrahimi 			if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1205*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_EVEXK;
1206*9a0e4156SSadaf Ebrahimi 			if (lFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1207*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_EVEXL;
1208*9a0e4156SSadaf Ebrahimi 			if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
1209*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_EVEXL2;
1210*9a0e4156SSadaf Ebrahimi 		} else if (insn->vectorExtensionType == TYPE_VEX_3B) {
1211*9a0e4156SSadaf Ebrahimi 			switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
1212*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
1213*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_OPSIZE;
1214*9a0e4156SSadaf Ebrahimi 					break;
1215*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F3:
1216*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XS;
1217*9a0e4156SSadaf Ebrahimi 					break;
1218*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F2:
1219*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XD;
1220*9a0e4156SSadaf Ebrahimi 					break;
1221*9a0e4156SSadaf Ebrahimi 			}
1222*9a0e4156SSadaf Ebrahimi 
1223*9a0e4156SSadaf Ebrahimi 			if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
1224*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_VEXL;
1225*9a0e4156SSadaf Ebrahimi 		} else if (insn->vectorExtensionType == TYPE_VEX_2B) {
1226*9a0e4156SSadaf Ebrahimi 			switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
1227*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
1228*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_OPSIZE;
1229*9a0e4156SSadaf Ebrahimi 					break;
1230*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F3:
1231*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XS;
1232*9a0e4156SSadaf Ebrahimi 					break;
1233*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F2:
1234*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XD;
1235*9a0e4156SSadaf Ebrahimi 					break;
1236*9a0e4156SSadaf Ebrahimi 			}
1237*9a0e4156SSadaf Ebrahimi 
1238*9a0e4156SSadaf Ebrahimi 			if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
1239*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_VEXL;
1240*9a0e4156SSadaf Ebrahimi 		} else if (insn->vectorExtensionType == TYPE_XOP) {
1241*9a0e4156SSadaf Ebrahimi 			switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
1242*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_66:
1243*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_OPSIZE;
1244*9a0e4156SSadaf Ebrahimi 					break;
1245*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F3:
1246*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XS;
1247*9a0e4156SSadaf Ebrahimi 					break;
1248*9a0e4156SSadaf Ebrahimi 				case VEX_PREFIX_F2:
1249*9a0e4156SSadaf Ebrahimi 					attrMask |= ATTR_XD;
1250*9a0e4156SSadaf Ebrahimi 					break;
1251*9a0e4156SSadaf Ebrahimi 			}
1252*9a0e4156SSadaf Ebrahimi 
1253*9a0e4156SSadaf Ebrahimi 			if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
1254*9a0e4156SSadaf Ebrahimi 				attrMask |= ATTR_VEXL;
1255*9a0e4156SSadaf Ebrahimi 		} else {
1256*9a0e4156SSadaf Ebrahimi 			return -1;
1257*9a0e4156SSadaf Ebrahimi 		}
1258*9a0e4156SSadaf Ebrahimi 	} else {
1259*9a0e4156SSadaf Ebrahimi 		if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) {
1260*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_OPSIZE;
1261*9a0e4156SSadaf Ebrahimi 		} else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) {
1262*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_ADSIZE;
1263*9a0e4156SSadaf Ebrahimi 		} else if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) {
1264*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_XS;
1265*9a0e4156SSadaf Ebrahimi 		} else if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) {
1266*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_XD;
1267*9a0e4156SSadaf Ebrahimi 		}
1268*9a0e4156SSadaf Ebrahimi 	}
1269*9a0e4156SSadaf Ebrahimi 
1270*9a0e4156SSadaf Ebrahimi 	if (insn->rexPrefix & 0x08)
1271*9a0e4156SSadaf Ebrahimi 		attrMask |= ATTR_REXW;
1272*9a0e4156SSadaf Ebrahimi 
1273*9a0e4156SSadaf Ebrahimi 	/*
1274*9a0e4156SSadaf Ebrahimi 	 * JCXZ/JECXZ need special handling for 16-bit mode because the meaning
1275*9a0e4156SSadaf Ebrahimi 	 * of the AdSize prefix is inverted w.r.t. 32-bit mode.
1276*9a0e4156SSadaf Ebrahimi 	 */
1277*9a0e4156SSadaf Ebrahimi 	if (insn->mode == MODE_16BIT && insn->opcodeType == ONEBYTE &&
1278*9a0e4156SSadaf Ebrahimi 			insn->opcode == 0xE3)
1279*9a0e4156SSadaf Ebrahimi 		attrMask ^= ATTR_ADSIZE;
1280*9a0e4156SSadaf Ebrahimi 
1281*9a0e4156SSadaf Ebrahimi 	if (getIDWithAttrMask(&instructionID, insn, attrMask))
1282*9a0e4156SSadaf Ebrahimi 		return -1;
1283*9a0e4156SSadaf Ebrahimi 
1284*9a0e4156SSadaf Ebrahimi 	/* The following clauses compensate for limitations of the tables. */
1285*9a0e4156SSadaf Ebrahimi 	if (insn->mode != MODE_64BIT &&
1286*9a0e4156SSadaf Ebrahimi 			insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
1287*9a0e4156SSadaf Ebrahimi 		/*
1288*9a0e4156SSadaf Ebrahimi 		 * The tables can't distinquish between cases where the W-bit is used to
1289*9a0e4156SSadaf Ebrahimi 		 * select register size and cases where its a required part of the opcode.
1290*9a0e4156SSadaf Ebrahimi 		 */
1291*9a0e4156SSadaf Ebrahimi 		if ((insn->vectorExtensionType == TYPE_EVEX &&
1292*9a0e4156SSadaf Ebrahimi 					wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
1293*9a0e4156SSadaf Ebrahimi 				(insn->vectorExtensionType == TYPE_VEX_3B &&
1294*9a0e4156SSadaf Ebrahimi 				 wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
1295*9a0e4156SSadaf Ebrahimi 				(insn->vectorExtensionType == TYPE_XOP &&
1296*9a0e4156SSadaf Ebrahimi 				 wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {
1297*9a0e4156SSadaf Ebrahimi 			uint16_t instructionIDWithREXW;
1298*9a0e4156SSadaf Ebrahimi 			if (getIDWithAttrMask(&instructionIDWithREXW,
1299*9a0e4156SSadaf Ebrahimi 						insn, attrMask | ATTR_REXW)) {
1300*9a0e4156SSadaf Ebrahimi 				insn->instructionID = instructionID;
1301*9a0e4156SSadaf Ebrahimi 				insn->spec = specifierForUID(instructionID);
1302*9a0e4156SSadaf Ebrahimi 
1303*9a0e4156SSadaf Ebrahimi 				return 0;
1304*9a0e4156SSadaf Ebrahimi 			}
1305*9a0e4156SSadaf Ebrahimi 
1306*9a0e4156SSadaf Ebrahimi 			// If not a 64-bit instruction. Switch the opcode.
1307*9a0e4156SSadaf Ebrahimi 			if (!is64Bit(instructionIDWithREXW)) {
1308*9a0e4156SSadaf Ebrahimi 				insn->instructionID = instructionIDWithREXW;
1309*9a0e4156SSadaf Ebrahimi 				insn->spec = specifierForUID(instructionIDWithREXW);
1310*9a0e4156SSadaf Ebrahimi 
1311*9a0e4156SSadaf Ebrahimi 				return 0;
1312*9a0e4156SSadaf Ebrahimi 			}
1313*9a0e4156SSadaf Ebrahimi 		}
1314*9a0e4156SSadaf Ebrahimi 	}
1315*9a0e4156SSadaf Ebrahimi 
1316*9a0e4156SSadaf Ebrahimi 	/*
1317*9a0e4156SSadaf Ebrahimi 	 * Absolute moves need special handling.
1318*9a0e4156SSadaf Ebrahimi 	 * -For 16-bit mode because the meaning of the AdSize and OpSize prefixes are
1319*9a0e4156SSadaf Ebrahimi 	 *  inverted w.r.t.
1320*9a0e4156SSadaf Ebrahimi 	 * -For 32-bit mode we need to ensure the ADSIZE prefix is observed in
1321*9a0e4156SSadaf Ebrahimi 	 *  any position.
1322*9a0e4156SSadaf Ebrahimi 	 */
1323*9a0e4156SSadaf Ebrahimi 	if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) {
1324*9a0e4156SSadaf Ebrahimi 		/* Make sure we observed the prefixes in any position. */
1325*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix67)
1326*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_ADSIZE;
1327*9a0e4156SSadaf Ebrahimi 		if (insn->isPrefix66)
1328*9a0e4156SSadaf Ebrahimi 			attrMask |= ATTR_OPSIZE;
1329*9a0e4156SSadaf Ebrahimi 
1330*9a0e4156SSadaf Ebrahimi 		/* In 16-bit, invert the attributes. */
1331*9a0e4156SSadaf Ebrahimi 		if (insn->mode == MODE_16BIT)
1332*9a0e4156SSadaf Ebrahimi 			attrMask ^= ATTR_ADSIZE | ATTR_OPSIZE;
1333*9a0e4156SSadaf Ebrahimi 
1334*9a0e4156SSadaf Ebrahimi 		if (getIDWithAttrMask(&instructionID, insn, attrMask))
1335*9a0e4156SSadaf Ebrahimi 			return -1;
1336*9a0e4156SSadaf Ebrahimi 
1337*9a0e4156SSadaf Ebrahimi 		insn->instructionID = instructionID;
1338*9a0e4156SSadaf Ebrahimi 		insn->spec = specifierForUID(instructionID);
1339*9a0e4156SSadaf Ebrahimi 
1340*9a0e4156SSadaf Ebrahimi 		return 0;
1341*9a0e4156SSadaf Ebrahimi 	}
1342*9a0e4156SSadaf Ebrahimi 
1343*9a0e4156SSadaf Ebrahimi 	if ((insn->mode == MODE_16BIT || insn->isPrefix66) &&
1344*9a0e4156SSadaf Ebrahimi 			!(attrMask & ATTR_OPSIZE)) {
1345*9a0e4156SSadaf Ebrahimi 		/*
1346*9a0e4156SSadaf Ebrahimi 		 * The instruction tables make no distinction between instructions that
1347*9a0e4156SSadaf Ebrahimi 		 * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a
1348*9a0e4156SSadaf Ebrahimi 		 * particular spot (i.e., many MMX operations).  In general we're
1349*9a0e4156SSadaf Ebrahimi 		 * conservative, but in the specific case where OpSize is present but not
1350*9a0e4156SSadaf Ebrahimi 		 * in the right place we check if there's a 16-bit operation.
1351*9a0e4156SSadaf Ebrahimi 		 */
1352*9a0e4156SSadaf Ebrahimi 
1353*9a0e4156SSadaf Ebrahimi 		const struct InstructionSpecifier *spec;
1354*9a0e4156SSadaf Ebrahimi 		uint16_t instructionIDWithOpsize;
1355*9a0e4156SSadaf Ebrahimi 
1356*9a0e4156SSadaf Ebrahimi 		spec = specifierForUID(instructionID);
1357*9a0e4156SSadaf Ebrahimi 
1358*9a0e4156SSadaf Ebrahimi 		if (getIDWithAttrMask(&instructionIDWithOpsize,
1359*9a0e4156SSadaf Ebrahimi 					insn, attrMask | ATTR_OPSIZE)) {
1360*9a0e4156SSadaf Ebrahimi 			/*
1361*9a0e4156SSadaf Ebrahimi 			 * ModRM required with OpSize but not present; give up and return version
1362*9a0e4156SSadaf Ebrahimi 			 * without OpSize set
1363*9a0e4156SSadaf Ebrahimi 			 */
1364*9a0e4156SSadaf Ebrahimi 
1365*9a0e4156SSadaf Ebrahimi 			insn->instructionID = instructionID;
1366*9a0e4156SSadaf Ebrahimi 			insn->spec = spec;
1367*9a0e4156SSadaf Ebrahimi 			return 0;
1368*9a0e4156SSadaf Ebrahimi 		}
1369*9a0e4156SSadaf Ebrahimi 
1370*9a0e4156SSadaf Ebrahimi 		if (is16BitEquivalent(instructionID, instructionIDWithOpsize) &&
1371*9a0e4156SSadaf Ebrahimi 				(insn->mode == MODE_16BIT) ^ insn->isPrefix66) {
1372*9a0e4156SSadaf Ebrahimi 			insn->instructionID = instructionIDWithOpsize;
1373*9a0e4156SSadaf Ebrahimi 			insn->spec = specifierForUID(instructionIDWithOpsize);
1374*9a0e4156SSadaf Ebrahimi 		} else {
1375*9a0e4156SSadaf Ebrahimi 			insn->instructionID = instructionID;
1376*9a0e4156SSadaf Ebrahimi 			insn->spec = spec;
1377*9a0e4156SSadaf Ebrahimi 		}
1378*9a0e4156SSadaf Ebrahimi 		return 0;
1379*9a0e4156SSadaf Ebrahimi 	}
1380*9a0e4156SSadaf Ebrahimi 
1381*9a0e4156SSadaf Ebrahimi 	if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
1382*9a0e4156SSadaf Ebrahimi 			insn->rexPrefix & 0x01) {
1383*9a0e4156SSadaf Ebrahimi 		/*
1384*9a0e4156SSadaf Ebrahimi 		 * NOOP shouldn't decode as NOOP if REX.b is set. Instead
1385*9a0e4156SSadaf Ebrahimi 		 * it should decode as XCHG %r8, %eax.
1386*9a0e4156SSadaf Ebrahimi 		 */
1387*9a0e4156SSadaf Ebrahimi 
1388*9a0e4156SSadaf Ebrahimi 		const struct InstructionSpecifier *spec;
1389*9a0e4156SSadaf Ebrahimi 		uint16_t instructionIDWithNewOpcode;
1390*9a0e4156SSadaf Ebrahimi 		const struct InstructionSpecifier *specWithNewOpcode;
1391*9a0e4156SSadaf Ebrahimi 
1392*9a0e4156SSadaf Ebrahimi 		spec = specifierForUID(instructionID);
1393*9a0e4156SSadaf Ebrahimi 
1394*9a0e4156SSadaf Ebrahimi 		/* Borrow opcode from one of the other XCHGar opcodes */
1395*9a0e4156SSadaf Ebrahimi 		insn->opcode = 0x91;
1396*9a0e4156SSadaf Ebrahimi 
1397*9a0e4156SSadaf Ebrahimi 		if (getIDWithAttrMask(&instructionIDWithNewOpcode,
1398*9a0e4156SSadaf Ebrahimi 					insn,
1399*9a0e4156SSadaf Ebrahimi 					attrMask)) {
1400*9a0e4156SSadaf Ebrahimi 			insn->opcode = 0x90;
1401*9a0e4156SSadaf Ebrahimi 
1402*9a0e4156SSadaf Ebrahimi 			insn->instructionID = instructionID;
1403*9a0e4156SSadaf Ebrahimi 			insn->spec = spec;
1404*9a0e4156SSadaf Ebrahimi 			return 0;
1405*9a0e4156SSadaf Ebrahimi 		}
1406*9a0e4156SSadaf Ebrahimi 
1407*9a0e4156SSadaf Ebrahimi 		specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode);
1408*9a0e4156SSadaf Ebrahimi 
1409*9a0e4156SSadaf Ebrahimi 		/* Change back */
1410*9a0e4156SSadaf Ebrahimi 		insn->opcode = 0x90;
1411*9a0e4156SSadaf Ebrahimi 
1412*9a0e4156SSadaf Ebrahimi 		insn->instructionID = instructionIDWithNewOpcode;
1413*9a0e4156SSadaf Ebrahimi 		insn->spec = specWithNewOpcode;
1414*9a0e4156SSadaf Ebrahimi 
1415*9a0e4156SSadaf Ebrahimi 		return 0;
1416*9a0e4156SSadaf Ebrahimi 	}
1417*9a0e4156SSadaf Ebrahimi 
1418*9a0e4156SSadaf Ebrahimi 	insn->instructionID = instructionID;
1419*9a0e4156SSadaf Ebrahimi 	insn->spec = specifierForUID(insn->instructionID);
1420*9a0e4156SSadaf Ebrahimi 
1421*9a0e4156SSadaf Ebrahimi 	return 0;
1422*9a0e4156SSadaf Ebrahimi }
1423*9a0e4156SSadaf Ebrahimi 
1424*9a0e4156SSadaf Ebrahimi /*
1425*9a0e4156SSadaf Ebrahimi  * readSIB - Consumes the SIB byte to determine addressing information for an
1426*9a0e4156SSadaf Ebrahimi  *   instruction.
1427*9a0e4156SSadaf Ebrahimi  *
1428*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose SIB byte is to be read.
1429*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the SIB byte was successfully read; nonzero otherwise.
1430*9a0e4156SSadaf Ebrahimi  */
readSIB(struct InternalInstruction * insn)1431*9a0e4156SSadaf Ebrahimi static int readSIB(struct InternalInstruction *insn)
1432*9a0e4156SSadaf Ebrahimi {
1433*9a0e4156SSadaf Ebrahimi 	SIBIndex sibIndexBase = SIB_INDEX_NONE;
1434*9a0e4156SSadaf Ebrahimi 	SIBBase sibBaseBase = SIB_BASE_NONE;
1435*9a0e4156SSadaf Ebrahimi 	uint8_t index, base;
1436*9a0e4156SSadaf Ebrahimi 
1437*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readSIB()");
1438*9a0e4156SSadaf Ebrahimi 
1439*9a0e4156SSadaf Ebrahimi 	if (insn->consumedSIB)
1440*9a0e4156SSadaf Ebrahimi 		return 0;
1441*9a0e4156SSadaf Ebrahimi 
1442*9a0e4156SSadaf Ebrahimi 	insn->consumedSIB = true;
1443*9a0e4156SSadaf Ebrahimi 
1444*9a0e4156SSadaf Ebrahimi 	switch (insn->addressSize) {
1445*9a0e4156SSadaf Ebrahimi 		case 2:
1446*9a0e4156SSadaf Ebrahimi 			// dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode");
1447*9a0e4156SSadaf Ebrahimi 			return -1;
1448*9a0e4156SSadaf Ebrahimi 		case 4:
1449*9a0e4156SSadaf Ebrahimi 			sibIndexBase = SIB_INDEX_EAX;
1450*9a0e4156SSadaf Ebrahimi 			sibBaseBase = SIB_BASE_EAX;
1451*9a0e4156SSadaf Ebrahimi 			break;
1452*9a0e4156SSadaf Ebrahimi 		case 8:
1453*9a0e4156SSadaf Ebrahimi 			sibIndexBase = SIB_INDEX_RAX;
1454*9a0e4156SSadaf Ebrahimi 			sibBaseBase = SIB_BASE_RAX;
1455*9a0e4156SSadaf Ebrahimi 			break;
1456*9a0e4156SSadaf Ebrahimi 	}
1457*9a0e4156SSadaf Ebrahimi 
1458*9a0e4156SSadaf Ebrahimi 	if (consumeByte(insn, &insn->sib))
1459*9a0e4156SSadaf Ebrahimi 		return -1;
1460*9a0e4156SSadaf Ebrahimi 
1461*9a0e4156SSadaf Ebrahimi 	index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3);
1462*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType == TYPE_EVEX)
1463*9a0e4156SSadaf Ebrahimi 		index |= v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4;
1464*9a0e4156SSadaf Ebrahimi 
1465*9a0e4156SSadaf Ebrahimi 	switch (index) {
1466*9a0e4156SSadaf Ebrahimi 		case 0x4:
1467*9a0e4156SSadaf Ebrahimi 			insn->sibIndex = SIB_INDEX_NONE;
1468*9a0e4156SSadaf Ebrahimi 			break;
1469*9a0e4156SSadaf Ebrahimi 		default:
1470*9a0e4156SSadaf Ebrahimi 			insn->sibIndex = (SIBIndex)(sibIndexBase + index);
1471*9a0e4156SSadaf Ebrahimi 			if (insn->sibIndex == SIB_INDEX_sib ||
1472*9a0e4156SSadaf Ebrahimi 					insn->sibIndex == SIB_INDEX_sib64)
1473*9a0e4156SSadaf Ebrahimi 				insn->sibIndex = SIB_INDEX_NONE;
1474*9a0e4156SSadaf Ebrahimi 			break;
1475*9a0e4156SSadaf Ebrahimi 	}
1476*9a0e4156SSadaf Ebrahimi 
1477*9a0e4156SSadaf Ebrahimi 	switch (scaleFromSIB(insn->sib)) {
1478*9a0e4156SSadaf Ebrahimi 		case 0:
1479*9a0e4156SSadaf Ebrahimi 			insn->sibScale = 1;
1480*9a0e4156SSadaf Ebrahimi 			break;
1481*9a0e4156SSadaf Ebrahimi 		case 1:
1482*9a0e4156SSadaf Ebrahimi 			insn->sibScale = 2;
1483*9a0e4156SSadaf Ebrahimi 			break;
1484*9a0e4156SSadaf Ebrahimi 		case 2:
1485*9a0e4156SSadaf Ebrahimi 			insn->sibScale = 4;
1486*9a0e4156SSadaf Ebrahimi 			break;
1487*9a0e4156SSadaf Ebrahimi 		case 3:
1488*9a0e4156SSadaf Ebrahimi 			insn->sibScale = 8;
1489*9a0e4156SSadaf Ebrahimi 			break;
1490*9a0e4156SSadaf Ebrahimi 	}
1491*9a0e4156SSadaf Ebrahimi 
1492*9a0e4156SSadaf Ebrahimi 	base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);
1493*9a0e4156SSadaf Ebrahimi 
1494*9a0e4156SSadaf Ebrahimi 	switch (base) {
1495*9a0e4156SSadaf Ebrahimi 		case 0x5:
1496*9a0e4156SSadaf Ebrahimi 		case 0xd:
1497*9a0e4156SSadaf Ebrahimi 			switch (modFromModRM(insn->modRM)) {
1498*9a0e4156SSadaf Ebrahimi 				case 0x0:
1499*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_32;
1500*9a0e4156SSadaf Ebrahimi 					insn->sibBase = SIB_BASE_NONE;
1501*9a0e4156SSadaf Ebrahimi 					break;
1502*9a0e4156SSadaf Ebrahimi 				case 0x1:
1503*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_8;
1504*9a0e4156SSadaf Ebrahimi 					insn->sibBase = (SIBBase)(sibBaseBase + base);
1505*9a0e4156SSadaf Ebrahimi 					break;
1506*9a0e4156SSadaf Ebrahimi 				case 0x2:
1507*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_32;
1508*9a0e4156SSadaf Ebrahimi 					insn->sibBase = (SIBBase)(sibBaseBase + base);
1509*9a0e4156SSadaf Ebrahimi 					break;
1510*9a0e4156SSadaf Ebrahimi 				case 0x3:
1511*9a0e4156SSadaf Ebrahimi 					//debug("Cannot have Mod = 0b11 and a SIB byte");
1512*9a0e4156SSadaf Ebrahimi 					return -1;
1513*9a0e4156SSadaf Ebrahimi 			}
1514*9a0e4156SSadaf Ebrahimi 			break;
1515*9a0e4156SSadaf Ebrahimi 		default:
1516*9a0e4156SSadaf Ebrahimi 			insn->sibBase = (SIBBase)(sibBaseBase + base);
1517*9a0e4156SSadaf Ebrahimi 			break;
1518*9a0e4156SSadaf Ebrahimi 	}
1519*9a0e4156SSadaf Ebrahimi 
1520*9a0e4156SSadaf Ebrahimi 	return 0;
1521*9a0e4156SSadaf Ebrahimi }
1522*9a0e4156SSadaf Ebrahimi 
1523*9a0e4156SSadaf Ebrahimi /*
1524*9a0e4156SSadaf Ebrahimi  * readDisplacement - Consumes the displacement of an instruction.
1525*9a0e4156SSadaf Ebrahimi  *
1526*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose displacement is to be read.
1527*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the displacement byte was successfully read; nonzero
1528*9a0e4156SSadaf Ebrahimi  *                otherwise.
1529*9a0e4156SSadaf Ebrahimi  */
readDisplacement(struct InternalInstruction * insn)1530*9a0e4156SSadaf Ebrahimi static int readDisplacement(struct InternalInstruction *insn)
1531*9a0e4156SSadaf Ebrahimi {
1532*9a0e4156SSadaf Ebrahimi 	int8_t d8;
1533*9a0e4156SSadaf Ebrahimi 	int16_t d16;
1534*9a0e4156SSadaf Ebrahimi 	int32_t d32;
1535*9a0e4156SSadaf Ebrahimi 
1536*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readDisplacement()");
1537*9a0e4156SSadaf Ebrahimi 
1538*9a0e4156SSadaf Ebrahimi 	if (insn->consumedDisplacement)
1539*9a0e4156SSadaf Ebrahimi 		return 0;
1540*9a0e4156SSadaf Ebrahimi 
1541*9a0e4156SSadaf Ebrahimi 	insn->consumedDisplacement = true;
1542*9a0e4156SSadaf Ebrahimi 	insn->displacementOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1543*9a0e4156SSadaf Ebrahimi 
1544*9a0e4156SSadaf Ebrahimi 	switch (insn->eaDisplacement) {
1545*9a0e4156SSadaf Ebrahimi 		case EA_DISP_NONE:
1546*9a0e4156SSadaf Ebrahimi 			insn->consumedDisplacement = false;
1547*9a0e4156SSadaf Ebrahimi 			break;
1548*9a0e4156SSadaf Ebrahimi 		case EA_DISP_8:
1549*9a0e4156SSadaf Ebrahimi 			if (consumeInt8(insn, &d8))
1550*9a0e4156SSadaf Ebrahimi 				return -1;
1551*9a0e4156SSadaf Ebrahimi 			insn->displacement = d8;
1552*9a0e4156SSadaf Ebrahimi 			break;
1553*9a0e4156SSadaf Ebrahimi 		case EA_DISP_16:
1554*9a0e4156SSadaf Ebrahimi 			if (consumeInt16(insn, &d16))
1555*9a0e4156SSadaf Ebrahimi 				return -1;
1556*9a0e4156SSadaf Ebrahimi 			insn->displacement = d16;
1557*9a0e4156SSadaf Ebrahimi 			break;
1558*9a0e4156SSadaf Ebrahimi 		case EA_DISP_32:
1559*9a0e4156SSadaf Ebrahimi 			if (consumeInt32(insn, &d32))
1560*9a0e4156SSadaf Ebrahimi 				return -1;
1561*9a0e4156SSadaf Ebrahimi 			insn->displacement = d32;
1562*9a0e4156SSadaf Ebrahimi 			break;
1563*9a0e4156SSadaf Ebrahimi 	}
1564*9a0e4156SSadaf Ebrahimi 
1565*9a0e4156SSadaf Ebrahimi 	return 0;
1566*9a0e4156SSadaf Ebrahimi }
1567*9a0e4156SSadaf Ebrahimi 
1568*9a0e4156SSadaf Ebrahimi /*
1569*9a0e4156SSadaf Ebrahimi  * readModRM - Consumes all addressing information (ModR/M byte, SIB byte, and
1570*9a0e4156SSadaf Ebrahimi  *   displacement) for an instruction and interprets it.
1571*9a0e4156SSadaf Ebrahimi  *
1572*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose addressing information is to be read.
1573*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the information was successfully read; nonzero otherwise.
1574*9a0e4156SSadaf Ebrahimi  */
readModRM(struct InternalInstruction * insn)1575*9a0e4156SSadaf Ebrahimi static int readModRM(struct InternalInstruction *insn)
1576*9a0e4156SSadaf Ebrahimi {
1577*9a0e4156SSadaf Ebrahimi 	uint8_t mod, rm, reg;
1578*9a0e4156SSadaf Ebrahimi 
1579*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readModRM()");
1580*9a0e4156SSadaf Ebrahimi 
1581*9a0e4156SSadaf Ebrahimi 	// already got ModRM byte?
1582*9a0e4156SSadaf Ebrahimi 	if (insn->consumedModRM)
1583*9a0e4156SSadaf Ebrahimi 		return 0;
1584*9a0e4156SSadaf Ebrahimi 
1585*9a0e4156SSadaf Ebrahimi 	insn->modRMOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1586*9a0e4156SSadaf Ebrahimi 
1587*9a0e4156SSadaf Ebrahimi 	if (consumeByte(insn, &insn->modRM))
1588*9a0e4156SSadaf Ebrahimi 		return -1;
1589*9a0e4156SSadaf Ebrahimi 
1590*9a0e4156SSadaf Ebrahimi 	// mark that we already got ModRM
1591*9a0e4156SSadaf Ebrahimi 	insn->consumedModRM = true;
1592*9a0e4156SSadaf Ebrahimi 
1593*9a0e4156SSadaf Ebrahimi 	// save original ModRM for later reference
1594*9a0e4156SSadaf Ebrahimi 	insn->orgModRM = insn->modRM;
1595*9a0e4156SSadaf Ebrahimi 
1596*9a0e4156SSadaf Ebrahimi 	// handle MOVcr, MOVdr, MOVrc, MOVrd by pretending they have MRM.mod = 3
1597*9a0e4156SSadaf Ebrahimi 	if ((insn->firstByte == 0x0f && insn->opcodeType == TWOBYTE) &&
1598*9a0e4156SSadaf Ebrahimi 			(insn->opcode >= 0x20 && insn->opcode <= 0x23 ))
1599*9a0e4156SSadaf Ebrahimi 		insn->modRM |= 0xC0;
1600*9a0e4156SSadaf Ebrahimi 
1601*9a0e4156SSadaf Ebrahimi 	mod     = modFromModRM(insn->modRM);
1602*9a0e4156SSadaf Ebrahimi 	rm      = rmFromModRM(insn->modRM);
1603*9a0e4156SSadaf Ebrahimi 	reg     = regFromModRM(insn->modRM);
1604*9a0e4156SSadaf Ebrahimi 
1605*9a0e4156SSadaf Ebrahimi 	/*
1606*9a0e4156SSadaf Ebrahimi 	 * This goes by insn->registerSize to pick the correct register, which messes
1607*9a0e4156SSadaf Ebrahimi 	 * up if we're using (say) XMM or 8-bit register operands.  That gets fixed in
1608*9a0e4156SSadaf Ebrahimi 	 * fixupReg().
1609*9a0e4156SSadaf Ebrahimi 	 */
1610*9a0e4156SSadaf Ebrahimi 	switch (insn->registerSize) {
1611*9a0e4156SSadaf Ebrahimi 		case 2:
1612*9a0e4156SSadaf Ebrahimi 			insn->regBase = MODRM_REG_AX;
1613*9a0e4156SSadaf Ebrahimi 			insn->eaRegBase = EA_REG_AX;
1614*9a0e4156SSadaf Ebrahimi 			break;
1615*9a0e4156SSadaf Ebrahimi 		case 4:
1616*9a0e4156SSadaf Ebrahimi 			insn->regBase = MODRM_REG_EAX;
1617*9a0e4156SSadaf Ebrahimi 			insn->eaRegBase = EA_REG_EAX;
1618*9a0e4156SSadaf Ebrahimi 			break;
1619*9a0e4156SSadaf Ebrahimi 		case 8:
1620*9a0e4156SSadaf Ebrahimi 			insn->regBase = MODRM_REG_RAX;
1621*9a0e4156SSadaf Ebrahimi 			insn->eaRegBase = EA_REG_RAX;
1622*9a0e4156SSadaf Ebrahimi 			break;
1623*9a0e4156SSadaf Ebrahimi 	}
1624*9a0e4156SSadaf Ebrahimi 
1625*9a0e4156SSadaf Ebrahimi 	reg |= rFromREX(insn->rexPrefix) << 3;
1626*9a0e4156SSadaf Ebrahimi 	rm  |= bFromREX(insn->rexPrefix) << 3;
1627*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType == TYPE_EVEX) {
1628*9a0e4156SSadaf Ebrahimi 		reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1629*9a0e4156SSadaf Ebrahimi 		rm  |=  xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1630*9a0e4156SSadaf Ebrahimi 	}
1631*9a0e4156SSadaf Ebrahimi 
1632*9a0e4156SSadaf Ebrahimi 	insn->reg = (Reg)(insn->regBase + reg);
1633*9a0e4156SSadaf Ebrahimi 
1634*9a0e4156SSadaf Ebrahimi 	switch (insn->addressSize) {
1635*9a0e4156SSadaf Ebrahimi 		case 2:
1636*9a0e4156SSadaf Ebrahimi 			insn->eaBaseBase = EA_BASE_BX_SI;
1637*9a0e4156SSadaf Ebrahimi 
1638*9a0e4156SSadaf Ebrahimi 			switch (mod) {
1639*9a0e4156SSadaf Ebrahimi 				case 0x0:
1640*9a0e4156SSadaf Ebrahimi 					if (rm == 0x6) {
1641*9a0e4156SSadaf Ebrahimi 						insn->eaBase = EA_BASE_NONE;
1642*9a0e4156SSadaf Ebrahimi 						insn->eaDisplacement = EA_DISP_16;
1643*9a0e4156SSadaf Ebrahimi 						if (readDisplacement(insn))
1644*9a0e4156SSadaf Ebrahimi 							return -1;
1645*9a0e4156SSadaf Ebrahimi 					} else {
1646*9a0e4156SSadaf Ebrahimi 						insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1647*9a0e4156SSadaf Ebrahimi 						insn->eaDisplacement = EA_DISP_NONE;
1648*9a0e4156SSadaf Ebrahimi 					}
1649*9a0e4156SSadaf Ebrahimi 					break;
1650*9a0e4156SSadaf Ebrahimi 				case 0x1:
1651*9a0e4156SSadaf Ebrahimi 					insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1652*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_8;
1653*9a0e4156SSadaf Ebrahimi 					insn->displacementSize = 1;
1654*9a0e4156SSadaf Ebrahimi 					if (readDisplacement(insn))
1655*9a0e4156SSadaf Ebrahimi 						return -1;
1656*9a0e4156SSadaf Ebrahimi 					break;
1657*9a0e4156SSadaf Ebrahimi 				case 0x2:
1658*9a0e4156SSadaf Ebrahimi 					insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1659*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_16;
1660*9a0e4156SSadaf Ebrahimi 					if (readDisplacement(insn))
1661*9a0e4156SSadaf Ebrahimi 						return -1;
1662*9a0e4156SSadaf Ebrahimi 					break;
1663*9a0e4156SSadaf Ebrahimi 				case 0x3:
1664*9a0e4156SSadaf Ebrahimi 					insn->eaBase = (EABase)(insn->eaRegBase + rm);
1665*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_NONE;
1666*9a0e4156SSadaf Ebrahimi 					if (readDisplacement(insn))
1667*9a0e4156SSadaf Ebrahimi 						return -1;
1668*9a0e4156SSadaf Ebrahimi 					break;
1669*9a0e4156SSadaf Ebrahimi 			}
1670*9a0e4156SSadaf Ebrahimi 			break;
1671*9a0e4156SSadaf Ebrahimi 		case 4:
1672*9a0e4156SSadaf Ebrahimi 		case 8:
1673*9a0e4156SSadaf Ebrahimi 			insn->eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX);
1674*9a0e4156SSadaf Ebrahimi 
1675*9a0e4156SSadaf Ebrahimi 			switch (mod) {
1676*9a0e4156SSadaf Ebrahimi 				case 0x0:
1677*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
1678*9a0e4156SSadaf Ebrahimi 					switch (rm) {
1679*9a0e4156SSadaf Ebrahimi 						case 0x14:
1680*9a0e4156SSadaf Ebrahimi 						case 0x4:
1681*9a0e4156SSadaf Ebrahimi 						case 0xc:   /* in case REXW.b is set */
1682*9a0e4156SSadaf Ebrahimi 							insn->eaBase = (insn->addressSize == 4 ?
1683*9a0e4156SSadaf Ebrahimi 									EA_BASE_sib : EA_BASE_sib64);
1684*9a0e4156SSadaf Ebrahimi 							if (readSIB(insn) || readDisplacement(insn))
1685*9a0e4156SSadaf Ebrahimi 								return -1;
1686*9a0e4156SSadaf Ebrahimi 							break;
1687*9a0e4156SSadaf Ebrahimi 						case 0x5:
1688*9a0e4156SSadaf Ebrahimi 						case 0xd:
1689*9a0e4156SSadaf Ebrahimi 							insn->eaBase = EA_BASE_NONE;
1690*9a0e4156SSadaf Ebrahimi 							insn->eaDisplacement = EA_DISP_32;
1691*9a0e4156SSadaf Ebrahimi 							if (readDisplacement(insn))
1692*9a0e4156SSadaf Ebrahimi 								return -1;
1693*9a0e4156SSadaf Ebrahimi 							break;
1694*9a0e4156SSadaf Ebrahimi 						default:
1695*9a0e4156SSadaf Ebrahimi 							insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1696*9a0e4156SSadaf Ebrahimi 							break;
1697*9a0e4156SSadaf Ebrahimi 					}
1698*9a0e4156SSadaf Ebrahimi 
1699*9a0e4156SSadaf Ebrahimi 					break;
1700*9a0e4156SSadaf Ebrahimi 				case 0x1:
1701*9a0e4156SSadaf Ebrahimi 					insn->displacementSize = 1;
1702*9a0e4156SSadaf Ebrahimi 					/* FALLTHROUGH */
1703*9a0e4156SSadaf Ebrahimi 				case 0x2:
1704*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
1705*9a0e4156SSadaf Ebrahimi 					switch (rm) {
1706*9a0e4156SSadaf Ebrahimi 						case 0x14:
1707*9a0e4156SSadaf Ebrahimi 						case 0x4:
1708*9a0e4156SSadaf Ebrahimi 						case 0xc:   /* in case REXW.b is set */
1709*9a0e4156SSadaf Ebrahimi 							insn->eaBase = EA_BASE_sib;
1710*9a0e4156SSadaf Ebrahimi 							if (readSIB(insn) || readDisplacement(insn))
1711*9a0e4156SSadaf Ebrahimi 								return -1;
1712*9a0e4156SSadaf Ebrahimi 							break;
1713*9a0e4156SSadaf Ebrahimi 						default:
1714*9a0e4156SSadaf Ebrahimi 							insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1715*9a0e4156SSadaf Ebrahimi 							if (readDisplacement(insn))
1716*9a0e4156SSadaf Ebrahimi 								return -1;
1717*9a0e4156SSadaf Ebrahimi 							break;
1718*9a0e4156SSadaf Ebrahimi 					}
1719*9a0e4156SSadaf Ebrahimi 					break;
1720*9a0e4156SSadaf Ebrahimi 				case 0x3:
1721*9a0e4156SSadaf Ebrahimi 					insn->eaDisplacement = EA_DISP_NONE;
1722*9a0e4156SSadaf Ebrahimi 					insn->eaBase = (EABase)(insn->eaRegBase + rm);
1723*9a0e4156SSadaf Ebrahimi 					break;
1724*9a0e4156SSadaf Ebrahimi 			}
1725*9a0e4156SSadaf Ebrahimi 			break;
1726*9a0e4156SSadaf Ebrahimi 	} /* switch (insn->addressSize) */
1727*9a0e4156SSadaf Ebrahimi 
1728*9a0e4156SSadaf Ebrahimi 	return 0;
1729*9a0e4156SSadaf Ebrahimi }
1730*9a0e4156SSadaf Ebrahimi 
1731*9a0e4156SSadaf Ebrahimi #define GENERIC_FIXUP_FUNC(name, base, prefix)            \
1732*9a0e4156SSadaf Ebrahimi   static uint8_t name(struct InternalInstruction *insn,   \
1733*9a0e4156SSadaf Ebrahimi                       OperandType type,                   \
1734*9a0e4156SSadaf Ebrahimi                       uint8_t index,                      \
1735*9a0e4156SSadaf Ebrahimi                       uint8_t *valid) {                   \
1736*9a0e4156SSadaf Ebrahimi     *valid = 1;                                           \
1737*9a0e4156SSadaf Ebrahimi     switch (type) {                                       \
1738*9a0e4156SSadaf Ebrahimi     default:                                              \
1739*9a0e4156SSadaf Ebrahimi       *valid = 0;                                         \
1740*9a0e4156SSadaf Ebrahimi       return 0;                                           \
1741*9a0e4156SSadaf Ebrahimi     case TYPE_Rv:                                         \
1742*9a0e4156SSadaf Ebrahimi       return base + index;                                \
1743*9a0e4156SSadaf Ebrahimi     case TYPE_R8:                                         \
1744*9a0e4156SSadaf Ebrahimi       if (insn->rexPrefix &&                              \
1745*9a0e4156SSadaf Ebrahimi          index >= 4 && index <= 7) {                      \
1746*9a0e4156SSadaf Ebrahimi         return prefix##_SPL + (index - 4);                \
1747*9a0e4156SSadaf Ebrahimi       } else {                                            \
1748*9a0e4156SSadaf Ebrahimi         return prefix##_AL + index;                       \
1749*9a0e4156SSadaf Ebrahimi       }                                                   \
1750*9a0e4156SSadaf Ebrahimi     case TYPE_R16:                                        \
1751*9a0e4156SSadaf Ebrahimi       return prefix##_AX + index;                         \
1752*9a0e4156SSadaf Ebrahimi     case TYPE_R32:                                        \
1753*9a0e4156SSadaf Ebrahimi       return prefix##_EAX + index;                        \
1754*9a0e4156SSadaf Ebrahimi     case TYPE_R64:                                        \
1755*9a0e4156SSadaf Ebrahimi       return prefix##_RAX + index;                        \
1756*9a0e4156SSadaf Ebrahimi     case TYPE_XMM512:                                     \
1757*9a0e4156SSadaf Ebrahimi       return prefix##_ZMM0 + index;                       \
1758*9a0e4156SSadaf Ebrahimi     case TYPE_XMM256:                                     \
1759*9a0e4156SSadaf Ebrahimi       return prefix##_YMM0 + index;                       \
1760*9a0e4156SSadaf Ebrahimi     case TYPE_XMM128:                                     \
1761*9a0e4156SSadaf Ebrahimi     case TYPE_XMM64:                                      \
1762*9a0e4156SSadaf Ebrahimi     case TYPE_XMM32:                                      \
1763*9a0e4156SSadaf Ebrahimi     case TYPE_XMM:                                        \
1764*9a0e4156SSadaf Ebrahimi       return prefix##_XMM0 + index;                       \
1765*9a0e4156SSadaf Ebrahimi     case TYPE_VK1:                                        \
1766*9a0e4156SSadaf Ebrahimi     case TYPE_VK8:                                        \
1767*9a0e4156SSadaf Ebrahimi     case TYPE_VK16:                                       \
1768*9a0e4156SSadaf Ebrahimi       if (index > 7)                                      \
1769*9a0e4156SSadaf Ebrahimi         *valid = 0;                                       \
1770*9a0e4156SSadaf Ebrahimi       return prefix##_K0 + index;                         \
1771*9a0e4156SSadaf Ebrahimi     case TYPE_MM64:                                       \
1772*9a0e4156SSadaf Ebrahimi       return prefix##_MM0 + (index & 0x7);                \
1773*9a0e4156SSadaf Ebrahimi     case TYPE_SEGMENTREG:                                 \
1774*9a0e4156SSadaf Ebrahimi       if (index > 5)                                      \
1775*9a0e4156SSadaf Ebrahimi         *valid = 0;                                       \
1776*9a0e4156SSadaf Ebrahimi       return prefix##_ES + index;                         \
1777*9a0e4156SSadaf Ebrahimi     case TYPE_DEBUGREG:                                   \
1778*9a0e4156SSadaf Ebrahimi       return prefix##_DR0 + index;                        \
1779*9a0e4156SSadaf Ebrahimi     case TYPE_CONTROLREG:                                 \
1780*9a0e4156SSadaf Ebrahimi       return prefix##_CR0 + index;                        \
1781*9a0e4156SSadaf Ebrahimi     }                                                     \
1782*9a0e4156SSadaf Ebrahimi   }
1783*9a0e4156SSadaf Ebrahimi 
1784*9a0e4156SSadaf Ebrahimi 
1785*9a0e4156SSadaf Ebrahimi /*
1786*9a0e4156SSadaf Ebrahimi  * fixup*Value - Consults an operand type to determine the meaning of the
1787*9a0e4156SSadaf Ebrahimi  *   reg or R/M field.  If the operand is an XMM operand, for example, an
1788*9a0e4156SSadaf Ebrahimi  *   operand would be XMM0 instead of AX, which readModRM() would otherwise
1789*9a0e4156SSadaf Ebrahimi  *   misinterpret it as.
1790*9a0e4156SSadaf Ebrahimi  *
1791*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction containing the operand.
1792*9a0e4156SSadaf Ebrahimi  * @param type  - The operand type.
1793*9a0e4156SSadaf Ebrahimi  * @param index - The existing value of the field as reported by readModRM().
1794*9a0e4156SSadaf Ebrahimi  * @param valid - The address of a uint8_t.  The target is set to 1 if the
1795*9a0e4156SSadaf Ebrahimi  *                field is valid for the register class; 0 if not.
1796*9a0e4156SSadaf Ebrahimi  * @return      - The proper value.
1797*9a0e4156SSadaf Ebrahimi  */
1798*9a0e4156SSadaf Ebrahimi GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase,    MODRM_REG)
1799*9a0e4156SSadaf Ebrahimi GENERIC_FIXUP_FUNC(fixupRMValue,  insn->eaRegBase,  EA_REG)
1800*9a0e4156SSadaf Ebrahimi 
1801*9a0e4156SSadaf Ebrahimi /*
1802*9a0e4156SSadaf Ebrahimi  * fixupReg - Consults an operand specifier to determine which of the
1803*9a0e4156SSadaf Ebrahimi  *   fixup*Value functions to use in correcting readModRM()'ss interpretation.
1804*9a0e4156SSadaf Ebrahimi  *
1805*9a0e4156SSadaf Ebrahimi  * @param insn  - See fixup*Value().
1806*9a0e4156SSadaf Ebrahimi  * @param op    - The operand specifier.
1807*9a0e4156SSadaf Ebrahimi  * @return      - 0 if fixup was successful; -1 if the register returned was
1808*9a0e4156SSadaf Ebrahimi  *                invalid for its class.
1809*9a0e4156SSadaf Ebrahimi  */
fixupReg(struct InternalInstruction * insn,const struct OperandSpecifier * op)1810*9a0e4156SSadaf Ebrahimi static int fixupReg(struct InternalInstruction *insn,
1811*9a0e4156SSadaf Ebrahimi 		const struct OperandSpecifier *op)
1812*9a0e4156SSadaf Ebrahimi {
1813*9a0e4156SSadaf Ebrahimi 	uint8_t valid;
1814*9a0e4156SSadaf Ebrahimi 
1815*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "fixupReg()");
1816*9a0e4156SSadaf Ebrahimi 
1817*9a0e4156SSadaf Ebrahimi 	switch ((OperandEncoding)op->encoding) {
1818*9a0e4156SSadaf Ebrahimi 		default:
1819*9a0e4156SSadaf Ebrahimi 			//debug("Expected a REG or R/M encoding in fixupReg");
1820*9a0e4156SSadaf Ebrahimi 			return -1;
1821*9a0e4156SSadaf Ebrahimi 		case ENCODING_VVVV:
1822*9a0e4156SSadaf Ebrahimi 			insn->vvvv = (Reg)fixupRegValue(insn,
1823*9a0e4156SSadaf Ebrahimi 					(OperandType)op->type,
1824*9a0e4156SSadaf Ebrahimi 					insn->vvvv,
1825*9a0e4156SSadaf Ebrahimi 					&valid);
1826*9a0e4156SSadaf Ebrahimi 			if (!valid)
1827*9a0e4156SSadaf Ebrahimi 				return -1;
1828*9a0e4156SSadaf Ebrahimi 			break;
1829*9a0e4156SSadaf Ebrahimi 		case ENCODING_REG:
1830*9a0e4156SSadaf Ebrahimi 			insn->reg = (Reg)fixupRegValue(insn,
1831*9a0e4156SSadaf Ebrahimi 					(OperandType)op->type,
1832*9a0e4156SSadaf Ebrahimi 					(uint8_t)(insn->reg - insn->regBase),
1833*9a0e4156SSadaf Ebrahimi 					&valid);
1834*9a0e4156SSadaf Ebrahimi 			if (!valid)
1835*9a0e4156SSadaf Ebrahimi 				return -1;
1836*9a0e4156SSadaf Ebrahimi 			break;
1837*9a0e4156SSadaf Ebrahimi 		CASE_ENCODING_RM:
1838*9a0e4156SSadaf Ebrahimi 			if (insn->eaBase >= insn->eaRegBase) {
1839*9a0e4156SSadaf Ebrahimi 				insn->eaBase = (EABase)fixupRMValue(insn,
1840*9a0e4156SSadaf Ebrahimi 						(OperandType)op->type,
1841*9a0e4156SSadaf Ebrahimi 						(uint8_t)(insn->eaBase - insn->eaRegBase),
1842*9a0e4156SSadaf Ebrahimi 						&valid);
1843*9a0e4156SSadaf Ebrahimi 				if (!valid)
1844*9a0e4156SSadaf Ebrahimi 					return -1;
1845*9a0e4156SSadaf Ebrahimi 			}
1846*9a0e4156SSadaf Ebrahimi 			break;
1847*9a0e4156SSadaf Ebrahimi 	}
1848*9a0e4156SSadaf Ebrahimi 
1849*9a0e4156SSadaf Ebrahimi 	return 0;
1850*9a0e4156SSadaf Ebrahimi }
1851*9a0e4156SSadaf Ebrahimi 
1852*9a0e4156SSadaf Ebrahimi /*
1853*9a0e4156SSadaf Ebrahimi  * readOpcodeRegister - Reads an operand from the opcode field of an
1854*9a0e4156SSadaf Ebrahimi  *   instruction and interprets it appropriately given the operand width.
1855*9a0e4156SSadaf Ebrahimi  *   Handles AddRegFrm instructions.
1856*9a0e4156SSadaf Ebrahimi  *
1857*9a0e4156SSadaf Ebrahimi  * @param insn  - the instruction whose opcode field is to be read.
1858*9a0e4156SSadaf Ebrahimi  * @param size  - The width (in bytes) of the register being specified.
1859*9a0e4156SSadaf Ebrahimi  *                1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
1860*9a0e4156SSadaf Ebrahimi  *                RAX.
1861*9a0e4156SSadaf Ebrahimi  * @return      - 0 on success; nonzero otherwise.
1862*9a0e4156SSadaf Ebrahimi  */
readOpcodeRegister(struct InternalInstruction * insn,uint8_t size)1863*9a0e4156SSadaf Ebrahimi static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size)
1864*9a0e4156SSadaf Ebrahimi {
1865*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readOpcodeRegister()");
1866*9a0e4156SSadaf Ebrahimi 
1867*9a0e4156SSadaf Ebrahimi 	if (size == 0)
1868*9a0e4156SSadaf Ebrahimi 		size = insn->registerSize;
1869*9a0e4156SSadaf Ebrahimi 
1870*9a0e4156SSadaf Ebrahimi 	insn->operandSize = size;
1871*9a0e4156SSadaf Ebrahimi 
1872*9a0e4156SSadaf Ebrahimi 	switch (size) {
1873*9a0e4156SSadaf Ebrahimi 		case 1:
1874*9a0e4156SSadaf Ebrahimi 			insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
1875*9a0e4156SSadaf Ebrahimi 						| (insn->opcode & 7)));
1876*9a0e4156SSadaf Ebrahimi 			if (insn->rexPrefix &&
1877*9a0e4156SSadaf Ebrahimi 					insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
1878*9a0e4156SSadaf Ebrahimi 					insn->opcodeRegister < MODRM_REG_AL + 0x8) {
1879*9a0e4156SSadaf Ebrahimi 				insn->opcodeRegister = (Reg)(MODRM_REG_SPL
1880*9a0e4156SSadaf Ebrahimi 						+ (insn->opcodeRegister - MODRM_REG_AL - 4));
1881*9a0e4156SSadaf Ebrahimi 			}
1882*9a0e4156SSadaf Ebrahimi 
1883*9a0e4156SSadaf Ebrahimi 			break;
1884*9a0e4156SSadaf Ebrahimi 		case 2:
1885*9a0e4156SSadaf Ebrahimi 			insn->opcodeRegister = (Reg)(MODRM_REG_AX
1886*9a0e4156SSadaf Ebrahimi 					+ ((bFromREX(insn->rexPrefix) << 3)
1887*9a0e4156SSadaf Ebrahimi 						| (insn->opcode & 7)));
1888*9a0e4156SSadaf Ebrahimi 			break;
1889*9a0e4156SSadaf Ebrahimi 		case 4:
1890*9a0e4156SSadaf Ebrahimi 			insn->opcodeRegister = (Reg)(MODRM_REG_EAX
1891*9a0e4156SSadaf Ebrahimi 					+ ((bFromREX(insn->rexPrefix) << 3)
1892*9a0e4156SSadaf Ebrahimi 						| (insn->opcode & 7)));
1893*9a0e4156SSadaf Ebrahimi 			break;
1894*9a0e4156SSadaf Ebrahimi 		case 8:
1895*9a0e4156SSadaf Ebrahimi 			insn->opcodeRegister = (Reg)(MODRM_REG_RAX
1896*9a0e4156SSadaf Ebrahimi 					+ ((bFromREX(insn->rexPrefix) << 3)
1897*9a0e4156SSadaf Ebrahimi 						| (insn->opcode & 7)));
1898*9a0e4156SSadaf Ebrahimi 			break;
1899*9a0e4156SSadaf Ebrahimi 	}
1900*9a0e4156SSadaf Ebrahimi 
1901*9a0e4156SSadaf Ebrahimi 	return 0;
1902*9a0e4156SSadaf Ebrahimi }
1903*9a0e4156SSadaf Ebrahimi 
1904*9a0e4156SSadaf Ebrahimi /*
1905*9a0e4156SSadaf Ebrahimi  * readImmediate - Consumes an immediate operand from an instruction, given the
1906*9a0e4156SSadaf Ebrahimi  *   desired operand size.
1907*9a0e4156SSadaf Ebrahimi  *
1908*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose operand is to be read.
1909*9a0e4156SSadaf Ebrahimi  * @param size  - The width (in bytes) of the operand.
1910*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the immediate was successfully consumed; nonzero
1911*9a0e4156SSadaf Ebrahimi  *                otherwise.
1912*9a0e4156SSadaf Ebrahimi  */
readImmediate(struct InternalInstruction * insn,uint8_t size)1913*9a0e4156SSadaf Ebrahimi static int readImmediate(struct InternalInstruction *insn, uint8_t size)
1914*9a0e4156SSadaf Ebrahimi {
1915*9a0e4156SSadaf Ebrahimi 	uint8_t imm8;
1916*9a0e4156SSadaf Ebrahimi 	uint16_t imm16;
1917*9a0e4156SSadaf Ebrahimi 	uint32_t imm32;
1918*9a0e4156SSadaf Ebrahimi 	uint64_t imm64;
1919*9a0e4156SSadaf Ebrahimi 
1920*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readImmediate()");
1921*9a0e4156SSadaf Ebrahimi 
1922*9a0e4156SSadaf Ebrahimi 	if (insn->numImmediatesConsumed == 2) {
1923*9a0e4156SSadaf Ebrahimi 		//debug("Already consumed two immediates");
1924*9a0e4156SSadaf Ebrahimi 		return -1;
1925*9a0e4156SSadaf Ebrahimi 	}
1926*9a0e4156SSadaf Ebrahimi 
1927*9a0e4156SSadaf Ebrahimi 	if (size == 0)
1928*9a0e4156SSadaf Ebrahimi 		size = insn->immediateSize;
1929*9a0e4156SSadaf Ebrahimi 	else
1930*9a0e4156SSadaf Ebrahimi 		insn->immediateSize = size;
1931*9a0e4156SSadaf Ebrahimi 	insn->immediateOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1932*9a0e4156SSadaf Ebrahimi 
1933*9a0e4156SSadaf Ebrahimi 	switch (size) {
1934*9a0e4156SSadaf Ebrahimi 		case 1:
1935*9a0e4156SSadaf Ebrahimi 			if (consumeByte(insn, &imm8))
1936*9a0e4156SSadaf Ebrahimi 				return -1;
1937*9a0e4156SSadaf Ebrahimi 			insn->immediates[insn->numImmediatesConsumed] = imm8;
1938*9a0e4156SSadaf Ebrahimi 			break;
1939*9a0e4156SSadaf Ebrahimi 		case 2:
1940*9a0e4156SSadaf Ebrahimi 			if (consumeUInt16(insn, &imm16))
1941*9a0e4156SSadaf Ebrahimi 				return -1;
1942*9a0e4156SSadaf Ebrahimi 			insn->immediates[insn->numImmediatesConsumed] = imm16;
1943*9a0e4156SSadaf Ebrahimi 			break;
1944*9a0e4156SSadaf Ebrahimi 		case 4:
1945*9a0e4156SSadaf Ebrahimi 			if (consumeUInt32(insn, &imm32))
1946*9a0e4156SSadaf Ebrahimi 				return -1;
1947*9a0e4156SSadaf Ebrahimi 			insn->immediates[insn->numImmediatesConsumed] = imm32;
1948*9a0e4156SSadaf Ebrahimi 			break;
1949*9a0e4156SSadaf Ebrahimi 		case 8:
1950*9a0e4156SSadaf Ebrahimi 			if (consumeUInt64(insn, &imm64))
1951*9a0e4156SSadaf Ebrahimi 				return -1;
1952*9a0e4156SSadaf Ebrahimi 			insn->immediates[insn->numImmediatesConsumed] = imm64;
1953*9a0e4156SSadaf Ebrahimi 			break;
1954*9a0e4156SSadaf Ebrahimi 	}
1955*9a0e4156SSadaf Ebrahimi 
1956*9a0e4156SSadaf Ebrahimi 	insn->numImmediatesConsumed++;
1957*9a0e4156SSadaf Ebrahimi 
1958*9a0e4156SSadaf Ebrahimi 	return 0;
1959*9a0e4156SSadaf Ebrahimi }
1960*9a0e4156SSadaf Ebrahimi 
1961*9a0e4156SSadaf Ebrahimi /*
1962*9a0e4156SSadaf Ebrahimi  * readVVVV - Consumes vvvv from an instruction if it has a VEX prefix.
1963*9a0e4156SSadaf Ebrahimi  *
1964*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose operand is to be read.
1965*9a0e4156SSadaf Ebrahimi  * @return      - 0 if the vvvv was successfully consumed; nonzero
1966*9a0e4156SSadaf Ebrahimi  *                otherwise.
1967*9a0e4156SSadaf Ebrahimi  */
readVVVV(struct InternalInstruction * insn)1968*9a0e4156SSadaf Ebrahimi static int readVVVV(struct InternalInstruction *insn)
1969*9a0e4156SSadaf Ebrahimi {
1970*9a0e4156SSadaf Ebrahimi 	int vvvv;
1971*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readVVVV()");
1972*9a0e4156SSadaf Ebrahimi 
1973*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType == TYPE_EVEX)
1974*9a0e4156SSadaf Ebrahimi 		vvvv = (v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4 |
1975*9a0e4156SSadaf Ebrahimi 				vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]));
1976*9a0e4156SSadaf Ebrahimi 	else if (insn->vectorExtensionType == TYPE_VEX_3B)
1977*9a0e4156SSadaf Ebrahimi 		vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
1978*9a0e4156SSadaf Ebrahimi 	else if (insn->vectorExtensionType == TYPE_VEX_2B)
1979*9a0e4156SSadaf Ebrahimi 		vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
1980*9a0e4156SSadaf Ebrahimi 	else if (insn->vectorExtensionType == TYPE_XOP)
1981*9a0e4156SSadaf Ebrahimi 		vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
1982*9a0e4156SSadaf Ebrahimi 	else
1983*9a0e4156SSadaf Ebrahimi 		return -1;
1984*9a0e4156SSadaf Ebrahimi 
1985*9a0e4156SSadaf Ebrahimi 	if (insn->mode != MODE_64BIT)
1986*9a0e4156SSadaf Ebrahimi 		vvvv &= 0x7;
1987*9a0e4156SSadaf Ebrahimi 
1988*9a0e4156SSadaf Ebrahimi 	insn->vvvv = vvvv;
1989*9a0e4156SSadaf Ebrahimi 
1990*9a0e4156SSadaf Ebrahimi 	return 0;
1991*9a0e4156SSadaf Ebrahimi }
1992*9a0e4156SSadaf Ebrahimi 
1993*9a0e4156SSadaf Ebrahimi /*
1994*9a0e4156SSadaf Ebrahimi  * readMaskRegister - Reads an mask register from the opcode field of an
1995*9a0e4156SSadaf Ebrahimi  *   instruction.
1996*9a0e4156SSadaf Ebrahimi  *
1997*9a0e4156SSadaf Ebrahimi  * @param insn    - The instruction whose opcode field is to be read.
1998*9a0e4156SSadaf Ebrahimi  * @return        - 0 on success; nonzero otherwise.
1999*9a0e4156SSadaf Ebrahimi  */
readMaskRegister(struct InternalInstruction * insn)2000*9a0e4156SSadaf Ebrahimi static int readMaskRegister(struct InternalInstruction *insn)
2001*9a0e4156SSadaf Ebrahimi {
2002*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "readMaskRegister()");
2003*9a0e4156SSadaf Ebrahimi 
2004*9a0e4156SSadaf Ebrahimi 	if (insn->vectorExtensionType != TYPE_EVEX)
2005*9a0e4156SSadaf Ebrahimi 		return -1;
2006*9a0e4156SSadaf Ebrahimi 
2007*9a0e4156SSadaf Ebrahimi 	insn->writemask = aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]);
2008*9a0e4156SSadaf Ebrahimi 
2009*9a0e4156SSadaf Ebrahimi 	return 0;
2010*9a0e4156SSadaf Ebrahimi }
2011*9a0e4156SSadaf Ebrahimi 
2012*9a0e4156SSadaf Ebrahimi /*
2013*9a0e4156SSadaf Ebrahimi  * readOperands - Consults the specifier for an instruction and consumes all
2014*9a0e4156SSadaf Ebrahimi  *   operands for that instruction, interpreting them as it goes.
2015*9a0e4156SSadaf Ebrahimi  *
2016*9a0e4156SSadaf Ebrahimi  * @param insn  - The instruction whose operands are to be read and interpreted.
2017*9a0e4156SSadaf Ebrahimi  * @return      - 0 if all operands could be read; nonzero otherwise.
2018*9a0e4156SSadaf Ebrahimi  */
readOperands(struct InternalInstruction * insn)2019*9a0e4156SSadaf Ebrahimi static int readOperands(struct InternalInstruction *insn)
2020*9a0e4156SSadaf Ebrahimi {
2021*9a0e4156SSadaf Ebrahimi 	int index;
2022*9a0e4156SSadaf Ebrahimi 	int hasVVVV, needVVVV;
2023*9a0e4156SSadaf Ebrahimi 	int sawRegImm = 0;
2024*9a0e4156SSadaf Ebrahimi 
2025*9a0e4156SSadaf Ebrahimi 	// printf(">>> readOperands(): ID = %u\n", insn->instructionID);
2026*9a0e4156SSadaf Ebrahimi 	/* If non-zero vvvv specified, need to make sure one of the operands
2027*9a0e4156SSadaf Ebrahimi 	   uses it. */
2028*9a0e4156SSadaf Ebrahimi 	hasVVVV = !readVVVV(insn);
2029*9a0e4156SSadaf Ebrahimi 	needVVVV = hasVVVV && (insn->vvvv != 0);
2030*9a0e4156SSadaf Ebrahimi 
2031*9a0e4156SSadaf Ebrahimi 	for (index = 0; index < X86_MAX_OPERANDS; ++index) {
2032*9a0e4156SSadaf Ebrahimi 		//printf(">>> encoding[%u] = %u\n", index, x86OperandSets[insn->spec->operands][index].encoding);
2033*9a0e4156SSadaf Ebrahimi 		switch (x86OperandSets[insn->spec->operands][index].encoding) {
2034*9a0e4156SSadaf Ebrahimi 			case ENCODING_NONE:
2035*9a0e4156SSadaf Ebrahimi 			case ENCODING_SI:
2036*9a0e4156SSadaf Ebrahimi 			case ENCODING_DI:
2037*9a0e4156SSadaf Ebrahimi 				break;
2038*9a0e4156SSadaf Ebrahimi 			case ENCODING_REG:
2039*9a0e4156SSadaf Ebrahimi 			CASE_ENCODING_RM:
2040*9a0e4156SSadaf Ebrahimi 				if (readModRM(insn))
2041*9a0e4156SSadaf Ebrahimi 					return -1;
2042*9a0e4156SSadaf Ebrahimi 				if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
2043*9a0e4156SSadaf Ebrahimi 					return -1;
2044*9a0e4156SSadaf Ebrahimi 				// Apply the AVX512 compressed displacement scaling factor.
2045*9a0e4156SSadaf Ebrahimi 				if (x86OperandSets[insn->spec->operands][index].encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
2046*9a0e4156SSadaf Ebrahimi 					insn->displacement *= (int64_t)1 << (x86OperandSets[insn->spec->operands][index].encoding - ENCODING_RM);
2047*9a0e4156SSadaf Ebrahimi 				break;
2048*9a0e4156SSadaf Ebrahimi 			case ENCODING_CB:
2049*9a0e4156SSadaf Ebrahimi 			case ENCODING_CW:
2050*9a0e4156SSadaf Ebrahimi 			case ENCODING_CD:
2051*9a0e4156SSadaf Ebrahimi 			case ENCODING_CP:
2052*9a0e4156SSadaf Ebrahimi 			case ENCODING_CO:
2053*9a0e4156SSadaf Ebrahimi 			case ENCODING_CT:
2054*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "We currently don't hande code-offset encodings");
2055*9a0e4156SSadaf Ebrahimi 				return -1;
2056*9a0e4156SSadaf Ebrahimi 			case ENCODING_IB:
2057*9a0e4156SSadaf Ebrahimi 				if (sawRegImm) {
2058*9a0e4156SSadaf Ebrahimi 					/* Saw a register immediate so don't read again and instead split the
2059*9a0e4156SSadaf Ebrahimi 					   previous immediate.  FIXME: This is a hack. */
2060*9a0e4156SSadaf Ebrahimi 					insn->immediates[insn->numImmediatesConsumed] =
2061*9a0e4156SSadaf Ebrahimi 						insn->immediates[insn->numImmediatesConsumed - 1] & 0xf;
2062*9a0e4156SSadaf Ebrahimi 					++insn->numImmediatesConsumed;
2063*9a0e4156SSadaf Ebrahimi 					break;
2064*9a0e4156SSadaf Ebrahimi 				}
2065*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, 1))
2066*9a0e4156SSadaf Ebrahimi 					return -1;
2067*9a0e4156SSadaf Ebrahimi 				if (x86OperandSets[insn->spec->operands][index].type == TYPE_XMM128 ||
2068*9a0e4156SSadaf Ebrahimi 						x86OperandSets[insn->spec->operands][index].type == TYPE_XMM256)
2069*9a0e4156SSadaf Ebrahimi 					sawRegImm = 1;
2070*9a0e4156SSadaf Ebrahimi 				break;
2071*9a0e4156SSadaf Ebrahimi 			case ENCODING_IW:
2072*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, 2))
2073*9a0e4156SSadaf Ebrahimi 					return -1;
2074*9a0e4156SSadaf Ebrahimi 				break;
2075*9a0e4156SSadaf Ebrahimi 			case ENCODING_ID:
2076*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, 4))
2077*9a0e4156SSadaf Ebrahimi 					return -1;
2078*9a0e4156SSadaf Ebrahimi 				break;
2079*9a0e4156SSadaf Ebrahimi 			case ENCODING_IO:
2080*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, 8))
2081*9a0e4156SSadaf Ebrahimi 					return -1;
2082*9a0e4156SSadaf Ebrahimi 				break;
2083*9a0e4156SSadaf Ebrahimi 			case ENCODING_Iv:
2084*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, insn->immediateSize))
2085*9a0e4156SSadaf Ebrahimi 					return -1;
2086*9a0e4156SSadaf Ebrahimi 				break;
2087*9a0e4156SSadaf Ebrahimi 			case ENCODING_Ia:
2088*9a0e4156SSadaf Ebrahimi 				if (readImmediate(insn, insn->addressSize))
2089*9a0e4156SSadaf Ebrahimi 					return -1;
2090*9a0e4156SSadaf Ebrahimi 				/* Direct memory-offset (moffset) immediate will get mapped
2091*9a0e4156SSadaf Ebrahimi 				   to memory operand later. We want the encoding info to
2092*9a0e4156SSadaf Ebrahimi 				   reflect that as well. */
2093*9a0e4156SSadaf Ebrahimi 				insn->displacementOffset = insn->immediateOffset;
2094*9a0e4156SSadaf Ebrahimi 				insn->consumedDisplacement = true;
2095*9a0e4156SSadaf Ebrahimi 				insn->displacementSize = insn->immediateSize;
2096*9a0e4156SSadaf Ebrahimi 				insn->displacement = insn->immediates[insn->numImmediatesConsumed - 1];
2097*9a0e4156SSadaf Ebrahimi 				insn->immediateOffset = 0;
2098*9a0e4156SSadaf Ebrahimi 				insn->immediateSize = 0;
2099*9a0e4156SSadaf Ebrahimi 				break;
2100*9a0e4156SSadaf Ebrahimi 			case ENCODING_RB:
2101*9a0e4156SSadaf Ebrahimi 				if (readOpcodeRegister(insn, 1))
2102*9a0e4156SSadaf Ebrahimi 					return -1;
2103*9a0e4156SSadaf Ebrahimi 				break;
2104*9a0e4156SSadaf Ebrahimi 			case ENCODING_RW:
2105*9a0e4156SSadaf Ebrahimi 				if (readOpcodeRegister(insn, 2))
2106*9a0e4156SSadaf Ebrahimi 					return -1;
2107*9a0e4156SSadaf Ebrahimi 				break;
2108*9a0e4156SSadaf Ebrahimi 			case ENCODING_RD:
2109*9a0e4156SSadaf Ebrahimi 				if (readOpcodeRegister(insn, 4))
2110*9a0e4156SSadaf Ebrahimi 					return -1;
2111*9a0e4156SSadaf Ebrahimi 				break;
2112*9a0e4156SSadaf Ebrahimi 			case ENCODING_RO:
2113*9a0e4156SSadaf Ebrahimi 				if (readOpcodeRegister(insn, 8))
2114*9a0e4156SSadaf Ebrahimi 					return -1;
2115*9a0e4156SSadaf Ebrahimi 				break;
2116*9a0e4156SSadaf Ebrahimi 			case ENCODING_Rv:
2117*9a0e4156SSadaf Ebrahimi 				if (readOpcodeRegister(insn, 0))
2118*9a0e4156SSadaf Ebrahimi 					return -1;
2119*9a0e4156SSadaf Ebrahimi 				break;
2120*9a0e4156SSadaf Ebrahimi 			case ENCODING_FP:
2121*9a0e4156SSadaf Ebrahimi 				break;
2122*9a0e4156SSadaf Ebrahimi 			case ENCODING_VVVV:
2123*9a0e4156SSadaf Ebrahimi 				needVVVV = 0; /* Mark that we have found a VVVV operand. */
2124*9a0e4156SSadaf Ebrahimi 				if (!hasVVVV)
2125*9a0e4156SSadaf Ebrahimi 					return -1;
2126*9a0e4156SSadaf Ebrahimi 				if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
2127*9a0e4156SSadaf Ebrahimi 					return -1;
2128*9a0e4156SSadaf Ebrahimi 				break;
2129*9a0e4156SSadaf Ebrahimi 			case ENCODING_WRITEMASK:
2130*9a0e4156SSadaf Ebrahimi 				if (readMaskRegister(insn))
2131*9a0e4156SSadaf Ebrahimi 					return -1;
2132*9a0e4156SSadaf Ebrahimi 				break;
2133*9a0e4156SSadaf Ebrahimi 			case ENCODING_DUP:
2134*9a0e4156SSadaf Ebrahimi 				break;
2135*9a0e4156SSadaf Ebrahimi 			default:
2136*9a0e4156SSadaf Ebrahimi 				// dbgprintf(insn, "Encountered an operand with an unknown encoding.");
2137*9a0e4156SSadaf Ebrahimi 				return -1;
2138*9a0e4156SSadaf Ebrahimi 		}
2139*9a0e4156SSadaf Ebrahimi 	}
2140*9a0e4156SSadaf Ebrahimi 
2141*9a0e4156SSadaf Ebrahimi 	/* If we didn't find ENCODING_VVVV operand, but non-zero vvvv present, fail */
2142*9a0e4156SSadaf Ebrahimi 	if (needVVVV) return -1;
2143*9a0e4156SSadaf Ebrahimi 
2144*9a0e4156SSadaf Ebrahimi 	return 0;
2145*9a0e4156SSadaf Ebrahimi }
2146*9a0e4156SSadaf Ebrahimi 
2147*9a0e4156SSadaf Ebrahimi // return True if instruction is illegal to use with prefixes
2148*9a0e4156SSadaf Ebrahimi // This also check & fix the isPrefixNN when a prefix is irrelevant.
checkPrefix(struct InternalInstruction * insn)2149*9a0e4156SSadaf Ebrahimi static bool checkPrefix(struct InternalInstruction *insn)
2150*9a0e4156SSadaf Ebrahimi {
2151*9a0e4156SSadaf Ebrahimi 	// LOCK prefix
2152*9a0e4156SSadaf Ebrahimi 	if (insn->isPrefixf0) {
2153*9a0e4156SSadaf Ebrahimi 		switch(insn->instructionID) {
2154*9a0e4156SSadaf Ebrahimi 			default:
2155*9a0e4156SSadaf Ebrahimi 				// invalid LOCK
2156*9a0e4156SSadaf Ebrahimi 				return true;
2157*9a0e4156SSadaf Ebrahimi 
2158*9a0e4156SSadaf Ebrahimi 			// nop dword [rax]
2159*9a0e4156SSadaf Ebrahimi 			case X86_NOOPL:
2160*9a0e4156SSadaf Ebrahimi 
2161*9a0e4156SSadaf Ebrahimi 			// DEC
2162*9a0e4156SSadaf Ebrahimi 			case X86_DEC16m:
2163*9a0e4156SSadaf Ebrahimi 			case X86_DEC32m:
2164*9a0e4156SSadaf Ebrahimi 			case X86_DEC64m:
2165*9a0e4156SSadaf Ebrahimi 			case X86_DEC8m:
2166*9a0e4156SSadaf Ebrahimi 
2167*9a0e4156SSadaf Ebrahimi 			// ADC
2168*9a0e4156SSadaf Ebrahimi 			case X86_ADC16mi:
2169*9a0e4156SSadaf Ebrahimi 			case X86_ADC16mi8:
2170*9a0e4156SSadaf Ebrahimi 			case X86_ADC16mr:
2171*9a0e4156SSadaf Ebrahimi 			case X86_ADC32mi:
2172*9a0e4156SSadaf Ebrahimi 			case X86_ADC32mi8:
2173*9a0e4156SSadaf Ebrahimi 			case X86_ADC32mr:
2174*9a0e4156SSadaf Ebrahimi 			case X86_ADC64mi32:
2175*9a0e4156SSadaf Ebrahimi 			case X86_ADC64mi8:
2176*9a0e4156SSadaf Ebrahimi 			case X86_ADC64mr:
2177*9a0e4156SSadaf Ebrahimi 			case X86_ADC8mi:
2178*9a0e4156SSadaf Ebrahimi 			case X86_ADC8mi8:
2179*9a0e4156SSadaf Ebrahimi 			case X86_ADC8mr:
2180*9a0e4156SSadaf Ebrahimi 
2181*9a0e4156SSadaf Ebrahimi 			// ADD
2182*9a0e4156SSadaf Ebrahimi 			case X86_ADD16mi:
2183*9a0e4156SSadaf Ebrahimi 			case X86_ADD16mi8:
2184*9a0e4156SSadaf Ebrahimi 			case X86_ADD16mr:
2185*9a0e4156SSadaf Ebrahimi 			case X86_ADD32mi:
2186*9a0e4156SSadaf Ebrahimi 			case X86_ADD32mi8:
2187*9a0e4156SSadaf Ebrahimi 			case X86_ADD32mr:
2188*9a0e4156SSadaf Ebrahimi 			case X86_ADD64mi32:
2189*9a0e4156SSadaf Ebrahimi 			case X86_ADD64mi8:
2190*9a0e4156SSadaf Ebrahimi 			case X86_ADD64mr:
2191*9a0e4156SSadaf Ebrahimi 			case X86_ADD8mi:
2192*9a0e4156SSadaf Ebrahimi 			case X86_ADD8mi8:
2193*9a0e4156SSadaf Ebrahimi 			case X86_ADD8mr:
2194*9a0e4156SSadaf Ebrahimi 
2195*9a0e4156SSadaf Ebrahimi 			// AND
2196*9a0e4156SSadaf Ebrahimi 			case X86_AND16mi:
2197*9a0e4156SSadaf Ebrahimi 			case X86_AND16mi8:
2198*9a0e4156SSadaf Ebrahimi 			case X86_AND16mr:
2199*9a0e4156SSadaf Ebrahimi 			case X86_AND32mi:
2200*9a0e4156SSadaf Ebrahimi 			case X86_AND32mi8:
2201*9a0e4156SSadaf Ebrahimi 			case X86_AND32mr:
2202*9a0e4156SSadaf Ebrahimi 			case X86_AND64mi32:
2203*9a0e4156SSadaf Ebrahimi 			case X86_AND64mi8:
2204*9a0e4156SSadaf Ebrahimi 			case X86_AND64mr:
2205*9a0e4156SSadaf Ebrahimi 			case X86_AND8mi:
2206*9a0e4156SSadaf Ebrahimi 			case X86_AND8mi8:
2207*9a0e4156SSadaf Ebrahimi 			case X86_AND8mr:
2208*9a0e4156SSadaf Ebrahimi 
2209*9a0e4156SSadaf Ebrahimi 			// BTC
2210*9a0e4156SSadaf Ebrahimi 			case X86_BTC16mi8:
2211*9a0e4156SSadaf Ebrahimi 			case X86_BTC16mr:
2212*9a0e4156SSadaf Ebrahimi 			case X86_BTC32mi8:
2213*9a0e4156SSadaf Ebrahimi 			case X86_BTC32mr:
2214*9a0e4156SSadaf Ebrahimi 			case X86_BTC64mi8:
2215*9a0e4156SSadaf Ebrahimi 			case X86_BTC64mr:
2216*9a0e4156SSadaf Ebrahimi 
2217*9a0e4156SSadaf Ebrahimi 			// BTR
2218*9a0e4156SSadaf Ebrahimi 			case X86_BTR16mi8:
2219*9a0e4156SSadaf Ebrahimi 			case X86_BTR16mr:
2220*9a0e4156SSadaf Ebrahimi 			case X86_BTR32mi8:
2221*9a0e4156SSadaf Ebrahimi 			case X86_BTR32mr:
2222*9a0e4156SSadaf Ebrahimi 			case X86_BTR64mi8:
2223*9a0e4156SSadaf Ebrahimi 			case X86_BTR64mr:
2224*9a0e4156SSadaf Ebrahimi 
2225*9a0e4156SSadaf Ebrahimi 			// BTS
2226*9a0e4156SSadaf Ebrahimi 			case X86_BTS16mi8:
2227*9a0e4156SSadaf Ebrahimi 			case X86_BTS16mr:
2228*9a0e4156SSadaf Ebrahimi 			case X86_BTS32mi8:
2229*9a0e4156SSadaf Ebrahimi 			case X86_BTS32mr:
2230*9a0e4156SSadaf Ebrahimi 			case X86_BTS64mi8:
2231*9a0e4156SSadaf Ebrahimi 			case X86_BTS64mr:
2232*9a0e4156SSadaf Ebrahimi 
2233*9a0e4156SSadaf Ebrahimi 			// CMPXCHG
2234*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG16B:
2235*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG16rm:
2236*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG32rm:
2237*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG64rm:
2238*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG8rm:
2239*9a0e4156SSadaf Ebrahimi 			case X86_CMPXCHG8B:
2240*9a0e4156SSadaf Ebrahimi 
2241*9a0e4156SSadaf Ebrahimi 			// INC
2242*9a0e4156SSadaf Ebrahimi 			case X86_INC16m:
2243*9a0e4156SSadaf Ebrahimi 			case X86_INC32m:
2244*9a0e4156SSadaf Ebrahimi 			case X86_INC64m:
2245*9a0e4156SSadaf Ebrahimi 			case X86_INC8m:
2246*9a0e4156SSadaf Ebrahimi 
2247*9a0e4156SSadaf Ebrahimi 			// NEG
2248*9a0e4156SSadaf Ebrahimi 			case X86_NEG16m:
2249*9a0e4156SSadaf Ebrahimi 			case X86_NEG32m:
2250*9a0e4156SSadaf Ebrahimi 			case X86_NEG64m:
2251*9a0e4156SSadaf Ebrahimi 			case X86_NEG8m:
2252*9a0e4156SSadaf Ebrahimi 
2253*9a0e4156SSadaf Ebrahimi 			// NOT
2254*9a0e4156SSadaf Ebrahimi 			case X86_NOT16m:
2255*9a0e4156SSadaf Ebrahimi 			case X86_NOT32m:
2256*9a0e4156SSadaf Ebrahimi 			case X86_NOT64m:
2257*9a0e4156SSadaf Ebrahimi 			case X86_NOT8m:
2258*9a0e4156SSadaf Ebrahimi 
2259*9a0e4156SSadaf Ebrahimi 			// OR
2260*9a0e4156SSadaf Ebrahimi 			case X86_OR16mi:
2261*9a0e4156SSadaf Ebrahimi 			case X86_OR16mi8:
2262*9a0e4156SSadaf Ebrahimi 			case X86_OR16mr:
2263*9a0e4156SSadaf Ebrahimi 			case X86_OR32mi:
2264*9a0e4156SSadaf Ebrahimi 			case X86_OR32mi8:
2265*9a0e4156SSadaf Ebrahimi 			case X86_OR32mr:
2266*9a0e4156SSadaf Ebrahimi 			case X86_OR32mrLocked:
2267*9a0e4156SSadaf Ebrahimi 			case X86_OR64mi32:
2268*9a0e4156SSadaf Ebrahimi 			case X86_OR64mi8:
2269*9a0e4156SSadaf Ebrahimi 			case X86_OR64mr:
2270*9a0e4156SSadaf Ebrahimi 			case X86_OR8mi8:
2271*9a0e4156SSadaf Ebrahimi 			case X86_OR8mi:
2272*9a0e4156SSadaf Ebrahimi 			case X86_OR8mr:
2273*9a0e4156SSadaf Ebrahimi 
2274*9a0e4156SSadaf Ebrahimi 			// SBB
2275*9a0e4156SSadaf Ebrahimi 			case X86_SBB16mi:
2276*9a0e4156SSadaf Ebrahimi 			case X86_SBB16mi8:
2277*9a0e4156SSadaf Ebrahimi 			case X86_SBB16mr:
2278*9a0e4156SSadaf Ebrahimi 			case X86_SBB32mi:
2279*9a0e4156SSadaf Ebrahimi 			case X86_SBB32mi8:
2280*9a0e4156SSadaf Ebrahimi 			case X86_SBB32mr:
2281*9a0e4156SSadaf Ebrahimi 			case X86_SBB64mi32:
2282*9a0e4156SSadaf Ebrahimi 			case X86_SBB64mi8:
2283*9a0e4156SSadaf Ebrahimi 			case X86_SBB64mr:
2284*9a0e4156SSadaf Ebrahimi 			case X86_SBB8mi:
2285*9a0e4156SSadaf Ebrahimi 			case X86_SBB8mi8:
2286*9a0e4156SSadaf Ebrahimi 			case X86_SBB8mr:
2287*9a0e4156SSadaf Ebrahimi 
2288*9a0e4156SSadaf Ebrahimi 			// SUB
2289*9a0e4156SSadaf Ebrahimi 			case X86_SUB16mi:
2290*9a0e4156SSadaf Ebrahimi 			case X86_SUB16mi8:
2291*9a0e4156SSadaf Ebrahimi 			case X86_SUB16mr:
2292*9a0e4156SSadaf Ebrahimi 			case X86_SUB32mi:
2293*9a0e4156SSadaf Ebrahimi 			case X86_SUB32mi8:
2294*9a0e4156SSadaf Ebrahimi 			case X86_SUB32mr:
2295*9a0e4156SSadaf Ebrahimi 			case X86_SUB64mi32:
2296*9a0e4156SSadaf Ebrahimi 			case X86_SUB64mi8:
2297*9a0e4156SSadaf Ebrahimi 			case X86_SUB64mr:
2298*9a0e4156SSadaf Ebrahimi 			case X86_SUB8mi8:
2299*9a0e4156SSadaf Ebrahimi 			case X86_SUB8mi:
2300*9a0e4156SSadaf Ebrahimi 			case X86_SUB8mr:
2301*9a0e4156SSadaf Ebrahimi 
2302*9a0e4156SSadaf Ebrahimi 			// XADD
2303*9a0e4156SSadaf Ebrahimi 			case X86_XADD16rm:
2304*9a0e4156SSadaf Ebrahimi 			case X86_XADD32rm:
2305*9a0e4156SSadaf Ebrahimi 			case X86_XADD64rm:
2306*9a0e4156SSadaf Ebrahimi 			case X86_XADD8rm:
2307*9a0e4156SSadaf Ebrahimi 
2308*9a0e4156SSadaf Ebrahimi 			// XCHG
2309*9a0e4156SSadaf Ebrahimi 			case X86_XCHG16rm:
2310*9a0e4156SSadaf Ebrahimi 			case X86_XCHG32rm:
2311*9a0e4156SSadaf Ebrahimi 			case X86_XCHG64rm:
2312*9a0e4156SSadaf Ebrahimi 			case X86_XCHG8rm:
2313*9a0e4156SSadaf Ebrahimi 
2314*9a0e4156SSadaf Ebrahimi 			// XOR
2315*9a0e4156SSadaf Ebrahimi 			case X86_XOR16mi:
2316*9a0e4156SSadaf Ebrahimi 			case X86_XOR16mi8:
2317*9a0e4156SSadaf Ebrahimi 			case X86_XOR16mr:
2318*9a0e4156SSadaf Ebrahimi 			case X86_XOR32mi:
2319*9a0e4156SSadaf Ebrahimi 			case X86_XOR32mi8:
2320*9a0e4156SSadaf Ebrahimi 			case X86_XOR32mr:
2321*9a0e4156SSadaf Ebrahimi 			case X86_XOR64mi32:
2322*9a0e4156SSadaf Ebrahimi 			case X86_XOR64mi8:
2323*9a0e4156SSadaf Ebrahimi 			case X86_XOR64mr:
2324*9a0e4156SSadaf Ebrahimi 			case X86_XOR8mi8:
2325*9a0e4156SSadaf Ebrahimi 			case X86_XOR8mi:
2326*9a0e4156SSadaf Ebrahimi 			case X86_XOR8mr:
2327*9a0e4156SSadaf Ebrahimi 
2328*9a0e4156SSadaf Ebrahimi 				// this instruction can be used with LOCK prefix
2329*9a0e4156SSadaf Ebrahimi 				return false;
2330*9a0e4156SSadaf Ebrahimi 		}
2331*9a0e4156SSadaf Ebrahimi 	}
2332*9a0e4156SSadaf Ebrahimi 
2333*9a0e4156SSadaf Ebrahimi 	// REPNE prefix
2334*9a0e4156SSadaf Ebrahimi 	if (insn->isPrefixf2) {
2335*9a0e4156SSadaf Ebrahimi 		// 0xf2 can be a part of instruction encoding, but not really a prefix.
2336*9a0e4156SSadaf Ebrahimi 		// In such a case, clear it.
2337*9a0e4156SSadaf Ebrahimi 		if (insn->twoByteEscape == 0x0f) {
2338*9a0e4156SSadaf Ebrahimi 			insn->prefix0 = 0;
2339*9a0e4156SSadaf Ebrahimi 		}
2340*9a0e4156SSadaf Ebrahimi 	}
2341*9a0e4156SSadaf Ebrahimi 
2342*9a0e4156SSadaf Ebrahimi 	// no invalid prefixes
2343*9a0e4156SSadaf Ebrahimi 	return false;
2344*9a0e4156SSadaf Ebrahimi }
2345*9a0e4156SSadaf Ebrahimi 
2346*9a0e4156SSadaf Ebrahimi /*
2347*9a0e4156SSadaf Ebrahimi  * decodeInstruction - Reads and interprets a full instruction provided by the
2348*9a0e4156SSadaf Ebrahimi  *   user.
2349*9a0e4156SSadaf Ebrahimi  *
2350*9a0e4156SSadaf Ebrahimi  * @param insn      - A pointer to the instruction to be populated.  Must be
2351*9a0e4156SSadaf Ebrahimi  *                    pre-allocated.
2352*9a0e4156SSadaf Ebrahimi  * @param reader    - The function to be used to read the instruction's bytes.
2353*9a0e4156SSadaf Ebrahimi  * @param readerArg - A generic argument to be passed to the reader to store
2354*9a0e4156SSadaf Ebrahimi  *                    any internal state.
2355*9a0e4156SSadaf Ebrahimi  * @param startLoc  - The address (in the reader's address space) of the first
2356*9a0e4156SSadaf Ebrahimi  *                    byte in the instruction.
2357*9a0e4156SSadaf Ebrahimi  * @param mode      - The mode (real mode, IA-32e, or IA-32e in 64-bit mode) to
2358*9a0e4156SSadaf Ebrahimi  *                    decode the instruction in.
2359*9a0e4156SSadaf Ebrahimi  * @return          - 0 if instruction is valid; nonzero if not.
2360*9a0e4156SSadaf Ebrahimi  */
decodeInstruction(struct InternalInstruction * insn,byteReader_t reader,const void * readerArg,uint64_t startLoc,DisassemblerMode mode)2361*9a0e4156SSadaf Ebrahimi int decodeInstruction(struct InternalInstruction *insn,
2362*9a0e4156SSadaf Ebrahimi 		byteReader_t reader,
2363*9a0e4156SSadaf Ebrahimi 		const void *readerArg,
2364*9a0e4156SSadaf Ebrahimi 		uint64_t startLoc,
2365*9a0e4156SSadaf Ebrahimi 		DisassemblerMode mode)
2366*9a0e4156SSadaf Ebrahimi {
2367*9a0e4156SSadaf Ebrahimi 	insn->reader = reader;
2368*9a0e4156SSadaf Ebrahimi 	insn->readerArg = readerArg;
2369*9a0e4156SSadaf Ebrahimi 	insn->startLocation = startLoc;
2370*9a0e4156SSadaf Ebrahimi 	insn->readerCursor = startLoc;
2371*9a0e4156SSadaf Ebrahimi 	insn->mode = mode;
2372*9a0e4156SSadaf Ebrahimi 
2373*9a0e4156SSadaf Ebrahimi 	if (readPrefixes(insn)       ||
2374*9a0e4156SSadaf Ebrahimi 			readOpcode(insn)         ||
2375*9a0e4156SSadaf Ebrahimi 			getID(insn)      ||
2376*9a0e4156SSadaf Ebrahimi 			insn->instructionID == 0 ||
2377*9a0e4156SSadaf Ebrahimi 			checkPrefix(insn) ||
2378*9a0e4156SSadaf Ebrahimi 			readOperands(insn))
2379*9a0e4156SSadaf Ebrahimi 		return -1;
2380*9a0e4156SSadaf Ebrahimi 
2381*9a0e4156SSadaf Ebrahimi 	insn->length = (size_t)(insn->readerCursor - insn->startLocation);
2382*9a0e4156SSadaf Ebrahimi 
2383*9a0e4156SSadaf Ebrahimi 	// instruction length must be <= 15 to be valid
2384*9a0e4156SSadaf Ebrahimi 	if (insn->length > 15)
2385*9a0e4156SSadaf Ebrahimi 		return -1;
2386*9a0e4156SSadaf Ebrahimi 
2387*9a0e4156SSadaf Ebrahimi 	if (insn->operandSize == 0)
2388*9a0e4156SSadaf Ebrahimi 		insn->operandSize = insn->registerSize;
2389*9a0e4156SSadaf Ebrahimi 
2390*9a0e4156SSadaf Ebrahimi 	insn->operands = &x86OperandSets[insn->spec->operands][0];
2391*9a0e4156SSadaf Ebrahimi 
2392*9a0e4156SSadaf Ebrahimi 	// dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu",
2393*9a0e4156SSadaf Ebrahimi 	// 		startLoc, insn->readerCursor, insn->length);
2394*9a0e4156SSadaf Ebrahimi 
2395*9a0e4156SSadaf Ebrahimi 	//if (insn->length > 15)
2396*9a0e4156SSadaf Ebrahimi 	//	dbgprintf(insn, "Instruction exceeds 15-byte limit");
2397*9a0e4156SSadaf Ebrahimi 
2398*9a0e4156SSadaf Ebrahimi #if 0
2399*9a0e4156SSadaf Ebrahimi 	printf("\n>>> x86OperandSets = %lu\n", sizeof(x86OperandSets));
2400*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerInstrSpecifiers = %lu\n", sizeof(x86DisassemblerInstrSpecifiers));
2401*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerContexts = %lu\n", sizeof(x86DisassemblerContexts));
2402*9a0e4156SSadaf Ebrahimi 	printf(">>> modRMTable = %lu\n", sizeof(modRMTable));
2403*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerOneByteOpcodes = %lu\n", sizeof(x86DisassemblerOneByteOpcodes));
2404*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerTwoByteOpcodes = %lu\n", sizeof(x86DisassemblerTwoByteOpcodes));
2405*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerThreeByte38Opcodes = %lu\n", sizeof(x86DisassemblerThreeByte38Opcodes));
2406*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerThreeByte3AOpcodes = %lu\n", sizeof(x86DisassemblerThreeByte3AOpcodes));
2407*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerThreeByteA6Opcodes = %lu\n", sizeof(x86DisassemblerThreeByteA6Opcodes));
2408*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerThreeByteA7Opcodes= %lu\n", sizeof(x86DisassemblerThreeByteA7Opcodes));
2409*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerXOP8Opcodes = %lu\n", sizeof(x86DisassemblerXOP8Opcodes));
2410*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerXOP9Opcodes = %lu\n", sizeof(x86DisassemblerXOP9Opcodes));
2411*9a0e4156SSadaf Ebrahimi 	printf(">>> x86DisassemblerXOPAOpcodes = %lu\n\n", sizeof(x86DisassemblerXOPAOpcodes));
2412*9a0e4156SSadaf Ebrahimi #endif
2413*9a0e4156SSadaf Ebrahimi 
2414*9a0e4156SSadaf Ebrahimi 	return 0;
2415*9a0e4156SSadaf Ebrahimi }
2416*9a0e4156SSadaf Ebrahimi 
2417*9a0e4156SSadaf Ebrahimi #endif
2418*9a0e4156SSadaf Ebrahimi 
2419