1#ifndef IA32_INSN_H
2#define IA32_INSN_H
3/* this file contains the structure of opcode definitions and the
4 * constants they use */
5
6#include <sys/types.h>
7#include "libdis.h"
8
9
10#define GET_BYTE( buf, buf_len ) buf_len ? *buf : 0
11
12#define OP_SIZE_16	1
13#define OP_SIZE_32	2
14#define ADDR_SIZE_16	4
15#define ADDR_SIZE_32	8
16
17#define MAX_INSTRUCTION_SIZE 20
18
19/* invalid instructions are handled by returning 0 [error] from the
20 * function, setting the size of the insn to 1 byte, and copying
21 * the byte at the start of the invalid insn into the x86_insn_t.
22 * if the caller is saving the x86_insn_t for invalid instructions,
23 * instead of discarding them, this will maintain a consistent
24 * address space in the x86_insn_ts */
25
26#define INVALID_INSN ((size_t) -1)	/* return value for invalid insn */
27#define MAKE_INVALID( i, buf )                          \
28                strcpy( i->mnemonic, "invalid" );       \
29                x86_oplist_free( i );                   \
30                i->size = 1;                            \
31                i->group = insn_none;                   \
32                i->type = insn_invalid;                 \
33                memcpy( i->bytes, buf, 1 );
34
35
36size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len,
37		x86_insn_t *insn);
38
39
40/* --------------------------------------------------------- Table Lookup */
41/* IA32 Instruction defintion for ia32_opcodes.c */
42typedef struct {
43   unsigned int table;          /* escape to this sub-table */
44   unsigned int mnem_flag;      /* Flags referring to mnemonic */
45   unsigned int notes;          /* Notes for this instruction */
46   unsigned int dest_flag, src_flag, aux_flag; /* and for specific operands */
47   unsigned int cpu;            /* minimumCPU [AND with clocks?? */
48   char mnemonic[16];           /* buffers for building instruction */
49   char mnemonic_att[16];       /* at&t style mnemonic name */
50   int32_t dest;
51   int32_t src;
52   int32_t aux;
53   unsigned int flags_effected;
54   unsigned int implicit_ops;	/* implicit operands */
55} ia32_insn_t;
56
57
58
59/* --------------------------------------------------------- Prefixes */
60/* Prefix Flags */
61/* Prefixes, same order as in the manual */
62/* had to reverse the values of the first three as they were entered into
63 * libdis.h incorrectly. */
64#define PREFIX_LOCK       0x0004
65#define PREFIX_REPNZ      0x0002
66#define PREFIX_REPZ       0x0001
67#define PREFIX_OP_SIZE    0x0010
68#define PREFIX_ADDR_SIZE  0x0020
69#define PREFIX_CS         0x0100
70#define PREFIX_SS         0x0200
71#define PREFIX_DS         0x0300
72#define PREFIX_ES         0x0400
73#define PREFIX_FS         0x0500
74#define PREFIX_GS         0x0600
75#define PREFIX_TAKEN      0x1000	/* branch taken */
76#define PREFIX_NOTTAKEN   0x2000	/* branch not taken */
77#define PREFIX_REG_MASK   0x0F00
78#define BRANCH_HINT_MASK  0x3000
79#define PREFIX_PRINT_MASK 0x000F	/* printable prefixes */
80#define PREFIX_MASK       0xFFFF
81
82/* ---------------------------------------------------------- CPU Type */
83
84#define cpu_8086         0x0001
85#define cpu_80286        0x0002
86#define cpu_80386        0x0003
87#define cpu_80387        0x0004 /* originally these were a co-proc */
88#define cpu_80486        0x0005
89#define cpu_PENTIUM      0x0006
90#define cpu_PENTPRO      0x0007
91#define cpu_PENTIUM2     0x0008
92#define cpu_PENTIUM3     0x0009
93#define cpu_PENTIUM4     0x000A
94#define cpu_K6		 0x0010
95#define cpu_K7		 0x0020
96#define cpu_ATHLON	 0x0030
97#define CPU_MODEL_MASK	 0xFFFF
98#define CPU_MODEL(cpu)	 (cpu & CPU_MODEL_MASK)
99/* intel instruction subsets */
100#define isa_GP		 0x10000	/* General Purpose Instructions */
101#define isa_FPU		 0x20000	/* FPU instructions */
102#define isa_FPUMGT	 0x30000	/* FPU/SIMD Management */
103#define isa_MMX		 0x40000	/* MMX */
104#define isa_SSE1	 0x50000	/* SSE */
105#define isa_SSE2	 0x60000	/* SSE 2 */
106#define isa_SSE3	 0x70000	/* SSE 3 */
107#define isa_3DNOW	 0x80000	/* AMD 3d Now */
108#define isa_SYS		 0x90000	/* System Instructions */
109#define ISA_SUBSET_MASK	 0xFFFF0000
110#define ISA_SUBSET(isa)	(isa & ISA_SUBSET_MASK)
111
112
113/* ------------------------------------------------------ Operand Decoding */
114#define ARG_NONE         0
115
116/* Using a mask allows us to store info such as OP_SIGNED in the
117 * operand flags field */
118#define   OPFLAGS_MASK 	0x0000FFFF
119
120/* Operand Addressing Methods, per intel manual */
121#define   ADDRMETH_MASK	0x00FF0000
122
123/* note: for instructions with implied operands, use no ADDRMETH */
124#define   ADDRMETH_A  	0x00010000
125#define   ADDRMETH_C   	0x00020000
126#define   ADDRMETH_D   	0x00030000
127#define   ADDRMETH_E   	0x00040000
128#define   ADDRMETH_F   	0x00050000
129#define   ADDRMETH_G   	0x00060000
130#define   ADDRMETH_I   	0x00070000
131#define   ADDRMETH_J   	0x00080000
132#define   ADDRMETH_M   	0x00090000
133#define   ADDRMETH_O   	0x000A0000
134#define   ADDRMETH_P   	0x000B0000
135#define   ADDRMETH_Q   	0x000C0000
136#define   ADDRMETH_R   	0x000D0000
137#define   ADDRMETH_S   	0x000E0000
138#define   ADDRMETH_T   	0x000F0000
139#define   ADDRMETH_V   	0x00100000
140#define   ADDRMETH_W   	0x00110000
141#define   ADDRMETH_X   	0x00120000
142#define   ADDRMETH_Y   	0x00130000
143#define	  ADDRMETH_RR  	0x00140000	/* gen reg hard-coded in opcode */
144#define	  ADDRMETH_RS  	0x00150000	/* seg reg hard-coded in opcode */
145#define	  ADDRMETH_RT  	0x00160000	/* test reg hard-coded in opcode */
146#define	  ADDRMETH_RF  	0x00170000	/* fpu reg hard-coded in opcode */
147#define	  ADDRMETH_II  	0x00180000	/* immediate hard-coded in opcode */
148#define   ADDRMETH_PP   0x00190000	/* mm reg ONLY in modr/m field */
149#define   ADDRMETH_VV   0x001A0000	/* xmm reg ONLY in mod/rm field */
150
151/* Operand Types, per intel manual */
152#define OPTYPE_MASK	0xFF000000
153
154#define OPTYPE_a	0x01000000 /* BOUND: h:h or w:w */
155#define OPTYPE_b   	0x02000000 /* byte */
156#define OPTYPE_c   	0x03000000 /* byte or word */
157#define OPTYPE_d   	0x04000000 /* word */
158#define OPTYPE_dq   	0x05000000 /* qword */
159#define OPTYPE_p   	0x06000000 /* 16:16 or 16:32 pointer */
160#define OPTYPE_pi   	0x07000000 /* dword MMX reg */
161#define OPTYPE_ps   	0x08000000 /* 128-bit single fp */
162#define OPTYPE_q   	0x09000000 /* dword */
163#define OPTYPE_s   	0x0A000000 /* 6-byte descriptor */
164#define OPTYPE_ss   	0x0B000000 /* scalar of 128-bit single fp */
165#define OPTYPE_si   	0x0C000000 /* word general register */
166#define OPTYPE_v   	0x0D000000 /* hword or word */
167#define OPTYPE_w   	0x0E000000 /* hword */
168#define OPTYPE_m   	0x0F000000	/* to handle LEA */
169#define OPTYPE_none 0xFF000000 /* no valid operand size, INVLPG */
170
171/* custom ones for FPU instructions */
172#define OPTYPE_fs	0x10000000	/* pointer to single-real*/
173#define OPTYPE_fd	0x20000000	/* pointer to double real */
174#define OPTYPE_fe	0x30000000	/* pointer to extended real */
175#define OPTYPE_fb	0x40000000	/* pointer to packed BCD */
176#define OPTYPE_fv	0x50000000	/* pointer to FPU env: 14|28-bytes */
177#define OPTYPE_ft	0x60000000	/* pointer to FPU state: 94|108-bytes */
178#define OPTYPE_fx       0x70000000      /* pointer to FPU regs: 512 bites */
179#define OPTYPE_fp       0x80000000      /* general fpu register: dbl ext */
180
181/* SSE2 operand types */
182#define OPTYPE_sd	0x90000000	/* scalar of 128-bit double fp */
183#define OPTYPE_pd	0xA0000000	/* 128-bit double fp */
184
185
186
187/* ---------------------------------------------- Opcode Table Descriptions */
188/* the table type describes how to handle byte/size increments before
189 * and after lookup. Some tables re-use the current byte, others
190 * consume a byte only if the ModR/M encodes no operands, etc */
191enum ia32_tbl_type_id {
192	tbl_opcode = 0,	/* standard opcode table: no surprises */
193	tbl_prefix,	/* Prefix Override, e.g. 66/F2/F3 */
194	tbl_suffix,	/* 3D Now style */
195	tbl_extension,	/* ModR/M extension: 00-FF -> 00-07 */
196	tbl_ext_ext,	/* extension of modr/m using R/M field */
197	tbl_fpu,	/* fpu table: 00-BF -> 00-0F */
198	tbl_fpu_ext	/* fpu extension : C0-FF -> 00-1F */
199 };
200
201/* How it works:
202 * Bytes are 'consumed' if the next table lookup requires that the byte
203 * pointer be advanced in the instruction stream. 'Does not consume' means
204 * that, when the lookup function recurses, the same byte it re-used in the
205 * new table. It also means that size is not decremented, for example when
206 * a ModR/M byte is used. Note that tbl_extension (ModR/M) instructions that
207 * do not increase the size of an insn with their operands have a forced
208 3 size increase in the lookup algo. Weird, yes, confusing, yes, welcome
209 * to the Intel ISA. Another note: tbl_prefix is used as an override, so an
210 * empty insn in a prefix table causes the instruction in the original table
211 * to be used, rather than an invalid insn being generated.
212 * 	tbl_opcode uses current byte and consumes it
213 * 	tbl_prefix uses current byte but does not consume it
214 * 	tbl_suffix uses and consumes last byte in insn
215 * 	tbl_extension uses current byte but does not consume it
216 * 	tbl_ext_ext uses current byte but does not consume it
217 * 	tbl_fpu uses current byte and consumes it
218 * 	tbl_fpu_ext uses current byte but does not consume it
219 */
220
221/* Convenience struct for opcode tables : these will be stored in a
222 * 'table of tables' so we can use a table index instead of a pointer */
223typedef struct {		/* Assembly instruction tables */
224   ia32_insn_t *table;		/* Pointer to table of instruction encodings */
225   enum ia32_tbl_type_id type;
226   unsigned char shift;		/* amount to shift modrm byte */
227   unsigned char mask;		/* bit mask for look up */
228   unsigned char minlim,maxlim;	/* limits on min/max entries. */
229} ia32_table_desc_t;
230
231
232/* ---------------------------------------------- 'Cooked' Operand Type Info */
233/*                   Permissions: */
234#define OP_R         0x001      /* operand is READ */
235#define OP_W         0x002      /* operand is WRITTEN */
236#define OP_RW        0x003	/* (OP_R|OP_W): convenience macro */
237#define OP_X         0x004      /* operand is EXECUTED */
238
239#define OP_PERM_MASK 0x0000007  /* perms are NOT mutually exclusive */
240#define OP_PERM( type )       (type & OP_PERM_MASK)
241
242/* Flags */
243#define OP_SIGNED    0x010   	/* operand is signed */
244
245#define OP_FLAG_MASK  0x0F0  /* mods are NOT mutually exclusive */
246#define OP_FLAGS( type )        (type & OP_FLAG_MASK)
247
248#define OP_REG_MASK    0x0000FFFF /* lower WORD is register ID */
249#define OP_REGTBL_MASK 0xFFFF0000 /* higher word is register type [gen/dbg] */
250#define OP_REGID( type )      (type & OP_REG_MASK)
251#define OP_REGTYPE( type )    (type & OP_REGTBL_MASK)
252
253/* ------------------------------------------'Cooked' Instruction Type Info */
254/* high-bit opcode types/insn meta-types */
255#define INS_FLAG_PREFIX		0x10000000	/* insn is a prefix */
256#define INS_FLAG_SUFFIX		0x20000000	/* followed by a suffix byte */
257#define INS_FLAG_MASK    	0xFF000000
258
259/* insn notes */
260#define INS_NOTE_RING0		0x00000001	/* insn is privileged */
261#define INS_NOTE_SMM		0x00000002	/* Sys Mgt Mode only */
262#define INS_NOTE_SERIAL		0x00000004	/* serializes */
263#define INS_NOTE_NONSWAP    0x00000008  /* insn is not swapped in att format */ // could be separate field?
264#define INS_NOTE_NOSUFFIX   0x00000010  /* insn has no size suffix in att format */ // could be separate field?
265//#define INS_NOTE_NMI
266
267#define INS_INVALID 	0
268
269/* instruction groups */
270#define INS_EXEC	0x1000
271#define INS_ARITH	0x2000
272#define INS_LOGIC	0x3000
273#define INS_STACK	0x4000
274#define INS_COND	0x5000
275#define INS_LOAD	0x6000
276#define INS_ARRAY	0x7000
277#define INS_BIT		0x8000
278#define INS_FLAG	0x9000
279#define INS_FPU		0xA000
280#define INS_TRAPS	0xD000
281#define INS_SYSTEM	0xE000
282#define INS_OTHER	0xF000
283
284#define INS_GROUP_MASK	0xF000
285#define INS_GROUP( type )     ( type & INS_GROUP_MASK )
286
287/* INS_EXEC group */
288#define INS_BRANCH	(INS_EXEC | 0x01)	/* Unconditional branch */
289#define INS_BRANCHCC	(INS_EXEC | 0x02)	/* Conditional branch */
290#define INS_CALL	(INS_EXEC | 0x03)	/* Jump to subroutine */
291#define INS_CALLCC	(INS_EXEC | 0x04)	/* Jump to subroutine */
292#define INS_RET		(INS_EXEC | 0x05)	/* Return from subroutine */
293
294/* INS_ARITH group */
295#define INS_ADD 	(INS_ARITH | 0x01)
296#define INS_SUB		(INS_ARITH | 0x02)
297#define INS_MUL		(INS_ARITH | 0x03)
298#define INS_DIV		(INS_ARITH | 0x04)
299#define INS_INC		(INS_ARITH | 0x05)	/* increment */
300#define INS_DEC		(INS_ARITH | 0x06)	/* decrement */
301#define INS_SHL		(INS_ARITH | 0x07)	/* shift right */
302#define INS_SHR		(INS_ARITH | 0x08)	/* shift left */
303#define INS_ROL		(INS_ARITH | 0x09)	/* rotate left */
304#define INS_ROR		(INS_ARITH | 0x0A)	/* rotate right */
305#define INS_MIN		(INS_ARITH | 0x0B)	/* min func */
306#define INS_MAX		(INS_ARITH | 0x0C)	/* max func */
307#define INS_AVG		(INS_ARITH | 0x0D)	/* avg func */
308#define INS_FLR		(INS_ARITH | 0x0E)	/* floor func */
309#define INS_CEIL	(INS_ARITH | 0x0F)	/* ceiling func */
310
311/* INS_LOGIC group */
312#define INS_AND		(INS_LOGIC | 0x01)
313#define INS_OR		(INS_LOGIC | 0x02)
314#define INS_XOR		(INS_LOGIC | 0x03)
315#define INS_NOT		(INS_LOGIC | 0x04)
316#define INS_NEG		(INS_LOGIC | 0x05)
317#define INS_NAND	(INS_LOGIC | 0x06)
318
319/* INS_STACK group */
320#define INS_PUSH	(INS_STACK | 0x01)
321#define INS_POP		(INS_STACK | 0x02)
322#define INS_PUSHREGS	(INS_STACK | 0x03)	/* push register context */
323#define INS_POPREGS	(INS_STACK | 0x04)	/* pop register context */
324#define INS_PUSHFLAGS	(INS_STACK | 0x05)	/* push all flags */
325#define INS_POPFLAGS	(INS_STACK | 0x06)	/* pop all flags */
326#define INS_ENTER	(INS_STACK | 0x07)	/* enter stack frame */
327#define INS_LEAVE	(INS_STACK | 0x08)	/* leave stack frame */
328
329/* INS_COND group */
330#define INS_TEST	(INS_COND | 0x01)
331#define INS_CMP		(INS_COND | 0x02)
332
333/* INS_LOAD group */
334#define INS_MOV		(INS_LOAD | 0x01)
335#define INS_MOVCC	(INS_LOAD | 0x02)
336#define INS_XCHG	(INS_LOAD | 0x03)
337#define INS_XCHGCC	(INS_LOAD | 0x04)
338#define INS_CONV	(INS_LOAD | 0x05)	/* move and convert type */
339
340/* INS_ARRAY group */
341#define INS_STRCMP	(INS_ARRAY | 0x01)
342#define INS_STRLOAD	(INS_ARRAY | 0x02)
343#define INS_STRMOV	(INS_ARRAY | 0x03)
344#define INS_STRSTOR	(INS_ARRAY | 0x04)
345#define INS_XLAT	(INS_ARRAY | 0x05)
346
347/* INS_BIT group */
348#define INS_BITTEST	(INS_BIT | 0x01)
349#define INS_BITSET	(INS_BIT | 0x02)
350#define INS_BITCLR	(INS_BIT | 0x03)
351
352/* INS_FLAG group */
353#define INS_CLEARCF	(INS_FLAG | 0x01)	/* clear Carry flag */
354#define INS_CLEARZF	(INS_FLAG | 0x02)	/* clear Zero flag */
355#define INS_CLEAROF	(INS_FLAG | 0x03)	/* clear Overflow flag */
356#define INS_CLEARDF	(INS_FLAG | 0x04)	/* clear Direction flag */
357#define INS_CLEARSF	(INS_FLAG | 0x05)	/* clear Sign flag */
358#define INS_CLEARPF	(INS_FLAG | 0x06)	/* clear Parity flag */
359#define INS_SETCF	(INS_FLAG | 0x07)
360#define INS_SETZF	(INS_FLAG | 0x08)
361#define INS_SETOF	(INS_FLAG | 0x09)
362#define INS_SETDF	(INS_FLAG | 0x0A)
363#define INS_SETSF	(INS_FLAG | 0x0B)
364#define INS_SETPF	(INS_FLAG | 0x0C)
365#define INS_TOGCF	(INS_FLAG | 0x10)	/* toggle */
366#define INS_TOGZF	(INS_FLAG | 0x20)
367#define INS_TOGOF	(INS_FLAG | 0x30)
368#define INS_TOGDF	(INS_FLAG | 0x40)
369#define INS_TOGSF	(INS_FLAG | 0x50)
370#define INS_TOGPF	(INS_FLAG | 0x60)
371
372/* INS_FPU */
373#define INS_FMOV       (INS_FPU | 0x1)
374#define INS_FMOVCC     (INS_FPU | 0x2)
375#define INS_FNEG       (INS_FPU | 0x3)
376#define INS_FABS       (INS_FPU | 0x4)
377#define INS_FADD       (INS_FPU | 0x5)
378#define INS_FSUB       (INS_FPU | 0x6)
379#define INS_FMUL       (INS_FPU | 0x7)
380#define INS_FDIV       (INS_FPU | 0x8)
381#define INS_FSQRT      (INS_FPU | 0x9)
382#define INS_FCMP       (INS_FPU | 0xA)
383#define INS_FCOS       (INS_FPU | 0xC)               /* cosine */
384#define INS_FLDPI      (INS_FPU | 0xD)               /* load pi */
385#define INS_FLDZ       (INS_FPU | 0xE)               /* load 0 */
386#define INS_FTAN       (INS_FPU | 0xF)               /* tanget */
387#define INS_FSINE      (INS_FPU | 0x10)              /* sine */
388#define INS_FSYS       (INS_FPU | 0x20)              /* misc */
389
390/* INS_TRAP */
391#define INS_TRAP	(INS_TRAPS | 0x01)	/* generate trap */
392#define INS_TRAPCC	(INS_TRAPS | 0x02)	/* conditional trap gen */
393#define INS_TRET	(INS_TRAPS | 0x03)	/* return from trap */
394#define INS_BOUNDS	(INS_TRAPS | 0x04)	/* gen bounds trap */
395#define INS_DEBUG	(INS_TRAPS | 0x05)	/* gen breakpoint trap */
396#define INS_TRACE	(INS_TRAPS | 0x06)	/* gen single step trap */
397#define INS_INVALIDOP	(INS_TRAPS | 0x07)	/* gen invalid insn */
398#define INS_OFLOW	(INS_TRAPS | 0x08)	/* gen overflow trap */
399#define INS_ICEBP	(INS_TRAPS | 0x09)	/* ICE breakpoint */
400
401/* INS_SYSTEM */
402#define INS_HALT	(INS_SYSTEM | 0x01)	/* halt machine */
403#define INS_IN		(INS_SYSTEM | 0x02)	/* input form port */
404#define INS_OUT		(INS_SYSTEM | 0x03)	/* output to port */
405#define INS_CPUID	(INS_SYSTEM | 0x04)	/* identify cpu */
406
407/* INS_OTHER */
408#define INS_NOP		(INS_OTHER | 0x01)
409#define INS_BCDCONV	(INS_OTHER | 0x02)	/* convert to/from BCD */
410#define INS_SZCONV	(INS_OTHER | 0x03)	/* convert size of operand */
411#define INS_SALC	(INS_OTHER | 0x04)	/* set %al on carry */
412#define INS_UNKNOWN	(INS_OTHER | 0x05)
413
414
415#define INS_TYPE_MASK	0xFFFF
416#define INS_TYPE( type )      ( type & INS_TYPE_MASK )
417
418   /* flags effected by instruction */
419#define INS_TEST_CARRY        0x01    /* carry */
420#define INS_TEST_ZERO         0x02    /* zero/equal */
421#define INS_TEST_OFLOW        0x04    /* overflow */
422#define INS_TEST_DIR          0x08    /* direction */
423#define INS_TEST_SIGN         0x10    /* negative */
424#define INS_TEST_PARITY       0x20    /* parity */
425#define INS_TEST_OR           0x40    /* used in jle */
426#define INS_TEST_NCARRY       0x100	/* ! carry */
427#define INS_TEST_NZERO        0x200	/* ! zero */
428#define INS_TEST_NOFLOW       0x400	/* ! oflow */
429#define INS_TEST_NDIR         0x800	/* ! dir */
430#define INS_TEST_NSIGN        0x100	/* ! sign */
431#define INS_TEST_NPARITY      0x2000	/* ! parity */
432/* SF == OF */
433#define INS_TEST_SFEQOF       0x4000
434/* SF != OF */
435#define INS_TEST_SFNEOF       0x8000
436
437#define INS_TEST_ALL		INS_TEST_CARRY | INS_TEST_ZERO | \
438				INS_TEST_OFLOW | INS_TEST_SIGN | \
439				INS_TEST_PARITY
440
441#define INS_SET_CARRY        0x010000    /* carry */
442#define INS_SET_ZERO         0x020000    /* zero/equal */
443#define INS_SET_OFLOW        0x040000    /* overflow */
444#define INS_SET_DIR          0x080000    /* direction */
445#define INS_SET_SIGN         0x100000    /* negative */
446#define INS_SET_PARITY       0x200000    /* parity */
447#define INS_SET_NCARRY       0x1000000
448#define INS_SET_NZERO        0x2000000
449#define INS_SET_NOFLOW       0x4000000
450#define INS_SET_NDIR         0x8000000
451#define INS_SET_NSIGN        0x10000000
452#define INS_SET_NPARITY      0x20000000
453#define INS_SET_SFEQOF       0x40000000
454#define INS_SET_SFNEOF       0x80000000
455
456#define INS_SET_ALL		INS_SET_CARRY | INS_SET_ZERO | \
457				INS_SET_OFLOW | INS_SET_SIGN | \
458				INS_SET_PARITY
459
460#define INS_TEST_MASK          0x0000FFFF
461#define INS_FLAGS_TEST(x)      (x & INS_TEST_MASK)
462#define INS_SET_MASK           0xFFFF0000
463#define INS_FLAGS_SET(x)       (x & INS_SET_MASK)
464
465#if 0
466/* TODO: actually start using these */
467#define X86_PAIR_NP	1		/* not pairable; execs in U */
468#define X86_PAIR_PU	2		/* pairable in U pipe */
469#define X86_PAIR_PV	3		/* pairable in V pipe */
470#define X86_PAIR_UV	4		/* pairable in UV pipe */
471#define X86_PAIR_FX	5		/* pairable with FXCH */
472
473#define X86_EXEC_PORT_0	1
474#define X86_EXEC_PORT_1	2
475#define X86_EXEC_PORT_2	4
476#define X86_EXEC_PORT_3	8
477#define X86_EXEC_PORT_4	16
478
479#define X86_EXEC_UNITS
480
481typedef struct {	/* representation of an insn during decoding */
482	uint32_t flags;		/* runtime settings */
483	/* instruction prefixes and other foolishness */
484	uint32_t prefix;		/* encoding of prefix */
485	char prefix_str[16];		/* mnemonics for prefix */
486	uint32_t branch_hint;	/* gah! */
487	unsigned int cpu_ver;		/* TODO: cpu version */
488	unsigned int clocks;		/* TODO: clock cycles: min/max */
489	unsigned char last_prefix;
490	/* runtime intruction decoding helpers */
491	unsigned char mode;		/* 16, 32, 64 */
492	unsigned char gen_regs;		/* offset of default general reg set */
493	unsigned char sz_operand;	/* operand size for insn */
494	unsigned char sz_address;	/* address size for insn */
495	unsigned char uops;		/* uops per insn */
496	unsigned char pairing;		/* np,pu,pv.lv */
497	unsigned char exec_unit;
498	unsigned char exec_port;
499	unsigned char latency;
500} ia32_info_t;
501#define MODE_32 0	/* default */
502#define MODE_16 1
503#define MODE_64 2
504#endif
505
506#endif
507