toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/ia32_insn.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial