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