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 _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 
    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 
    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  */
    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  */
    705 inline unsigned getRegMask(RegName reg)
    706 {
    707     return 1<<(reg&0xff);
    708 }
    709 /**
    710  * @brief Extracts #RegKind from the #RegName.
    711  */
    712 inline OpndKind getRegKind(RegName reg)
    713 {
    714     return (OpndKind)(reg>>24);
    715 }
    716 /**
    717  * @brief Extracts #OpndSize from #RegName.
    718  */
    719 inline OpndSize getRegSize(RegName reg)
    720 {
    721     return (OpndSize)((reg>>16)&0xFF);
    722 }
    723 /**
    724  * Extracts an index from the given RegName.
    725  */
    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  */
    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  */
    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