Home | History | Annotate | Download | only in libenc
      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