1 /**
2  * @namespace   biew_plugins_II
3  * @file        plugins/disasm/ix86/ix86.h
4  * @brief       This file contains declaration of internal Intel x86 disassembler functions.
5  * @version     -
6  * @remark      this source file is part of Binary vIEW project (BIEW).
7  *              The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8  *              All rights reserved. This software is redistributable under the
9  *              licence given in the file "Licence.en" ("Licence.ru" in russian
10  *              translation) distributed in the BIEW archive.
11  * @note        Requires POSIX compatible development system
12  *
13  * @author      Nickols_K
14  * @since       1995
15  * @note        Development, fixes and improvements
16 **/
17 #ifndef ____DISASM_H
18 #define ____DISASM_H
19 
20 #define IX86_64 1 /* enable athlon64 disassembler by default */
21 
22 #include "plugins/disasm.h"
23 
24 #ifndef __BIEWLIB_H
25 #include "biewlib/biewlib.h"
26 #endif
27 
28 #define TAB_POS 10
29 #define TILE_SAFE 4000
30 
31 #define DUMMY_PTR 0 /**< "" */
32 #define BYTE_PTR  1 /**<" <b>"*/
33 #define WORD_PTR  2 /**<" <w>"*/
34 #define DWORD_PTR 3 /**<" <d>"*/
35 #define PWORD_PTR 4 /**<" <p>"*/
36 #define QWORD_PTR 5 /**<" <q>"*/
37 #define TWORD_PTR 6 /**<" <t>"*/
38 
39 /*
40    This struct is ordered as it documented in Athlon manual
41    Publication # 22007 Rev: D
42 */
43 typedef struct tagix86Param
44 {
45   unsigned long pro_clone; /**< processor family */
46   __filesize_t  DisasmPrefAddr; /**< address of instruction with prefixes */
47   __filesize_t  CodeAddress; /**< without prefixes */
48   MBuffer       CodeBuffer; /**< buffer with source code */
49   MBuffer       RealCmd; /**< buffer without prefixes */
50   unsigned      flags; /**< refer to disasm.h header */
51   unsigned char codelen;
52   unsigned long insn_flags; /**< contains copy of flags32/flags64 field from INSN_TABLE */
53 #define PFX_SEGMASK		0x00000007
54 #define  PFX_SEG_CS		0x00000000
55 #define  PFX_SEG_DS		0x00000001
56 #define  PFX_SEG_ES		0x00000002
57 #define  PFX_SEG_SS		0x00000003
58 #define  PFX_SEG_FS		0x00000004
59 #define  PFX_SEG_GS		0x00000005
60 #define  PFX_SEG_US		0x00000006
61 #define  PFX_SEG_XS		0x00000007
62 #define PFX_LOCK		0x00000008
63 #define PFX_F2_REPNE		0x00000010
64 #define PFX_F3_REP		0x00000020
65 #define PFX_66			0x00000040
66 #define PFX_67			0x00000080
67 #define PFX_OF			0x00000100 /* for VEX compatibility */
68 #define PFX_REX			0x01000000
69 #define PFX_VEX			0x02000000
70 #define PFX_XOP			0x04000000
71   unsigned long pfx;
72 #define MOD_WIDE_DATA		0x00000001
73 #define MOD_WIDE_ADDR		0x00000002
74 #define MOD_MMX			0x00000010
75 #define MOD_SSE			0x00000020
76   unsigned long mode;
77 /*
78   REX is 0x4? opcodes
79   bits  meaning
80   0     rex.b (extension to the Base)
81   1     rex.x (extsnsion to the SIB indeX)
82   2     rex.r (extension to the ModRM/REG)
83   3     rex.w (extension to the operand Width)
84   7-4   0100
85   DEFAULT operand size:
86     if rex.w then 64
87     else 66_pref then 16
88     else 32
89   DEFAULT address size:
90     if 67_pref then 32
91     else 64
92     (note: address displasement always has 8, 16 or 32-bit)
93 */
94   unsigned char REX;
95 /*
96   VEX is C4, C5 opcodes
97                    Byte 0         Byte 1             Byte 2
98   (Bit Position) 7        0   7 6 5 4        0   7 6    3 2 1 0
99 		+----------+ +-----+----------+ +-+------+-+---+
100   3-byte VEX C4 | 11000100 | |R X B|  m-mmmm  | |W| vvvv |L| pp|
101                 +----------+ +-----+----------+ +-+------+-+---+
102                  7        0   7 6   3 2 1 0
103 		+----------+ +-+-----+-+---+
104   2-byte VEX C5 | 11000101 | |R| vvvv|L| pp|
105                 +----------+ +-+-----+-+---+
106 
107    R: REX.R in 1's complement (inverted) form
108       1: Same as REX.R=0 (must be 1 in 32-bit mode)
109       0: Same as REX.R=1 (64-bit mode only)
110    X: REX.X in 1's complement (inverted) form
111       1: Same as REX.X=0 (must be 1 in 32-bit mode)
112       0: Same as REX.X=1 (64-bit mode only)
113    B: REX.B in 1's complement (inverted) form
114       1: Same as REX.B=0 (Ignored in 32-bit mode).
115       0: Same as REX.B=1 (64-bit mode only)
116    W: opcode specific (use like REX.W, or used for memory operand
117       select on 4-operand instructions, or ignored, depending on the opcode)
118    m-mmmm:
119      00000: Reserved for future use (will #UD)
120      00001: implied 0F leading opcode byte
121      00010: implied 0F 38 leading opcode bytes
122      00011: implied 0F 3A leading opcode bytes
123      00100-11111: Reserved for future use (will #UD)
124    vvvv: a register specifier (in 1's complement form) or 1111 if unused.
125    L: Vector Length
126         0: scalar or 128-bit vector
127         1: 256-bit vector
128    pp: opcode extension providing equivalent functionality of a SIMD prefix
129         00: None
130         01: 66
131         10: F3
132         11: F2
133 */
134   unsigned char VEX_m;
135   unsigned char VEX_vlp;
136   unsigned char XOP_m;
137 }ix86Param;
138 
139 #define K86_REX (DisP->REX)
140 #define REX_W(rex) (((rex)&0x08)>>3)
141 #define REX_R(rex) (((rex)&0x04)>>2)
142 #define REX_X(rex) (((rex)&0x02)>>1)
143 #define REX_B(rex) ((rex)&0x01)
144 #define REX_w(rex) ((rex)&0x08)
145 #define REX_r(rex) ((rex)&0x04)
146 #define REX_x(rex) ((rex)&0x02)
147 #define REX_b(rex) ((rex)&0x01)
148 
149 extern char * SJump[];
150 typedef void (__FASTCALL__*ix86_method)(char *encode_str,ix86Param *);
151 
152 #define IX86_CPU086	0x00000000UL
153 #define IX86_CPU186	0x00000001UL
154 #define IX86_CPU286	0x00000002UL
155 #define IX86_CPU386	0x00000003UL
156 #define IX86_CPU486	0x00000004UL
157 #define IX86_CPU586	0x00000005UL
158 #define IX86_CPU686	0x00000006UL
159 #define IX86_CPU786	0x00000007UL
160 #define IX86_CPU886	0x00000008UL
161 #define IX86_CPU986	0x00000009UL
162 #define IX86_CPU1086	0x0000000AUL
163 #define IX86_CPU1186	0x0000000BUL
164 #define IX86_CPU1286	0x0000000CUL
165 #define IX86_CPUMASK	0x000000FFUL
166 
167 #define IX86_P2		IX86_CPU686
168 #define IX86_P3		IX86_CPU786
169 #define IX86_P4		IX86_CPU886
170 /* Prescott processor (SSE3) */
171 #define IX86_P5		IX86_CPU986
172 /* Xeon5100 processor (SSSE3)*/
173 #define IX86_P6		IX86_CPU1086
174 /* Xeon5200 processor (SSE4)*/
175 #define IX86_P7		IX86_CPU1186
176 #define IX86_P8		IX86_CPU1286
177 
178 #define K64_ATHLON	0x00000000UL
179 #define K64_FAM9	0x00000001UL
180 #define K64_FAM10	0x00000002UL
181 #define K64_FAM11	0x00000003UL
182 #define K64_CPUMASK	0x000000FFUL
183 
184 #define IX86_CLONEMASK	0x00000700UL
185 #define IX86_INTEL	0x00000000UL
186 #define IX86_AMD	0x00000100UL
187 #define IX86_CYRIX	0x00000200UL
188 #define IX86_VIA	0x00000300UL
189 
190 #define INSN_SYSTEMMASK	0x00000800UL
191 #define INSN_CPL0	0x00000800UL
192 
193 #define INSN_REGGROUP	0x0000F000UL
194 #define INSN_GPR	0x00000000UL /* insn works with general purpose registers */
195 #define INSN_FPU	0x00001000UL /* insn works with fpu registers */
196 #define INSN_MMX	0x00002000UL /* insn works with mmx registers */
197 #define INSN_SSE	0x00004000UL /* insn works with sse registers */
198 #define INSN_AVX	0x0000C000UL /* insn works with avx registers */
199 
200 #define INSN_VEXMASK		0x000F0000UL
201 #define INSN_VEX_V		0x00010000UL /* means insns use VVVV register extension from VEX prefix*/
202 #define INSN_VEXW_AS_SWAP	0x00020000UL /* means use VEX.W register to swap sources */
203 
204 #define INSN_FLAGS_MASK	0xFFF00000UL
205 #define INSN_LOAD	0x00000000UL /* means direction: OPCODE reg,[mem] */
206 #define INSN_STORE	0x00100000UL /* means direction: OPCODE [mem],reg */
207 #define INSN_OP_BYTE	0x00200000UL /* means operand size is 1 byte */
208 #define INSN_OP_WORD	0x00000000UL /* means operand size is word (16,32 or 64) depends on mode */
209 #define K64_NOCOMPAT	0x01000000UL /* means insns has no 16 or 32 bit forms */
210 #define K64_DEF32	0x02000000UL /* means insns size depends on default data size but not address size */
211 #define INSN_USERBIT	0x40000000UL /* overloaded for special purposes */
212 
213 #define BRIDGE_MMX_SSE	INSN_USERBIT
214 #define BRIDGE_SSE_MMX	0x00000000UL
215 #define BRIDGE_CPU_SSE	INSN_USERBIT
216 #define BRIDGE_SSE_CPU	0x00000000UL
217 #define IMM_BYTE	INSN_USERBIT
218 #define IMM_WORD	0x00000000UL
219 #define K64_FORCE64	INSN_USERBIT
220 
221 /* Special features flags */
222 #define TABDESC_MASK		0x80000000UL
223 #define TAB_NAME_IS_TABLE	0x80000000UL
224 
225 /* Furter processors */
226 #define IX86_UNKCPU	IX86_CPU1286
227 #define IX86_UNKFPU	(IX86_UNKCPU|INSN_FPU)
228 #define IX86_UNKMMX	(IX86_UNKCPU|INSN_MMX)
229 #define IX86_UNKSSE	(IX86_UNKCPU|INSN_SSE)
230 #define IX86_UNKAVX	(IX86_UNKCPU|INSN_AVX)
231 
232 #define IX86_K6		(IX86_AMD|IX86_CPU586)
233 #define IX86_3DNOW	(IX86_AMD|IX86_CPU686|INSN_MMX)
234 #define IX86_ATHLON	(IX86_AMD|IX86_CPU786|INSN_MMX)
235 #define IX86_UNKAMD	(IX86_AMD|IX86_CPU886|INSN_MMX)
236 
237 #define IX86_CYRIX486		(IX86_CYRIX|IX86_CPU486)
238 #define IX86_CYRIX686		(IX86_CYRIX|IX86_CPU586)
239 #define IX86_CYRIX686MMX	(IX86_CYRIX|IX86_CPU586|INSN_MMX)
240 #define IX86_UNKCYRIX		(IX86_CYRIX|IX86_CPU686)
241 
242 typedef struct tag_ix86opcodes
243 {
244   const char *  name16;
245   const char *  name32;
246 #ifdef IX86_64
247   const char *  name64;
248 #endif
249   ix86_method   method;
250   unsigned long pro_clone;
251 #ifdef IX86_64
252   ix86_method   method64;
253   unsigned long flags64;
254 #endif
255 }ix86_Opcodes;
256 
257 typedef struct tag_ix86ExOpcodes
258 {
259   const char *  name;
260 #ifdef IX86_64
261   const char *  name64;
262 #endif
263   ix86_method   method;
264 #ifdef IX86_64
265   ix86_method   method64;
266   unsigned long flags64;
267 #endif
268   unsigned long pro_clone;
269 }ix86_ExOpcodes;
270 
271 typedef struct tag_ix3dNowopcodes
272 {
273   const char *  name;
274   unsigned long pro_clone;
275 }ix86_3dNowopcodes;
276 
277 extern unsigned x86_Bitness;
278 
279 extern const ix86_Opcodes ix86_table[];
280 extern const ix86_ExOpcodes ix86_extable[];
281 extern const ix86_3dNowopcodes ix86_3dNowtable[];
282 
283 extern char ix86_segpref[];
284 extern const char * ix86_sizes[];
285 extern const char * ix86_A16[];
286 extern const char * i8086_ByteRegs[];
287 extern const char * k64_ByteRegs[];
288 
289 extern const char * ix86_MMXRegs[];
290 
291 extern const char * k64_WordRegs[];
292 extern const char * k64_DWordRegs[];
293 extern const char * k64_QWordRegs[];
294 extern const char * k64_XMMXRegs[];
295 extern const char * k64_YMMXRegs[];
296 extern const char * k64_CrxRegs[];
297 extern const char * k64_DrxRegs[];
298 extern const char * k64_TrxRegs[];
299 extern const char * k64_XrxRegs[];
300 
301 extern const char * ix86_SegRegs[];
302 
303 extern const char * ix86_Op1Names[];
304 extern const char * ix86_ShNames[];
305 extern const char * ix86_Gr1Names[];
306 extern const char * ix86_Gr2Names[];
307 
308 extern const char * ix86_ExGrp0[];
309 extern const char * ix86_BitGrpNames[];
310 
311 extern const char * ix86_MMXGr1[];
312 extern const char * ix86_MMXGr2[];
313 extern const char * ix86_MMXGr3[];
314 extern const char * ix86_XMMXGr1[];
315 extern const char * ix86_XMMXGr2[];
316 extern const char * ix86_XMMXGr3[];
317 
318 extern const char * ix86_3dPrefetchGrp[];
319 
320 extern const char * ix86_KatmaiGr2Names[];
321 
322 extern const ix86_ExOpcodes* __FASTCALL__ ix86_prepare_flags(const ix86_ExOpcodes *extable,ix86Param *DisP,unsigned char *code,unsigned char *codelen);
323 extern char * __FASTCALL__ ix86_getModRM(tBool w,unsigned char mod,unsigned char rm,ix86Param *DisP);
324 extern void   __FASTCALL__ ix86_setModifier(char *str,const char *modf);
325 extern char * __FASTCALL__ ix86_CStile(ix86Param *DisP,char *str,const char *arg2);
326 
327 /* methods */
328 
329 extern void   __FASTCALL__ ix86_ArgES(char *str,ix86Param *);
330 extern void   __FASTCALL__ ix86_ArgDS(char *str,ix86Param *);
331 extern void   __FASTCALL__ ix86_ArgSS(char *str,ix86Param *);
332 extern void   __FASTCALL__ ix86_ArgCS(char *str,ix86Param *);
333 extern void   __FASTCALL__ ix86_ArgFS(char *str,ix86Param *);
334 extern void   __FASTCALL__ ix86_ArgGS(char *str,ix86Param *);
335 
336 extern void   __FASTCALL__ arg_cpu_modregrm(char * str,ix86Param *DisP);
337 extern void   __FASTCALL__ arg_cpu_modREGrm(char * str,ix86Param *DisP); /* CRC32 */
338 extern void   __FASTCALL__ arg_cpu_mod_rm(char* str,ix86Param *DisP);
339 extern void   __FASTCALL__ arg_cpu_mod_rm_imm(char *str,ix86Param *DisP);
340 extern void   __FASTCALL__ arg_cpu_modregrm_imm(char *str,ix86Param *DisP);
341 extern void   __FASTCALL__ arg_offset(char *str,ix86Param *);
342 extern void   __FASTCALL__ arg_segoff(char *str,ix86Param *);
343 extern void   __FASTCALL__ arg_insnreg(char *str,ix86Param *); /* reg is part of insn */
344 extern void   __FASTCALL__ arg_insnreg_imm(char *str,ix86Param *);
345 extern void   __FASTCALL__ arg_cpu_modsegrm(char * str,ix86Param *DisP);
346 extern void   __FASTCALL__ arg_r0_imm(char *str,ix86Param *);
347 extern void   __FASTCALL__ arg_r0rm(char *str,ix86Param *);
348 extern void   __FASTCALL__ arg_r0mem(char *str,ix86Param *DisP);
349 extern void   __FASTCALL__ arg_imm(char *str,ix86Param *);
350 extern void   __FASTCALL__ arg_imm8(char *str,ix86Param *);
351 extern void   __FASTCALL__ arg_imm16(char *str,ix86Param *);
352 extern void   __FASTCALL__ arg_imm16_imm8(char *str,ix86Param *);
353 
354 extern void   __FASTCALL__ ix86_ArgOp1(char *str,ix86Param *);
355 extern void   __FASTCALL__ ix86_ArgOp2(char *str,ix86Param *);
356 extern void   __FASTCALL__ ix86_ShOp2(char *str,ix86Param *);
357 extern void   __FASTCALL__ ix86_ShOp1(char *str,ix86Param *);
358 extern void   __FASTCALL__ ix86_ShOpCL(char *str,ix86Param *);
359 extern void   __FASTCALL__ ix86_ArgGrp1(char *str,ix86Param *);
360 extern void   __FASTCALL__ ix86_ArgGrp2(char *str,ix86Param *);
361 extern void   __FASTCALL__ ix86_InOut(char *str,ix86Param *);
362 extern void   __FASTCALL__ ix86_FPUCmd(char *str,ix86Param *);
363 
364 extern void   __FASTCALL__ ix86_ExOpCodes(char *str,ix86Param *);
365 extern void   __FASTCALL__ ix86_3dNowOpCodes(char *str,ix86Param *);
366 extern void   __FASTCALL__ ix86_3dNowPrefetchGrp(char *str,ix86Param *);
367 extern void   __FASTCALL__ ix86_BitGrp(char *str,ix86Param *);
368 
369 extern void   __FASTCALL__ ix86_ArgExGr0(char *str,ix86Param *);
370 extern void   __FASTCALL__ ix86_ArgExGr1(char *str,ix86Param *);
371 extern void   __FASTCALL__ ix86_ArgMovXRY(char *str,ix86Param *);
372 extern void   __FASTCALL__ ix86_DblShift(char *str,ix86Param *);
373 
374 extern void   __FASTCALL__ arg_emms(char *str,ix86Param *);
375 extern void   __FASTCALL__ arg_simd(char *str,ix86Param *);
376 extern void   __FASTCALL__ arg_simd_imm8(char *str,ix86Param *);
377 extern void   __FASTCALL__ arg_simd_xmm0(char *str,ix86Param *);
378 extern void   __FASTCALL__ arg_simd_regrm(char *str,ix86Param *);
379 extern void   __FASTCALL__ arg_simd_regrm_imm8_imm8(char *str,ix86Param *);
380 extern void   __FASTCALL__ arg_simd_rm_imm8_imm8(char *str,ix86Param *);
381 extern void   __FASTCALL__ bridge_sse_mmx(char *str,ix86Param* DisP);
382 extern void   __FASTCALL__ bridge_simd_cpu(char *str,ix86Param* DisP);
383 extern void   __FASTCALL__ bridge_simd_cpu_imm8(char *str,ix86Param* DisP);
384 extern void   __FASTCALL__ arg_fma(char *str,ix86Param *);
385 extern void   __FASTCALL__ arg_fma4(char *str,ix86Param *);
386 extern void   __FASTCALL__ arg_fma4_imm8(char *str,ix86Param *DisP);
387 
388 extern void   __FASTCALL__ ix86_ArgMMXGr1(char *str,ix86Param *);
389 extern void   __FASTCALL__ ix86_ArgMMXGr2(char *str,ix86Param *);
390 extern void   __FASTCALL__ ix86_ArgMMXGr3(char *str,ix86Param *);
391 extern void   __FASTCALL__ ix86_ArgXMMXGr1(char *str,ix86Param *);
392 extern void   __FASTCALL__ ix86_ArgXMMXGr2(char *str,ix86Param *);
393 extern void   __FASTCALL__ ix86_ArgXMMXGr3(char *str,ix86Param *);
394 
395 extern void   __FASTCALL__ ix86_ArgKatmaiGrp1(char *str,ix86Param *);
396 extern void   __FASTCALL__ ix86_ArgKatmaiGrp2(char *str,ix86Param *);
397 extern void   __FASTCALL__ ix86_ArgMovYX(char *str,ix86Param *);
398 extern void   __FASTCALL__ arg_simd_cmp(char *str,ix86Param *DisP);
399 extern void   __FASTCALL__ arg_simd_clmul(char *str,ix86Param *DisP);
400 extern void   __FASTCALL__ arg_xop_cmp(char *str,ix86Param *DisP);
401 
402 
403 extern void   __FASTCALL__ ix86_VMX(char *str,ix86Param *);
404 extern void   __FASTCALL__ ix86_0FVMX(char *str,ix86Param *DisP);
405 extern void   __FASTCALL__ ix86_660FVMX(char *str,ix86Param *DisP);
406 
407 #endif
408 
409 
410