• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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