enc_defs.h revision 0c2dc522d0e120f346cf0a40c8cf0c93346131c2
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
63ENCODER_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 */
84typedef 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 */
127typedef 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.
140typedef 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
156typedef 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 */
368enum 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//=========================================================================================================
394enum Mnemonic {
395
396Mnemonic_NULL=0, Mnemonic_Null=Mnemonic_NULL,
397Mnemonic_ADC,                           // Add with Carry
398Mnemonic_ADD,                           // Add
399Mnemonic_ADDSD,                         // Add Scalar Double-Precision Floating-Point Values
400Mnemonic_ADDSS,                         // Add Scalar Single-Precision Floating-Point Values
401Mnemonic_AND,                           // Logical AND
402
403Mnemonic_BSF,                           // Bit scan forward
404Mnemonic_BSR,                           // Bit scan reverse
405
406Mnemonic_CALL,                          // Call Procedure
407Mnemonic_CMC,                           // Complement Carry Flag
408Mnemonic_CWD, Mnemonic_CDQ=Mnemonic_CWD,// Convert Word to Doubleword/Convert Doubleword to Qua T dword
409Mnemonic_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
428Mnemonic_CMP,                           // Compare Two Operands
429Mnemonic_CMPXCHG,                       // Compare and exchange
430Mnemonic_CMPXCHG8B,                     // Compare and Exchange 8 Bytes
431Mnemonic_CMPSB,                         // Compare Two Bytes at DS:ESI and ES:EDI
432Mnemonic_CMPSW,                         // Compare Two Words at DS:ESI and ES:EDI
433Mnemonic_CMPSD,                         // Compare Two Doublewords at DS:ESI and ES:EDI
434//
435// double -> float
436Mnemonic_CVTSD2SS,                      // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
437// double -> I_32
438Mnemonic_CVTSD2SI,                      // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
439// double [truncated] -> I_32
440Mnemonic_CVTTSD2SI,                     // Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer
441//
442// float -> double
443Mnemonic_CVTSS2SD,                      // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
444// float -> I_32
445Mnemonic_CVTSS2SI,                      // Convert Scalar Single-Precision Floating-Point Value to Doubleword Integer
446// float [truncated] -> I_32
447Mnemonic_CVTTSS2SI,                     // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
448//
449// I_32 -> double
450Mnemonic_CVTSI2SD,                      // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
451// I_32 -> float
452Mnemonic_CVTSI2SS,                      // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
453
454Mnemonic_COMISD,                        // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
455Mnemonic_COMISS,                        // Compare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
456Mnemonic_DEC,                           // Decrement by 1
457//Mnemonic_DIV,                         // Unsigned Divide
458Mnemonic_DIVSD,                         // Divide Scalar Double-Precision Floating-Point Values
459Mnemonic_DIVSS,                         // Divide Scalar Single-Precision Floating-Point Values
460
461#ifdef _HAVE_MMX_
462Mnemonic_EMMS,                          // Empty MMX Technology State
463#endif
464
465Mnemonic_ENTER,                         // ENTER-Make Stack Frame for Procedure Parameters
466Mnemonic_FLDCW,                         // Load FPU control word
467Mnemonic_FADDP,
468Mnemonic_FLDZ,
469Mnemonic_FADD,
470Mnemonic_FSUBP,
471Mnemonic_FSUB,
472Mnemonic_FISUB,
473Mnemonic_FMUL,
474Mnemonic_FMULP,
475Mnemonic_FDIVP,
476Mnemonic_FDIV,
477Mnemonic_FUCOMPP,
478Mnemonic_FRNDINT,
479Mnemonic_FNSTCW,                        // Store FPU control word
480Mnemonic_FSTSW,                         // Store FPU status word
481Mnemonic_FNSTSW,                         // Store FPU status word
482//Mnemonic_FDECSTP,                     // Decrement Stack-Top Pointer
483Mnemonic_FILD,                          // Load Integer
484Mnemonic_FLD,                           // Load Floating Point Value
485Mnemonic_FLDLG2,
486Mnemonic_FLDLN2,
487Mnemonic_FLD1,
488
489Mnemonic_FCLEX,                         // Clear Exceptions
490Mnemonic_FCHS,                          // Change sign of ST0
491Mnemonic_FNCLEX,                        // Clear Exceptions
492
493//Mnemonic_FINCSTP,                     // Increment Stack-Top Pointer
494Mnemonic_FIST,                          // Store Integer
495Mnemonic_FISTP,                         // Store Integer, pop FPU stack
496Mnemonic_FISTTP,                        // Store Integer with Truncation
497Mnemonic_FPREM,                         // Partial Remainder
498Mnemonic_FPREM1,                        // Partial Remainder
499Mnemonic_FST,                           // Store Floating Point Value
500Mnemonic_FSTP,                          // Store Floating Point Value and pop the FP stack
501Mnemonic_FSQRT,                         //Computes the square root of the source value in the stack and pop the FP stack
502Mnemonic_FABS,                          //Computes the absolute value of the source value in the stack and pop the FP stack
503Mnemonic_FSIN,                          //Computes the sine of the source value in the stack and pop the FP stack
504Mnemonic_FCOS,                          //Computes the cosine of the source value in the stack and pop the FP stack
505Mnemonic_FPTAN,                         //Computes the tangent of the source value in the stack and pop the FP stack
506Mnemonic_FYL2X,
507Mnemonic_FYL2XP1,
508Mnemonic_F2XM1,
509Mnemonic_FPATAN,
510Mnemonic_FXCH,
511Mnemonic_FSCALE,
512
513Mnemonic_XCHG,
514Mnemonic_DIV,                           // Unsigned Divide
515Mnemonic_IDIV,                          // Signed Divide
516Mnemonic_MUL,                           // Unsigned Multiply
517Mnemonic_IMUL,                          // Signed Multiply
518Mnemonic_INC,                           // Increment by 1
519Mnemonic_INT3,                          // Call break point
520Mnemonic_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),
537Mnemonic_JMP,                           // Jump
538Mnemonic_LEA,                           // Load Effective Address
539Mnemonic_LEAVE,                         // High Level Procedure Exit
540Mnemonic_LOOP,                          // Loop according to ECX counter
541Mnemonic_LOOPE,                          // Loop according to ECX counter
542Mnemonic_LOOPNE, Mnemonic_LOOPNZ = Mnemonic_LOOPNE, // Loop according to ECX
543Mnemonic_LAHF,                          // Load Flags into AH
544Mnemonic_MOV,                           // Move
545Mnemonic_MOVD,                          // Move Double word
546Mnemonic_MOVQ,                          // Move Quadword
547/*Mnemonic_MOVS,                        // Move Data from String to String*/
548// MOVS is a special case: see encoding table for more details,
549Mnemonic_MOVS8, Mnemonic_MOVS16, Mnemonic_MOVS32, Mnemonic_MOVS64,
550//
551Mnemonic_MOVAPD,                         // Move Scalar Double-Precision Floating-Point Value
552Mnemonic_MOVSD,                         // Move Scalar Double-Precision Floating-Point Value
553Mnemonic_MOVSS,                         // Move Scalar Single-Precision Floating-Point Values
554Mnemonic_MOVSX,                         // Move with Sign-Extension
555Mnemonic_MOVZX,                         // Move with Zero-Extend
556//Mnemonic_MUL,                         // Unsigned Multiply
557Mnemonic_MULSD,                         // Multiply Scalar Double-Precision Floating-Point Values
558Mnemonic_MULSS,                         // Multiply Scalar Single-Precision Floating-Point Values
559Mnemonic_NEG,                           // Two's Complement Negation
560Mnemonic_NOP,                           // No Operation
561Mnemonic_NOT,                           // One's Complement Negation
562Mnemonic_OR,                            // Logical Inclusive OR
563Mnemonic_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
572Mnemonic_PXOR,                          // Logical Exclusive OR
573Mnemonic_POP,                           // Pop a Value from the Stack
574Mnemonic_POPFD,                         // Pop a Value of EFLAGS register from the Stack
575Mnemonic_PUSH,                          // Push Word or Doubleword Onto the Stack
576Mnemonic_PUSHFD,                        // Push EFLAGS Doubleword Onto the Stack
577Mnemonic_RET,                           // Return from Procedure
578
579Mnemonic_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
597Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left
598Mnemonic_SAR,                           // Shift right
599Mnemonic_ROR,                           // Rotate right
600Mnemonic_RCR,                           // Rotate right through CARRY flag
601Mnemonic_ROL,                           // Rotate left
602Mnemonic_RCL,                           // Rotate left through CARRY flag
603Mnemonic_SHR,                           // Unsigned shift right
604Mnemonic_SHRD,                          // Double Precision Shift Right
605Mnemonic_SHLD,                          // Double Precision Shift Left
606
607Mnemonic_SBB,                           // Integer Subtraction with Borrow
608Mnemonic_SUB,                           // Subtract
609Mnemonic_SUBSD,                         // Subtract Scalar Double-Precision Floating-Point Values
610Mnemonic_SUBSS,                         // Subtract Scalar Single-Precision Floating-Point Values
611
612Mnemonic_TEST,                          // Logical Compare
613
614Mnemonic_UCOMISD,                       // Unordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
615Mnemonic_UCOMISS,                       // Unordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
616
617Mnemonic_XOR,                           // Logical Exclusive OR
618//
619// packed things,
620//
621Mnemonic_XORPD,                         // Bitwise Logical XOR for Double-Precision Floating-Point Values
622Mnemonic_XORPS,                         // Bitwise Logical XOR for Single-Precision Floating-Point Values
623
624Mnemonic_CVTDQ2PD,                      // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
625Mnemonic_CVTTPD2DQ,                     // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
626
627Mnemonic_CVTDQ2PS,                      // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
628Mnemonic_CVTTPS2DQ,                     // Convert with Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
629//
630// String operations
631//
632Mnemonic_STD,                           // Set direction flag
633Mnemonic_CLD,                           // Clear direction flag
634Mnemonic_SCAS,                          // Scan string
635Mnemonic_STOS,                          // Store string
636
637//
638Mnemonic_WAIT,                          // Check pending pending unmasked floating-point exception
639//
640Mnemonic_Count
641};
642
643#undef CCM
644#endif
645
646/**
647 * @brief Instruction prefixes, according to arch manual.
648 */
649typedef 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
672inline 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
682inline 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 */
694RegName         getRegName(const char * regname);
695/**
696 * Constructs RegName from the given OpndKind, size and index.
697 */
698inline 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 */
705inline unsigned getRegMask(RegName reg)
706{
707    return 1<<(reg&0xff);
708}
709/**
710 * @brief Extracts #RegKind from the #RegName.
711 */
712inline OpndKind getRegKind(RegName reg)
713{
714    return (OpndKind)(reg>>24);
715}
716/**
717 * @brief Extracts #OpndSize from #RegName.
718 */
719inline OpndSize getRegSize(RegName reg)
720{
721    return (OpndSize)((reg>>16)&0xFF);
722}
723/**
724 * Extracts an index from the given RegName.
725 */
726inline 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 */
734const char *    getRegNameString(RegName reg);
735/**
736 * Returns string name of a given OpndSize.
737 * Returns NULL if invalid OpndSize passed.
738 */
739const 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 */
745OpndSize        getOpndSize(const char * sizeString);
746/**
747 * Returns string name of a given OpndKind.
748 * Returns NULL if the passed kind is invalid.
749 */
750const 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 */
756OpndKind        getOpndKind(const char * kindString);
757/**
758 *
759 */
760const 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 */
768inline 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 */
778inline bool equals(RegName r0, RegName r1)
779{
780    return getRegKind(r0) == getRegKind(r1) &&
781           getRegIndex(r0) == getRegIndex(r1);
782}
783
784ENCODER_NAMESPACE_END
785
786#endif  // ifndef _ENCODER_DEFS_H_
787