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 21 22 #include <assert.h> 23 #include <stdio.h> 24 #include <stdlib.h> //qsort 25 #include <string.h> 26 #include <memory.h> 27 #include <errno.h> 28 #include <stdlib.h> 29 30 31 // need to use EM64T-specifics - new registers, defines from enc_prvt, etc... 32 #if !defined(_EM64T_) 33 #define UNDEF_EM64T 34 #define _EM64T_ 35 #endif 36 37 #define USE_ENCODER_DEFINES 38 #include "enc_prvt.h" 39 #include "enc_defs.h" 40 41 #ifdef UNDEF_EM64T 42 #undef _EM64T_ 43 #endif 44 45 //Android x86 46 #if 0 //!defined(_HAVE_MMX_) 47 #define Mnemonic_PADDQ Mnemonic_Null 48 #define Mnemonic_PAND Mnemonic_Null 49 #define Mnemonic_POR Mnemonic_Null 50 #define Mnemonic_PSUBQ Mnemonic_Null 51 #endif 52 53 ENCODER_NAMESPACE_START 54 55 56 EncoderBase::MnemonicDesc EncoderBase::mnemonics[Mnemonic_Count]; 57 EncoderBase::OpcodeDesc EncoderBase::opcodes[Mnemonic_Count][MAX_OPCODES]; 58 unsigned char EncoderBase::opcodesHashMap[Mnemonic_Count][HASH_MAX]; 59 60 61 /** 62 * @file 63 * @brief 'Master' copy of encoding data. 64 */ 65 66 /* 67 This file contains a 'master copy' of encoding table - this is the info used 68 by both generator of native instructions (EncoderBase class) and by 69 disassembling routines. The first one uses an info how to encode the 70 instruction, and the second does an opposite - several separate tables are 71 built at runtime from this main table. 72 73 ============================================================================= 74 75 The table was designed for easy support and maintenance. Thus, it was made as 76 much close as possible to the Intel's IA32 Architecture Manual descriptions. 77 The info is based on the latest (at the moment of writing) revision which is 78 June 2005, order number 253666-016. 79 80 Normally, almost all of opcodes in the 'master' table represented exactly as 81 they are shown in the Intel's Architecture manual (well, with slashes 82 replaced with underscore). There are several exclusions especially marked. 83 84 Normally, to add an opcode/instruction, one only need to copy the whole 85 string from the manual, and simply replace '/' with '_'. 86 87 I.e., TheManual reads for DEC: 88 (1) FE /1 DEC r/m8 Valid Valid Decrement r/m8 by 1. 89 (2) REX + FE /1 DEC r/m8* Valid N.E. Decrement r/m8 by 1. 90 (3) REX.W + FF /1 DEC r/m64 Valid N.E. Decrement r/m64 by 1. 91 92 1. Note, that there is no need to explicitly specify REX-based opcodes for 93 instruction to handle additional registers on EM64T: 94 95 (1) FE /1 DEC r/m8 Valid Valid Decrement r/m8 by 1. 96 (3) REX.W + FF /1 DEC r/m64 Valid N.E. Decrement r/m64 by 1. 97 98 2. Copy the string, strip off the text comments, replace '/'=>'_'. Note, that 99 the second line is for EM64T only 100 101 (1) FE /1 DEC r/m8 102 (3) REX.W + FF /1 DEC r/m64 103 104 3. Fill out the mnemonic, opcode parameters parts 105 106 BEGIN_MNEMONIC(DEC, MF_AFFECTS_FLAGS, DU) 107 BEGIN_OPCODES() 108 {OpcodeInfo::all, {0xFE, _1}, {r_m8}, DU }, 109 {OpcodeInfo::em64t, {REX_W, 0xFF, _1}, {r_m64}, DU }, 110 111 DU here - one argument, it's used and defined 112 113 4. That's it, that simple ! 114 115 The operand roles (DU here) are used by Jitrino's optimizing engine to 116 perform data flow analysis. It also used to store/obtain number of operands. 117 118 Special cases are (see the table for details): 119 LEA 120 Some FPU operations (i.e. FSTP) 121 packed things (XORPD, XORPS, CVTDQ2PD, CVTTPD2DQ) 122 123 Also, the Jitrino's needs require to specify all operands - including 124 implicit ones (see IMUL). 125 126 The master table iself does not need to be ordered - it's get sorted before 127 processing. It's recommended (though it's not a law) to group similar 128 instructions together - i.e. FPU instructions, MMX, etc. 129 130 ============================================================================= 131 132 The encoding engine builds several tables basing on the 'master' one (here 133 'mnemonic' is a kind of synonim for 'instruction'): 134 135 - list of mnemonics which holds general info about instructions 136 (EncoderBase::mnemonics) 137 - an array of opcodes descriptions (EncodeBase::opcodes) 138 - a mapping between a hash value and an opcode description record for a given 139 mnemonic (EncoderBase::opcodesHashMap) 140 141 The EncoderBase::mnemonics holds general info about instructions. 142 The EncoderBase::opcodesHashMap is used for fast opcode selection basing on 143 a hash value. 144 The EncodeBase::opcodes is used for the encoding itself. 145 146 ============================================================================= 147 The hash value is calculated and used as follows: 148 149 JIT-ted code uses the following operand sizes: 8-, 16-, 32- and 64-bits and 150 size for an operand can be encoded in just 2 bits. 151 152 The following operand locations are available: one of registers - GP, FP, 153 MMX, XMM (not taking segment registers), a memory and an immediate, which 154 gives us 6 variants and can be enumerated in 3 bits. 155 156 As a grand total, the the whole operand's info needed for opcode selection 157 can be packed in 5 bits. Taking into account the IMUL mnemonic with its 3 158 operands (including implicit ones), we're getting 15 bits per instruction and 159 the complete table is about 32768 items per single instruction. 160 161 Seems too many, but luckily, the 15 bit limit will never be reached: the 162 worst case is IMUL with its 3 operands: 163 (IMUL r64, r/m64, imm32)/(IMUL r32, r/m32, imm32). 164 So, assigning lowest value to GP register, the max value of hash can be 165 reduced. 166 167 The hash values to use are: 168 sizes: 169 8 -> 11 170 16 -> 10 171 32 -> 01 172 64 -> 00 173 locations: 174 gp reg -> 000 175 memory -> 001 176 fp reg -> 010 177 mmx reg -> 011 178 xmm reg -> 100 179 immediate -> 101 180 and the grand total for the worst case would be 181 [ GP 32] [GP 32] [Imm 32] 182 [000-01] [000-01] [101 01] = 1077 183 184 However, the implicit operands adds additional value, and the worstest case 185 is 'SHLD r_m32, r32, CL=r8'. This gives us the maximum number of: 186 187 [mem 32] [GP 32] [GP 8b] 188 [001-01] [000-01] [000-11] = 5155. 189 190 The max number is pretty big and the hash functions is quite rare, thus it 191 is not resonable to use a direct addressing i.e. 192 OpcodeDesc[mnemonic][hash_code] - there would be a huge waste of space. 193 194 Instead, we use a kind of mapping: the opcodes info is stored in packed 195 (here: non rare) array. The max number of opcodes will not exceed 255 for 196 each instruction. And we have an index array in which we store a mapping 197 between a hash code value and opcode position for each given instruction. 198 199 Sounds a bit sophisticated, but in real is simple, the opcode gets selected 200 in 2 simple steps: 201 202 1. Select [hash,mnemonic] => 'n'. 203 204 The array is pretty rare - many cells contain 0xFF which 205 means 'invalid hash - no opcode with given characteristics' 206 207 char EnbcoderBase::opcodesHashMap[Mnemonic_Count][HASH_MAX] = 208 209 +----+----+----+----+----+----+ 210 | 00 | 05 | FF | FF | 03 | 12 | ... 211 |---------+-------------------+ 212 | 12 | FF | FF | n | 04 | 25 | ... <- Mnemonic 213 |-----------------------------+ 214 | FF | 11 | FF | 10 | 13 | .. | ... 215 +-----------------------------+ 216 ... ^ 217 | 218 hash 219 220 2. Select [n,mnemonic] => 'opcode_desc11' 221 222 OpcodeDesc EncoderBase::opcodes[Mnemonic_Count][MAX_OPCODES] = 223 224 +---------------+---------------+---------------+---------------+ 225 | opcode_desc00 | opcode_desc01 | opcode_desc02 | last_opcode | ... 226 +---------------+---------------+---------------+---------------+ 227 | opcode_desc10 | opcode_desc11 | last_opcode | xxx | <- Mnemonic 228 +---------------+---------------+---------------+---------------+ 229 | opcode_desc20 | opcode_desc21 | opcode_desc22 | opcode_desc23 | ... 230 +---------------+---------------+---------------+---------------+ 231 ... 232 ^ 233 | 234 n 235 236 Now, use 'opcode_desc11'. 237 238 ============================================================================= 239 The array of opcodes descriptions (EncodeBase::opcodes) is specially prepared 240 to maximize performance - the EncoderBase::encode() is quite hot on client 241 applications for the Jitrino/Jitrino.JET. 242 The preparation is that opcode descriptions from the 'master' encoding table 243 are preprocessed and a special set of OpcodeDesc prepared: 244 First, the 'raw' opcode bytes are extracted. Here, 'raw' means the bytes that 245 do not depened on any operands values, do not require any analysis and can be 246 simply copied into the output buffer during encoding. Also, number of these 247 'raw' bytes is counted. The fields are OpcodeDesc::opcode and 248 OpcodeDesc::opcode_len. 249 250 Then the fisrt non-implicit operand found and its index is stored in 251 OpcodeDesc::first_opnd. 252 253 The bytes that require processing and analysis ('/r', '+i', etc) are 254 extracted and stored in OpcodeDesc::aux0 and OpcodeDesc::aux1 fields. 255 256 Here, a special trick is performed: 257 Some opcodes have register/memory operand, but this is not reflected in 258 opcode column - for example, (MOVQ xmm64, xmm_m64). In this case, a fake 259 '_r' added to OpcodeDesc::aux field. 260 Some other opcodes have immediate operands, but this is again not 261 reflected in opcode column - for example, CALL cd or PUSH imm32. 262 In this case, a fake '/cd' or fake '/id' added to appropriate 263 OpcodeDesc::aux field. 264 265 The OpcodeDesc::last is non-zero for the final OpcodeDesc record (which does 266 not have valid data itself). 267 */ 268 269 // TODO: To extend flexibility, replace bool fields in MnemonicDesc & 270 // MnemonicInfo with a set of flags packed into integer field. 271 272 unsigned short EncoderBase::getHash(const OpcodeInfo* odesc) 273 { 274 /* 275 NOTE: any changes in the hash computation must be stricty balanced with 276 EncoderBase::Operand::hash_it and EncoderBase::Operands() 277 */ 278 unsigned short hash = 0; 279 // The hash computation, uses fast way - table selection instead of if-s. 280 if (odesc->roles.count > 0) { 281 OpndKind kind = odesc->opnds[0].kind; 282 OpndSize size = odesc->opnds[0].size; 283 assert(kind<COUNTOF(kind_hash)); 284 assert(size<COUNTOF(size_hash)); 285 hash = get_kind_hash(kind) | get_size_hash(size); 286 } 287 288 if (odesc->roles.count > 1) { 289 OpndKind kind = odesc->opnds[1].kind; 290 OpndSize size = odesc->opnds[1].size; 291 assert(kind<COUNTOF(kind_hash)); 292 assert(size<COUNTOF(size_hash)); 293 hash = (hash<<HASH_BITS_PER_OPERAND) | 294 (get_kind_hash(kind) | get_size_hash(size)); 295 } 296 297 if (odesc->roles.count > 2) { 298 OpndKind kind = odesc->opnds[2].kind; 299 OpndSize size = odesc->opnds[2].size; 300 assert(kind<COUNTOF(kind_hash)); 301 assert(size<COUNTOF(size_hash)); 302 hash = (hash<<HASH_BITS_PER_OPERAND) | 303 (get_kind_hash(kind) | get_size_hash(size)); 304 } 305 assert(hash <= HASH_MAX); 306 return hash; 307 } 308 309 310 #define BEGIN_MNEMONIC(mn, flags, roles) \ 311 { Mnemonic_##mn, flags, roles, #mn, 312 #define END_MNEMONIC() }, 313 #define BEGIN_OPCODES() { 314 #define END_OPCODES() { OpcodeInfo::all, {OpcodeByteKind_LAST} }} 315 316 //#define BEGIN_MNEMONIC(mn, affflags, ulags, cond, symm, roles) \ 317 // { Mnemonic_##mn, affflags, ulags, cond, symm, roles, #mn, 318 319 320 static MnemonicInfo masterEncodingTable[] = { 321 // 322 // Null 323 // 324 BEGIN_MNEMONIC(Null, MF_NONE, N) 325 BEGIN_OPCODES() 326 END_OPCODES() 327 END_MNEMONIC() 328 329 BEGIN_MNEMONIC(LAHF, MF_USES_FLAGS, D) 330 BEGIN_OPCODES() 331 // TheManual says it's not always supported in em64t mode, thus excluding it 332 {OpcodeInfo::ia32, {0x9F}, {EAX}, D }, 333 END_OPCODES() 334 END_MNEMONIC() 335 // 336 // ALU mnemonics - add, adc, or, xor, and, cmp, sub, sbb 337 // as they differ only in the opcode extention (/digit) number and 338 // in which number the opcode start from, the opcode definitions 339 // for those instructions are packed together 340 // 341 // The 'opcode_starts_from' and 'opcode_ext' in DEFINE_ALU_OPCODES() 342 // are enough to define OpcodeInfo::all opcodes and the 'first_opcode' 343 // parameter is only due to ADD instruction, which requires an zero opcode 344 // byte which, in turn, is coded especially in the current coding scheme. 345 // 346 347 #define DEFINE_ALU_OPCODES( opc_ext, opcode_starts_from, first_opcode, def_use ) \ 348 \ 349 {OpcodeInfo::decoder, {opcode_starts_from + 4, ib}, {AL, imm8}, DU_U },\ 350 {OpcodeInfo::decoder, {Size16, opcode_starts_from + 5, iw}, {AX, imm16}, DU_U },\ 351 {OpcodeInfo::decoder, {opcode_starts_from + 5, id}, {EAX, imm32}, DU_U },\ 352 {OpcodeInfo::decoder64, {REX_W, opcode_starts_from+5, id}, {RAX, imm32s},DU_U },\ 353 \ 354 {OpcodeInfo::all, {0x80, opc_ext, ib}, {r_m8, imm8}, def_use },\ 355 {OpcodeInfo::all, {Size16, 0x81, opc_ext, iw}, {r_m16, imm16}, def_use },\ 356 {OpcodeInfo::all, {0x81, opc_ext, id}, {r_m32, imm32}, def_use },\ 357 {OpcodeInfo::em64t, {REX_W, 0x81, opc_ext, id}, {r_m64, imm32s}, def_use },\ 358 \ 359 {OpcodeInfo::all, {Size16, 0x83, opc_ext, ib}, {r_m16, imm8s}, def_use },\ 360 {OpcodeInfo::all, {0x83, opc_ext, ib}, {r_m32, imm8s}, def_use },\ 361 {OpcodeInfo::em64t, {REX_W, 0x83, opc_ext, ib}, {r_m64, imm8s}, def_use },\ 362 \ 363 {OpcodeInfo::all, {first_opcode, _r}, {r_m8, r8}, def_use },\ 364 \ 365 {OpcodeInfo::all, {Size16, opcode_starts_from+1, _r}, {r_m16, r16}, def_use },\ 366 {OpcodeInfo::all, {opcode_starts_from+1, _r}, {r_m32, r32}, def_use },\ 367 {OpcodeInfo::em64t, {REX_W, opcode_starts_from+1, _r}, {r_m64, r64}, def_use },\ 368 \ 369 {OpcodeInfo::all, {opcode_starts_from+2, _r}, {r8, r_m8}, def_use },\ 370 \ 371 {OpcodeInfo::all, {Size16, opcode_starts_from+3, _r}, {r16, r_m16}, def_use },\ 372 {OpcodeInfo::all, {opcode_starts_from+3, _r}, {r32, r_m32}, def_use },\ 373 {OpcodeInfo::em64t, {REX_W, opcode_starts_from+3, _r}, {r64, r_m64}, def_use }, 374 375 BEGIN_MNEMONIC(ADD, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U) 376 BEGIN_OPCODES() 377 DEFINE_ALU_OPCODES(_0, 0x00, OxOO, DU_U ) 378 END_OPCODES() 379 END_MNEMONIC() 380 381 BEGIN_MNEMONIC(OR, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U) 382 BEGIN_OPCODES() 383 DEFINE_ALU_OPCODES(_1, 0x08, 0x08, DU_U ) 384 END_OPCODES() 385 END_MNEMONIC() 386 387 BEGIN_MNEMONIC(ADC, MF_AFFECTS_FLAGS|MF_USES_FLAGS|MF_SYMMETRIC, DU_U) 388 BEGIN_OPCODES() 389 DEFINE_ALU_OPCODES(_2, 0x10, 0x10, DU_U ) 390 END_OPCODES() 391 END_MNEMONIC() 392 393 BEGIN_MNEMONIC(SBB, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) 394 BEGIN_OPCODES() 395 DEFINE_ALU_OPCODES(_3, 0x18, 0x18, DU_U ) 396 END_OPCODES() 397 END_MNEMONIC() 398 399 BEGIN_MNEMONIC(AND, MF_AFFECTS_FLAGS|MF_SYMMETRIC, DU_U) 400 BEGIN_OPCODES() 401 DEFINE_ALU_OPCODES(_4, 0x20, 0x20, DU_U ) 402 END_OPCODES() 403 END_MNEMONIC() 404 405 406 BEGIN_MNEMONIC(SUB, MF_AFFECTS_FLAGS|MF_SAME_ARG_NO_USE, DU_U) 407 BEGIN_OPCODES() 408 DEFINE_ALU_OPCODES(_5, 0x28, 0x28, DU_U ) 409 END_OPCODES() 410 END_MNEMONIC() 411 412 413 BEGIN_MNEMONIC(XOR, MF_AFFECTS_FLAGS|MF_SYMMETRIC|MF_SAME_ARG_NO_USE, DU_U) 414 BEGIN_OPCODES() 415 DEFINE_ALU_OPCODES( _6, 0x30, 0x30, DU_U ) 416 END_OPCODES() 417 END_MNEMONIC() 418 419 BEGIN_MNEMONIC(CMP, MF_AFFECTS_FLAGS, U_U) 420 BEGIN_OPCODES() 421 DEFINE_ALU_OPCODES( _7, 0x38, 0x38, U_U ) 422 END_OPCODES() 423 END_MNEMONIC() 424 425 BEGIN_MNEMONIC(CMPXCHG, MF_AFFECTS_FLAGS, N) 426 BEGIN_OPCODES() 427 {OpcodeInfo::all, {0x0F, 0xB0, _r}, {r_m8, r8, AL}, DU_DU_DU }, 428 {OpcodeInfo::all, {Size16, 0x0F, 0xB1, _r}, {r_m16, r16, AX}, DU_DU_DU }, 429 {OpcodeInfo::all, {0x0F, 0xB1, _r}, {r_m32, r32, EAX}, DU_DU_DU}, 430 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r}, {r_m64, r64, RAX}, DU_DU_DU }, 431 END_OPCODES() 432 END_MNEMONIC() 433 434 BEGIN_MNEMONIC(CMPXCHG8B, MF_AFFECTS_FLAGS, D) 435 BEGIN_OPCODES() 436 {OpcodeInfo::all, {0x0F, 0xC7, _1}, {m64}, DU }, 437 END_OPCODES() 438 END_MNEMONIC() 439 440 #undef DEFINE_ALU_OPCODES 441 // 442 // 443 // 444 BEGIN_MNEMONIC(ADDSD, MF_NONE, DU_U) 445 BEGIN_OPCODES() 446 {OpcodeInfo::all, {0xF2, 0x0F, 0x58, _r}, {xmm64, xmm_m64}, DU_U}, 447 END_OPCODES() 448 END_MNEMONIC() 449 450 BEGIN_MNEMONIC(ADDSS, MF_NONE, DU_U) 451 BEGIN_OPCODES() 452 {OpcodeInfo::all, {0xF3, 0x0F, 0x58, _r}, {xmm32, xmm_m32}, DU_U}, 453 END_OPCODES() 454 END_MNEMONIC() 455 456 457 BEGIN_MNEMONIC(BSF, MF_AFFECTS_FLAGS, N) 458 BEGIN_OPCODES() 459 {OpcodeInfo::all, {0x0F, 0xBC}, {r32, r_m32}, D_U}, 460 END_OPCODES() 461 END_MNEMONIC() 462 463 BEGIN_MNEMONIC(BSR, MF_AFFECTS_FLAGS, N) 464 BEGIN_OPCODES() 465 {OpcodeInfo::all, {0x0F, 0xBD}, {r32, r_m32}, D_U}, 466 END_OPCODES() 467 END_MNEMONIC() 468 469 470 BEGIN_MNEMONIC(CALL, MF_NONE, U ) 471 BEGIN_OPCODES() 472 {OpcodeInfo::all, {0xE8, cd}, {rel32}, U }, 473 {OpcodeInfo::ia32, {Size16, 0xE8, cw}, {rel16}, U }, 474 {OpcodeInfo::ia32, {0xFF, _2}, {r_m32}, U }, 475 {OpcodeInfo::em64t, {0xFF, _2}, {r_m64}, U }, 476 END_OPCODES() 477 END_MNEMONIC() 478 479 BEGIN_MNEMONIC(CMC, MF_USES_FLAGS|MF_AFFECTS_FLAGS, N) 480 BEGIN_OPCODES() 481 {OpcodeInfo::decoder, {0xF5}, {}, N }, 482 END_OPCODES() 483 END_MNEMONIC() 484 485 //TODO: Workaround. Actually, it's D_DU, but Jitrino's CG thinks it's D_U 486 BEGIN_MNEMONIC(CDQ, MF_NONE, D_U ) 487 BEGIN_OPCODES() 488 {OpcodeInfo::all, {0x99}, {DX, AX}, D_U }, 489 {OpcodeInfo::all, {0x99}, {EDX, EAX}, D_U }, 490 {OpcodeInfo::em64t, {REX_W, 0x99}, {RDX, RAX}, D_U }, 491 END_OPCODES() 492 END_MNEMONIC() 493 494 #define DEFINE_CMOVcc_MNEMONIC( cc ) \ 495 BEGIN_MNEMONIC(CMOV##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU_U ) \ 496 BEGIN_OPCODES() \ 497 {OpcodeInfo::all, {Size16, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r16, r_m16}, DU_U }, \ 498 {OpcodeInfo::all, {0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r32, r_m32}, DU_U }, \ 499 {OpcodeInfo::em64t, {REX_W, 0x0F, 0x40 + ConditionMnemonic_##cc, _r}, {r64, r_m64}, DU_U }, \ 500 END_OPCODES() \ 501 END_MNEMONIC() 502 503 DEFINE_CMOVcc_MNEMONIC(O) 504 DEFINE_CMOVcc_MNEMONIC(NO) 505 DEFINE_CMOVcc_MNEMONIC(B) 506 DEFINE_CMOVcc_MNEMONIC(NB) 507 DEFINE_CMOVcc_MNEMONIC(Z) 508 DEFINE_CMOVcc_MNEMONIC(NZ) 509 DEFINE_CMOVcc_MNEMONIC(BE) 510 DEFINE_CMOVcc_MNEMONIC(NBE) 511 DEFINE_CMOVcc_MNEMONIC(S) 512 DEFINE_CMOVcc_MNEMONIC(NS) 513 DEFINE_CMOVcc_MNEMONIC(P) 514 DEFINE_CMOVcc_MNEMONIC(NP) 515 DEFINE_CMOVcc_MNEMONIC(L) 516 DEFINE_CMOVcc_MNEMONIC(NL) 517 DEFINE_CMOVcc_MNEMONIC(LE) 518 DEFINE_CMOVcc_MNEMONIC(NLE) 519 520 #undef DEFINE_CMOVcc_MNEMONIC 521 522 /***************************************************************************** 523 ***** SSE conversion routines ***** 524 *****************************************************************************/ 525 // 526 // double -> float 527 BEGIN_MNEMONIC(CVTSD2SS, MF_NONE, D_U ) 528 BEGIN_OPCODES() 529 {OpcodeInfo::all, {0xF2, 0x0F, 0x5A, _r}, {xmm32, xmm_m64}, D_U }, 530 END_OPCODES() 531 END_MNEMONIC() 532 533 // double -> I_32 534 BEGIN_MNEMONIC(CVTSD2SI, MF_NONE, D_U ) 535 BEGIN_OPCODES() 536 {OpcodeInfo::all, {0xF2, 0x0F, 0x2D, _r}, {r32, xmm_m64}, D_U }, 537 {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2D, _r}, {r64, xmm_m64}, D_U }, 538 END_OPCODES() 539 END_MNEMONIC() 540 541 // double [truncated] -> I_32 542 BEGIN_MNEMONIC(CVTTSD2SI, MF_NONE, D_U ) 543 BEGIN_OPCODES() 544 {OpcodeInfo::all, {0xF2, 0x0F, 0x2C, _r}, {r32, xmm_m64}, D_U }, 545 {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2C, _r}, {r64, xmm_m64}, D_U }, 546 END_OPCODES() 547 END_MNEMONIC() 548 549 // float -> double 550 BEGIN_MNEMONIC(CVTSS2SD, MF_NONE, D_U ) 551 BEGIN_OPCODES() 552 {OpcodeInfo::all, {0xF3, 0x0F, 0x5A, _r}, {xmm64, xmm_m32}, D_U }, 553 END_OPCODES() 554 END_MNEMONIC() 555 556 // float -> I_32 557 BEGIN_MNEMONIC(CVTSS2SI, MF_NONE, D_U ) 558 BEGIN_OPCODES() 559 {OpcodeInfo::all, {0xF3, 0x0F, 0x2D, _r}, {r32, xmm_m32}, D_U}, 560 {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2D, _r}, {r64, xmm_m32}, D_U}, 561 END_OPCODES() 562 END_MNEMONIC() 563 564 // float [truncated] -> I_32 565 BEGIN_MNEMONIC(CVTTSS2SI, MF_NONE, D_U ) 566 BEGIN_OPCODES() 567 {OpcodeInfo::all, {0xF3, 0x0F, 0x2C, _r}, {r32, xmm_m32}, D_U}, 568 {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2C, _r}, {r64, xmm_m32}, D_U}, 569 END_OPCODES() 570 END_MNEMONIC() 571 572 // I_32 -> double 573 BEGIN_MNEMONIC(CVTSI2SD, MF_NONE, D_U ) 574 BEGIN_OPCODES() 575 {OpcodeInfo::all, {0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m32}, D_U}, 576 {OpcodeInfo::em64t, {REX_W, 0xF2, 0x0F, 0x2A, _r}, {xmm64, r_m64}, D_U}, 577 END_OPCODES() 578 END_MNEMONIC() 579 580 // I_32 -> float 581 BEGIN_MNEMONIC(CVTSI2SS, MF_NONE, D_U ) 582 BEGIN_OPCODES() 583 {OpcodeInfo::all, {0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m32}, D_U}, 584 {OpcodeInfo::em64t, {REX_W, 0xF3, 0x0F, 0x2A, _r}, {xmm32, r_m64}, D_U}, 585 END_OPCODES() 586 END_MNEMONIC() 587 588 // 589 // ~ SSE conversions 590 // 591 592 BEGIN_MNEMONIC(DEC, MF_AFFECTS_FLAGS, DU ) 593 BEGIN_OPCODES() 594 {OpcodeInfo::all, {0xFE, _1}, {r_m8}, DU }, 595 596 {OpcodeInfo::all, {Size16, 0xFF, _1}, {r_m16}, DU }, 597 {OpcodeInfo::all, {0xFF, _1}, {r_m32}, DU }, 598 {OpcodeInfo::em64t, {REX_W, 0xFF, _1}, {r_m64}, DU }, 599 600 {OpcodeInfo::ia32, {Size16, 0x48|rw}, {r16}, DU }, 601 {OpcodeInfo::ia32, {0x48|rd}, {r32}, DU }, 602 END_OPCODES() 603 END_MNEMONIC() 604 605 606 BEGIN_MNEMONIC(DIVSD, MF_NONE, DU_U) 607 BEGIN_OPCODES() 608 {OpcodeInfo::all, {0xF2, 0x0F, 0x5E, _r}, {xmm64, xmm_m64}, DU_U }, 609 END_OPCODES() 610 END_MNEMONIC() 611 612 613 BEGIN_MNEMONIC(DIVSS, MF_NONE, DU_U) 614 BEGIN_OPCODES() 615 {OpcodeInfo::all, {0xF3, 0x0F, 0x5E, _r}, {xmm32, xmm_m32}, DU_U }, 616 END_OPCODES() 617 END_MNEMONIC() 618 619 /**************************************************************************** 620 ***** FPU operations ***** 621 ****************************************************************************/ 622 623 BEGIN_MNEMONIC(FADDP, MF_NONE, DU ) 624 BEGIN_OPCODES() 625 {OpcodeInfo::all, {0xDE, 0xC1}, {FP0D}, DU }, 626 {OpcodeInfo::all, {0xDE, 0xC1}, {FP0S}, DU }, 627 END_OPCODES() 628 END_MNEMONIC() 629 630 BEGIN_MNEMONIC(FLDZ, MF_NONE, U ) 631 BEGIN_OPCODES() 632 {OpcodeInfo::all, {0xD9, 0xEE}, {FP0D}, D }, 633 {OpcodeInfo::all, {0xD9, 0xEE}, {FP0S}, D }, 634 END_OPCODES() 635 END_MNEMONIC() 636 637 BEGIN_MNEMONIC(FADD, MF_NONE, U ) 638 BEGIN_OPCODES() 639 {OpcodeInfo::all, {0xDC, _0}, {FP0D, m64}, DU_U }, 640 {OpcodeInfo::all, {0xD8, _0}, {FP0S, m32}, DU_U }, 641 END_OPCODES() 642 END_MNEMONIC() 643 644 BEGIN_MNEMONIC(FSUBP, MF_NONE, DU ) 645 BEGIN_OPCODES() 646 {OpcodeInfo::all, {0xDE, 0xE9}, {FP0D}, DU }, 647 {OpcodeInfo::all, {0xDE, 0xE9}, {FP0S}, DU }, 648 END_OPCODES() 649 END_MNEMONIC() 650 651 BEGIN_MNEMONIC(FSUB, MF_NONE, U ) 652 BEGIN_OPCODES() 653 {OpcodeInfo::all, {0xDC, _4}, {FP0D, m64}, DU_U }, 654 {OpcodeInfo::all, {0xD8, _4}, {FP0S, m32}, DU_U }, 655 END_OPCODES() 656 END_MNEMONIC() 657 658 BEGIN_MNEMONIC(FISUB, MF_NONE, U ) 659 BEGIN_OPCODES() 660 {OpcodeInfo::all, {0xDA, _4}, {FP0S, m32}, DU_U }, 661 // {OpcodeInfo::all, {0xDE, _4}, {FP0S, m16}, DU_U }, 662 END_OPCODES() 663 END_MNEMONIC() 664 665 666 667 BEGIN_MNEMONIC(FMUL, MF_NONE, DU_U ) 668 BEGIN_OPCODES() 669 {OpcodeInfo::all, {0xD8, _1}, {FP0S, m32}, DU_U }, 670 {OpcodeInfo::all, {0xDC, _1}, {FP0D, m64}, DU_U }, 671 END_OPCODES() 672 END_MNEMONIC() 673 674 BEGIN_MNEMONIC(FMULP, MF_NONE, DU ) 675 BEGIN_OPCODES() 676 {OpcodeInfo::all, {0xDE, 0xC9}, {FP0D}, DU }, 677 {OpcodeInfo::all, {0xDE, 0xC9}, {FP0S}, DU }, 678 END_OPCODES() 679 END_MNEMONIC() 680 681 BEGIN_MNEMONIC(FDIVP, MF_NONE, DU ) 682 BEGIN_OPCODES() 683 {OpcodeInfo::all, {0xDE, 0xF9}, {FP0D}, DU }, 684 {OpcodeInfo::all, {0xDE, 0xF9}, {FP0S}, DU }, 685 END_OPCODES() 686 END_MNEMONIC() 687 688 BEGIN_MNEMONIC(FDIV, MF_NONE, U ) 689 BEGIN_OPCODES() 690 {OpcodeInfo::all, {0xDC, _6}, {FP0D, m64}, DU_U }, 691 {OpcodeInfo::all, {0xD8, _6}, {FP0S, m32}, DU_U }, 692 END_OPCODES() 693 END_MNEMONIC() 694 695 696 BEGIN_MNEMONIC(FUCOM, MF_NONE, D_U ) 697 BEGIN_OPCODES() 698 {OpcodeInfo::all, {0xDD, 0xE1}, {FP0D, FP1D}, DU_U }, 699 {OpcodeInfo::all, {0xDD, 0xE1}, {FP0S, FP1S}, DU_U }, 700 // A little trick: actually, these 2 opcodes take only index of the 701 // needed register. To make the things similar to other instructions 702 // we encode here as if they took FPREG. 703 {OpcodeInfo::all, {0xDD, 0xE0|_i}, {fp32}, DU }, 704 {OpcodeInfo::all, {0xDD, 0xE0|_i}, {fp64}, DU }, 705 END_OPCODES() 706 END_MNEMONIC() 707 708 BEGIN_MNEMONIC(FUCOMI, MF_NONE, D_U ) 709 BEGIN_OPCODES() 710 // A little trick: actually, these 2 opcodes take only index of the 711 // needed register. To make the things similar to other instructions 712 // we encode here as if they took FPREG. 713 {OpcodeInfo::all, {0xDB, 0xE8|_i}, {fp32}, DU }, 714 {OpcodeInfo::all, {0xDB, 0xE8|_i}, {fp64}, DU }, 715 END_OPCODES() 716 END_MNEMONIC() 717 718 BEGIN_MNEMONIC(FUCOMP, MF_NONE, D_U ) 719 BEGIN_OPCODES() 720 {OpcodeInfo::all, {0xDD, 0xE9}, {FP0D, FP1D}, DU_U }, 721 {OpcodeInfo::all, {0xDD, 0xE9}, {FP0S, FP1S}, DU_U }, 722 // A little trick: actually, these 2 opcodes take only index of the 723 // needed register. To make the things similar to other instructions 724 // we encode here as if they took FPREG. 725 {OpcodeInfo::all, {0xDD, 0xE8|_i}, {fp32}, DU }, 726 {OpcodeInfo::all, {0xDD, 0xE8|_i}, {fp64}, DU }, 727 END_OPCODES() 728 END_MNEMONIC() 729 730 BEGIN_MNEMONIC(FUCOMIP, MF_NONE, D_U ) 731 BEGIN_OPCODES() 732 // A little trick: actually, these 2 opcodes take only index of the 733 // needed register. To make the things similar to other instructions 734 // we encode here as if they took FPREG. 735 {OpcodeInfo::all, {0xDF, 0xE8|_i}, {fp32}, DU }, 736 {OpcodeInfo::all, {0xDF, 0xE8|_i}, {fp64}, DU }, 737 END_OPCODES() 738 END_MNEMONIC() 739 740 BEGIN_MNEMONIC(FUCOMPP, MF_NONE, U ) 741 BEGIN_OPCODES() 742 {OpcodeInfo::all, {0xDA, 0xE9}, {FP0D, FP1D}, DU_U }, 743 {OpcodeInfo::all, {0xDA, 0xE9}, {FP0S, FP1S}, DU_U }, 744 END_OPCODES() 745 END_MNEMONIC() 746 747 BEGIN_MNEMONIC(FLDCW, MF_NONE, U ) 748 BEGIN_OPCODES() 749 {OpcodeInfo::all, {0xD9, _5}, {m16}, U }, 750 END_OPCODES() 751 END_MNEMONIC() 752 753 BEGIN_MNEMONIC(FNSTCW, MF_NONE, D) 754 BEGIN_OPCODES() 755 {OpcodeInfo::all, {0xD9, _7}, {m16}, D }, 756 END_OPCODES() 757 END_MNEMONIC() 758 759 BEGIN_MNEMONIC(FSTSW, MF_NONE, D) 760 BEGIN_OPCODES() 761 {OpcodeInfo::all, {0x9B, 0xDF, 0xE0}, {EAX}, D }, 762 END_OPCODES() 763 END_MNEMONIC() 764 765 BEGIN_MNEMONIC(FNSTSW, MF_NONE, D) 766 BEGIN_OPCODES() 767 {OpcodeInfo::all, {0xDF, 0xE0}, {EAX}, D }, 768 END_OPCODES() 769 END_MNEMONIC() 770 771 BEGIN_MNEMONIC(FCHS, MF_NONE, DU ) 772 BEGIN_OPCODES() 773 {OpcodeInfo::all, {0xD9, 0xE0}, {FP0D}, DU }, 774 {OpcodeInfo::all, {0xD9, 0xE0}, {FP0S}, DU }, 775 END_OPCODES() 776 END_MNEMONIC() 777 778 BEGIN_MNEMONIC(FCLEX, MF_NONE, N) 779 BEGIN_OPCODES() 780 {OpcodeInfo::all, {0x9B, 0xDB, 0xE2}, {}, N }, 781 END_OPCODES() 782 END_MNEMONIC() 783 784 BEGIN_MNEMONIC(FNCLEX, MF_NONE, N) 785 BEGIN_OPCODES() 786 {OpcodeInfo::all, {0xDB, 0xE2}, {}, N }, 787 END_OPCODES() 788 END_MNEMONIC() 789 790 //BEGIN_MNEMONIC(FDECSTP, MF_NONE, N) 791 // BEGIN_OPCODES() 792 // {OpcodeInfo::all, {0xD9, 0xF6}, {}, N }, 793 // END_OPCODES() 794 //END_MNEMONIC() 795 796 BEGIN_MNEMONIC(FILD, MF_NONE, D_U ) 797 BEGIN_OPCODES() 798 {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, 799 {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, 800 {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, 801 END_OPCODES() 802 END_MNEMONIC() 803 804 //BEGIN_MNEMONIC(FINCSTP, MF_NONE, N) 805 // BEGIN_OPCODES() 806 // {OpcodeInfo::all, {0xD9, 0xF7}, {}, N }, 807 // END_OPCODES() 808 //END_MNEMONIC() 809 810 BEGIN_MNEMONIC(FIST, MF_NONE, D_U ) 811 BEGIN_OPCODES() 812 {OpcodeInfo::all, {0xDB, _2}, {m32, FP0S}, D_U }, 813 END_OPCODES() 814 END_MNEMONIC() 815 816 BEGIN_MNEMONIC(FISTP, MF_NONE, D_U ) 817 BEGIN_OPCODES() 818 {OpcodeInfo::all, {0xDB, _3}, {m32, FP0S}, D_U }, 819 {OpcodeInfo::all, {0xDF, _7}, {m64, FP0D}, D_U }, 820 END_OPCODES() 821 END_MNEMONIC() 822 823 BEGIN_MNEMONIC(FISTTP, MF_NONE, D_U ) 824 BEGIN_OPCODES() 825 {OpcodeInfo::all, {0xDD, _1}, {m64, FP0D}, D_U }, 826 {OpcodeInfo::all, {0xDB, _1}, {m32, FP0S}, D_U }, 827 END_OPCODES() 828 END_MNEMONIC() 829 830 BEGIN_MNEMONIC(FRNDINT, MF_NONE, DU ) 831 BEGIN_OPCODES() 832 {OpcodeInfo::all, {0xD9, 0xFC}, {FP0S}, DU }, 833 {OpcodeInfo::all, {0xD9, 0xFC}, {FP0D}, DU }, 834 END_OPCODES() 835 END_MNEMONIC() 836 837 BEGIN_MNEMONIC(FLD, MF_NONE, D_U ) 838 BEGIN_OPCODES() 839 {OpcodeInfo::all, {0xD9, _0}, {FP0S, m32}, D_U }, 840 {OpcodeInfo::all, {0xDD, _0}, {FP0D, m64}, D_U }, 841 END_OPCODES() 842 END_MNEMONIC() 843 844 BEGIN_MNEMONIC(FLDLG2, MF_NONE, U ) 845 BEGIN_OPCODES() 846 {OpcodeInfo::all, {0xD9, 0xEC}, {FP0S}, D }, 847 {OpcodeInfo::all, {0xD9, 0xEC}, {FP0D}, D }, 848 END_OPCODES() 849 END_MNEMONIC() 850 851 BEGIN_MNEMONIC(FLDLN2, MF_NONE, U ) 852 BEGIN_OPCODES() 853 {OpcodeInfo::all, {0xD9, 0xED}, {FP0S}, D }, 854 {OpcodeInfo::all, {0xD9, 0xED}, {FP0D}, D }, 855 END_OPCODES() 856 END_MNEMONIC() 857 858 BEGIN_MNEMONIC(FLD1, MF_NONE, U ) 859 BEGIN_OPCODES() 860 {OpcodeInfo::all, {0xD9, 0xE8}, {FP0S}, D }, 861 {OpcodeInfo::all, {0xD9, 0xE8}, {FP0D}, D }, 862 END_OPCODES() 863 END_MNEMONIC() 864 865 866 BEGIN_MNEMONIC(FPREM, MF_NONE, N) 867 BEGIN_OPCODES() 868 {OpcodeInfo::all, {0xD9, 0xF8}, {}, N }, 869 END_OPCODES() 870 END_MNEMONIC() 871 872 BEGIN_MNEMONIC(FPREM1, MF_NONE, N) 873 BEGIN_OPCODES() 874 {OpcodeInfo::all, {0xD9, 0xF5}, {}, N }, 875 END_OPCODES() 876 END_MNEMONIC() 877 878 BEGIN_MNEMONIC(FST, MF_NONE, D_U ) 879 BEGIN_OPCODES() 880 {OpcodeInfo::all, {0xD9, _2}, {m32, FP0S}, D_U }, 881 {OpcodeInfo::all, {0xDD, _2}, {m64, FP0D}, D_U }, 882 // A little trick: actually, these 2 opcodes take only index of the 883 // needed register. To make the things similar to other instructions 884 // we encode here as if they took FPREG. 885 {OpcodeInfo::all, {0xDD, 0xD0|_i}, {fp32}, D }, 886 {OpcodeInfo::all, {0xDD, 0xD0|_i}, {fp64}, D }, 887 END_OPCODES() 888 END_MNEMONIC() 889 890 BEGIN_MNEMONIC(FSTP, MF_NONE, D_U ) 891 BEGIN_OPCODES() 892 {OpcodeInfo::all, {0xD9, _3}, {m32, FP0S}, D_U }, 893 {OpcodeInfo::all, {0xDD, _3}, {m64, FP0D}, D_U }, 894 // A little trick: actually, these 2 opcodes take only index of the 895 // needed register. To make the things similar to other instructions 896 // we encode here as if they took FPREG. 897 {OpcodeInfo::all, {0xDD, 0xD8|_i}, {fp32}, D }, 898 {OpcodeInfo::all, {0xDD, 0xD8|_i}, {fp64}, D }, 899 END_OPCODES() 900 END_MNEMONIC() 901 902 BEGIN_MNEMONIC(FSQRT, MF_NONE, DU) 903 BEGIN_OPCODES() 904 {OpcodeInfo::all, {0xD9, 0xFA}, {FP0S}, DU }, 905 {OpcodeInfo::all, {0xD9, 0xFA}, {FP0D}, DU }, 906 END_OPCODES() 907 END_MNEMONIC() 908 909 910 BEGIN_MNEMONIC(FYL2X, MF_NONE, DU) 911 BEGIN_OPCODES() 912 {OpcodeInfo::all, {0xD9, 0xF1}, {FP0S}, DU }, 913 {OpcodeInfo::all, {0xD9, 0xF1}, {FP0D}, DU }, 914 END_OPCODES() 915 END_MNEMONIC() 916 917 918 BEGIN_MNEMONIC(FYL2XP1, MF_NONE, DU) 919 BEGIN_OPCODES() 920 {OpcodeInfo::all, {0xD9, 0xF9}, {FP0S}, DU }, 921 {OpcodeInfo::all, {0xD9, 0xF9}, {FP0D}, DU }, 922 END_OPCODES() 923 END_MNEMONIC() 924 925 BEGIN_MNEMONIC(F2XM1, MF_NONE, DU) 926 BEGIN_OPCODES() 927 {OpcodeInfo::all, {0xD9, 0xF0}, {FP0S}, DU }, 928 {OpcodeInfo::all, {0xD9, 0xF0}, {FP0D}, DU }, 929 END_OPCODES() 930 END_MNEMONIC() 931 932 BEGIN_MNEMONIC(FPATAN, MF_NONE, DU) 933 BEGIN_OPCODES() 934 {OpcodeInfo::all, {0xD9, 0xF3}, {FP0S}, DU }, 935 {OpcodeInfo::all, {0xD9, 0xF3}, {FP0D}, DU }, 936 END_OPCODES() 937 END_MNEMONIC() 938 939 BEGIN_MNEMONIC(FXCH, MF_NONE, DU) 940 BEGIN_OPCODES() 941 {OpcodeInfo::all, {0xD9, 0xC9}, {FP0S}, DU }, 942 {OpcodeInfo::all, {0xD9, 0xC9}, {FP0D}, DU }, 943 END_OPCODES() 944 END_MNEMONIC() 945 946 BEGIN_MNEMONIC(FSCALE, MF_NONE, DU) 947 BEGIN_OPCODES() 948 {OpcodeInfo::all, {0xD9, 0xFD}, {FP0S}, DU }, 949 {OpcodeInfo::all, {0xD9, 0xFD}, {FP0D}, DU }, 950 END_OPCODES() 951 END_MNEMONIC() 952 953 BEGIN_MNEMONIC(FABS, MF_NONE, DU) 954 BEGIN_OPCODES() 955 {OpcodeInfo::all, {0xD9, 0xE1}, {FP0S}, DU }, 956 {OpcodeInfo::all, {0xD9, 0xE1}, {FP0D}, DU }, 957 END_OPCODES() 958 END_MNEMONIC() 959 960 BEGIN_MNEMONIC(FSIN, MF_NONE, DU) 961 BEGIN_OPCODES() 962 {OpcodeInfo::all, {0xD9, 0xFE}, {FP0S}, DU }, 963 {OpcodeInfo::all, {0xD9, 0xFE}, {FP0D}, DU }, 964 END_OPCODES() 965 END_MNEMONIC() 966 967 BEGIN_MNEMONIC(FCOS, MF_NONE, DU) 968 BEGIN_OPCODES() 969 {OpcodeInfo::all, {0xD9, 0xFF}, {FP0S}, DU }, 970 {OpcodeInfo::all, {0xD9, 0xFF}, {FP0D}, DU }, 971 END_OPCODES() 972 END_MNEMONIC() 973 974 BEGIN_MNEMONIC(FPTAN, MF_NONE, DU) 975 BEGIN_OPCODES() 976 {OpcodeInfo::all, {0xD9, 0xF2}, {FP0S}, DU }, 977 {OpcodeInfo::all, {0xD9, 0xF2}, {FP0D}, DU }, 978 END_OPCODES() 979 END_MNEMONIC() 980 981 // 982 // ~ FPU 983 // 984 985 BEGIN_MNEMONIC(DIV, MF_AFFECTS_FLAGS, DU_DU_U) 986 BEGIN_OPCODES() 987 {OpcodeInfo::all, {0xF7, _6}, {EDX, EAX, r_m32}, DU_DU_U }, 988 END_OPCODES() 989 END_MNEMONIC() 990 991 BEGIN_MNEMONIC(IDIV, MF_AFFECTS_FLAGS, DU_DU_U) 992 BEGIN_OPCODES() 993 #if !defined(_EM64T_) 994 {OpcodeInfo::all, {0xF6, _7}, {AH, AL, r_m8}, DU_DU_U }, 995 {OpcodeInfo::all, {Size16, 0xF7, _7}, {DX, AX, r_m16}, DU_DU_U }, 996 #endif 997 {OpcodeInfo::all, {0xF7, _7}, {EDX, EAX, r_m32}, DU_DU_U }, 998 {OpcodeInfo::em64t, {REX_W, 0xF7, _7}, {RDX, RAX, r_m64}, DU_DU_U }, 999 END_OPCODES() 1000 END_MNEMONIC() 1001 1002 1003 BEGIN_MNEMONIC(IMUL, MF_AFFECTS_FLAGS, D_DU_U) 1004 BEGIN_OPCODES() 1005 /*{OpcodeInfo::all, {0xF6, _5}, {AH, AL, r_m8}, D_DU_U }, 1006 {OpcodeInfo::all, {Size16, 0xF7, _5}, {DX, AX, r_m16}, D_DU_U }, 1007 */ 1008 // 1009 {OpcodeInfo::all, {0xF7, _5}, {EDX, EAX, r_m32}, D_DU_U }, 1010 //todo: this opcode's hash conflicts with IMUL r64,r_m64 - they're both 0. 1011 // this particular is not currently used, so we may safely drop it, but need to 1012 // revisit the hash implementation 1013 // {OpcodeInfo::em64t, {REX_W, 0xF7, _5}, {RDX, RAX, r_m64}, D_DU_U }, 1014 // 1015 {OpcodeInfo::all, {Size16, 0x0F, 0xAF, _r}, {r16,r_m16}, DU_U }, 1016 {OpcodeInfo::all, {0x0F, 0xAF, _r}, {r32,r_m32}, DU_U }, 1017 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xAF, _r}, {r64,r_m64}, DU_U }, 1018 {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,r_m16,imm8s}, D_DU_U }, 1019 {OpcodeInfo::all, {0x6B, _r, ib}, {r32,r_m32,imm8s}, D_DU_U }, 1020 {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,r_m64,imm8s}, D_DU_U }, 1021 {OpcodeInfo::all, {Size16, 0x6B, _r, ib}, {r16,imm8s}, DU_U }, 1022 {OpcodeInfo::all, {0x6B, _r, ib}, {r32,imm8s}, DU_U }, 1023 {OpcodeInfo::em64t, {REX_W, 0x6B, _r, ib}, {r64,imm8s}, DU_U }, 1024 {OpcodeInfo::all, {Size16, 0x69, _r, iw}, {r16,r_m16,imm16}, D_U_U }, 1025 {OpcodeInfo::all, {0x69, _r, id}, {r32,r_m32,imm32}, D_U_U }, 1026 {OpcodeInfo::em64t, {REX_W, 0x69, _r, id}, {r64,r_m64,imm32s}, D_U_U }, 1027 {OpcodeInfo::all, {Size16, 0x69, _r, iw}, {r16,imm16}, DU_U }, 1028 {OpcodeInfo::all, {0x69, _r, id}, {r32,imm32}, DU_U }, 1029 END_OPCODES() 1030 END_MNEMONIC() 1031 1032 BEGIN_MNEMONIC(MUL, MF_AFFECTS_FLAGS, U ) 1033 BEGIN_OPCODES() 1034 {OpcodeInfo::all, {0xF6, _4}, {AX, AL, r_m8}, D_DU_U }, 1035 {OpcodeInfo::all, {Size16, 0xF7, _4}, {DX, AX, r_m16}, D_DU_U }, 1036 {OpcodeInfo::all, {0xF7, _4}, {EDX, EAX, r_m32}, D_DU_U }, 1037 {OpcodeInfo::em64t, {REX_W, 0xF7, _4}, {RDX, RAX, r_m64}, D_DU_U }, 1038 END_OPCODES() 1039 END_MNEMONIC() 1040 1041 BEGIN_MNEMONIC(INC, MF_AFFECTS_FLAGS, DU ) 1042 BEGIN_OPCODES() 1043 {OpcodeInfo::all, {0xFE, _0}, {r_m8}, DU }, 1044 {OpcodeInfo::all, {Size16, 0xFF, _0}, {r_m16}, DU }, 1045 {OpcodeInfo::all, {0xFF, _0}, {r_m32}, DU }, 1046 {OpcodeInfo::em64t, {REX_W, 0xFF, _0}, {r_m64}, DU }, 1047 {OpcodeInfo::ia32, {Size16, 0x40|rw}, {r16}, DU }, 1048 {OpcodeInfo::ia32, {0x40|rd}, {r32}, DU }, 1049 END_OPCODES() 1050 END_MNEMONIC() 1051 1052 BEGIN_MNEMONIC(INT3, MF_NONE, N) 1053 BEGIN_OPCODES() 1054 {OpcodeInfo::all, {0xCC}, {}, N }, 1055 END_OPCODES() 1056 END_MNEMONIC() 1057 1058 #define DEFINE_Jcc_MNEMONIC( cc ) \ 1059 BEGIN_MNEMONIC(J##cc, MF_USES_FLAGS|MF_CONDITIONAL, U ) \ 1060 BEGIN_OPCODES() \ 1061 {OpcodeInfo::all, {0x70 + ConditionMnemonic_##cc, cb }, { rel8 }, U }, \ 1062 {OpcodeInfo::ia32, {Size16, 0x0F, 0x80 + ConditionMnemonic_##cc, cw}, { rel16 }, U }, \ 1063 {OpcodeInfo::all, {0x0F, 0x80 + ConditionMnemonic_##cc, cd}, { rel32 }, U }, \ 1064 END_OPCODES() \ 1065 END_MNEMONIC() 1066 1067 1068 DEFINE_Jcc_MNEMONIC(O) 1069 DEFINE_Jcc_MNEMONIC(NO) 1070 DEFINE_Jcc_MNEMONIC(B) 1071 DEFINE_Jcc_MNEMONIC(NB) 1072 DEFINE_Jcc_MNEMONIC(Z) 1073 DEFINE_Jcc_MNEMONIC(NZ) 1074 DEFINE_Jcc_MNEMONIC(BE) 1075 DEFINE_Jcc_MNEMONIC(NBE) 1076 1077 DEFINE_Jcc_MNEMONIC(S) 1078 DEFINE_Jcc_MNEMONIC(NS) 1079 DEFINE_Jcc_MNEMONIC(P) 1080 DEFINE_Jcc_MNEMONIC(NP) 1081 DEFINE_Jcc_MNEMONIC(L) 1082 DEFINE_Jcc_MNEMONIC(NL) 1083 DEFINE_Jcc_MNEMONIC(LE) 1084 DEFINE_Jcc_MNEMONIC(NLE) 1085 1086 #undef DEFINE_Jcc_MNEMONIC 1087 1088 BEGIN_MNEMONIC(JMP, MF_NONE, U ) 1089 BEGIN_OPCODES() 1090 {OpcodeInfo::all, {0xEB, cb}, {rel8}, U }, 1091 {OpcodeInfo::ia32, {Size16, 0xE9, cw}, {rel16}, U }, 1092 {OpcodeInfo::all, {0xE9, cd}, {rel32}, U }, 1093 {OpcodeInfo::ia32, {Size16, 0xFF, _4}, {r_m16}, U }, 1094 {OpcodeInfo::ia32, {0xFF, _4}, {r_m32}, U }, 1095 {OpcodeInfo::em64t, {0xFF, _4}, {r_m64}, U }, 1096 END_OPCODES() 1097 END_MNEMONIC() 1098 1099 BEGIN_MNEMONIC(LEA, MF_NONE, D_U ) 1100 BEGIN_OPCODES() 1101 /* 1102 A special case: the LEA instruction itself does not care about size of 1103 second operand. This is obviuos why it is, and thus in The Manual, a 1104 simple 'm' without size is used. 1105 However, in the Jitrino's instrucitons we'll have an operand with a size. 1106 Also, the hashing scheme is not supposed to handle OpndSize_Null, and 1107 making it to do so will lead to unnecessary complication of hashing 1108 scheme. Thus, instead of handling it as a special case, we simply make 1109 copies of the opcodes with sizes set. 1110 {OpcodeInfo::all, {0x8D, _r}, {r32, m}, D_U }, 1111 {OpcodeInfo::em64t, {0x8D, _r}, {r64, m}, D_U }, 1112 */ 1113 //Android x86: keep r32, m32 only, otherwise, will have decoding error 1114 //{OpcodeInfo::all, {0x8D, _r}, {r32, m8}, D_U }, 1115 {OpcodeInfo::em64t, {REX_W, 0x8D, _r}, {r64, m8}, D_U }, 1116 //{OpcodeInfo::all, {0x8D, _r}, {r32, m16}, D_U }, 1117 {OpcodeInfo::em64t, {REX_W, 0x8D, _r}, {r64, m16}, D_U }, 1118 {OpcodeInfo::all, {0x8D, _r}, {r32, m32}, D_U }, 1119 {OpcodeInfo::em64t, {REX_W, 0x8D, _r}, {r64, m32}, D_U }, 1120 {OpcodeInfo::all, {0x8D, _r}, {r32, m64}, D_U }, 1121 {OpcodeInfo::em64t, {REX_W, 0x8D, _r}, {r64, m64}, D_U }, 1122 END_OPCODES() 1123 END_MNEMONIC() 1124 1125 BEGIN_MNEMONIC(LOOP, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) 1126 BEGIN_OPCODES() 1127 {OpcodeInfo::all, {0xE2, cb}, {ECX, rel8}, DU_U }, 1128 END_OPCODES() 1129 END_MNEMONIC() 1130 1131 BEGIN_MNEMONIC(LOOPE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) 1132 BEGIN_OPCODES() 1133 {OpcodeInfo::all, {0xE1, cb}, {ECX, rel8}, DU_U }, 1134 END_OPCODES() 1135 END_MNEMONIC() 1136 1137 BEGIN_MNEMONIC(LOOPNE, MF_AFFECTS_FLAGS|MF_USES_FLAGS, DU_U) 1138 BEGIN_OPCODES() 1139 {OpcodeInfo::all, {0xE0, cb}, {ECX, rel8}, DU_U }, 1140 END_OPCODES() 1141 END_MNEMONIC() 1142 1143 BEGIN_MNEMONIC(MOV, MF_NONE, D_U) 1144 BEGIN_OPCODES() 1145 {OpcodeInfo::all, {0x88, _r}, {r_m8,r8}, D_U }, 1146 1147 {OpcodeInfo::all, {Size16, 0x89, _r}, {r_m16,r16}, D_U }, 1148 {OpcodeInfo::all, {0x89, _r}, {r_m32,r32}, D_U }, 1149 {OpcodeInfo::em64t, {REX_W, 0x89, _r}, {r_m64,r64}, D_U }, 1150 {OpcodeInfo::all, {0x8A, _r}, {r8,r_m8}, D_U }, 1151 1152 {OpcodeInfo::all, {Size16, 0x8B, _r}, {r16,r_m16}, D_U }, 1153 {OpcodeInfo::all, {0x8B, _r}, {r32,r_m32}, D_U }, 1154 {OpcodeInfo::em64t, {REX_W, 0x8B, _r}, {r64,r_m64}, D_U }, 1155 1156 {OpcodeInfo::all, {0xB0|rb}, {r8,imm8}, D_U }, 1157 1158 {OpcodeInfo::all, {Size16, 0xB8|rw}, {r16,imm16}, D_U }, 1159 {OpcodeInfo::all, {0xB8|rd}, {r32,imm32}, D_U }, 1160 {OpcodeInfo::em64t, {REX_W, 0xB8|rd}, {r64,imm64}, D_U }, 1161 {OpcodeInfo::all, {0xC6, _0}, {r_m8,imm8}, D_U }, 1162 1163 {OpcodeInfo::all, {Size16, 0xC7, _0}, {r_m16,imm16}, D_U }, 1164 {OpcodeInfo::all, {0xC7, _0}, {r_m32,imm32}, D_U }, 1165 {OpcodeInfo::em64t, {REX_W, 0xC7, _0}, {r_m64,imm32s}, D_U }, 1166 1167 {OpcodeInfo::decoder, {0xA0}, {AL, moff8}, D_U }, 1168 {OpcodeInfo::decoder, {Size16, 0xA1}, {AX, moff16}, D_U }, 1169 {OpcodeInfo::decoder, {0xA1}, {EAX, moff32}, D_U }, 1170 //{OpcodeInfo::decoder64, {REX_W, 0xA1}, {RAX, moff64}, D_U }, 1171 1172 {OpcodeInfo::decoder, {0xA2}, {moff8, AL}, D_U }, 1173 {OpcodeInfo::decoder, {Size16, 0xA3}, {moff16, AX}, D_U }, 1174 {OpcodeInfo::decoder, {0xA3}, {moff32, EAX}, D_U }, 1175 //{OpcodeInfo::decoder64, {REX_W, 0xA3}, {moff64, RAX}, D_U }, 1176 END_OPCODES() 1177 END_MNEMONIC() 1178 1179 1180 1181 BEGIN_MNEMONIC(XCHG, MF_NONE, DU_DU ) 1182 BEGIN_OPCODES() 1183 {OpcodeInfo::all, {0x87, _r}, {r_m32,r32}, DU_DU }, 1184 END_OPCODES() 1185 END_MNEMONIC() 1186 1187 1188 BEGIN_MNEMONIC(MOVQ, MF_NONE, D_U ) 1189 BEGIN_OPCODES() 1190 #ifdef _HAVE_MMX_ 1191 {OpcodeInfo::all, {0x0F, 0x6F, _r}, {mm64, mm_m64}, D_U }, 1192 {OpcodeInfo::all, {0x0F, 0x7F, _r}, {mm_m64, mm64}, D_U }, 1193 #endif 1194 {OpcodeInfo::all, {0xF3, 0x0F, 0x7E }, {xmm64, xmm_m64}, D_U }, 1195 {OpcodeInfo::all, {0x66, 0x0F, 0xD6 }, {xmm_m64, xmm64}, D_U }, 1196 // {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r}, {xmm64, r_m64}, D_U }, 1197 // {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x7E, _r}, {r_m64, xmm64}, D_U }, 1198 {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x6E, _r}, {xmm64, r64}, D_U }, 1199 {OpcodeInfo::em64t, {REX_W, 0x66, 0x0F, 0x7E, _r}, {r64, xmm64}, D_U }, 1200 END_OPCODES() 1201 END_MNEMONIC() 1202 1203 1204 BEGIN_MNEMONIC(MOVD, MF_NONE, D_U ) 1205 BEGIN_OPCODES() 1206 {OpcodeInfo::all, {0x66, 0x0F, 0x6E, _r}, {xmm32, r_m32}, D_U }, 1207 {OpcodeInfo::all, {0x66, 0x0F, 0x7E, _r}, {r_m32, xmm32}, D_U }, 1208 END_OPCODES() 1209 END_MNEMONIC() 1210 1211 // 1212 // A bunch of MMX instructions 1213 // 1214 #ifdef _HAVE_MMX_ 1215 1216 BEGIN_MNEMONIC(EMMS, MF_NONE, N) 1217 BEGIN_OPCODES() 1218 {OpcodeInfo::all, {0x0F, 0x77}, {}, N }, 1219 END_OPCODES() 1220 END_MNEMONIC() 1221 1222 #endif 1223 1224 BEGIN_MNEMONIC(PADDQ, MF_NONE, DU_U) 1225 BEGIN_OPCODES() 1226 #ifdef _HAVE_MMX_ 1227 {OpcodeInfo::all, {0x0F, 0xD4, _r}, {mm64, mm_m64}, DU_U }, 1228 #endif 1229 {OpcodeInfo::all, {0x66, 0x0F, 0xD4, _r}, {xmm64, xmm_m64}, DU_U }, 1230 END_OPCODES() 1231 END_MNEMONIC() 1232 1233 BEGIN_MNEMONIC(PAND, MF_NONE, DU_U) 1234 BEGIN_OPCODES() 1235 #ifdef _HAVE_MMX_ 1236 {OpcodeInfo::all, {0x0F, 0xDB, _r}, {mm64, mm_m64}, DU_U }, 1237 #endif 1238 {OpcodeInfo::all, {0x66, 0x0F, 0xDB, _r}, {xmm64, xmm_m64}, DU_U }, 1239 END_OPCODES() 1240 END_MNEMONIC() 1241 1242 BEGIN_MNEMONIC(POR, MF_NONE, DU_U) 1243 BEGIN_OPCODES() 1244 #ifdef _HAVE_MMX_ 1245 {OpcodeInfo::all, {0x0F, 0xEB, _r}, {mm64, mm_m64}, DU_U }, 1246 #endif 1247 {OpcodeInfo::all, {0x66, 0x0F, 0xEB, _r}, {xmm64, xmm_m64}, DU_U }, 1248 END_OPCODES() 1249 END_MNEMONIC() 1250 1251 BEGIN_MNEMONIC(PSUBQ, MF_NONE, DU_U) 1252 BEGIN_OPCODES() 1253 #ifdef _HAVE_MMX_ 1254 {OpcodeInfo::all, {0x0F, 0xFB, _r}, {mm64, mm_m64}, DU_U }, 1255 #endif 1256 {OpcodeInfo::all, {0x66, 0x0F, 0xFB, _r}, {xmm64, xmm_m64}, DU_U }, 1257 END_OPCODES() 1258 END_MNEMONIC() 1259 1260 BEGIN_MNEMONIC(PANDN, MF_NONE, DU_U) 1261 BEGIN_OPCODES() 1262 #ifdef _HAVE_MMX_ 1263 {OpcodeInfo::all, {0x0F, 0xDF, _r}, {mm64, mm_m64}, DU_U }, 1264 #endif 1265 {OpcodeInfo::all, {0x66, 0x0F, 0xDF, _r}, {xmm64, xmm_m64}, DU_U }, 1266 END_OPCODES() 1267 END_MNEMONIC() 1268 BEGIN_MNEMONIC(PSLLQ, MF_NONE, DU_U) 1269 BEGIN_OPCODES() 1270 #ifdef _HAVE_MMX_ 1271 {OpcodeInfo::all, {0x0F, 0xF3, _r}, {mm64, mm_m64}, DU_U }, 1272 #endif 1273 {OpcodeInfo::all, {0x66, 0x0F, 0xF3, _r}, {xmm64, xmm_m64}, DU_U }, 1274 END_OPCODES() 1275 END_MNEMONIC() 1276 BEGIN_MNEMONIC(PSRLQ, MF_NONE, DU_U) 1277 BEGIN_OPCODES() 1278 #ifdef _HAVE_MMX_ 1279 {OpcodeInfo::all, {0x0F, 0xD3, _r}, {mm64, mm_m64}, DU_U }, 1280 #endif 1281 {OpcodeInfo::all, {0x66, 0x0F, 0xD3, _r}, {xmm64, xmm_m64}, DU_U }, 1282 END_OPCODES() 1283 END_MNEMONIC() 1284 1285 BEGIN_MNEMONIC(PXOR, MF_NONE, DU_U) 1286 BEGIN_OPCODES() 1287 #ifdef _HAVE_MMX_ 1288 {OpcodeInfo::all, {0x0F, 0xEF, _r}, {mm64, mm_m64}, DU_U }, 1289 #endif 1290 {OpcodeInfo::all, {0x66, 0x0F, 0xEF, _r}, {xmm64, xmm_m64}, DU_U }, 1291 END_OPCODES() 1292 END_MNEMONIC() 1293 1294 1295 BEGIN_MNEMONIC(MOVAPD, MF_NONE, D_U ) 1296 BEGIN_OPCODES() 1297 {OpcodeInfo::all, {0x66, 0x0F, 0x28, _r}, {xmm64, xmm_m64}, D_U }, 1298 {OpcodeInfo::all, {0x66, 0x0F, 0x29, _r}, {xmm_m64, xmm64}, D_U }, 1299 END_OPCODES() 1300 END_MNEMONIC() 1301 1302 1303 BEGIN_MNEMONIC(MOVSD, MF_NONE, D_U ) 1304 BEGIN_OPCODES() 1305 {OpcodeInfo::all, {0xF2, 0x0F, 0x10, _r}, {xmm64, xmm_m64}, D_U }, 1306 {OpcodeInfo::all, {0xF2, 0x0F, 0x11, _r}, {xmm_m64, xmm64}, D_U }, 1307 END_OPCODES() 1308 END_MNEMONIC() 1309 1310 BEGIN_MNEMONIC(MOVSS, MF_NONE, D_U ) 1311 BEGIN_OPCODES() 1312 {OpcodeInfo::all, {0xF3, 0x0F, 0x10, _r}, {xmm32, xmm_m32}, D_U }, 1313 {OpcodeInfo::all, {0xF3, 0x0F, 0x11, _r}, {xmm_m32, xmm32}, D_U }, 1314 END_OPCODES() 1315 END_MNEMONIC() 1316 1317 BEGIN_MNEMONIC(MOVSX, MF_NONE, D_U ) 1318 BEGIN_OPCODES() 1319 {OpcodeInfo::all, {Size16, 0x0F, 0xBE, _r}, {r16, r_m8s}, D_U }, 1320 {OpcodeInfo::all, {0x0F, 0xBE, _r}, {r32, r_m8s}, D_U }, 1321 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBE, _r}, {r64, r_m8s}, D_U }, 1322 1323 {OpcodeInfo::all, {0x0F, 0xBF, _r}, {r32, r_m16s}, D_U }, 1324 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xBF, _r}, {r64, r_m16s}, D_U }, 1325 1326 {OpcodeInfo::em64t, {REX_W, 0x63, _r}, {r64, r_m32s}, D_U }, 1327 END_OPCODES() 1328 END_MNEMONIC() 1329 1330 BEGIN_MNEMONIC(MOVZX, MF_NONE, D_U ) 1331 BEGIN_OPCODES() 1332 {OpcodeInfo::all, {Size16, 0x0F, 0xB6, _r}, {r16, r_m8u}, D_U }, 1333 {OpcodeInfo::all, {0x0F, 0xB6, _r}, {r32, r_m8u}, D_U }, 1334 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB6, _r}, {r64, r_m8u}, D_U }, 1335 1336 {OpcodeInfo::all, {0x0F, 0xB7, _r}, {r32, r_m16u}, D_U }, 1337 {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB7, _r}, {r64, r_m16u}, D_U }, 1338 //workaround to get r/rm32->r64 ZX mov functionality: 1339 //simple 32bit reg copying zeros high bits in 64bit reg 1340 {OpcodeInfo::em64t, {0x8B, _r}, {r64, r_m32u}, D_U }, 1341 END_OPCODES() 1342 END_MNEMONIC() 1343 1344 BEGIN_MNEMONIC(MULSD, MF_NONE, DU_U) 1345 BEGIN_OPCODES() 1346 {OpcodeInfo::all, {0xF2, 0x0F, 0x59, _r}, {xmm64, xmm_m64}, DU_U }, 1347 END_OPCODES() 1348 END_MNEMONIC() 1349 1350 BEGIN_MNEMONIC(MULSS, MF_NONE, DU_U) 1351 BEGIN_OPCODES() 1352 {OpcodeInfo::all, {0xF3, 0x0F, 0x59, _r}, {xmm32, xmm_m32}, DU_U }, 1353 END_OPCODES() 1354 END_MNEMONIC() 1355 1356 BEGIN_MNEMONIC(NEG, MF_AFFECTS_FLAGS, DU ) 1357 BEGIN_OPCODES() 1358 {OpcodeInfo::all, {0xF6, _3}, {r_m8}, DU }, 1359 1360 {OpcodeInfo::all, {Size16, 0xF7, _3}, {r_m16}, DU }, 1361 {OpcodeInfo::all, {0xF7, _3}, {r_m32}, DU }, 1362 {OpcodeInfo::em64t, {REX_W, 0xF7, _3}, {r_m64}, DU }, 1363 END_OPCODES() 1364 END_MNEMONIC() 1365 1366 BEGIN_MNEMONIC(NOP, MF_NONE, N) 1367 BEGIN_OPCODES() 1368 {OpcodeInfo::all, {0x90}, {}, N }, 1369 END_OPCODES() 1370 END_MNEMONIC() 1371 1372 BEGIN_MNEMONIC(NOT, MF_AFFECTS_FLAGS, DU ) 1373 BEGIN_OPCODES() 1374 {OpcodeInfo::all, {0xF6, _2}, {r_m8}, DU }, 1375 {OpcodeInfo::all, {Size16, 0xF7, _2}, {r_m16}, DU }, 1376 {OpcodeInfo::all, {0xF7, _2}, {r_m32}, DU }, 1377 {OpcodeInfo::em64t, {REX_W, 0xF7, _2}, {r_m64}, DU }, 1378 END_OPCODES() 1379 END_MNEMONIC() 1380 1381 BEGIN_MNEMONIC(POP, MF_NONE, D) 1382 BEGIN_OPCODES() 1383 {OpcodeInfo::all, {Size16, 0x8F, _0}, {r_m16}, D }, 1384 {OpcodeInfo::ia32, {0x8F, _0}, {r_m32}, D }, 1385 {OpcodeInfo::em64t, {0x8F, _0}, {r_m64}, D }, 1386 1387 {OpcodeInfo::all, {Size16, 0x58|rw }, {r16}, D }, 1388 {OpcodeInfo::ia32, {0x58|rd }, {r32}, D }, 1389 {OpcodeInfo::em64t, {0x58|rd }, {r64}, D }, 1390 END_OPCODES() 1391 END_MNEMONIC() 1392 1393 BEGIN_MNEMONIC(POPFD, MF_AFFECTS_FLAGS, N) 1394 BEGIN_OPCODES() 1395 {OpcodeInfo::all, {0x9D}, {}, N }, 1396 END_OPCODES() 1397 END_MNEMONIC() 1398 1399 BEGIN_MNEMONIC(PREFETCH, MF_NONE, U) 1400 BEGIN_OPCODES() 1401 {OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U }, 1402 END_OPCODES() 1403 END_MNEMONIC() 1404 1405 BEGIN_MNEMONIC(PUSH, MF_NONE, U ) 1406 BEGIN_OPCODES() 1407 {OpcodeInfo::all, {Size16, 0xFF, _6}, {r_m16}, U }, 1408 {OpcodeInfo::ia32, {0xFF, _6}, {r_m32}, U }, 1409 {OpcodeInfo::em64t, {0xFF, _6}, {r_m64}, U }, 1410 1411 {OpcodeInfo::all, {Size16, 0x50|rw }, {r16}, U }, 1412 {OpcodeInfo::ia32, {0x50|rd }, {r32}, U }, 1413 {OpcodeInfo::em64t, {0x50|rd }, {r64}, U }, 1414 1415 {OpcodeInfo::all, {0x6A}, {imm8}, U }, 1416 {OpcodeInfo::all, {Size16, 0x68}, {imm16}, U }, 1417 {OpcodeInfo::ia32, {0x68}, {imm32}, U }, 1418 // {OpcodeInfo::em64t, {0x68}, {imm64}, U }, 1419 END_OPCODES() 1420 END_MNEMONIC() 1421 1422 BEGIN_MNEMONIC(PUSHFD, MF_USES_FLAGS, N) 1423 BEGIN_OPCODES() 1424 {OpcodeInfo::all, {0x9C}, {}, N }, 1425 END_OPCODES() 1426 END_MNEMONIC() 1427 1428 1429 BEGIN_MNEMONIC(RET, MF_NONE, N) 1430 BEGIN_OPCODES() 1431 {OpcodeInfo::all, {0xC3}, {}, N }, 1432 {OpcodeInfo::all, {0xC2, iw}, {imm16}, U }, 1433 END_OPCODES() 1434 END_MNEMONIC() 1435 1436 #define DEFINE_SETcc_MNEMONIC( cc ) \ 1437 BEGIN_MNEMONIC(SET##cc, MF_USES_FLAGS|MF_CONDITIONAL, DU) \ 1438 BEGIN_OPCODES() \ 1439 {OpcodeInfo::all, {0x0F, 0x90 + ConditionMnemonic_##cc}, {r_m8}, DU }, \ 1440 END_OPCODES() \ 1441 END_MNEMONIC() 1442 1443 DEFINE_SETcc_MNEMONIC(O) 1444 DEFINE_SETcc_MNEMONIC(NO) 1445 DEFINE_SETcc_MNEMONIC(B) 1446 DEFINE_SETcc_MNEMONIC(NB) 1447 DEFINE_SETcc_MNEMONIC(Z) 1448 DEFINE_SETcc_MNEMONIC(NZ) 1449 DEFINE_SETcc_MNEMONIC(BE) 1450 DEFINE_SETcc_MNEMONIC(NBE) 1451 1452 DEFINE_SETcc_MNEMONIC(S) 1453 DEFINE_SETcc_MNEMONIC(NS) 1454 DEFINE_SETcc_MNEMONIC(P) 1455 DEFINE_SETcc_MNEMONIC(NP) 1456 DEFINE_SETcc_MNEMONIC(L) 1457 DEFINE_SETcc_MNEMONIC(NL) 1458 DEFINE_SETcc_MNEMONIC(LE) 1459 DEFINE_SETcc_MNEMONIC(NLE) 1460 1461 #undef DEFINE_SETcc_MNEMONIC 1462 1463 #define DEFINE_SHIFT_MNEMONIC(nam, slash_num, flags) \ 1464 BEGIN_MNEMONIC(nam, flags, DU_U) \ 1465 BEGIN_OPCODES()\ 1466 /* D0 & D1 opcodes are added w/o 2nd operand (1) because */\ 1467 /* they are used for decoding only so only instruction length is needed */\ 1468 {OpcodeInfo::decoder, {0xD0, slash_num}, {r_m8/*,const_1*/}, DU },\ 1469 {OpcodeInfo::all, {0xD2, slash_num}, {r_m8, CL}, DU_U },\ 1470 {OpcodeInfo::all, {0xC0, slash_num, ib}, {r_m8, imm8}, DU_U },\ 1471 \ 1472 {OpcodeInfo::decoder, {Size16, 0xD1, slash_num}, {r_m16/*,const_1*/}, DU },\ 1473 {OpcodeInfo::all, {Size16, 0xD3, slash_num}, {r_m16, CL}, DU_U },\ 1474 {OpcodeInfo::all, {Size16, 0xC1, slash_num, ib}, {r_m16, imm8 }, DU_U },\ 1475 \ 1476 {OpcodeInfo::decoder, {0xD1, slash_num}, {r_m32/*,const_1*/}, DU },\ 1477 {OpcodeInfo::decoder64, {REX_W, 0xD1, slash_num}, {r_m64/*,const_1*/}, DU },\ 1478 \ 1479 {OpcodeInfo::all, {0xD3, slash_num}, {r_m32, CL}, DU_U },\ 1480 {OpcodeInfo::em64t, {REX_W, 0xD3, slash_num}, {r_m64, CL}, DU_U },\ 1481 \ 1482 {OpcodeInfo::all, {0xC1, slash_num, ib}, {r_m32, imm8}, DU_U },\ 1483 {OpcodeInfo::em64t, {REX_W, 0xC1, slash_num, ib}, {r_m64, imm8}, DU_U },\ 1484 END_OPCODES()\ 1485 END_MNEMONIC() 1486 1487 1488 DEFINE_SHIFT_MNEMONIC(ROL, _0, MF_AFFECTS_FLAGS) 1489 DEFINE_SHIFT_MNEMONIC(ROR, _1, MF_AFFECTS_FLAGS) 1490 DEFINE_SHIFT_MNEMONIC(RCL, _2, MF_AFFECTS_FLAGS|MF_USES_FLAGS) 1491 DEFINE_SHIFT_MNEMONIC(RCR, _3, MF_AFFECTS_FLAGS|MF_USES_FLAGS) 1492 1493 DEFINE_SHIFT_MNEMONIC(SAL, _4, MF_AFFECTS_FLAGS) 1494 DEFINE_SHIFT_MNEMONIC(SHR, _5, MF_AFFECTS_FLAGS) 1495 DEFINE_SHIFT_MNEMONIC(SAR, _7, MF_AFFECTS_FLAGS) 1496 1497 #undef DEFINE_SHIFT_MNEMONIC 1498 1499 BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N) 1500 BEGIN_OPCODES() 1501 {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, CL}, DU_DU_U }, 1502 {OpcodeInfo::all, {0x0F, 0xA4}, {r_m32, r32, imm8}, DU_DU_U }, 1503 END_OPCODES() 1504 END_MNEMONIC() 1505 1506 BEGIN_MNEMONIC(SHRD, MF_AFFECTS_FLAGS, N) 1507 // TODO: the def/use info is wrong 1508 BEGIN_OPCODES() 1509 {OpcodeInfo::all, {0x0F, 0xAD}, {r_m32, r32, CL}, DU_DU_U }, 1510 END_OPCODES() 1511 END_MNEMONIC() 1512 1513 1514 BEGIN_MNEMONIC(SUBSD, MF_NONE, DU_U) 1515 BEGIN_OPCODES() 1516 {OpcodeInfo::all, {0xF2, 0x0F, 0x5C, _r}, {xmm64, xmm_m64}, DU_U }, 1517 END_OPCODES() 1518 END_MNEMONIC() 1519 1520 BEGIN_MNEMONIC(SUBSS, MF_NONE, DU_U) 1521 BEGIN_OPCODES() 1522 {OpcodeInfo::all, {0xF3, 0x0F, 0x5C, _r}, {xmm32, xmm_m32}, DU_U }, 1523 END_OPCODES() 1524 END_MNEMONIC() 1525 1526 BEGIN_MNEMONIC(TEST, MF_AFFECTS_FLAGS, U_U) 1527 BEGIN_OPCODES() 1528 1529 {OpcodeInfo::decoder, {0xA8, ib}, { AL, imm8}, U_U }, 1530 {OpcodeInfo::decoder, {0xA9, iw}, { AX, imm16}, U_U }, 1531 {OpcodeInfo::decoder, {0xA9, id}, { EAX, imm32}, U_U }, 1532 {OpcodeInfo::decoder64, {REX_W, 0xA9, id}, { RAX, imm32s}, U_U }, 1533 1534 {OpcodeInfo::all, {0xF6, _0, ib}, {r_m8,imm8}, U_U }, 1535 1536 {OpcodeInfo::all, {Size16, 0xF7, _0, iw}, {r_m16,imm16}, U_U }, 1537 {OpcodeInfo::all, {0xF7, _0, id}, {r_m32,imm32}, U_U }, 1538 {OpcodeInfo::em64t, {REX_W, 0xF7, _0, id}, {r_m64,imm32s}, U_U }, 1539 1540 {OpcodeInfo::all, {0x84, _r}, {r_m8,r8}, U_U }, 1541 1542 {OpcodeInfo::all, {Size16, 0x85, _r}, {r_m16,r16}, U_U }, 1543 {OpcodeInfo::all, {0x85, _r}, {r_m32,r32}, U_U }, 1544 {OpcodeInfo::em64t, {REX_W, 0x85, _r}, {r_m64,r64}, U_U }, 1545 END_OPCODES() 1546 END_MNEMONIC() 1547 1548 1549 BEGIN_MNEMONIC(UCOMISD, MF_AFFECTS_FLAGS, U_U) 1550 BEGIN_OPCODES() 1551 {OpcodeInfo::all, {0x66, 0x0F, 0x2E, _r}, {xmm64, xmm_m64}, U_U }, 1552 END_OPCODES() 1553 END_MNEMONIC() 1554 1555 BEGIN_MNEMONIC(UCOMISS, MF_AFFECTS_FLAGS, U_U) 1556 BEGIN_OPCODES() 1557 {OpcodeInfo::all, {0x0F, 0x2E, _r}, {xmm32, xmm_m32}, U_U }, 1558 END_OPCODES() 1559 END_MNEMONIC() 1560 1561 BEGIN_MNEMONIC(COMISD, MF_AFFECTS_FLAGS, U_U) 1562 BEGIN_OPCODES() 1563 {OpcodeInfo::all, {0x66, 0x0F, 0x2F, _r}, {xmm64, xmm_m64}, U_U }, 1564 END_OPCODES() 1565 END_MNEMONIC() 1566 1567 BEGIN_MNEMONIC(COMISS, MF_AFFECTS_FLAGS, U_U) 1568 BEGIN_OPCODES() 1569 {OpcodeInfo::all, {0x0F, 0x2F, _r}, {xmm32, xmm_m32}, U_U }, 1570 END_OPCODES() 1571 END_MNEMONIC() 1572 1573 BEGIN_MNEMONIC(XORPD, MF_SAME_ARG_NO_USE|MF_SYMMETRIC, DU_U) 1574 BEGIN_OPCODES() 1575 //Note: they're actually 128 bits 1576 {OpcodeInfo::all, {0x66, 0x0F, 0x57, _r}, {xmm64, xmm_m64}, DU_U }, 1577 END_OPCODES() 1578 END_MNEMONIC() 1579 1580 BEGIN_MNEMONIC(XORPS, MF_SAME_ARG_NO_USE|MF_SYMMETRIC, DU_U) 1581 BEGIN_OPCODES() 1582 //Note: they're actually 128 bits 1583 {OpcodeInfo::all, {0x0F, 0x57, _r}, {xmm32, xmm_m32}, DU_U }, 1584 END_OPCODES() 1585 END_MNEMONIC() 1586 1587 BEGIN_MNEMONIC(CVTDQ2PD, MF_NONE, D_U ) 1588 BEGIN_OPCODES() 1589 //Note: they're actually 128 bits 1590 {OpcodeInfo::all, {0xF3, 0x0F, 0xE6}, {xmm64, xmm_m64}, D_U }, 1591 END_OPCODES() 1592 END_MNEMONIC() 1593 1594 BEGIN_MNEMONIC(CVTDQ2PS, MF_NONE, D_U ) 1595 BEGIN_OPCODES() 1596 //Note: they're actually 128 bits 1597 {OpcodeInfo::all, {0x0F, 0x5B, _r}, {xmm32, xmm_m32}, D_U }, 1598 END_OPCODES() 1599 END_MNEMONIC() 1600 1601 BEGIN_MNEMONIC(CVTTPD2DQ, MF_NONE, D_U ) 1602 BEGIN_OPCODES() 1603 //Note: they're actually 128 bits 1604 {OpcodeInfo::all, {0x66, 0x0F, 0xE6}, {xmm64, xmm_m64}, D_U }, 1605 END_OPCODES() 1606 END_MNEMONIC() 1607 1608 BEGIN_MNEMONIC(CVTTPS2DQ, MF_NONE, D_U ) 1609 BEGIN_OPCODES() 1610 //Note: they're actually 128 bits 1611 {OpcodeInfo::all, {0xF3, 0x0F, 0x5B, _r}, {xmm32, xmm_m32}, D_U }, 1612 END_OPCODES() 1613 END_MNEMONIC() 1614 1615 // 1616 // String operations 1617 // 1618 BEGIN_MNEMONIC(STD, MF_AFFECTS_FLAGS, N) 1619 BEGIN_OPCODES() 1620 {OpcodeInfo::all, {0xFD}, {}, N }, 1621 END_OPCODES() 1622 END_MNEMONIC() 1623 1624 BEGIN_MNEMONIC(CLD, MF_AFFECTS_FLAGS, N) 1625 BEGIN_OPCODES() 1626 {OpcodeInfo::all, {0xFC}, {}, N }, 1627 END_OPCODES() 1628 END_MNEMONIC() 1629 1630 BEGIN_MNEMONIC(SCAS, MF_AFFECTS_FLAGS, N) 1631 // to be symmetric, this mnemonic must have either m32 or RegName_EAX 1632 // but as long, as Jitrino's CG does not use the mnemonic, leaving it 1633 // in its natural form 1634 BEGIN_OPCODES() 1635 {OpcodeInfo::all, {0xAF}, {}, N }, 1636 END_OPCODES() 1637 END_MNEMONIC() 1638 1639 BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U) 1640 BEGIN_OPCODES() 1641 {OpcodeInfo::all, {0xAB}, {EDI, ECX, EAX}, DU_DU_U }, 1642 {OpcodeInfo::all, {0xAA}, {EDI, ECX, AL}, DU_DU_U }, 1643 {OpcodeInfo::em64t, {REX_W, 0xAB}, {RDI, RCX, RAX}, DU_DU_U }, 1644 END_OPCODES() 1645 END_MNEMONIC() 1646 1647 /* 1648 MOVS and CMPS are the special cases. 1649 Most the code in both CG and Encoder do not expect 2 memory operands. 1650 Also, they are not supposed to setup constrains on which register the 1651 memory reference must reside - m8,m8 or m32,m32 is not the choice. 1652 We can't use r8,r8 either - will have problem with 8bit EDI, ESI. 1653 So, as the workaround we do r32,r32 and specify size of the operand through 1654 the specific mnemonic - the same is in the codegen. 1655 */ 1656 BEGIN_MNEMONIC(MOVS8, MF_NONE, DU_DU_DU) 1657 BEGIN_OPCODES() 1658 {OpcodeInfo::ia32, {0xA4}, {r32,r32,ECX}, DU_DU_DU }, 1659 {OpcodeInfo::em64t, {0xA4}, {r64,r64,RCX}, DU_DU_DU }, 1660 END_OPCODES() 1661 END_MNEMONIC() 1662 1663 BEGIN_MNEMONIC(MOVS16, MF_NONE, DU_DU_DU) 1664 BEGIN_OPCODES() 1665 {OpcodeInfo::ia32, {Size16, 0xA5}, {r32,r32,ECX}, DU_DU_DU }, 1666 {OpcodeInfo::em64t, {Size16, 0xA5}, {r64,r64,RCX}, DU_DU_DU }, 1667 END_OPCODES() 1668 END_MNEMONIC() 1669 1670 BEGIN_MNEMONIC(MOVS32, MF_NONE, DU_DU_DU) 1671 BEGIN_OPCODES() 1672 {OpcodeInfo::ia32, {0xA5}, {r32,r32,ECX}, DU_DU_DU }, 1673 {OpcodeInfo::em64t, {0xA5}, {r64,r64,RCX}, DU_DU_DU }, 1674 END_OPCODES() 1675 END_MNEMONIC() 1676 1677 BEGIN_MNEMONIC(MOVS64, MF_NONE, DU_DU_DU) 1678 BEGIN_OPCODES() 1679 {OpcodeInfo::em64t, {REX_W,0xA5}, {r64,r64,RCX}, DU_DU_DU }, 1680 END_OPCODES() 1681 END_MNEMONIC() 1682 1683 BEGIN_MNEMONIC(CMPSB, MF_AFFECTS_FLAGS, DU_DU_DU) 1684 BEGIN_OPCODES() 1685 {OpcodeInfo::ia32, {0xA6}, {ESI,EDI,ECX}, DU_DU_DU }, 1686 {OpcodeInfo::em64t, {0xA6}, {RSI,RDI,RCX}, DU_DU_DU }, 1687 END_OPCODES() 1688 END_MNEMONIC() 1689 1690 BEGIN_MNEMONIC(CMPSW, MF_AFFECTS_FLAGS, DU_DU_DU) 1691 BEGIN_OPCODES() 1692 {OpcodeInfo::ia32, {Size16, 0xA7}, {ESI,EDI,ECX}, DU_DU_DU }, 1693 {OpcodeInfo::em64t, {Size16, 0xA7}, {RSI,RDI,RCX}, DU_DU_DU }, 1694 END_OPCODES() 1695 END_MNEMONIC() 1696 1697 BEGIN_MNEMONIC(CMPSD, MF_AFFECTS_FLAGS, DU_DU_DU) 1698 BEGIN_OPCODES() 1699 {OpcodeInfo::ia32, {0xA7}, {ESI,EDI,ECX}, DU_DU_DU }, 1700 {OpcodeInfo::em64t, {0xA7}, {RSI,RDI,RCX}, DU_DU_DU }, 1701 END_OPCODES() 1702 END_MNEMONIC() 1703 1704 1705 BEGIN_MNEMONIC(WAIT, MF_AFFECTS_FLAGS, N) 1706 BEGIN_OPCODES() 1707 {OpcodeInfo::all, {0x9B}, {}, N }, 1708 END_OPCODES() 1709 END_MNEMONIC() 1710 1711 // 1712 // ~String operations 1713 // 1714 1715 // 1716 //Note: the instructions below added for the sake of disassembling routine. 1717 // They need to have flags, params and params usage to be defined more precisely. 1718 // 1719 BEGIN_MNEMONIC(LEAVE, MF_NONE, N) 1720 BEGIN_OPCODES() 1721 {OpcodeInfo::decoder, {0xC9}, {}, N }, 1722 END_OPCODES() 1723 END_MNEMONIC() 1724 1725 BEGIN_MNEMONIC(ENTER, MF_NONE, N) 1726 BEGIN_OPCODES() 1727 {OpcodeInfo::decoder, {0xC8, iw, ib}, {imm16, imm8}, N }, 1728 END_OPCODES() 1729 END_MNEMONIC() 1730 1731 }; // ~masterEncodingTable[] 1732 1733 ENCODER_NAMESPACE_END 1734 1735 //#include <algorithm> 1736 1737 ENCODER_NAMESPACE_START 1738 1739 static bool mnemonic_info_comparator(const MnemonicInfo& one, 1740 const MnemonicInfo& two) 1741 { 1742 return one.mn < two.mn; 1743 } 1744 1745 1746 static int compareMnemonicInfo(const void* info1, const void* info2) 1747 { 1748 Mnemonic id1, id2; 1749 1750 id1 = ((const MnemonicInfo*) info1)->mn; 1751 id2 = ((const MnemonicInfo*) info2)->mn; 1752 if (id1 < id2) 1753 return -1; 1754 if (id1 > id2) 1755 return 1; 1756 return 0; 1757 } 1758 1759 int EncoderBase::buildTable(void) 1760 { 1761 // A check: all mnemonics must be covered 1762 assert(COUNTOF(masterEncodingTable) == Mnemonic_Count); 1763 // sort out the mnemonics so the list become ordered 1764 #if 0 //Android x86 1765 std::sort(masterEncodingTable, masterEncodingTable+Mnemonic_Count, 1766 mnemonic_info_comparator); 1767 #else 1768 qsort(masterEncodingTable, Mnemonic_Count, sizeof(MnemonicInfo), compareMnemonicInfo); 1769 #endif 1770 // 1771 // clear the things 1772 // 1773 memset(opcodesHashMap, NOHASH, sizeof(opcodesHashMap)); 1774 memset(opcodes, 0, sizeof(opcodes)); 1775 // 1776 // and, finally, build it 1777 for (unsigned i=0; i<Mnemonic_Count; i++) { 1778 assert((Mnemonic)i == (masterEncodingTable + i)->mn); 1779 buildMnemonicDesc(masterEncodingTable+i); 1780 } 1781 return 0; 1782 } 1783 1784 void EncoderBase::buildMnemonicDesc(const MnemonicInfo * minfo) 1785 { 1786 MnemonicDesc& mdesc = mnemonics[minfo->mn]; 1787 mdesc.mn = minfo->mn; 1788 mdesc.flags = minfo->flags; 1789 mdesc.roles = minfo->roles; 1790 mdesc.name = minfo->name; 1791 1792 // 1793 // fill the used opcodes 1794 // 1795 for (unsigned i=0, oindex=0; i<COUNTOF(minfo->opcodes); i++) { 1796 1797 const OpcodeInfo& oinfo = minfo->opcodes[i]; 1798 OpcodeDesc& odesc = opcodes[minfo->mn][oindex]; 1799 // last opcode ? 1800 if (oinfo.opcode[0] == OpcodeByteKind_LAST) { 1801 // mark the opcode 'last', exit 1802 odesc.opcode_len = 0; 1803 odesc.last = 1; 1804 break; 1805 } 1806 odesc.last = 0; 1807 #ifdef _EM64T_ 1808 if (oinfo.platf == OpcodeInfo::ia32) { continue; } 1809 if (oinfo.platf == OpcodeInfo::decoder32) { continue; } 1810 #else 1811 if (oinfo.platf == OpcodeInfo::em64t) { continue; } 1812 if (oinfo.platf == OpcodeInfo::decoder64) { continue; } 1813 #endif 1814 if (oinfo.platf == OpcodeInfo::decoder64 || 1815 oinfo.platf == OpcodeInfo::decoder32) { 1816 odesc.platf = OpcodeInfo::decoder; 1817 } 1818 else { 1819 odesc.platf = (char)oinfo.platf; 1820 } 1821 // 1822 // fill out opcodes 1823 // 1824 unsigned j = 0; 1825 odesc.opcode_len = 0; 1826 for(; oinfo.opcode[j]; j++) { 1827 unsigned opcod = oinfo.opcode[j]; 1828 unsigned kind = opcod&OpcodeByteKind_KindMask; 1829 if (kind == OpcodeByteKind_REX_W) { 1830 odesc.opcode[odesc.opcode_len++] = (unsigned char)0x48; 1831 continue; 1832 } 1833 else if(kind != 0 && kind != OpcodeByteKind_ZeroOpcodeByte) { 1834 break; 1835 } 1836 unsigned lowByte = (opcod & OpcodeByteKind_OpcodeMask); 1837 odesc.opcode[odesc.opcode_len++] = (unsigned char)lowByte; 1838 } 1839 assert(odesc.opcode_len<5); 1840 odesc.aux0 = odesc.aux1 = 0; 1841 if (oinfo.opcode[j] != 0) { 1842 odesc.aux0 = oinfo.opcode[j]; 1843 assert((odesc.aux0 & OpcodeByteKind_KindMask) != 0); 1844 ++j; 1845 if(oinfo.opcode[j] != 0) { 1846 odesc.aux1 = oinfo.opcode[j]; 1847 assert((odesc.aux1 & OpcodeByteKind_KindMask) != 0); 1848 } 1849 } 1850 else if (oinfo.roles.count>=2) { 1851 if (((oinfo.opnds[0].kind&OpndKind_Mem) && 1852 (isRegKind(oinfo.opnds[1].kind))) || 1853 ((oinfo.opnds[1].kind&OpndKind_Mem) && 1854 (isRegKind(oinfo.opnds[0].kind)))) { 1855 // Example: MOVQ xmm1, xmm/m64 has only opcodes 1856 // same with SHRD 1857 // Adding fake /r 1858 odesc.aux0 = _r; 1859 } 1860 } 1861 else if (oinfo.roles.count==1) { 1862 if (oinfo.opnds[0].kind&OpndKind_Mem) { 1863 // Example: SETcc r/m8, adding fake /0 1864 odesc.aux0 = _0; 1865 } 1866 } 1867 // check imm 1868 if (oinfo.roles.count > 0 && 1869 (oinfo.opnds[0].kind == OpndKind_Imm || 1870 oinfo.opnds[oinfo.roles.count-1].kind == OpndKind_Imm)) { 1871 // Example: CALL cd, PUSH imm32 - they fit both opnds[0] and 1872 // opnds[oinfo.roles.count-1]. 1873 // The A3 opcode fits only opnds[0] - it's currently have 1874 // MOV imm32, EAX. Looks ridiculous, but this is how the 1875 // moffset is currently implemented. Will need to fix together 1876 // with other usages of moff. 1877 // adding fake /cd or fake /id 1878 unsigned imm_opnd_index = 1879 oinfo.opnds[0].kind == OpndKind_Imm ? 0 : oinfo.roles.count-1; 1880 OpndSize sz = oinfo.opnds[imm_opnd_index].size; 1881 unsigned imm_encode, coff_encode; 1882 if (sz==OpndSize_8) {imm_encode = ib; coff_encode=cb; } 1883 else if (sz==OpndSize_16) {imm_encode = iw; coff_encode=cw;} 1884 else if (sz==OpndSize_32) {imm_encode = id; coff_encode=cd; } 1885 else if (sz==OpndSize_64) {imm_encode = io; coff_encode=0xCC; } 1886 else { assert(false); imm_encode=0xCC; coff_encode=0xCC; } 1887 if (odesc.aux1 == 0) { 1888 if (odesc.aux0==0) { 1889 odesc.aux0 = imm_encode; 1890 } 1891 else { 1892 if (odesc.aux0 != imm_encode && odesc.aux0 != coff_encode) { 1893 odesc.aux1 = imm_encode; 1894 } 1895 } 1896 } 1897 else { 1898 assert(odesc.aux1==imm_encode); 1899 } 1900 1901 } 1902 1903 assert(sizeof(odesc.opnds) == sizeof(oinfo.opnds)); 1904 memcpy(odesc.opnds, oinfo.opnds, sizeof(odesc.opnds)); 1905 odesc.roles = oinfo.roles; 1906 odesc.first_opnd = 0; 1907 if (odesc.opnds[0].reg != RegName_Null) { 1908 ++odesc.first_opnd; 1909 if (odesc.opnds[1].reg != RegName_Null) { 1910 ++odesc.first_opnd; 1911 } 1912 } 1913 1914 if (odesc.platf == OpcodeInfo::decoder) { 1915 // if the opcode is only for decoding info, then do not hash it. 1916 ++oindex; 1917 continue; 1918 } 1919 1920 // 1921 // check whether the operand info is a mask (i.e. r_m*). 1922 // in this case, split the info to have separate entries for 'r' 1923 // and for 'm'. 1924 // the good news is that there can be only one such operand. 1925 // 1926 int opnd2split = -1; 1927 for (unsigned k=0; k<oinfo.roles.count; k++) { 1928 if ((oinfo.opnds[k].kind & OpndKind_Mem) && 1929 (OpndKind_Mem != oinfo.opnds[k].kind)) { 1930 opnd2split = k; 1931 break; 1932 } 1933 }; 1934 1935 if (opnd2split == -1) { 1936 // not a mask, hash it, store it, continue. 1937 unsigned short hash = getHash(&oinfo); 1938 opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex; 1939 ++oindex; 1940 continue; 1941 }; 1942 1943 OpcodeInfo storeItem = oinfo; 1944 unsigned short hash; 1945 1946 // remove the memory part of the mask, and store only 'r' part 1947 storeItem.opnds[opnd2split].kind = (OpndKind)(storeItem.opnds[opnd2split].kind & ~OpndKind_Mem); 1948 hash = getHash(&storeItem); 1949 if (opcodesHashMap[minfo->mn][hash] == NOHASH) { 1950 opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex; 1951 } 1952 // else { 1953 // do not overwrite if there is something there, just check that operands match 1954 // the reason is that for some instructions there are several possibilities: 1955 // say 'DEC r' may be encode as either '48+r' or 'FF /1', and I believe 1956 // the first one is better for 'dec r'. 1957 // as we're currently processing an opcode with memory part in operand, 1958 // leave already filled items intact, so if there is 'OP reg' there, this 1959 // better choice will be left in the table instead of 'OP r_m' 1960 // } 1961 1962 // compute hash of memory-based operand, 'm' part in 'r_m' 1963 storeItem.opnds[opnd2split].kind = OpndKind_Mem; 1964 hash = getHash(&storeItem); 1965 // should not happen: for the r_m opcodes, there is a possibility 1966 // that hash value of 'r' part intersects with 'OP r' value, but it's 1967 // impossible for 'm' part. 1968 assert(opcodesHashMap[minfo->mn][hash] == NOHASH); 1969 opcodesHashMap[minfo->mn][hash] = (unsigned char)oindex; 1970 1971 ++oindex; 1972 } 1973 } 1974 1975 ENCODER_NAMESPACE_END 1976