1 /* 2 * x86 Architecture header file 3 * 4 * Copyright (C) 2001-2007 Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef YASM_X86ARCH_H 28 #define YASM_X86ARCH_H 29 30 #include <libyasm/bitvect.h> 31 32 /* Available CPU feature flags */ 33 #define CPU_Any 0 /* Any old cpu will do */ 34 #define CPU_086 CPU_Any 35 #define CPU_186 1 /* i186 or better required */ 36 #define CPU_286 2 /* i286 or better required */ 37 #define CPU_386 3 /* i386 or better required */ 38 #define CPU_486 4 /* i486 or better required */ 39 #define CPU_586 5 /* i585 or better required */ 40 #define CPU_686 6 /* i686 or better required */ 41 #define CPU_P3 7 /* Pentium3 or better required */ 42 #define CPU_P4 8 /* Pentium4 or better required */ 43 #define CPU_IA64 9 /* IA-64 or better required */ 44 #define CPU_K6 10 /* AMD K6 or better required */ 45 #define CPU_Athlon 11 /* AMD Athlon or better required */ 46 #define CPU_Hammer 12 /* AMD Sledgehammer or better required */ 47 #define CPU_FPU 13 /* FPU support required */ 48 #define CPU_MMX 14 /* MMX support required */ 49 #define CPU_SSE 15 /* Streaming SIMD extensions required */ 50 #define CPU_SSE2 16 /* Streaming SIMD extensions 2 required */ 51 #define CPU_SSE3 17 /* Streaming SIMD extensions 3 required */ 52 #define CPU_3DNow 18 /* 3DNow! support required */ 53 #define CPU_Cyrix 19 /* Cyrix-specific instruction */ 54 #define CPU_AMD 20 /* AMD-specific inst. (older than K6) */ 55 #define CPU_SMM 21 /* System Management Mode instruction */ 56 #define CPU_Prot 22 /* Protected mode only instruction */ 57 #define CPU_Undoc 23 /* Undocumented instruction */ 58 #define CPU_Obs 24 /* Obsolete instruction */ 59 #define CPU_Priv 25 /* Priveleged instruction */ 60 #define CPU_SVM 26 /* Secure Virtual Machine instruction */ 61 #define CPU_PadLock 27 /* VIA PadLock instruction */ 62 #define CPU_EM64T 28 /* Intel EM64T or better */ 63 #define CPU_SSSE3 29 /* Streaming SIMD extensions 3 required */ 64 #define CPU_SSE41 30 /* Streaming SIMD extensions 4.1 required */ 65 #define CPU_SSE42 31 /* Streaming SIMD extensions 4.2 required */ 66 #define CPU_SSE4a 32 /* AMD Streaming SIMD extensions 4a required */ 67 #define CPU_XSAVE 33 /* Intel XSAVE instructions */ 68 #define CPU_AVX 34 /* Intel Advanced Vector Extensions */ 69 #define CPU_FMA 35 /* Intel Fused-Multiply-Add Extensions */ 70 #define CPU_AES 36 /* AES instruction */ 71 #define CPU_CLMUL 37 /* PCLMULQDQ instruction */ 72 #define CPU_MOVBE 38 /* MOVBE instruction */ 73 #define CPU_XOP 39 /* AMD XOP extensions */ 74 #define CPU_FMA4 40 /* AMD Fused-Multiply-Add extensions */ 75 #define CPU_F16C 41 /* Intel float-16 instructions */ 76 #define CPU_FSGSBASE 42 /* Intel FSGSBASE instructions */ 77 #define CPU_RDRAND 43 /* Intel RDRAND instruction */ 78 #define CPU_XSAVEOPT 44 /* Intel XSAVEOPT instruction */ 79 #define CPU_EPTVPID 45 /* Intel INVEPT, INVVPID instructions */ 80 #define CPU_SMX 46 /* Intel SMX instruction (GETSEC) */ 81 #define CPU_AVX2 47 /* Intel AVX2 instructions */ 82 #define CPU_BMI1 48 /* Intel BMI1 instructions */ 83 #define CPU_BMI2 49 /* Intel BMI2 instructions */ 84 #define CPU_INVPCID 50 /* Intel INVPCID instruction */ 85 #define CPU_LZCNT 51 /* Intel LZCNT instruction */ 86 87 enum x86_parser_type { 88 X86_PARSER_NASM = 0, 89 X86_PARSER_TASM = 1, 90 X86_PARSER_GAS = 2 91 }; 92 93 #define PARSER(arch) (((arch)->parser == X86_PARSER_GAS && (arch)->gas_intel_mode) ? X86_PARSER_NASM : (arch)->parser) 94 95 typedef struct yasm_arch_x86 { 96 yasm_arch_base arch; /* base structure */ 97 98 /* What instructions/features are enabled? */ 99 unsigned int active_cpu; /* active index into cpu_enables table */ 100 unsigned int cpu_enables_size; /* size of cpu_enables table */ 101 wordptr *cpu_enables; 102 103 unsigned int amd64_machine; 104 enum x86_parser_type parser; 105 unsigned int mode_bits; 106 unsigned int force_strict; 107 unsigned int default_rel; 108 unsigned int gas_intel_mode; 109 110 enum { 111 X86_NOP_BASIC = 0, 112 X86_NOP_INTEL = 1, 113 X86_NOP_AMD = 2 114 } nop; 115 } yasm_arch_x86; 116 117 /* 0-15 (low 4 bits) used for register number, stored in same data area. 118 * Note 8-15 are only valid for some registers, and only in 64-bit mode. 119 */ 120 typedef enum { 121 X86_REG8 = 0x1<<4, 122 X86_REG8X = 0x2<<4, /* 64-bit mode only, REX prefix version of REG8 */ 123 X86_REG16 = 0x3<<4, 124 X86_REG32 = 0x4<<4, 125 X86_REG64 = 0x5<<4, /* 64-bit mode only */ 126 X86_FPUREG = 0x6<<4, 127 X86_MMXREG = 0x7<<4, 128 X86_XMMREG = 0x8<<4, 129 X86_YMMREG = 0x9<<4, 130 X86_CRREG = 0xA<<4, 131 X86_DRREG = 0xB<<4, 132 X86_TRREG = 0xC<<4, 133 X86_RIP = 0xD<<4 /* 64-bit mode only, always RIP (regnum ignored) */ 134 } x86_expritem_reg_size; 135 136 /* Low 8 bits are used for the prefix value, stored in same data area. */ 137 typedef enum { 138 X86_LOCKREP = 1<<8, 139 X86_ADDRSIZE = 2<<8, 140 X86_OPERSIZE = 3<<8, 141 X86_SEGREG = 4<<8, 142 X86_REX = 5<<8 143 } x86_parse_insn_prefix; 144 145 typedef enum { 146 X86_NEAR = 1, 147 X86_SHORT, 148 X86_FAR, 149 X86_TO 150 } x86_parse_targetmod; 151 152 typedef enum { 153 JMP_NONE, 154 JMP_SHORT, 155 JMP_NEAR, 156 JMP_SHORT_FORCED, 157 JMP_NEAR_FORCED 158 } x86_jmp_opcode_sel; 159 160 typedef enum { 161 X86_REX_W = 3, 162 X86_REX_R = 2, 163 X86_REX_X = 1, 164 X86_REX_B = 0 165 } x86_rex_bit_pos; 166 167 /* Sets REX (4th bit) and 3 LS bits from register size/number. Returns 1 if 168 * impossible to fit reg into REX, otherwise returns 0. Input parameter rexbit 169 * indicates bit of REX to use if REX is needed. Will not modify REX if not 170 * in 64-bit mode or if it wasn't needed to express reg. 171 */ 172 int yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3, 173 uintptr_t reg, unsigned int bits, 174 x86_rex_bit_pos rexbit); 175 176 /* Effective address type */ 177 typedef struct x86_effaddr { 178 yasm_effaddr ea; /* base structure */ 179 180 /* VSIB uses the normal SIB byte, but this flag enables it. */ 181 unsigned char vsib_mode; /* 0 if not, 1 if XMM, 2 if YMM */ 182 183 /* How the spare (register) bits in Mod/RM are handled: 184 * Even if valid_modrm=0, the spare bits are still valid (don't overwrite!) 185 * They're set in bytecode_create_insn(). 186 */ 187 unsigned char modrm; 188 unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */ 189 unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */ 190 191 unsigned char sib; 192 unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */ 193 unsigned char need_sib; /* 1 if SIB byte needed, 0 if not, 194 0xff if unknown */ 195 } x86_effaddr; 196 197 void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, 198 yasm_bytecode *precbc); 199 200 void yasm_x86__ea_set_disponly(x86_effaddr *x86_ea); 201 x86_effaddr *yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg, 202 unsigned char *rex, unsigned int bits); 203 x86_effaddr *yasm_x86__ea_create_imm 204 (x86_effaddr *x86_ea, /*@keep@*/ yasm_expr *imm, unsigned int im_len); 205 yasm_effaddr *yasm_x86__ea_create_expr(yasm_arch *arch, 206 /*@keep@*/ yasm_expr *e); 207 void yasm_x86__ea_destroy(yasm_effaddr *ea); 208 void yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level); 209 210 void yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, 211 unsigned int opersize); 212 void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, 213 unsigned int addrsize); 214 void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, 215 unsigned int prefix); 216 217 /* Bytecode types */ 218 typedef struct x86_common { 219 unsigned char addrsize; /* 0 or =mode_bits => no override */ 220 unsigned char opersize; /* 0 or =mode_bits => no override */ 221 unsigned char lockrep_pre; /* 0 indicates no prefix */ 222 223 unsigned char mode_bits; 224 } x86_common; 225 226 typedef struct x86_opcode { 227 unsigned char opcode[3]; /* opcode */ 228 unsigned char len; 229 } x86_opcode; 230 231 typedef struct x86_insn { 232 x86_common common; /* common x86 information */ 233 x86_opcode opcode; 234 235 /*@null@*/ x86_effaddr *x86_ea; /* effective address */ 236 237 /*@null@*/ yasm_value *imm; /* immediate or relative value */ 238 239 unsigned char def_opersize_64; /* default operand size in 64-bit mode */ 240 unsigned char special_prefix; /* "special" prefix (0=none) */ 241 242 unsigned char rex; /* REX AMD64 extension, 0 if none, 243 0xff if not allowed (high 8 bit reg used) */ 244 245 /* Postponed (from parsing to later binding) action options. */ 246 enum { 247 /* None */ 248 X86_POSTOP_NONE = 0, 249 250 /* Instructions that take a sign-extended imm8 as well as imm values 251 * (eg, the arith instructions and a subset of the imul instructions) 252 * should set this and put the imm8 form as the "normal" opcode (in 253 * the first one or two bytes) and non-imm8 form in the second or 254 * third byte of the opcode. 255 */ 256 X86_POSTOP_SIGNEXT_IMM8, 257 258 /* Override any attempt at address-size override to 16 bits, and never 259 * generate a prefix. This is used for the ENTER opcode. 260 */ 261 X86_POSTOP_ADDRESS16 262 } postop; 263 } x86_insn; 264 265 typedef struct x86_jmp { 266 x86_common common; /* common x86 information */ 267 x86_opcode shortop, nearop; 268 269 yasm_value target; /* jump target */ 270 271 /* which opcode are we using? */ 272 /* The *FORCED forms are specified in the source as such */ 273 x86_jmp_opcode_sel op_sel; 274 } x86_jmp; 275 276 /* Direct (immediate) FAR jumps ONLY; indirect FAR jumps get turned into 277 * x86_insn bytecodes; relative jumps turn into x86_jmp bytecodes. 278 * This bytecode is not legal in 64-bit mode. 279 */ 280 typedef struct x86_jmpfar { 281 x86_common common; /* common x86 information */ 282 x86_opcode opcode; 283 284 yasm_value segment; /* target segment */ 285 yasm_value offset; /* target offset */ 286 } x86_jmpfar; 287 288 void yasm_x86__bc_transform_insn(yasm_bytecode *bc, x86_insn *insn); 289 void yasm_x86__bc_transform_jmp(yasm_bytecode *bc, x86_jmp *jmp); 290 void yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar); 291 292 void yasm_x86__bc_apply_prefixes 293 (x86_common *common, unsigned char *rex, unsigned int def_opersize_64, 294 unsigned int num_prefixes, uintptr_t *prefixes); 295 296 /* Check an effective address. Returns 0 if EA was successfully determined, 297 * 1 if invalid EA, or 2 if indeterminate EA. 298 */ 299 int yasm_x86__expr_checkea 300 (x86_effaddr *x86_ea, unsigned char *addrsize, unsigned int bits, 301 int address16_op, unsigned char *rex, yasm_bytecode *bc); 302 303 void yasm_x86__parse_cpu(yasm_arch_x86 *arch_x86, const char *cpuid, 304 size_t cpuid_len); 305 306 yasm_arch_insnprefix yasm_x86__parse_check_insnprefix 307 (yasm_arch *arch, const char *id, size_t id_len, unsigned long line, 308 /*@out@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix); 309 yasm_arch_regtmod yasm_x86__parse_check_regtmod 310 (yasm_arch *arch, const char *id, size_t id_len, 311 /*@out@*/ uintptr_t *data); 312 313 int yasm_x86__floatnum_tobytes 314 (yasm_arch *arch, const yasm_floatnum *flt, unsigned char *buf, 315 size_t destsize, size_t valsize, size_t shift, int warn); 316 int yasm_x86__intnum_tobytes 317 (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf, 318 size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc, 319 int warn); 320 321 unsigned int yasm_x86__get_reg_size(uintptr_t reg); 322 323 /*@only@*/ yasm_bytecode *yasm_x86__create_empty_insn(yasm_arch *arch, 324 unsigned long line); 325 #endif 326