1 // Copyright (C) 2004, Matt Conover (mconover@gmail.com)
2 #ifndef X86_DISASM_H
3 #define X86_DISASM_H
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 // NOTE: the processor may actually accept less than this amount (officially 15)
9 // #define AMD64_MAX_INSTRUCTION_LEN 15 // theoretical max 25=5+2+1+1+8+8
10 #define AMD64_MAX_PREFIX_LENGTH 5 // 4 legacy + 1 rex
11 #define AMD64_MAX_ADDRESS_LENGTH 18 // modrm + sib + 8 byte displacement + 8 byte immediate value
12 
13 // NOTE: the processor may actually accept less than this amount (officially 15)
14 #define X86_MAX_INSTRUCTION_LEN 15 // theoretical 16=4+2+1+1+4+4
15 #define X86_MAX_PREFIX_LENGTH 4
16 #define X86_MAX_OPCODE_LENGTH 3 // third byte is either a suffix or prefix
17 #define X86_MAX_ADDRESS_LENGTH 10 // modrm + sib + 4 byte displacement + 4 byte immediate value
18 #define X86_MAX_OPERANDS 3
19 
20 #define X86_PREFIX(a) ((a)->MnemonicFlags == ITYPE_EXT_PREFIX)
21 #define X86_SPECIAL_EXTENSION(a) ((a)->MnemonicFlags & (ITYPE_EXT_MODRM|ITYPE_EXT_FPU|ITYPE_EXT_SUFFIX|ITYPE_EXT_64))
22 #define X86_EXTENDED_OPCODE(a) ((a)->Table)
23 #define X86_INVALID(a) (!(a)->MnemonicFlags && !(a)->Table)
24 #define X86_OPERAND_COUNT(a) ((a)->OperandFlags[0] ? ((a)->OperandFlags[1] ? ((a)->OperandFlags[2] ? 3 : 2) : 1) : 0)
25 #define X86_GET_CATEGORY(p) ((p)->MnemonicFlags & ITYPE_GROUP_MASK)
26 #define X86_GET_TYPE(p) ((p)->MnemonicFlags & ITYPE_TYPE_MASK)
27 
28 // Various instructions being specially decoded
29 #define X86_TWO_BYTE_OPCODE 0x0f
30 #define PREFIX_SEGMENT_OVERRIDE_ES 0x26
31 #define PREFIX_SEGMENT_OVERRIDE_CS 0x2e
32 #define PREFIX_BRANCH_NOT_TAKEN 0x2e // used only with conditional jumps
33 #define PREFIX_SEGMENT_OVERRIDE_SS 0x36
34 #define PREFIX_SEGMENT_OVERRIDE_DS 0x3e
35 #define PREFIX_BRANCH_TAKEN 0x3e // used only with conditional jumps
36 #define PREFIX_SEGMENT_OVERRIDE_FS 0x64
37 #define PREFIX_SEGMENT_OVERRIDE_GS 0x65
38 #define PREFIX_OPERAND_SIZE 0x66
39 #define PREFIX_ADDRESS_SIZE 0x67
40 #define PREFIX_LOCK 0xf0
41 #define PREFIX_REPNE 0xf2
42 #define PREFIX_REP 0xf3
43 
44 //////////////////////////////////////////////////////////////////
45 // Implicit operand handling
46 //////////////////////////////////////////////////////////////////
47 
48 #define X86_AMODE_MASK   0x00FF0000 // bits 16-23 (AMODE_*)
49 #define X86_OPFLAGS_MASK 0x0000FF80 // bits 7-15 (OPTYPE_*)
50 #define X86_OPTYPE_MASK  0xFF0000FF // bits 0-7 (OPTYPE_* below + OP_REG) and 24-31 (OPTYPE_* above)
51 
52 #define OPTYPE_0   0x01
53 #define OPTYPE_1   0x02
54 #define OPTYPE_FF  0x03
55 //...
56 #define OPTYPE_CS  0x10
57 #define OPTYPE_DS  0x11
58 #define OPTYPE_ES  0x12
59 #define OPTYPE_FS  0x13
60 #define OPTYPE_GS  0x14
61 #define OPTYPE_SS  0x15
62 #define OPTYPE_CR0 0x16
63 #define OPTYPE_TSC 0x17 // time stamp counter
64 //...
65 #define OPTYPE_FLAGS  0x20
66 #define OPTYPE_xFLAGS 0x21 // RFLAGS/EFLAGS (depending on operand size)
67 #define OPTYPE_xCX_HI_xBX_LO 0x22 // represented by 2 registers CX:BX or ECX:EBX (depending on operand size)
68 #define OPTYPE_xDX_HI_xAX_LO 0x23 // DX:AX or EDX:EAX (depending on operand size)
69 #define OPTYPE_EDX_HI_EAX_LO 0x24 // DX:AX or EDX:EAX (depending on operand size)
70 #define OPTYPE_EDX_ECX_EBX_EAX 0x25 // all registers are set
71 //...
72 #define OPTYPE_STx 0x30
73 #define OPTYPE_ST0 0x31
74 #define OPTYPE_ST1 0x32
75 #define OPTYPE_FPU_STATUS  0x33
76 #define OPTYPE_FPU_CONTROL 0x34
77 #define OPTYPE_FPU_TAG 0x35
78 #define OPTYPE_FLDZ   0x36 // 0
79 #define OPTYPE_FLD1   0x37 // 1
80 #define OPTYPE_FLDPI  0x38 // pi
81 #define OPTYPE_FLDL2T 0x39 // lg 10
82 #define OPTYPE_FLDL2E 0x3A // lg e
83 #define OPTYPE_FLDLG2 0x3B // log_10 2
84 #define OPTYPE_FLDLN2 0x3C // log_e 2
85 //...
86 #define OPTYPE_CS_MSR 0x40
87 #define OPTYPE_EIP_MSR 0x41
88 #define OPTYPE_ESP_MSR 0x42
89 #define OPTYPE_KERNELBASE_MSR 0x43
90 #define OPTYPE_FMASK_MSR 0x44
91 #define OPTYPE_STAR_MSR 0x45
92 #define OPTYPE_CSTAR_MSR 0x46 // 32-bit mode
93 #define OPTYPE_LSTAR_MSR 0x47 // 64-bit mode
94 
95 
96 // NOTE: OPTYPES >= 0x80 reserved for registers (OP_REG+XX)
97 #define OPTYPE_REG_AL (OP_REG+0x01)
98 #define OPTYPE_REG_CL (OP_REG+0x02)
99 #define OPTYPE_REG_AH (OP_REG+0x03)
100 #define OPTYPE_REG_AX (OP_REG+0x04)
101 #define OPTYPE_REG_DX (OP_REG+0x05)
102 #define OPTYPE_REG_ECX (OP_REG+0x06)
103 #define OPTYPE_REG8 (OP_REG+0x07)
104 
105 // If address size is 2, use BP
106 // If address size is 4, use EBP
107 // If address size is 8, use RBP
108 #define OPTYPE_REG_xBP (OP_REG+0x08)
109 
110 // If address size is 2, use BP
111 // If address size is 4, use EBP
112 // If address size is 8, use RBP
113 #define OPTYPE_REG_xSP (OP_REG+0x09)
114 
115 // If operand size is 2, take 8-bit register
116 // If operand size is 4, take 16-bit register
117 // If operand size is 8, take 32-bit register
118 #define OPTYPE_REG_xAX_SMALL (OP_REG+0x0a)
119 
120 // If operand size is 2, take 16-bit register
121 // If operand size is 4, take 32-bit register
122 // If operand size is 8, take 64-bit register
123 #define OPTYPE_REG_xAX_BIG (OP_REG+0x0b)
124 
125 typedef enum _CPU_TYPE
126 {
127 	CPU_UNKNOWN=0,
128 
129 	///////////////////////////////////////
130 	// 1st generation
131 	///////////////////////////////////////
132 	// 1978
133 	//CPU_8086 = 1MB address limit, 16-bit registers
134 	// 1982
135 	//CPU_i186
136 
137 	///////////////////////////////////////
138 	// 2nd generation
139 	///////////////////////////////////////
140 	// 1982
141 	//CPU_I286 // 16MB limit, 16-bit registers, added protected mode
142 	CPU_I287, // CPU_I286 + math coprocessor
143 
144 	///////////////////////////////////////
145 	// 3rd generation
146 	///////////////////////////////////////
147 	// 1985
148 	CPU_I386, // 32-bit registers, 4GB memory limit
149 	// 1988
150 	CPU_I387, // CPU_I386 + math coprocessor
151 
152 	///////////////////////////////////////
153 	// 4th generation (1989)
154 	///////////////////////////////////////
155 	CPU_I486,
156 
157 	///////////////////////////////////////
158 	// 5th generation
159 	///////////////////////////////////////
160 	// 1993
161 	CPU_PENTIUM, // superscalar architecture
162 	// 1997
163 	//CPU_PENTIUM_MMX
164 
165 	///////////////////////////////////////
166 	// 6th generation (1995)
167 	///////////////////////////////////////
168 	CPU_PENTIUM_PRO, // P6 architecture, no MMX, out-of-order execution, speculative execution
169 	//CPU_CYRIX_6X86,
170 	//CPU_AMD_K5 // RISC processor
171 	// 1997
172 	CPU_PENTIUM2, // Pentium Pro architecture + MMX
173 	//CPU_AMD_K6,
174 	//CPU_CYRIX_6X86MX, // Cyrix 6x86 + MMX
175 	// 1998
176 	CPU_AMD_K6_2, // added 3DNow! (MMX)
177 	// 1999
178 	// CPU_AMD_K6_3 // added SSE
179 
180 	///////////////////////////////////////
181 	// 7th generation
182 	///////////////////////////////////////
183 	// 1999
184 	CPU_PENTIUM3, // introduced SSE
185 	// CPU_AMD_K7 // aka Athlon
186 	// 2000
187 	CPU_PENTIUM4, // introduced SSE2 and hyperthreading
188 
189 	// 2004? 2005?
190 	CPU_PRESCOTT, // introduced SSE3
191 
192 	///////////////////////////////////////
193 	// 8th generation (X86-64)
194 	// IA32 instruction set with 64-bit extensions, >4GB RAM
195 	///////////////////////////////////////
196 
197 	// 2003
198 	CPU_AMD64, // includes Athlon 64 and Opteron aka X86-64
199 
200 	// 2004?
201 	//CPU_EMD64 // Intel's version of AMD64
202 	CPU_IA64 // aka Itanium: new instruction set -- adds JMPE to IA32 mode to return to IA64 native code
203 
204 } CPU_TYPE;
205 
206 //////////////////////////////////////////////////////////////////
207 // Conditions (these can be OR'd)
208 //////////////////////////////////////////////////////////////////
209 
210 // Used for Flags.Preconditions
211 #define COND_O   (1<<0)  // overflow (signed)
212 #define COND_C   (1<<1)  // below (unsigned)
213 #define COND_Z   (1<<2)  // equal (unsigned)
214 #define COND_S   (1<<3)  // sign set (signed)
215 #define COND_P   (1<<4)  // parity even
216 #define COND_BE  (1<<5)  // CF or ZF is set (unsigned)
217 #define COND_L   (1<<6)  // (SF && !OF) || (OF && !SF)
218 #define COND_LE  (1<<7)  // ZF || (SF && !OF) || (OF && !SF) (signed)
219 #define COND_NO  (1<<8)  // !O
220 #define COND_NC  (1<<9)  // !C (not below, above or equal to)
221 #define COND_NZ  (1<<10) // !Z (not equal)
222 #define COND_NS  (1<<11) // !S
223 #define COND_NP  (1<<12) // !P (parity odd)
224 #define COND_NL  (1<<13) // (!SF && !OF) || (SF && OF)
225 #define COND_G   (1<<14) // !ZF && ((!SF && !OF) || (SF && OF))
226 #define COND_D   (1<<15) // DF
227 #define COND_REG_xCX_BIG_Z  (1<<16) // CX/ECX/RCX (depending on address size) == 0
228 #define COND_REG_xCX_BIG_NZ (1<<17) // CX/ECX/RCX (depending on address size) != 0
229 #define COND_OP1_EQ_OP2 (1<<18)
230 #define COND_OP1_EQ_OP3 (1<<19)
231 #define COND_B   COND_C
232 #define COND_NAE COND_C
233 #define COND_E   COND_Z
234 #define COND_NA  COND_BE
235 #define COND_PE  COND_P
236 #define COND_U   COND_P
237 #define COND_NGE COND_L
238 #define COND_NG  COND_LE
239 #define COND_PO  COND_NP
240 #define COND_NU  COND_NP
241 #define COND_NE  COND_NZ
242 #define COND_NB  COND_NC
243 #define COND_AE  COND_NC
244 #define COND_NE  COND_NZ
245 #define COND_A   (COND_NC|COND_NZ)
246 #define COND_NBE COND_A
247 #define COND_GE COND_NL
248 #define COND_NLE COND_G
249 
250 // Used for Opcode.FlagsChanged
251 #define FLAG_CF_SET (1<<0)
252 #define FLAG_DF_SET (1<<1)
253 #define FLAG_IF_SET (1<<2)
254 #define FLAG_SET_MASK (FLAG_CF_SET|FLAG_DF_SET|FLAG_IF_SET)
255 
256 #define FLAG_SF_CLR (1<<3)
257 #define FLAG_ZF_CLR (1<<4)
258 #define FLAG_AF_CLR (1<<5)
259 #define FLAG_CF_CLR (1<<6)
260 #define FLAG_DF_CLR (1<<7)
261 #define FLAG_IF_CLR (1<<8)
262 #define FLAG_OF_CLR (1<<9)
263 #define FPU_C0_CLR (1<<19)
264 #define FPU_C1_CLR (1<<20)
265 #define FPU_C2_CLR (1<<21)
266 #define FPU_C3_CLR (1<<22)
267 #define FPU_ALL_CLR (FPU_C0_CLR|FPU_C1_CLR|FPU_C2_CLR|FPU_C3_CLR)
268 #define FLAG_CLR_MASK (FLAG_SF_CLR|FLAG_ZF_CLR|FLAG_AF_CLR|FLAG_CF_CLR|FLAG_DF_CLR|FLAG_IF_CLR|FLAG_OF_CLR|FPU_ALL_CLR)
269 
270 #define FLAG_OF_MOD (1<<10)
271 #define FLAG_SF_MOD (1<<11)
272 #define FLAG_ZF_MOD (1<<12)
273 #define FLAG_AF_MOD (1<<13)
274 #define FLAG_PF_MOD (1<<14)
275 #define FLAG_CF_MOD (1<<15)
276 #define FLAG_DF_MOD (1<<16)
277 #define FLAG_IF_MOD (1<<17)
278 #define FLAG_ALL_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD|FLAG_DF_MOD|FLAG_IF_MOD)
279 #define FLAG_COMMON_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD)
280 #define FPU_C0_MOD (1<<23)
281 #define FPU_C1_MOD (1<<24)
282 #define FPU_C2_MOD (1<<25)
283 #define FPU_C3_MOD (1<<26)
284 #define FPU_ALL_MOD (FPU_C0_MOD|FPU_C1_MOD|FPU_C2_MOD|FPU_C3_MOD)
285 #define FLAG_MOD_MASK (FLAG_ALL_MOD|FPU_ALL_MOD)
286 
287 #define FLAG_CF_TOG (1<<18)
288 #define FLAG_TOG_MASK FLAG_CF_TOG
289 
290 // Used for Opcode.ResultsIfTrue and Opcode.ResultsIfFalse
291 #define OP1_DST         (1<<0)
292 #define OP2_DST         (1<<1)
293 #define OP3_DST         (1<<2)
294 #define OP1_SRC         (1<<3)
295 #define OP2_SRC         (1<<4)
296 #define OP3_SRC         (1<<5)
297 #define FPU_STACK_INC   (1<<6)
298 #define FPU_STACK_INC2  (1<<7)
299 #define FPU_STACK_DEC   (1<<8)
300 #define SERIALIZE_WRITE (1<<9)
301 #define SERIALIZE_READ  (1<<10)
302 #define xCX_DEC         (1<<11)
303 #define xCX_REP_DEC     (1<<12)
304 #define xDI_DEC         (1<<13)
305 #define xDI_INC         (1<<14)
306 #define xSI_DEC         (1<<15)
307 #define xSI_INC         (1<<16)
308 #define xDI_DECx        (1<<17)
309 #define xDI_INCx        (1<<18)
310 #define xSI_DECx        (1<<19)
311 #define xSI_INCx        (1<<20)
312 #define FPU_STACK_PUSH FPU_STACK_DEC
313 #define FPU_STACK_POP  FPU_STACK_INC
314 #define FPU_STACK_POP2 FPU_STACK_INC2
315 #define SERIALIZE_ALL (SERIALIZE_WRITE|SERIALIZE_READ)
316 
317 #define X86_SEGMENT_OFFSET 0x00
318 #define X86_TEST_OFFSET    0x10
319 #define X86_CONTROL_OFFSET 0x20
320 #define X86_DEBUG_OFFSET   0x30
321 #define X86_FPU_OFFSET     0x40
322 #define X86_MMX_OFFSET     0x50
323 #define X86_XMM_OFFSET     0x60
324 #define X86_8BIT_OFFSET    0x70
325 #define X86_16BIT_OFFSET   0x80
326 #define X86_32BIT_OFFSET   0x90
327 #define AMD64_8BIT_OFFSET  0xA0
328 #define AMD64_16BIT_OFFSET 0xB0
329 #define AMD64_32BIT_OFFSET 0xC0
330 #define AMD64_64BIT_OFFSET 0xD0
331 
332 typedef enum _X86_REGISTER
333 {
334 	// Segments
335 	X86_SEG_ES = X86_SEGMENT_OFFSET,
336 	X86_SEG_CS,
337 	X86_SEG_SS,
338 	X86_SEG_DS,
339 	X86_SEG_FS,
340 	X86_SEG_GS,
341 
342 	// Miscellaneous
343 	X86_REG_FLAGS,
344 	X86_REG_EFLAGS,
345 	AMD64_REG_RFLAGS,
346 	X86_REG_IP,
347 	X86_REG_EIP,
348 	AMD64_REG_RIP,
349 
350 	// Test registers
351 	X86_REG_TR0 = X86_TEST_OFFSET,
352 	X86_REG_TR1,
353 	X86_REG_TR2,
354 	X86_REG_TR3,
355 	X86_REG_TR4,
356 	X86_REG_TR5,
357 	X86_REG_TR6,
358 	X86_REG_TR7,
359 	X86_REG_TR8,
360 	X86_REG_TR9,
361 	X86_REG_TR10,
362 	X86_REG_TR11,
363 	X86_REG_TR12,
364 	X86_REG_TR13,
365 	X86_REG_TR14,
366 	X86_REG_TR15,
367 
368 	// Control registers
369 	X86_REG_CR0=X86_CONTROL_OFFSET,
370 	X86_REG_CR1,
371 	X86_REG_CR2,
372 	X86_REG_CR3,
373 	X86_REG_CR4,
374 	X86_REG_CR5,
375 	X86_REG_CR6,
376 	X86_REG_CR7,
377 	X86_REG_CR8,
378 	X86_REG_CR9,
379 	X86_REG_CR10,
380 	X86_REG_CR11,
381 	X86_REG_CR12,
382 	X86_REG_CR13,
383 	X86_REG_CR14,
384 	X86_REG_CR15,
385 
386 	// Debug registers
387 	X86_REG_DR0=X86_DEBUG_OFFSET,
388 	X86_REG_DR1,
389 	X86_REG_DR2,
390 	X86_REG_DR3,
391 	X86_REG_DR4,
392 	X86_REG_DR5,
393 	X86_REG_DR6,
394 	X86_REG_DR7,
395 	X86_REG_DR8,
396 	X86_REG_DR9,
397 	X86_REG_DR10,
398 	X86_REG_DR11,
399 	X86_REG_DR12,
400 	X86_REG_DR13,
401 	X86_REG_DR14,
402 	X86_REG_DR15,
403 
404 	// FPU registers
405 	X86_REG_ST0=X86_FPU_OFFSET,
406 	X86_REG_ST1,
407 	X86_REG_ST2,
408 	X86_REG_ST3,
409 	X86_REG_ST4,
410 	X86_REG_ST5,
411 	X86_REG_ST6,
412 	X86_REG_ST7,
413 
414 	// MMX registers
415 	X86_REG_MM0=X86_MMX_OFFSET,
416 	X86_REG_MM1,
417 	X86_REG_MM2,
418 	X86_REG_MM3,
419 	X86_REG_MM4,
420 	X86_REG_MM5,
421 	X86_REG_MM6,
422 	X86_REG_MM7,
423 
424 	// XMM registers
425 	X86_REG_XMM0=X86_XMM_OFFSET,
426 	X86_REG_XMM1,
427 	X86_REG_XMM2,
428 	X86_REG_XMM3,
429 	X86_REG_XMM4,
430 	X86_REG_XMM5,
431 	X86_REG_XMM6,
432 	X86_REG_XMM7,
433 
434 	// 8-bit registers
435 	X86_REG_AL=X86_8BIT_OFFSET,
436 	X86_REG_CL,
437 	X86_REG_DL,
438 	X86_REG_BL,
439 	X86_REG_AH,
440 	X86_REG_CH,
441 	X86_REG_DH,
442 	X86_REG_BH,
443 
444 	// 16-bit registers
445 	X86_REG_AX=X86_16BIT_OFFSET,
446 	X86_REG_CX,
447 	X86_REG_DX,
448 	X86_REG_BX,
449 	X86_REG_SP,
450 	X86_REG_BP,
451 	X86_REG_SI,
452 	X86_REG_DI,
453 
454 	// 32-bit registers
455 	X86_REG_EAX=X86_32BIT_OFFSET,
456 	X86_REG_ECX,
457 	X86_REG_EDX,
458 	X86_REG_EBX,
459 	X86_REG_ESP,
460 	X86_REG_EBP,
461 	X86_REG_ESI,
462 	X86_REG_EDI,
463 
464 	// AMD64 8-bit registers
465 	AMD64_REG_AL=AMD64_8BIT_OFFSET,
466 	AMD64_REG_CL,
467 	AMD64_REG_DL,
468 	AMD64_REG_BL,
469 	AMD64_REG_SPL,
470 	AMD64_REG_BPL,
471 	AMD64_REG_SIL,
472 	AMD64_REG_DIL,
473 	AMD64_REG_R8B,
474 	AMD64_REG_R9B,
475 	AMD64_REG_R10B,
476 	AMD64_REG_R11B,
477 	AMD64_REG_R12B,
478 	AMD64_REG_R13B,
479 	AMD64_REG_R14B,
480 	AMD64_REG_R15B,
481 
482 	// AMD64 16-bit registers
483 	AMD64_REG_AX=AMD64_16BIT_OFFSET,
484 	AMD64_REG_CX,
485 	AMD64_REG_DX,
486 	AMD64_REG_BX,
487 	AMD64_REG_SP,
488 	AMD64_REG_BP,
489 	AMD64_REG_SI,
490 	AMD64_REG_DI,
491 	AMD64_REG_R8W,
492 	AMD64_REG_R9W,
493 	AMD64_REG_R10W,
494 	AMD64_REG_R11W,
495 	AMD64_REG_R12W,
496 	AMD64_REG_R13W,
497 	AMD64_REG_R14W,
498 	AMD64_REG_R15W,
499 
500 	// AMD64 32-bit registers
501 	AMD64_REG_EAX=AMD64_32BIT_OFFSET,
502 	AMD64_REG_ECX,
503 	AMD64_REG_EDX,
504 	AMD64_REG_EBX,
505 	AMD64_REG_ESP,
506 	AMD64_REG_EBP,
507 	AMD64_REG_ESI,
508 	AMD64_REG_EDI,
509 	AMD64_REG_R8D,
510 	AMD64_REG_R9D,
511 	AMD64_REG_R10D,
512 	AMD64_REG_R11D,
513 	AMD64_REG_R12D,
514 	AMD64_REG_R13D,
515 	AMD64_REG_R14D,
516 	AMD64_REG_R15D,
517 
518 	// AMD64 64-bit registers
519 	AMD64_REG_RAX=AMD64_64BIT_OFFSET,
520 	AMD64_REG_RCX,
521 	AMD64_REG_RDX,
522 	AMD64_REG_RBX,
523 	AMD64_REG_RSP,
524 	AMD64_REG_RBP,
525 	AMD64_REG_RSI,
526 	AMD64_REG_RDI,
527 	AMD64_REG_R8,
528 	AMD64_REG_R9,
529 	AMD64_REG_R10,
530 	AMD64_REG_R11,
531 	AMD64_REG_R12,
532 	AMD64_REG_R13,
533 	AMD64_REG_R14,
534 	AMD64_REG_R15
535 } X86_REGISTER;
536 
537 typedef enum _X86_TEST_REGISTER
538 {
539 	REG_TR0=0,
540 	REG_TR1,
541 	REG_TR2,
542 	REG_TR3,
543 	REG_TR4,
544 	REG_TR5,
545 	REG_TR6,
546 	REG_TR7,
547 	REG_TR8,
548 	REG_TR9,
549 	REG_TR10,
550 	REG_TR11,
551 	REG_TR12,
552 	REG_TR13,
553 	REG_TR14,
554 	REG_TR15
555 } X86_TEST_REGISTER;
556 
557 typedef enum _X86_CONTROL_REGISTER
558 {
559 	REG_CR0,
560 	REG_CR1,
561 	REG_CR2,
562 	REG_CR3,
563 	REG_CR4,
564 	REG_CR5,
565 	REG_CR6,
566 	REG_CR7,
567 	REG_CR8,
568 	REG_CR9,
569 	REG_CR10,
570 	REG_CR11,
571 	REG_CR12,
572 	REG_CR13,
573 	REG_CR14,
574 	REG_CR15
575 } X86_CONTROL_REGISTER;
576 
577 typedef enum _X86_DEBUG_REGISTER
578 {
579 	REG_DR0,
580 	REG_DR1,
581 	REG_DR2,
582 	REG_DR3,
583 	REG_DR4,
584 	REG_DR5,
585 	REG_DR6,
586 	REG_DR7,
587 	REG_DR8,
588 	REG_DR9,
589 	REG_DR10,
590 	REG_DR11,
591 	REG_DR12,
592 	REG_DR13,
593 	REG_DR14,
594 	REG_DR15
595 } X86_DEBUG_REGISTER;
596 
597 typedef enum _X86_MMX_REGISTER
598 {
599 	REG_MM0=0,
600 	REG_MM1=1,
601 	REG_MM2=2,
602 	REG_MM3=3,
603 	REG_MM4=4,
604 	REG_MM5=5,
605 	REG_MM6=6,
606 	REG_MM7=7
607 } X86_MMX_REGISTER;
608 
609 typedef enum _X86_SSE_REGISTER
610 {
611 	REG_XMM0=0,
612 	REG_XMM1=1,
613 	REG_XMM2=2,
614 	REG_XMM3=3,
615 	REG_XMM4=4,
616 	REG_XMM5=5,
617 	REG_XMM6=6,
618 	REG_XMM7=7
619 } X86_SSE_REGISTER;
620 
621 typedef enum _X86_FPU_REGISTER
622 {
623 	REG_ST0=0,
624 	REG_ST1=1,
625 	REG_ST2=2,
626 	REG_ST3=3,
627 	REG_ST4=4,
628 	REG_ST5=5,
629 	REG_ST6=6,
630 	REG_ST7=7
631 } X86_FPU_REGISTER;
632 
633 typedef enum _X86_8BIT_REGISTER
634 {
635 	REG_AL = 0,
636 	REG_CL = 1,
637 	REG_DL = 2,
638 	REG_BL = 3,
639 	REG_AH = 4,
640 	REG_CH = 5,
641 	REG_DH = 6,
642 	REG_BH = 7
643 } X86_8BIT_REGISTER;
644 
645 typedef enum _X86_16BIT_REGISTER
646 {
647 	REG_AX = 0,
648 	REG_CX = 1,
649 	REG_DX = 2,
650 	REG_BX = 3,
651 	REG_SP = 4,
652 	REG_BP = 5,
653 	REG_SI = 6,
654 	REG_DI = 7
655 } X86_16BIT_REGISTER;
656 
657 typedef enum _X86_32BIT_REGISTER
658 {
659 	REG_EAX = 0,
660 	REG_ECX = 1,
661 	REG_EDX = 2,
662 	REG_EBX = 3,
663 	REG_ESP = 4,
664 	REG_EBP = 5,
665 	REG_ESI = 6,
666 	REG_EDI = 7
667 } X86_32BIT_REGISTER;
668 
669 typedef enum _X86_SEGMENT
670 {
671 	SEG_ES = 0,
672 	SEG_CS = 1,
673 	SEG_SS = 2,
674 	SEG_DS = 3,
675 	SEG_FS = 4,
676 	SEG_GS = 5,
677 	SEG_MAX = 6
678 } X86_SEGMENT;
679 
680 extern char *X86_Registers[];
681 
682 #pragma pack(push,1)
683 typedef struct _MODRM
684 {
685 	U8 mod : 2;
686 	U8 reg : 3;
687 	U8 rm : 3;
688 } MODRM;
689 typedef struct _SIB
690 {
691 	U8 scale : 2;
692 	U8 index : 3;
693 	U8 base : 3;
694 } SIB;
695 typedef struct _REX
696 {
697 	U8 unused : 4; // bits 4,5,6,7
698 	U8 w : 1; // bit 3
699 	U8 r : 1; // bit 2
700 	U8 x : 1; // bit 1
701 	U8 b : 1; // bit 0
702 } REX;
703 typedef struct _REX_MODRM
704 {
705 	U8 reg : 4;
706 	U8 rm : 4;
707 } REX_MODRM;
708 typedef struct _REX_SIB
709 {
710 	U8 index : 4;
711 	U8 base : 4;
712 } REX_SIB;
713 #pragma pack(pop)
714 
715 //
716 // Properties:
717 // If an operand is OP_COND_EXEC, it means that it is executed only if the pre-conditions are met.
718 //
719 // If if an instruction has one or more OP_COND_DST operands, then the actions are determined by
720 // whether the Opcode.Preconditions are met or not. If all the COND_* flags in Opcode.Preconditions
721 // are true, then the results are determined by ResultsIfTrue. If the preconditions are not met, then
722 // the results are determined by ResultsIfFalse.
723 //
724 // If Preconditions == NOCOND, then results in ResultsIfTrue are unconditional and ResultsIfFalse
725 // is ignored
726 //
727 typedef struct _X86_OPCODE
728 {
729 	struct _X86_OPCODE *Table;
730 	CPU_TYPE CPU; // minimum CPU (starting with i386)
731 	U32 MnemonicFlags;
732 	char Mnemonic[X86_MAX_INSTRUCTION_LEN+1];
733 	U32 OperandFlags[X86_MAX_OPERANDS];
734 	U32 Preconditions;
735 	U32 FlagsChanged; // changes in flags
736 	U32 ResultsIfTrue; // results if Preconditions are met
737 	U32 ResultsIfFalse; // results if Preconditions are not met
738 } X86_OPCODE;
739 
740 typedef struct _X86_INSTRUCTION
741 {
742 	struct _INSTRUCTION *Instruction; // the generic instruction format representing this instruction
743 
744 	X86_OPCODE Opcode;
745 
746 	U8 sib_b;
747 	U8 modrm_b;
748 	MODRM modrm;
749 	SIB sib;
750 	U8 rex_b;
751 	REX rex;
752 	REX_MODRM rex_modrm;
753 	REX_SIB rex_sib;
754 
755 	X86_SEGMENT DstSegment;
756 	union
757 	{
758 		X86_SEGMENT Segment;
759 		DWORD Selector;
760 	};
761 
762 	// NOTE: these are for internal use, use Instruction->Operands[]
763 	//
764 	// If DstRegAddressing or SrcRegAddressing = TRUE then BaseRegister is the base register
765 	// It is the operand represented by SIBOperand
766 	//
767 	// The operand indices of the destination operands is in DstOpIndex[0 to DstOpCount-1]
768 	// The operand indices of the source operands is in SrcOpIndex[0 to SrcOpCount-1]
769 	//
770 	// These are used both for instructions like xadd/xchg (where both operands are source/destination)
771 	// and to represent implicit registers (e.g., cmpxchg)
772 
773 	U8 SrcOpIndex[3];
774 	U8 DstOpIndex[3];
775 
776 	// Addressing mode:
777 	// If DstRegAddressing = TRUE, then these apply to DstReg
778 	// If SrcRegAddressing = TRUE, then this applies to SrcReg[AddressIndex]
779 	// If both are false, then SrcReg and DstReg are not addresses
780 	X86_REGISTER BaseRegister;
781 	X86_REGISTER IndexRegister;
782 
783 	U8 Scale;
784 	U8 HasDefault64Operand : 1;
785 	U8 HasOperandSizePrefix : 1;
786 	U8 HasAddressSizePrefix : 1;
787 	U8 HasSegmentOverridePrefix : 1;
788 	U8 HasLockPrefix : 1;
789 	U8 HasRepeatWhileEqualPrefix : 1;
790 	U8 HasRepeatWhileNotEqualPrefix : 1;
791 	U8 HasBranchTakenPrefix : 1;
792 	U8 HasBranchNotTakenPrefix : 1;
793 	U8 HasDstAddressing : 1;
794 	U8 HasSrcAddressing : 1;
795 	U8 HasModRM : 1;
796 	U8 HasBaseRegister : 1;
797 	U8 HasIndexRegister : 1;
798 	U8 HasFullDisplacement : 1;
799 	U8 HasDstSegment : 1; // used for ins/cmps/scas/movs/etc which have 2 segments
800 	U8 DstAddressIndex : 2; // DstOpIndex[DstAddressIndex]
801 	U8 SrcAddressIndex : 2; // SrcOpIndex[SrcAddressIndex]
802 	U8 DstOpCount : 2;
803 	U8 SrcOpCount : 2;
804 	U8 OperandSize : 4;
805 	U8 AddressSize : 4;
806 	U8 Relative : 1;
807 	U8 HasSelector : 1; // segment is actually a selector
808 	U8 Group : 5;
809 
810 	S64 Displacement;
811 
812 } X86_INSTRUCTION;
813 
814 ////////////////////////////////////////////////////////////////////////////////////
815 // Exported functions
816 ////////////////////////////////////////////////////////////////////////////////////
817 
818 extern ARCHITECTURE_FORMAT_FUNCTIONS X86;
819 
820 // Instruction setup
821 BOOL X86_InitInstruction(struct _INSTRUCTION *Instruction);
822 void X86_CloseInstruction(struct _INSTRUCTION *Instruction);
823 
824 // Instruction translator
825 BOOL X86_TranslateInstruction(struct _INSTRUCTION *Instruction, BOOL Verbose);
826 
827 // Instruction decoder
828 BOOL X86_GetInstruction(struct _INSTRUCTION *Instruction, U8 *Address, DWORD Flags);
829 
830 // Function finding
831 U8 *X86_FindFunctionByPrologue(struct _INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, DWORD Flags);
832 
833 #ifdef __cplusplus
834 }
835 #endif
836 #endif // X86_DISASM_H
837 
838