Home | History | Annotate | Download | only in libdisasm
      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
    507