x86arch.h 14 KB

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