1 /* 2 * HT Editor 3 * x86opc.h 4 * 5 * Copyright (C) 1999-2002 Stefan Weyergraf 6 * Copyright (C) 2005-2007 Sebastian Biallas (sb@biallas.net) 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 #ifndef __X86OPC_H__ 23 #define __X86OPC_H__ 24 25 #include "io/types.h" 26 27 #define X86_PREFIX_NO -1 28 29 #define X86_PREFIX_LOCK 0 /* f0 */ 30 31 #define X86_PREFIX_ES 0 /* 26 */ 32 #define X86_PREFIX_CS 1 /* 2e */ 33 #define X86_PREFIX_SS 2 /* 36 */ 34 #define X86_PREFIX_DS 3 /* 3e */ 35 #define X86_PREFIX_FS 4 /* 64 */ 36 #define X86_PREFIX_GS 5 /* 65 */ 37 38 #define X86_PREFIX_REPNZ 0 /* f2 */ 39 #define X86_PREFIX_REPZ 1 /* f3 */ 40 41 #define X86_PREFIX_OPSIZE 0 /* 66 */ 42 #define X86_PREFIX_NOOPSIZE 1 /* no 66 allowed */ 43 44 enum X86OpSize { 45 X86_OPSIZEUNKNOWN = -1, 46 X86_OPSIZE16 = 0, 47 X86_OPSIZE32 = 1, 48 X86_OPSIZE64 = 2, 49 }; 50 51 enum X86AddrSize { 52 X86_ADDRSIZEUNKNOWN = -1, 53 X86_ADDRSIZE16 = 0, 54 X86_ADDRSIZE32 = 1, 55 X86_ADDRSIZE64 = 2, 56 }; 57 58 enum X86_Optype { 59 X86_OPTYPE_EMPTY = 0, 60 X86_OPTYPE_IMM = 1, 61 X86_OPTYPE_REG = 2, 62 X86_OPTYPE_SEG = 3, 63 X86_OPTYPE_MEM = 4, 64 X86_OPTYPE_CRX = 5, 65 X86_OPTYPE_DRX = 6, 66 X86_OPTYPE_STX = 7, 67 X86_OPTYPE_MMX = 8, 68 X86_OPTYPE_XMM = 9, 69 X86_OPTYPE_YMM = 10, 70 X86_OPTYPE_FARPTR = 11, 71 72 // user defined types start here 73 X86_OPTYPE_USER = 32, 74 }; 75 76 struct x86_insn_op { 77 X86_Optype type; 78 int size; 79 bool need_rex; 80 bool forbid_rex; 81 union { 82 struct { 83 uint32 seg; 84 uint32 offset; 85 } farptr; 86 uint64 imm; 87 int reg; 88 int seg; 89 struct { 90 uint64 disp; 91 int base; 92 int index; 93 int scale; 94 int addrsize; 95 bool floatptr; 96 bool addrptr; 97 bool hasdisp; 98 } mem; 99 int crx; 100 int drx; 101 int trx; 102 int stx; 103 int mmx; 104 int xmm; 105 int ymm; 106 union { 107 int i; 108 void *p; 109 } user[4]; 110 }; 111 }; 112 113 enum { 114 TYPE_0 = 0, 115 TYPE_A, /* direct address without ModR/M (generally */ 116 /* like imm, but can be 16:32 = 48 bit) */ 117 TYPE_C, /* reg of ModR/M picks control register */ 118 TYPE_D, /* reg of ModR/M picks debug register */ 119 TYPE_E, /* ModR/M (general reg or memory) */ 120 TYPE_F, /* r/m of ModR/M picks a fpu register */ 121 TYPE_Fx, /* extra picks a fpu register */ 122 TYPE_G, /* reg of ModR/M picks general register */ 123 TYPE_Is, /* signed immediate */ 124 TYPE_I, /* unsigned immediate */ 125 TYPE_I4, /* 4 bit immediate (see TYPE_VI, TYPE_YI) */ 126 TYPE_Ix, /* fixed immediate */ 127 TYPE_J, /* relative branch offset */ 128 TYPE_M, /* ModR/M (memory only) */ 129 TYPE_MR, /* Same as E, but extra picks reg size */ 130 TYPE_O, /* direct memory without ModR/M */ 131 TYPE_P, /* reg of ModR/M picks MMX register */ 132 TYPE_PR, /* rm of ModR/M picks MMX register */ 133 TYPE_Q, /* ModR/M (MMX reg or memory) */ 134 TYPE_R, /* rm of ModR/M picks general register */ 135 TYPE_Rx, /* extra picks register */ 136 TYPE_RXx, /* extra picks register, no REX extension */ 137 TYPE_RV, /* VEX.vvvv picks general register */ 138 TYPE_S, /* reg of ModR/M picks segment register */ 139 TYPE_Sx, /* extra picks segment register */ 140 141 TYPE_V, /* reg of ModR/M picks XMM register */ 142 TYPE_VI, /* bits 7-4 of imm picks XMM register */ 143 TYPE_VV, /* VEX.vvvv pick XMM register */ 144 TYPE_Vx, /* extra picks XMM register */ 145 TYPE_VR, /* rm of ModR/M picks XMM register */ 146 TYPE_W, /* ModR/M (XMM reg or memory) */ 147 148 TYPE_Y, /* reg of ModR/M picks YMM register */ 149 TYPE_YV, /* VEX.vvvv picks YMM register */ 150 TYPE_YI, /* bits 7-4 of imm picks YMM register */ 151 TYPE_YR, /* rm of ModR/M picks YMM register */ 152 TYPE_X, /* ModR/M (YMM reg or memory) */ 153 154 TYPE_VD, /* SSE5: drex.dest */ 155 TYPE_VS, /* SSE5: src (mod/rm) */ 156 }; 157 158 enum X86_VEX { 159 W0 = 0x00, 160 W1 = 0x80, 161 162 _128 = 0x00, 163 _256 = 0x40, 164 165 _66 = 0x01, 166 _f3 = 0x02, 167 _f2 = 0x03, 168 169 _0f = 0x04, // mmmm = 1 170 _0f38 = 0x08, // mmmm = 2 171 _0f3a = 0x0c, // mmmm = 3 172 // _0f4 = 0x10, // mmmm = 4 173 // _0f5 = 0x14, // mmmm = 5 174 // _0f6 = 0x18, // mmmm = 6 175 // _0f7 = 0x1c, // mmmm = 7 176 _0f24 = 0x20, // mmmm = 8 177 _0f25 = 0x24, // mmmm = 9 178 _0fA = 0x28, // mmmm = 10 179 }; 180 181 /* when name is == 0, the first op has a special meaning (layout see x86_insn_op_special) */ 182 #define SPECIAL_TYPE_INVALID 0 183 #define SPECIAL_TYPE_PREFIX 1 184 #define SPECIAL_TYPE_OPC_GROUP 2 185 #define SPECIAL_TYPE_GROUP 3 186 #define SPECIAL_TYPE_SGROUP 4 187 #define SPECIAL_TYPE_FGROUP 5 188 189 enum { 190 SIZE_0 = '0', /* size unimportant */ 191 SIZE_B = 'b', /* byte */ 192 SIZE_BV = 'B', /* byte, extended to SIZE_V */ 193 SIZE_W = 'w', /* word */ 194 SIZE_D = 'd', /* dword */ 195 SIZE_Q = 'q', /* qword */ 196 SIZE_U = 'u', /* qword OR oword (depending on 0x66 prefix) */ 197 SIZE_Z = 'z', /* dword OR qword (depending on 0x66 prefix) */ 198 SIZE_O = 'o', /* oword (128 bit) */ 199 SIZE_V = 'v', /* word OR dword OR qword */ 200 SIZE_VV = 'V', /* word OR dword OR sign extended dword */ 201 SIZE_R = 'r', /* dword OR qword (depending on rex size) */ 202 SIZE_P = 'p', /* word:word OR word:dword, memory only! */ 203 SIZE_S = 's', /* short/single real (32-bit) */ 204 SIZE_L = 'l', /* long/double real (64-bit) */ 205 SIZE_T = 't', /* temp/extended real (80-bit) */ 206 SIZE_A = 'a', /* packed decimal (80-bit BCD) */ 207 SIZE_Y = 'y', /* ymmword (256 bit) */ 208 }; 209 210 #define INFO_DEFAULT_64 0x80 211 212 struct x86opc_insn_op { 213 byte type; 214 byte extra; 215 byte info; 216 byte size; 217 }; 218 219 struct x86opc_insn { 220 const char *name; 221 byte op[4]; 222 }; 223 224 struct x86opc_vex_insn { 225 const char *name; 226 byte vex; 227 byte op[5]; 228 }; 229 230 struct x86_64_insn_patch { 231 int opc; 232 x86opc_insn insn; 233 }; 234 235 /* this can be a group (group!=0), an insn (group==0) && (insn.name!=0) or 236 (otherwise) a reserved instruction. */ 237 struct x86opc_finsn { 238 x86opc_insn *group; 239 x86opc_insn insn; 240 }; 241 242 #define X86_REG_INVALID -2 243 #define X86_REG_NO (-1 & ~8) 244 #define X86_REG_AX 0 245 #define X86_REG_CX 1 246 #define X86_REG_DX 2 247 #define X86_REG_BX 3 248 #define X86_REG_SP 4 249 #define X86_REG_BP 5 250 #define X86_REG_SI 6 251 #define X86_REG_DI 7 252 #define X86_REG_R8 8 253 #define X86_REG_R9 9 254 #define X86_REG_R10 10 255 #define X86_REG_R11 11 256 #define X86_REG_R12 12 257 #define X86_REG_R13 13 258 #define X86_REG_R14 14 259 #define X86_REG_R15 15 260 #define X86_REG_IP 66 261 262 #define X86_OPC_GROUPS 9 263 #define X86_SPECIAL_GROUPS 15 264 265 extern x86opc_insn x86_les; 266 extern x86opc_insn x86_lds; 267 extern x86opc_insn x86_pop_group; 268 269 extern const char *x86_regs[4][8]; 270 extern const char *x86_64regs[4][16]; 271 extern const char *x86_ipregs[4]; 272 extern const char *x86_segs[8]; 273 extern x86opc_insn_op x86_op_type[]; 274 extern x86opc_insn x86_32_insns[256]; 275 extern x86_64_insn_patch x86_64_insn_patches[]; 276 extern x86opc_insn x86_insns_ext[256]; 277 extern x86opc_insn x86_insns_ext_66[256]; 278 extern x86opc_insn x86_insns_ext_f2[256]; 279 extern x86opc_insn x86_insns_ext_f3[256]; 280 extern x86opc_insn x86_opc_group_insns[X86_OPC_GROUPS][256]; 281 extern x86opc_insn x86_group_insns[][8]; 282 extern x86opc_insn x86_special_group_insns[X86_SPECIAL_GROUPS][9]; 283 extern x86opc_vex_insn *x86_vex_insns[256]; 284 extern x86opc_vex_insn x86_group_vex_insns[][8]; 285 286 extern x86opc_insn x86_modfloat_group_insns[8][8]; 287 extern x86opc_finsn x86_float_group_insns[8][8]; 288 289 #endif /* __X86OPC_H__ */ 290