• 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 __ENC_PRVT_H_INCLUDED__
21 #define __ENC_PRVT_H_INCLUDED__
22 
23 #include "enc_base.h"
24 
25 ENCODER_NAMESPACE_START
26 /*
27  * @file
28  * @brief Contains some definitions/constants and other stuff used by the
29  *        Encoder internally.
30  */
31 
32 enum OpcodeByteKind {
33     //OpcodeByteKind_Opcode = 0x0000,
34     OpcodeByteKind_ZeroOpcodeByte           = 0x0100,
35     //
36     // The names _SlashR,  _SlahsNum, _ib, _iw, etc
37     // represent the appropriate abbreviations used
38     // in the mnemonic descriptions in the Intel's arch manual.
39     //
40     OpcodeByteKind_SlashR                   = 0x0200,
41     OpcodeByteKind_SlashNum                 = 0x0300,
42     OpcodeByteKind_ib                       = 0x0400,
43     OpcodeByteKind_iw                       = 0x0500,
44     OpcodeByteKind_id                       = 0x0600,
45 #ifdef _EM64T_
46     OpcodeByteKind_io                       = 0x0700,
47 #endif
48     OpcodeByteKind_cb                       = 0x0800,
49     OpcodeByteKind_cw                       = 0x0900,
50     OpcodeByteKind_cd                       = 0x0A00,
51     //OpcodeByteKind_cp                     = 0x0B00,
52     //OpcodeByteKind_co                     = 0x0C00,
53     //OpcodeByteKind_ct                     = 0x0D00,
54 
55     OpcodeByteKind_rb                       = 0x0E00,
56     OpcodeByteKind_rw                       = 0x0F00,
57     OpcodeByteKind_rd                       = 0x1000,
58 #ifdef _EM64T_
59     OpcodeByteKind_ro                       = 0x1100,
60     //OpcodeByteKind_REX                    = 0x1200,
61     OpcodeByteKind_REX_W                    = 0x1300,
62 #endif
63     OpcodeByteKind_plus_i                   = 0x1400,
64     /**
65         * a special marker, means 'no opcode on the given position'
66         * used in opcodes array, to specify the empty slot, say
67         * to fill an em64t-specific opcode on ia32.
68         * last 'e' made lowercase to avoid a mess with 'F' in
69         * OpcodeByteKind_LAST .
70         */
71     OpcodeByteKind_EMPTY                    = 0xFFFE,
72     /**
73         * a special marker, means 'no more opcodes in the array'
74         * used in in opcodes array to show that there are no more
75         * opcodes in the array for a given mnemonic.
76         */
77     OpcodeByteKind_LAST                     = 0xFFFF,
78     /**
79         * a mask to extract the OpcodeByteKind
80         */
81     OpcodeByteKind_KindMask                 = 0xFF00,
82     /**
83         * a mask to extract the opcode byte when presented
84         */
85     OpcodeByteKind_OpcodeMask               = 0x00FF
86 };
87 
88 #ifdef USE_ENCODER_DEFINES
89 
90 #define N           {0, 0, 0, 0 }
91 #define U           {1, 0, 1, OpndRole_Use }
92 #define D           {1, 1, 0, OpndRole_Def }
93 #define DU          {1, 1, 1, OpndRole_Def|OpndRole_Use }
94 
95 #define U_U         {2, 0, 2, OpndRole_Use<<2 | OpndRole_Use }
96 #define D_U         {2, 1, 1, OpndRole_Def<<2 | OpndRole_Use }
97 #define D_DU        {2, 2, 1, OpndRole_Def<<2 | (OpndRole_Def|OpndRole_Use) }
98 #define DU_U        {2, 1, 2, ((OpndRole_Def|OpndRole_Use)<<2 | OpndRole_Use) }
99 #define DU_DU       {2, 2, 2, ((OpndRole_Def|OpndRole_Use)<<2 | (OpndRole_Def|OpndRole_Use)) }
100 
101 #define DU_DU_DU    {3, 3, 3, ((OpndRole_Def|OpndRole_Use)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | (OpndRole_Def|OpndRole_Use) }
102 #define DU_DU_U     {3, 2, 3, (((OpndRole_Def|OpndRole_Use)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | OpndRole_Use) }
103 #define D_DU_U      {3, 2, 2, (((OpndRole_Def)<<4) | ((OpndRole_Def|OpndRole_Use)<<2) | OpndRole_Use) }
104 #define D_U_U       {3, 1, 2, (((OpndRole_Def)<<4) | ((OpndRole_Use)<<2) | OpndRole_Use) }
105 
106 // Special encoding of 0x00 opcode byte. Note: it's all O-s, not zeros.
107 #define OxOO        OpcodeByteKind_ZeroOpcodeByte
108 
109 #define Size16      InstPrefix_OpndSize
110 
111 #define _r          OpcodeByteKind_SlashR
112 
113 #define _0          OpcodeByteKind_SlashNum|0
114 #define _1          OpcodeByteKind_SlashNum|1
115 #define _2          OpcodeByteKind_SlashNum|2
116 #define _3          OpcodeByteKind_SlashNum|3
117 #define _4          OpcodeByteKind_SlashNum|4
118 #define _5          OpcodeByteKind_SlashNum|5
119 #define _6          OpcodeByteKind_SlashNum|6
120 #define _7          OpcodeByteKind_SlashNum|7
121 
122 // '+i' for floating-point instructions
123 #define _i          OpcodeByteKind_plus_i
124 
125 
126 #define ib          OpcodeByteKind_ib
127 #define iw          OpcodeByteKind_iw
128 #define id          OpcodeByteKind_id
129 
130 #define cb          OpcodeByteKind_cb
131 #define cw          OpcodeByteKind_cw
132 #define cd          OpcodeByteKind_cd
133 
134 #define rb          OpcodeByteKind_rb
135 #define rw          OpcodeByteKind_rw
136 #define rd          OpcodeByteKind_rd
137 
138 #define AL          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_AL}
139 #define AH          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_AH}
140 #define AX          {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_AX}
141 #define EAX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EAX}
142 #ifdef _EM64T_
143     #define RAX     {OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RAX }
144 #endif
145 
146 #define CL          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_CL}
147 #define ECX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ECX}
148 #ifdef _EM64T_
149     #define RCX         {OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RCX}
150 #endif
151 
152 #define DX          {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_DX}
153 #define EDX         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDX}
154 #ifdef _EM64T_
155     #define RDX     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RDX }
156 #endif
157 
158 #define ESI         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_ESI}
159 #ifdef _EM64T_
160     #define RSI     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RSI }
161 #endif
162 
163 #define EDI         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_EDI}
164 #ifdef _EM64T_
165     #define RDI     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_RDI }
166 #endif
167 
168 #define r8          {OpndKind_GPReg, OpndSize_8, OpndExt_Any, RegName_Null}
169 #define r16         {OpndKind_GPReg, OpndSize_16, OpndExt_Any, RegName_Null}
170 #define r32         {OpndKind_GPReg, OpndSize_32, OpndExt_Any, RegName_Null}
171 #ifdef _EM64T_
172     #define r64     { OpndKind_GPReg, OpndSize_64, OpndExt_Any, RegName_Null }
173 #endif
174 
175 #define r_m8        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Any, RegName_Null}
176 #define r_m16       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Any, RegName_Null}
177 #define r_m32       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, RegName_Null}
178 
179 #define r_m8s        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Signed, RegName_Null}
180 #define r_m16s       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Signed, RegName_Null}
181 #define r_m32s       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Signed, RegName_Null}
182 
183 #define r_m8u        {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_8, OpndExt_Zero, RegName_Null}
184 #define r_m16u       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_16, OpndExt_Zero, RegName_Null}
185 #define r_m32u       {(OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_32, OpndExt_Zero, RegName_Null}
186 
187 //'m' was only used in LEA mnemonic, but is replaced with
188 // set of exact sizes. See more comments for LEA instruction in TheTable.
189 //#define m           {OpndKind_Mem, OpndSize_Null, RegName_Null}
190 #define m8          {OpndKind_Mem, OpndSize_8, OpndExt_Any, RegName_Null}
191 #define m16         {OpndKind_Mem, OpndSize_16, OpndExt_Any, RegName_Null}
192 #define m32         {OpndKind_Mem, OpndSize_32, OpndExt_Any, RegName_Null}
193 #define m64         {OpndKind_Mem, OpndSize_64, OpndExt_Any, RegName_Null}
194 #ifdef _EM64T_
195     #define r_m64   { (OpndKind)(OpndKind_GPReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null }
196 #endif
197 
198 #define imm8        {OpndKind_Imm, OpndSize_8, OpndExt_Any, RegName_Null}
199 #define imm16       {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null}
200 #define imm32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
201 
202 #define imm8s        {OpndKind_Imm, OpndSize_8, OpndExt_Signed, RegName_Null}
203 #define imm16s       {OpndKind_Imm, OpndSize_16, OpndExt_Signed, RegName_Null}
204 #define imm32s       {OpndKind_Imm, OpndSize_32, OpndExt_Signed, RegName_Null}
205 
206 #define imm8u        {OpndKind_Imm, OpndSize_8, OpndExt_Zero, RegName_Null}
207 #define imm16u       {OpndKind_Imm, OpndSize_16, OpndExt_Zero, RegName_Null}
208 #define imm32u       {OpndKind_Imm, OpndSize_32, OpndExt_Zero, RegName_Null}
209 
210 #ifdef _EM64T_
211     #define imm64   {OpndKind_Imm, OpndSize_64, OpndExt_Any, RegName_Null }
212 #endif
213 
214 //FIXME: moff-s are in fact memory refs, but presented as immediate.
215 // Need to specify this in OpndDesc.
216 #define moff8        {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
217 #define moff16       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
218 #define moff32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
219 #ifdef _EM64T_
220     #define moff64       {OpndKind_Imm, OpndSize_64, OpndExt_Any, RegName_Null}
221 #endif
222 
223 
224 #define rel8        {OpndKind_Imm, OpndSize_8, OpndExt_Any, RegName_Null}
225 #define rel16       {OpndKind_Imm, OpndSize_16, OpndExt_Any, RegName_Null}
226 #define rel32       {OpndKind_Imm, OpndSize_32, OpndExt_Any, RegName_Null}
227 
228 #define mm64        {OpndKind_MMXReg, OpndSize_64, OpndExt_Any, RegName_Null}
229 #define mm_m64      {(OpndKind)(OpndKind_MMXReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null}
230 
231 #define xmm64       {OpndKind_XMMReg, OpndSize_64, OpndExt_Any, RegName_Null}
232 #define xmm_m64     {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_64, OpndExt_Any, RegName_Null}
233 
234 #define xmm32       {OpndKind_XMMReg, OpndSize_32, OpndExt_Any, RegName_Null}
235 #define xmm_m32     {(OpndKind)(OpndKind_XMMReg|OpndKind_Mem), OpndSize_32, OpndExt_Any, RegName_Null}
236 
237 #define FP0S        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_FP0S}
238 #define FP0D        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP0D}
239 #define FP1S        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_FP1S}
240 #define FP1D        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_FP1D}
241 #define fp32        {OpndKind_FPReg, OpndSize_32, OpndExt_Any, RegName_Null}
242 #define fp64        {OpndKind_FPReg, OpndSize_64, OpndExt_Any, RegName_Null}
243 
244 #ifdef _EM64T_
245     #define io      OpcodeByteKind_io
246     #define REX_W   OpcodeByteKind_REX_W
247 
248 #endif
249 
250 #endif // USE_ENCODER_DEFINES
251 
252 /**
253  * @brief Represents the REX part of instruction.
254  */
255 struct  Rex {
256     unsigned char b : 1;
257     unsigned char x : 1;
258     unsigned char r : 1;
259     unsigned char w : 1;
260     unsigned char dummy : 4;        // must be '0100'b
261     unsigned int  :24;
262 };
263 
264 /**
265  * @brief Describes SIB (scale,index,base) byte.
266  */
267 struct SIB {
268     unsigned char base:3;
269     unsigned char index:3;
270     unsigned char scale:2;
271     unsigned int  padding:24;
272 };
273 /**
274  * @brief Describes ModRM byte.
275  */
276 struct ModRM
277 {
278     unsigned char rm:3;
279     unsigned char reg:3;
280     unsigned char mod:2;
281     unsigned int  padding:24;
282 };
283 
284 
285 
286 /**
287 * exactly the same as EncoderBase::OpcodeDesc, but also holds info about
288 * platform on which the opcode is applicable.
289 */
290 struct OpcodeInfo {
291     enum platform {
292         /// an opcode is valid on all platforms
293         all,
294         // opcode is valid on IA-32 only
295         em64t,
296         // opcode is valid on Intel64 only
297         ia32,
298         // opcode is added for the sake of disassembling, should not be used in encoding
299         decoder,
300         // only appears in master table, replaced with 'decoder' in hashed version
301         decoder32,
302         // only appears in master table, replaced with 'decoder' in hashed version
303         decoder64,
304     };
305     platform                        platf;
306     unsigned                        opcode[4+1+1];
307     EncoderBase::OpndDesc           opnds[3];
308     EncoderBase::OpndRolesDesc      roles;
309 };
310 
311 /**
312  * @defgroup MF_ Mnemonic flags
313 */
314 
315     /**
316  * Operation has no special properties.
317     */
318 #define MF_NONE             (0x00000000)
319     /**
320  * Operation affects flags
321     */
322 #define MF_AFFECTS_FLAGS    (0x00000001)
323     /**
324  * Operation uses flags - conditional operations, ADC/SBB/ETC
325     */
326 #define MF_USES_FLAGS       (0x00000002)
327     /**
328  * Operation is conditional - MOVcc/SETcc/Jcc/ETC
329     */
330 #define MF_CONDITIONAL      (0x00000004)
331 /**
332  * Operation is symmetric - its args can be swapped (ADD/MUL/etc).
333  */
334 #define MF_SYMMETRIC        (0x00000008)
335 /**
336  * Operation is XOR-like - XOR, SUB - operations of 'arg,arg' is pure def,
337  * without use.
338  */
339 #define MF_SAME_ARG_NO_USE  (0x00000010)
340 
341 ///@} // ~MNF
342 
343 /**
344  * @see same structure as EncoderBase::MnemonicDesc, but carries
345  * MnemonicInfo::OpcodeInfo[] instead of OpcodeDesc[].
346  * Only used during prebuilding the encoding tables, thus it's hidden under
347  * the appropriate define.
348  */
349 struct MnemonicInfo {
350     /**
351     * The mnemonic itself
352     */
353     Mnemonic    mn;
354     /**
355      * Various characteristics of mnemonic.
356      * @see MF_
357      */
358     unsigned    flags;
359     /**
360      * Number of args/des/uses/roles for the operation. For the operations
361      * which may use different number of operands (i.e. IMUL/SHL) use the
362      * most common value, or leave '0' if you are sure this info is not
363      * required.
364      */
365     EncoderBase::OpndRolesDesc              roles;
366     /**
367      * Print name of the mnemonic
368      */
369     const char *                            name;
370     /**
371      * Array of opcodes.
372      * The terminating opcode description always have OpcodeByteKind_LAST
373      * at the opcodes[i].opcode[0].
374      * The size of '25' has nothing behind it, just counted the max
375      * number of opcodes currently used (MOV instruction).
376      */
377     OpcodeInfo                              opcodes[25];
378 };
379 
380 ENCODER_NAMESPACE_END
381 
382 #endif  // ~__ENC_PRVT_H_INCLUDED__
383