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
getHash(const OpcodeInfo * odesc)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
mnemonic_info_comparator(const MnemonicInfo & one,const MnemonicInfo & two)1739 static bool mnemonic_info_comparator(const MnemonicInfo& one,
1740 const MnemonicInfo& two)
1741 {
1742 return one.mn < two.mn;
1743 }
1744
1745
compareMnemonicInfo(const void * info1,const void * info2)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
buildTable(void)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
buildMnemonicDesc(const MnemonicInfo * minfo)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