OLD | NEW |
| (Empty) |
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 | |
36 size_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 */ | |
42 typedef 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 */ | |
191 enum 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 */ | |
223 typedef 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 | |
481 typedef 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 | |
OLD | NEW |