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