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