1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 /**
18 * @author Alexander V. Astapchuk
19 */
20 #ifndef _ENCODER_DEFS_H_
21 #define _ENCODER_DEFS_H_
22
23
24 // Used to isolate experimental or being tuned encoder into a separate
25 // namespace so it can coexist with a stable one in the same bundle.
26 #ifdef ENCODER_ISOLATE
27 #define ENCODER_NAMESPACE_START namespace enc_ia32 {
28 #define ENCODER_NAMESPACE_END };
29 #else
30 #define ENCODER_NAMESPACE_START
31 #define ENCODER_NAMESPACE_END
32 #endif
33
34 #include <assert.h>
35 #include "enc_defs_ext.h"
36
37 #ifndef COUNTOF
38 /**
39 * Number of items in an array.
40 */
41 #define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
42 #endif
43
44 #ifdef _EM64T_
45 /**
46 * A stack pointer of default platform's size.
47 */
48 #define REG_STACK RegName_RSP
49 /**
50 * A max GP register (with a highest index number)
51 */
52 #define REG_MAX RegName_R15
53 /**
54 * Total number of GP registers including stack pointer.
55 */
56 #define MAX_REGS 15
57 #else
58 #define REG_STACK RegName_ESP
59 #define REG_MAX RegName_EDI
60 #define MAX_REGS 8
61 #endif
62
63 ENCODER_NAMESPACE_START
64
65 /**
66 * A number of bytes 'eaten' by an ordinary PUSH/POP.
67 */
68 #define STACK_SLOT_SIZE (sizeof(void*))
69
70
71 /**
72 * A recommended by Intel Arch Manual aligment for instructions that
73 * are targets for jmps.
74 */
75 #define JMP_TARGET_ALIGMENT (16)
76 /**
77 * A maximum possible size of native instruction.
78 */
79 #define MAX_NATIVE_INST_SIZE (15)
80 /**
81 * The enum OpndKind describes an operand's location - memory, immediate or a register.
82 * It can be used as a bit mask.
83 */
84 typedef enum OpndKind {
85 /**
86 * A change must be balanced with at least the following places:
87 * Ia32::Constraint-s use the OpndKind as a mask
88 * encoder.cpp & encoder_master_info.cpp uses OpndKind as an index for hashing
89 * - perhaps there are much more places
90 *
91 * NOTE: an MMXReg kind is incompatible with the current constraints framework,
92 * as it's not encoded as a mask.
93 */
94 OpndKind_Null=0,
95 OpndKind_GPReg = 0x01, OpndKind_MinRegKind = OpndKind_GPReg,
96 OpndKind_SReg = 0x02,
97 #ifdef _HAVE_MMX_
98 OpndKind_MMXReg = 0x03,
99 #endif
100 OpndKind_FPReg = 0x04,
101 OpndKind_XMMReg = 0x08,
102 OpndKind_OtherReg = 0x10,
103 OpndKind_StatusReg = OpndKind_OtherReg,
104 OpndKind_MaxRegKind = OpndKind_StatusReg, // a max existing kind of register
105 OpndKind_MaxReg, // -'- + 1 to be used in array defs
106 //
107 OpndKind_Immediate = 0x20, OpndKind_Imm=OpndKind_Immediate,
108 OpndKind_Memory = 0x40, OpndKind_Mem=OpndKind_Memory,
109 //
110 OpndKind_Reg = 0x1F,
111 OpndKind_Any = 0x7F,
112 // syntetic constants. Normally not used anywhere, but are used for
113 // human-readable showing under the debugger
114 OpndKind_GPReg_Mem = OpndKind_GPReg|OpndKind_Mem,
115 #ifdef _HAVE_MMX_
116 OpndKind_MMXReg_Mem = OpndKind_MMXReg|OpndKind_Mem,
117 #endif
118 OpndKind_XMMReg_Mem = OpndKind_XMMReg|OpndKind_Mem,
119 } OpndKind;
120
121 /**
122 * Defines type of extention allowed for particular operand.
123 * For example imul r32,r_m32,imm8 sign extend imm8 before performing multiplication.
124 * To satisfy instruction constraints immediate operand should be either OpndExt_Signed
125 * or OpndExt_Any.
126 */
127 typedef enum OpndExt {
128 OpndExt_None = 0x0,
129 OpndExt_Signed = 0x1,
130 OpndExt_Zero = 0x2,
131 OpndExt_Any = 0x3,
132 }OpndExt;
133
134 /**
135 * enum OpndRole defines the role of an operand in an instruction
136 * Can be used as mask to combine def and use. The complete def+use
137 * info can be combined in 2 bits which is used, say in Encoder::OpndRole.
138 */
139 //TODO: this duplicates an Role used in the Ia32::Inst. That duplicate enum should be removed.
140 typedef enum OpndRole {
141 OpndRole_Null=0,
142 OpndRole_Use=0x1,
143 OpndRole_Def=0x2,
144 OpndRole_UseDef=OpndRole_Use|OpndRole_Def,
145 OpndRole_All=0xffff,
146 } OpndRole;
147
148
149 #define REGNAME(k,s,i) ( ((k & OpndKind_Any)<<24) | ((s & OpndSize_Any)<<16) | (i&0xFF) )
150
151 // Gregory -
152 // It is critical that all register indexes (3rd number) inside of the
153 // following table go in ascending order. That is R8 goes after
154 // RDI. It is necessary for decoder when extending registers from RAX-RDI
155 // to R8-R15 by simply adding 8 to the index on EM64T architecture
156 typedef enum RegName {
157
158 RegName_Null = 0,
159
160 #ifdef _EM64T_
161 /*
162 An index part of the RegName-s for RAX-RDI, EAX-ESI, AX-SI and AL-BH is
163 the same as the index used during instructions encoding. The same rule
164 applies for XMM regsters for IA32.
165 For new EM64T registers (both GP and XMM) the index need to be corrected to
166 obtain the index used in processor's instructions.
167 */
168 RegName_RAX = REGNAME(OpndKind_GPReg,OpndSize_64,0),
169 RegName_RCX = REGNAME(OpndKind_GPReg,OpndSize_64,1),
170 RegName_RDX = REGNAME(OpndKind_GPReg,OpndSize_64,2),
171 RegName_RBX = REGNAME(OpndKind_GPReg,OpndSize_64,3),
172 RegName_RSP = REGNAME(OpndKind_GPReg,OpndSize_64,4),
173 RegName_RBP = REGNAME(OpndKind_GPReg,OpndSize_64,5),
174 RegName_RSI = REGNAME(OpndKind_GPReg,OpndSize_64,6),
175 RegName_RDI = REGNAME(OpndKind_GPReg,OpndSize_64,7),
176
177 RegName_R8 = REGNAME(OpndKind_GPReg,OpndSize_64,8),
178 RegName_R9 = REGNAME(OpndKind_GPReg,OpndSize_64,9),
179 RegName_R10 = REGNAME(OpndKind_GPReg,OpndSize_64,10),
180 RegName_R11 = REGNAME(OpndKind_GPReg,OpndSize_64,11),
181 RegName_R12 = REGNAME(OpndKind_GPReg,OpndSize_64,12),
182 RegName_R13 = REGNAME(OpndKind_GPReg,OpndSize_64,13),
183 RegName_R14 = REGNAME(OpndKind_GPReg,OpndSize_64,14),
184 RegName_R15 = REGNAME(OpndKind_GPReg,OpndSize_64,15),
185 #endif //~_EM64T_
186
187 RegName_EAX=REGNAME(OpndKind_GPReg,OpndSize_32,0),
188 RegName_ECX=REGNAME(OpndKind_GPReg,OpndSize_32,1),
189 RegName_EDX=REGNAME(OpndKind_GPReg,OpndSize_32,2),
190 RegName_EBX=REGNAME(OpndKind_GPReg,OpndSize_32,3),
191 RegName_ESP=REGNAME(OpndKind_GPReg,OpndSize_32,4),
192 RegName_EBP=REGNAME(OpndKind_GPReg,OpndSize_32,5),
193 RegName_ESI=REGNAME(OpndKind_GPReg,OpndSize_32,6),
194 RegName_EDI=REGNAME(OpndKind_GPReg,OpndSize_32,7),
195
196 #ifdef _EM64T_
197 RegName_R8D = REGNAME(OpndKind_GPReg,OpndSize_32,8),
198 RegName_R9D = REGNAME(OpndKind_GPReg,OpndSize_32,9),
199 RegName_R10D = REGNAME(OpndKind_GPReg,OpndSize_32,10),
200 RegName_R11D = REGNAME(OpndKind_GPReg,OpndSize_32,11),
201 RegName_R12D = REGNAME(OpndKind_GPReg,OpndSize_32,12),
202 RegName_R13D = REGNAME(OpndKind_GPReg,OpndSize_32,13),
203 RegName_R14D = REGNAME(OpndKind_GPReg,OpndSize_32,14),
204 RegName_R15D = REGNAME(OpndKind_GPReg,OpndSize_32,15),
205 #endif //~_EM64T_
206
207 RegName_AX=REGNAME(OpndKind_GPReg,OpndSize_16,0),
208 RegName_CX=REGNAME(OpndKind_GPReg,OpndSize_16,1),
209 RegName_DX=REGNAME(OpndKind_GPReg,OpndSize_16,2),
210 RegName_BX=REGNAME(OpndKind_GPReg,OpndSize_16,3),
211 RegName_SP=REGNAME(OpndKind_GPReg,OpndSize_16,4),
212 RegName_BP=REGNAME(OpndKind_GPReg,OpndSize_16,5),
213 RegName_SI=REGNAME(OpndKind_GPReg,OpndSize_16,6),
214 RegName_DI=REGNAME(OpndKind_GPReg,OpndSize_16,7),
215
216 #ifdef _EM64T_
217 RegName_R8S = REGNAME(OpndKind_GPReg,OpndSize_16,8),
218 RegName_R9S = REGNAME(OpndKind_GPReg,OpndSize_16,9),
219 RegName_R10S = REGNAME(OpndKind_GPReg,OpndSize_16,10),
220 RegName_R11S = REGNAME(OpndKind_GPReg,OpndSize_16,11),
221 RegName_R12S = REGNAME(OpndKind_GPReg,OpndSize_16,12),
222 RegName_R13S = REGNAME(OpndKind_GPReg,OpndSize_16,13),
223 RegName_R14S = REGNAME(OpndKind_GPReg,OpndSize_16,14),
224 RegName_R15S = REGNAME(OpndKind_GPReg,OpndSize_16,15),
225 #endif //~_EM64T_
226
227 RegName_AL=REGNAME(OpndKind_GPReg,OpndSize_8,0),
228 RegName_CL=REGNAME(OpndKind_GPReg,OpndSize_8,1),
229 RegName_DL=REGNAME(OpndKind_GPReg,OpndSize_8,2),
230 RegName_BL=REGNAME(OpndKind_GPReg,OpndSize_8,3),
231 // FIXME: Used in enc_tabl.cpp
232 // AH is not accessible on EM64T, instead encoded register is SPL, so decoded
233 // register will return incorrect enum
234 RegName_AH=REGNAME(OpndKind_GPReg,OpndSize_8,4),
235 #if !defined(_EM64T_)
236 RegName_CH=REGNAME(OpndKind_GPReg,OpndSize_8,5),
237 RegName_DH=REGNAME(OpndKind_GPReg,OpndSize_8,6),
238 RegName_BH=REGNAME(OpndKind_GPReg,OpndSize_8,7),
239 #else
240 RegName_SPL=REGNAME(OpndKind_GPReg,OpndSize_8,4),
241 RegName_BPL=REGNAME(OpndKind_GPReg,OpndSize_8,5),
242 RegName_SIL=REGNAME(OpndKind_GPReg,OpndSize_8,6),
243 RegName_DIL=REGNAME(OpndKind_GPReg,OpndSize_8,7),
244 RegName_R8L=REGNAME(OpndKind_GPReg,OpndSize_8,8),
245 RegName_R9L=REGNAME(OpndKind_GPReg,OpndSize_8,9),
246 RegName_R10L=REGNAME(OpndKind_GPReg,OpndSize_8,10),
247 RegName_R11L=REGNAME(OpndKind_GPReg,OpndSize_8,11),
248 RegName_R12L=REGNAME(OpndKind_GPReg,OpndSize_8,12),
249 RegName_R13L=REGNAME(OpndKind_GPReg,OpndSize_8,13),
250 RegName_R14L=REGNAME(OpndKind_GPReg,OpndSize_8,14),
251 RegName_R15L=REGNAME(OpndKind_GPReg,OpndSize_8,15),
252 #endif
253
254 RegName_ES=REGNAME(OpndKind_SReg,OpndSize_16,0),
255 RegName_CS=REGNAME(OpndKind_SReg,OpndSize_16,1),
256 RegName_SS=REGNAME(OpndKind_SReg,OpndSize_16,2),
257 RegName_DS=REGNAME(OpndKind_SReg,OpndSize_16,3),
258 RegName_FS=REGNAME(OpndKind_SReg,OpndSize_16,4),
259 RegName_GS=REGNAME(OpndKind_SReg,OpndSize_16,5),
260
261 RegName_EFLAGS=REGNAME(OpndKind_StatusReg,OpndSize_32,0),
262
263 #if !defined(TESTING_ENCODER)
264 RegName_FP0=REGNAME(OpndKind_FPReg,OpndSize_80,0),
265 RegName_FP1=REGNAME(OpndKind_FPReg,OpndSize_80,1),
266 RegName_FP2=REGNAME(OpndKind_FPReg,OpndSize_80,2),
267 RegName_FP3=REGNAME(OpndKind_FPReg,OpndSize_80,3),
268 RegName_FP4=REGNAME(OpndKind_FPReg,OpndSize_80,4),
269 RegName_FP5=REGNAME(OpndKind_FPReg,OpndSize_80,5),
270 RegName_FP6=REGNAME(OpndKind_FPReg,OpndSize_80,6),
271 RegName_FP7=REGNAME(OpndKind_FPReg,OpndSize_80,7),
272 #endif
273 RegName_FP0S=REGNAME(OpndKind_FPReg,OpndSize_32,0),
274 RegName_FP1S=REGNAME(OpndKind_FPReg,OpndSize_32,1),
275 RegName_FP2S=REGNAME(OpndKind_FPReg,OpndSize_32,2),
276 RegName_FP3S=REGNAME(OpndKind_FPReg,OpndSize_32,3),
277 RegName_FP4S=REGNAME(OpndKind_FPReg,OpndSize_32,4),
278 RegName_FP5S=REGNAME(OpndKind_FPReg,OpndSize_32,5),
279 RegName_FP6S=REGNAME(OpndKind_FPReg,OpndSize_32,6),
280 RegName_FP7S=REGNAME(OpndKind_FPReg,OpndSize_32,7),
281
282 RegName_FP0D=REGNAME(OpndKind_FPReg,OpndSize_64,0),
283 RegName_FP1D=REGNAME(OpndKind_FPReg,OpndSize_64,1),
284 RegName_FP2D=REGNAME(OpndKind_FPReg,OpndSize_64,2),
285 RegName_FP3D=REGNAME(OpndKind_FPReg,OpndSize_64,3),
286 RegName_FP4D=REGNAME(OpndKind_FPReg,OpndSize_64,4),
287 RegName_FP5D=REGNAME(OpndKind_FPReg,OpndSize_64,5),
288 RegName_FP6D=REGNAME(OpndKind_FPReg,OpndSize_64,6),
289 RegName_FP7D=REGNAME(OpndKind_FPReg,OpndSize_64,7),
290
291 #if !defined(TESTING_ENCODER)
292 RegName_XMM0=REGNAME(OpndKind_XMMReg,OpndSize_128,0),
293 RegName_XMM1=REGNAME(OpndKind_XMMReg,OpndSize_128,1),
294 RegName_XMM2=REGNAME(OpndKind_XMMReg,OpndSize_128,2),
295 RegName_XMM3=REGNAME(OpndKind_XMMReg,OpndSize_128,3),
296 RegName_XMM4=REGNAME(OpndKind_XMMReg,OpndSize_128,4),
297 RegName_XMM5=REGNAME(OpndKind_XMMReg,OpndSize_128,5),
298 RegName_XMM6=REGNAME(OpndKind_XMMReg,OpndSize_128,6),
299 RegName_XMM7=REGNAME(OpndKind_XMMReg,OpndSize_128,7),
300
301 #ifdef _EM64T_
302 RegName_XMM8 = REGNAME(OpndKind_XMMReg,OpndSize_128,0),
303 RegName_XMM9 = REGNAME(OpndKind_XMMReg,OpndSize_128,1),
304 RegName_XMM10 = REGNAME(OpndKind_XMMReg,OpndSize_128,2),
305 RegName_XMM11 = REGNAME(OpndKind_XMMReg,OpndSize_128,3),
306 RegName_XMM12 = REGNAME(OpndKind_XMMReg,OpndSize_128,4),
307 RegName_XMM13 = REGNAME(OpndKind_XMMReg,OpndSize_128,5),
308 RegName_XMM14 = REGNAME(OpndKind_XMMReg,OpndSize_128,6),
309 RegName_XMM15 = REGNAME(OpndKind_XMMReg,OpndSize_128,7),
310 #endif //~_EM64T_
311
312 #endif // ~TESTING_ENCODER
313
314 RegName_XMM0S=REGNAME(OpndKind_XMMReg,OpndSize_32,0),
315 RegName_XMM1S=REGNAME(OpndKind_XMMReg,OpndSize_32,1),
316 RegName_XMM2S=REGNAME(OpndKind_XMMReg,OpndSize_32,2),
317 RegName_XMM3S=REGNAME(OpndKind_XMMReg,OpndSize_32,3),
318 RegName_XMM4S=REGNAME(OpndKind_XMMReg,OpndSize_32,4),
319 RegName_XMM5S=REGNAME(OpndKind_XMMReg,OpndSize_32,5),
320 RegName_XMM6S=REGNAME(OpndKind_XMMReg,OpndSize_32,6),
321 RegName_XMM7S=REGNAME(OpndKind_XMMReg,OpndSize_32,7),
322 #ifdef _EM64T_
323 RegName_XMM8S=REGNAME(OpndKind_XMMReg,OpndSize_32,8),
324 RegName_XMM9S=REGNAME(OpndKind_XMMReg,OpndSize_32,9),
325 RegName_XMM10S=REGNAME(OpndKind_XMMReg,OpndSize_32,10),
326 RegName_XMM11S=REGNAME(OpndKind_XMMReg,OpndSize_32,11),
327 RegName_XMM12S=REGNAME(OpndKind_XMMReg,OpndSize_32,12),
328 RegName_XMM13S=REGNAME(OpndKind_XMMReg,OpndSize_32,13),
329 RegName_XMM14S=REGNAME(OpndKind_XMMReg,OpndSize_32,14),
330 RegName_XMM15S=REGNAME(OpndKind_XMMReg,OpndSize_32,15),
331 #endif // ifdef _EM64T_
332 RegName_XMM0D=REGNAME(OpndKind_XMMReg,OpndSize_64,0),
333 RegName_XMM1D=REGNAME(OpndKind_XMMReg,OpndSize_64,1),
334 RegName_XMM2D=REGNAME(OpndKind_XMMReg,OpndSize_64,2),
335 RegName_XMM3D=REGNAME(OpndKind_XMMReg,OpndSize_64,3),
336 RegName_XMM4D=REGNAME(OpndKind_XMMReg,OpndSize_64,4),
337 RegName_XMM5D=REGNAME(OpndKind_XMMReg,OpndSize_64,5),
338 RegName_XMM6D=REGNAME(OpndKind_XMMReg,OpndSize_64,6),
339 RegName_XMM7D=REGNAME(OpndKind_XMMReg,OpndSize_64,7),
340 #ifdef _EM64T_
341 RegName_XMM8D=REGNAME(OpndKind_XMMReg,OpndSize_64,8),
342 RegName_XMM9D=REGNAME(OpndKind_XMMReg,OpndSize_64,9),
343 RegName_XMM10D=REGNAME(OpndKind_XMMReg,OpndSize_64,10),
344 RegName_XMM11D=REGNAME(OpndKind_XMMReg,OpndSize_64,11),
345 RegName_XMM12D=REGNAME(OpndKind_XMMReg,OpndSize_64,12),
346 RegName_XMM13D=REGNAME(OpndKind_XMMReg,OpndSize_64,13),
347 RegName_XMM14D=REGNAME(OpndKind_XMMReg,OpndSize_64,14),
348 RegName_XMM15D=REGNAME(OpndKind_XMMReg,OpndSize_64,15),
349 #endif // ifdef _EM64T_
350 #ifdef _HAVE_MMX_
351 RegName_MMX0=REGNAME(OpndKind_MMXReg,OpndSize_64,0),
352 RegName_MMX1=REGNAME(OpndKind_MMXReg,OpndSize_64,1),
353 RegName_MMX2=REGNAME(OpndKind_MMXReg,OpndSize_64,2),
354 RegName_MMX3=REGNAME(OpndKind_MMXReg,OpndSize_64,3),
355 RegName_MMX4=REGNAME(OpndKind_MMXReg,OpndSize_64,4),
356 RegName_MMX5=REGNAME(OpndKind_MMXReg,OpndSize_64,5),
357 RegName_MMX6=REGNAME(OpndKind_MMXReg,OpndSize_64,6),
358 RegName_MMX7=REGNAME(OpndKind_MMXReg,OpndSize_64,7),
359 #endif // _HAVE_MMX_
360 } RegName;
361
362 #if 0 // Android x86: use mnemonics defined in enc_defs_ext.h
363 /**
364 * Conditional mnemonics.
365 * The values match the 'real' (==processor's) values of the appropriate
366 * condition values used in the opcodes.
367 */
368 enum ConditionMnemonic {
369
370 ConditionMnemonic_O=0,
371 ConditionMnemonic_NO=1,
372 ConditionMnemonic_B=2, ConditionMnemonic_NAE=ConditionMnemonic_B, ConditionMnemonic_C=ConditionMnemonic_B,
373 ConditionMnemonic_NB=3, ConditionMnemonic_AE=ConditionMnemonic_NB, ConditionMnemonic_NC=ConditionMnemonic_NB,
374 ConditionMnemonic_Z=4, ConditionMnemonic_E=ConditionMnemonic_Z,
375 ConditionMnemonic_NZ=5, ConditionMnemonic_NE=ConditionMnemonic_NZ,
376 ConditionMnemonic_BE=6, ConditionMnemonic_NA=ConditionMnemonic_BE,
377 ConditionMnemonic_NBE=7, ConditionMnemonic_A=ConditionMnemonic_NBE,
378
379 ConditionMnemonic_S=8,
380 ConditionMnemonic_NS=9,
381 ConditionMnemonic_P=10, ConditionMnemonic_PE=ConditionMnemonic_P,
382 ConditionMnemonic_NP=11, ConditionMnemonic_PO=ConditionMnemonic_NP,
383 ConditionMnemonic_L=12, ConditionMnemonic_NGE=ConditionMnemonic_L,
384 ConditionMnemonic_NL=13, ConditionMnemonic_GE=ConditionMnemonic_NL,
385 ConditionMnemonic_LE=14, ConditionMnemonic_NG=ConditionMnemonic_LE,
386 ConditionMnemonic_NLE=15, ConditionMnemonic_G=ConditionMnemonic_NLE,
387 ConditionMnemonic_Count=16
388 };
389
390
391 #define CCM(prefix,cond) Mnemonic_##prefix##cond=Mnemonic_##prefix##cc+ConditionMnemonic_##cond
392
393 //=========================================================================================================
394 enum Mnemonic {
395
396 Mnemonic_NULL=0, Mnemonic_Null=Mnemonic_NULL,
397 Mnemonic_ADC, // Add with Carry
398 Mnemonic_ADD, // Add
399 Mnemonic_ADDSD, // Add Scalar Double-Precision Floating-Point Values
400 Mnemonic_ADDSS, // Add Scalar Single-Precision Floating-Point Values
401 Mnemonic_AND, // Logical AND
402
403 Mnemonic_BSF, // Bit scan forward
404 Mnemonic_BSR, // Bit scan reverse
405
406 Mnemonic_CALL, // Call Procedure
407 Mnemonic_CMC, // Complement Carry Flag
408 Mnemonic_CWD, Mnemonic_CDQ=Mnemonic_CWD,// Convert Word to Doubleword/Convert Doubleword to Qua T dword
409 Mnemonic_CMOVcc, // Conditional Move
410 CCM(CMOV,O),
411 CCM(CMOV,NO),
412 CCM(CMOV,B), CCM(CMOV,NAE), CCM(CMOV,C),
413 CCM(CMOV,NB), CCM(CMOV,AE), CCM(CMOV,NC),
414 CCM(CMOV,Z), CCM(CMOV,E),
415 CCM(CMOV,NZ), CCM(CMOV,NE),
416 CCM(CMOV,BE), CCM(CMOV,NA),
417 CCM(CMOV,NBE), CCM(CMOV,A),
418
419 CCM(CMOV,S),
420 CCM(CMOV,NS),
421 CCM(CMOV,P), CCM(CMOV,PE),
422 CCM(CMOV,NP), CCM(CMOV,PO),
423 CCM(CMOV,L), CCM(CMOV,NGE),
424 CCM(CMOV,NL), CCM(CMOV,GE),
425 CCM(CMOV,LE), CCM(CMOV,NG),
426 CCM(CMOV,NLE), CCM(CMOV,G),
427
428 Mnemonic_CMP, // Compare Two Operands
429 Mnemonic_CMPXCHG, // Compare and exchange
430 Mnemonic_CMPXCHG8B, // Compare and Exchange 8 Bytes
431 Mnemonic_CMPSB, // Compare Two Bytes at DS:ESI and ES:EDI
432 Mnemonic_CMPSW, // Compare Two Words at DS:ESI and ES:EDI
433 Mnemonic_CMPSD, // Compare Two Doublewords at DS:ESI and ES:EDI
434 //
435 // double -> float
436 Mnemonic_CVTSD2SS, // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
437 // double -> I_32
438 Mnemonic_CVTSD2SI, // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
439 // double [truncated] -> I_32
440 Mnemonic_CVTTSD2SI, // Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer
441 //
442 // float -> double
443 Mnemonic_CVTSS2SD, // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
444 // float -> I_32
445 Mnemonic_CVTSS2SI, // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer
446 // float [truncated] -> I_32
447 Mnemonic_CVTTSS2SI, // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
448 //
449 // I_32 -> double
450 Mnemonic_CVTSI2SD, // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
451 // I_32 -> float
452 Mnemonic_CVTSI2SS, // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
453
454 Mnemonic_COMISD, // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
455 Mnemonic_COMISS, // Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
456 Mnemonic_DEC, // Decrement by 1
457 //Mnemonic_DIV, // Unsigned Divide
458 Mnemonic_DIVSD, // Divide Scalar Double-Precision Floating-Point Values
459 Mnemonic_DIVSS, // Divide Scalar Single-Precision Floating-Point Values
460
461 #ifdef _HAVE_MMX_
462 Mnemonic_EMMS, // Empty MMX Technology State
463 #endif
464
465 Mnemonic_ENTER, // ENTER-Make Stack Frame for Procedure Parameters
466 Mnemonic_FLDCW, // Load FPU control word
467 Mnemonic_FADDP,
468 Mnemonic_FLDZ,
469 Mnemonic_FADD,
470 Mnemonic_FSUBP,
471 Mnemonic_FSUB,
472 Mnemonic_FISUB,
473 Mnemonic_FMUL,
474 Mnemonic_FMULP,
475 Mnemonic_FDIVP,
476 Mnemonic_FDIV,
477 Mnemonic_FUCOMPP,
478 Mnemonic_FRNDINT,
479 Mnemonic_FNSTCW, // Store FPU control word
480 Mnemonic_FSTSW, // Store FPU status word
481 Mnemonic_FNSTSW, // Store FPU status word
482 //Mnemonic_FDECSTP, // Decrement Stack-Top Pointer
483 Mnemonic_FILD, // Load Integer
484 Mnemonic_FLD, // Load Floating Point Value
485 Mnemonic_FLDLG2,
486 Mnemonic_FLDLN2,
487 Mnemonic_FLD1,
488
489 Mnemonic_FCLEX, // Clear Exceptions
490 Mnemonic_FCHS, // Change sign of ST0
491 Mnemonic_FNCLEX, // Clear Exceptions
492
493 //Mnemonic_FINCSTP, // Increment Stack-Top Pointer
494 Mnemonic_FIST, // Store Integer
495 Mnemonic_FISTP, // Store Integer, pop FPU stack
496 Mnemonic_FISTTP, // Store Integer with Truncation
497 Mnemonic_FPREM, // Partial Remainder
498 Mnemonic_FPREM1, // Partial Remainder
499 Mnemonic_FST, // Store Floating Point Value
500 Mnemonic_FSTP, // Store Floating Point Value and pop the FP stack
501 Mnemonic_FSQRT, //Computes the square root of the source value in the stack and pop the FP stack
502 Mnemonic_FABS, //Computes the absolute value of the source value in the stack and pop the FP stack
503 Mnemonic_FSIN, //Computes the sine of the source value in the stack and pop the FP stack
504 Mnemonic_FCOS, //Computes the cosine of the source value in the stack and pop the FP stack
505 Mnemonic_FPTAN, //Computes the tangent of the source value in the stack and pop the FP stack
506 Mnemonic_FYL2X,
507 Mnemonic_FYL2XP1,
508 Mnemonic_F2XM1,
509 Mnemonic_FPATAN,
510 Mnemonic_FXCH,
511 Mnemonic_FSCALE,
512
513 Mnemonic_XCHG,
514 Mnemonic_DIV, // Unsigned Divide
515 Mnemonic_IDIV, // Signed Divide
516 Mnemonic_MUL, // Unsigned Multiply
517 Mnemonic_IMUL, // Signed Multiply
518 Mnemonic_INC, // Increment by 1
519 Mnemonic_INT3, // Call break point
520 Mnemonic_Jcc, // Jump if Condition Is Met
521 CCM(J,O),
522 CCM(J,NO),
523 CCM(J,B), CCM(J,NAE), CCM(J,C),
524 CCM(J,NB), CCM(J,AE), CCM(J,NC),
525 CCM(J,Z), CCM(J,E),
526 CCM(J,NZ), CCM(J,NE),
527 CCM(J,BE), CCM(J,NA),
528 CCM(J,NBE), CCM(J,A),
529 CCM(J,S),
530 CCM(J,NS),
531 CCM(J,P), CCM(J,PE),
532 CCM(J,NP), CCM(J,PO),
533 CCM(J,L), CCM(J,NGE),
534 CCM(J,NL), CCM(J,GE),
535 CCM(J,LE), CCM(J,NG),
536 CCM(J,NLE), CCM(J,G),
537 Mnemonic_JMP, // Jump
538 Mnemonic_LEA, // Load Effective Address
539 Mnemonic_LEAVE, // High Level Procedure Exit
540 Mnemonic_LOOP, // Loop according to ECX counter
541 Mnemonic_LOOPE, // Loop according to ECX counter
542 Mnemonic_LOOPNE, Mnemonic_LOOPNZ = Mnemonic_LOOPNE, // Loop according to ECX
543 Mnemonic_LAHF, // Load Flags into AH
544 Mnemonic_MOV, // Move
545 Mnemonic_MOVD, // Move Double word
546 Mnemonic_MOVQ, // Move Quadword
547 /*Mnemonic_MOVS, // Move Data from String to String*/
548 // MOVS is a special case: see encoding table for more details,
549 Mnemonic_MOVS8, Mnemonic_MOVS16, Mnemonic_MOVS32, Mnemonic_MOVS64,
550 //
551 Mnemonic_MOVAPD, // Move Scalar Double-Precision Floating-Point Value
552 Mnemonic_MOVSD, // Move Scalar Double-Precision Floating-Point Value
553 Mnemonic_MOVSS, // Move Scalar Single-Precision Floating-Point Values
554 Mnemonic_MOVSX, // Move with Sign-Extension
555 Mnemonic_MOVZX, // Move with Zero-Extend
556 //Mnemonic_MUL, // Unsigned Multiply
557 Mnemonic_MULSD, // Multiply Scalar Double-Precision Floating-Point Values
558 Mnemonic_MULSS, // Multiply Scalar Single-Precision Floating-Point Values
559 Mnemonic_NEG, // Two's Complement Negation
560 Mnemonic_NOP, // No Operation
561 Mnemonic_NOT, // One's Complement Negation
562 Mnemonic_OR, // Logical Inclusive OR
563 Mnemonic_PREFETCH, // prefetch
564
565 #ifdef _HAVE_MMX_
566 Mnemonic_PADDQ, // Add Packed Quadword Integers
567 Mnemonic_PAND, // Logical AND
568 Mnemonic_POR, // Bitwise Logical OR
569 Mnemonic_PSUBQ, // Subtract Packed Quadword Integers
570 #endif
571
572 Mnemonic_PXOR, // Logical Exclusive OR
573 Mnemonic_POP, // Pop a Value from the Stack
574 Mnemonic_POPFD, // Pop a Value of EFLAGS register from the Stack
575 Mnemonic_PUSH, // Push Word or Doubleword Onto the Stack
576 Mnemonic_PUSHFD, // Push EFLAGS Doubleword Onto the Stack
577 Mnemonic_RET, // Return from Procedure
578
579 Mnemonic_SETcc, // Set Byte on Condition
580 CCM(SET,O),
581 CCM(SET,NO),
582 CCM(SET,B), CCM(SET,NAE), CCM(SET,C),
583 CCM(SET,NB), CCM(SET,AE), CCM(SET,NC),
584 CCM(SET,Z), CCM(SET,E),
585 CCM(SET,NZ), CCM(SET,NE),
586 CCM(SET,BE), CCM(SET,NA),
587 CCM(SET,NBE), CCM(SET,A),
588 CCM(SET,S),
589 CCM(SET,NS),
590 CCM(SET,P), CCM(SET,PE),
591 CCM(SET,NP), CCM(SET,PO),
592 CCM(SET,L), CCM(SET,NGE),
593 CCM(SET,NL), CCM(SET,GE),
594 CCM(SET,LE), CCM(SET,NG),
595 CCM(SET,NLE), CCM(SET,G),
596
597 Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left
598 Mnemonic_SAR, // Shift right
599 Mnemonic_ROR, // Rotate right
600 Mnemonic_RCR, // Rotate right through CARRY flag
601 Mnemonic_ROL, // Rotate left
602 Mnemonic_RCL, // Rotate left through CARRY flag
603 Mnemonic_SHR, // Unsigned shift right
604 Mnemonic_SHRD, // Double Precision Shift Right
605 Mnemonic_SHLD, // Double Precision Shift Left
606
607 Mnemonic_SBB, // Integer Subtraction with Borrow
608 Mnemonic_SUB, // Subtract
609 Mnemonic_SUBSD, // Subtract Scalar Double-Precision Floating-Point Values
610 Mnemonic_SUBSS, // Subtract Scalar Single-Precision Floating-Point Values
611
612 Mnemonic_TEST, // Logical Compare
613
614 Mnemonic_UCOMISD, // Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
615 Mnemonic_UCOMISS, // Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
616
617 Mnemonic_XOR, // Logical Exclusive OR
618 //
619 // packed things,
620 //
621 Mnemonic_XORPD, // Bitwise Logical XOR for Double-Precision Floating-Point Values
622 Mnemonic_XORPS, // Bitwise Logical XOR for Single-Precision Floating-Point Values
623
624 Mnemonic_CVTDQ2PD, // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
625 Mnemonic_CVTTPD2DQ, // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
626
627 Mnemonic_CVTDQ2PS, // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
628 Mnemonic_CVTTPS2DQ, // Convert with Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
629 //
630 // String operations
631 //
632 Mnemonic_STD, // Set direction flag
633 Mnemonic_CLD, // Clear direction flag
634 Mnemonic_SCAS, // Scan string
635 Mnemonic_STOS, // Store string
636
637 //
638 Mnemonic_WAIT, // Check pending pending unmasked floating-point exception
639 //
640 Mnemonic_Count
641 };
642
643 #undef CCM
644 #endif
645
646 /**
647 * @brief Instruction prefixes, according to arch manual.
648 */
649 typedef enum InstPrefix {
650 InstPrefix_Null = 0,
651 // Group 1
652 InstPrefix_LOCK = 0xF0,
653 InstPrefix_REPNE = 0xF2,
654 InstPrefix_REPNZ = InstPrefix_REPNE,
655 InstPrefix_REP = 0xF3, InstPrefix_REPZ = InstPrefix_REP,
656 // Group 2
657 InstPrefix_CS = 0x2E,
658 InstPrefix_SS = 0x36,
659 InstPrefix_DS = 0x3E,
660 InstPrefix_ES = 0x26,
661 InstPrefix_FS = 0x64,
662 InstPrefix_GS = 0x65,
663 //
664 InstPrefix_HintTaken = 0x3E,
665 InstPrefix_HintNotTaken = 0x2E,
666 // Group 3
667 InstPrefix_OpndSize = 0x66,
668 // Group 4
669 InstPrefix_AddrSize = 0x67
670 } InstPrefix;
671
getSizeBytes(OpndSize sz)672 inline unsigned getSizeBytes(OpndSize sz)
673 {
674 if (sz==OpndSize_64) { return 8; }
675 if (sz==OpndSize_32) { return 4; }
676 if (sz==OpndSize_16) { return 2; }
677 if (sz==OpndSize_8) { return 1; }
678 assert(false);
679 return 0;
680 }
681
isRegKind(OpndKind kind)682 inline bool isRegKind(OpndKind kind)
683 {
684 return OpndKind_GPReg<= kind && kind<=OpndKind_MaxRegKind;
685 }
686
687 /**
688 * @brief Returns #RegName for a given name.
689 *
690 * Name is case-insensitive.
691 * @param regname - string name of a register
692 * @return #RegName for the given name, or #RegName_Null if name is invalid
693 */
694 RegName getRegName(const char * regname);
695 /**
696 * Constructs RegName from the given OpndKind, size and index.
697 */
getRegName(OpndKind k,OpndSize s,int idx)698 inline RegName getRegName(OpndKind k, OpndSize s, int idx)
699 {
700 return (RegName)REGNAME(k,s,idx);
701 }
702 /**
703 * Extracts a bit mask with a bit set at the position of the register's index.
704 */
getRegMask(RegName reg)705 inline unsigned getRegMask(RegName reg)
706 {
707 return 1<<(reg&0xff);
708 }
709 /**
710 * @brief Extracts #RegKind from the #RegName.
711 */
getRegKind(RegName reg)712 inline OpndKind getRegKind(RegName reg)
713 {
714 return (OpndKind)(reg>>24);
715 }
716 /**
717 * @brief Extracts #OpndSize from #RegName.
718 */
getRegSize(RegName reg)719 inline OpndSize getRegSize(RegName reg)
720 {
721 return (OpndSize)((reg>>16)&0xFF);
722 }
723 /**
724 * Extracts an index from the given RegName.
725 */
getRegIndex(RegName reg)726 inline unsigned char getRegIndex(RegName reg)
727 {
728 return (unsigned char)(reg&0xFF);
729 }
730 /**
731 * Returns a string name of the given RegName. The name returned is in upper-case.
732 * Returns NULL if invalid RegName specified.
733 */
734 const char * getRegNameString(RegName reg);
735 /**
736 * Returns string name of a given OpndSize.
737 * Returns NULL if invalid OpndSize passed.
738 */
739 const char * getOpndSizeString(OpndSize size);
740 /**
741 * Returns OpndSize passed by its string representation (case insensitive).
742 * Returns OpndSize_Null if invalid string specified.
743 * The 'sizeString' can not be NULL.
744 */
745 OpndSize getOpndSize(const char * sizeString);
746 /**
747 * Returns string name of a given OpndKind.
748 * Returns NULL if the passed kind is invalid.
749 */
750 const char * getOpndKindString(OpndKind kind);
751 /**
752 * Returns OpndKind found by its string representation (case insensitive).
753 * Returns OpndKind_Null if the name is invalid.
754 * The 'kindString' can not be NULL.
755 */
756 OpndKind getOpndKind(const char * kindString);
757 /**
758 *
759 */
760 const char * getConditionString(ConditionMnemonic cm);
761
762 /**
763 * Constructs an RegName with the same index and kind, but with a different size from
764 * the given RegName (i.e. getRegAlias(EAX, OpndSize_16) => AX; getRegAlias(BL, OpndSize_32) => EBX).
765 * The constructed RegName is not checked in any way and thus may be invalid.
766 * Note, that the aliasing does not work for at least AH,BH,CH,DH, ESI, EDI, ESP and EBP regs.
767 */
getAliasReg(RegName reg,OpndSize sz)768 inline RegName getAliasReg(RegName reg, OpndSize sz)
769 {
770 return (RegName)REGNAME(getRegKind(reg), sz, getRegIndex(reg));
771 }
772
773 /**
774 * brief Tests two RegName-s of the same kind for equality.
775 *
776 * @note Does work for 8 bit general purpose registers (AH, AL, BH, BL, etc).
777 */
equals(RegName r0,RegName r1)778 inline bool equals(RegName r0, RegName r1)
779 {
780 return getRegKind(r0) == getRegKind(r1) &&
781 getRegIndex(r0) == getRegIndex(r1);
782 }
783
784 ENCODER_NAMESPACE_END
785
786 #endif // ifndef _ENCODER_DEFS_H_
787