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