GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 1.4% 28 / 0 / 1933
Functions: 5.2% 25 / 0 / 485
Branches: 0.0% 0 / 0 / 2758

filters/exprfilter/jitasm.h
Line Branch Exec Source
1 // Copyright (c) 2009-2011, Hikaru Inoue, Akihiro Yamasaki,
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following
12 // disclaimer in the documentation and/or other materials provided
13 // with the distribution.
14 // * The names of the contributors may not be used to endorse or promote
15 // products derived from this software without specific prior written
16 // permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Changes 2017 by pinterf
31 // - AVX friendly prolog/epilog with vzeroupper
32 // - Aligned stack slots for ymm spill variables
33 // - VEX encoded aligned store and load for temporary xmm/ymm registers
34 // - Fix: false codegen when rearranging multiple working registers in MoveGenerator by
35 // tracking real register usage for an xchg sequence
36
37 #include <stdint.h>
38
39 #pragma once
40 #ifndef JITASM_H
41 #define JITASM_H
42
43 #if defined(_WIN32)
44 #define JITASM_WIN // Windows
45 #endif
46
47 #if (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || defined(__x86_64__)
48 #define JITASM64
49 #endif
50
51 #if defined(__GNUC__)
52 #define JITASM_GCC
53 #endif
54
55 #if !defined(JITASM_MMINTRIN)
56 #if !defined(__GNUC__) || defined(__MMX__)
57 #define JITASM_MMINTRIN 1
58 #else
59 #define JITASM_MMINTRIN 0
60 #endif
61 #endif
62 #if !defined(JITASM_XMMINTRIN)
63 #if !defined(__GNUC__) || defined(__SSE__)
64 #define JITASM_XMMINTRIN 1
65 #else
66 #define JITASM_XMMINTRIN 0
67 #endif
68 #endif
69 #if !defined(JITASM_EMMINTRIN)
70 #if !defined(__GNUC__) || defined(__SSE2__)
71 #define JITASM_EMMINTRIN 1
72 #else
73 #define JITASM_EMMINTRIN 0
74 #endif
75 #endif
76
77
78 #include <string>
79 #include <deque>
80 #include <vector>
81 #include <map>
82 #include <algorithm>
83 #include <string.h>
84
85 #if defined(JITASM_WIN)
86 #include <windows.h>
87 #else
88 #include <unistd.h>
89 #include <sys/types.h>
90 #include <sys/mman.h>
91 #endif
92
93 #if JITASM_MMINTRIN
94 #include <mmintrin.h>
95 #endif
96 #if JITASM_XMMINTRIN
97 #include <xmmintrin.h>
98 #endif
99 #if JITASM_EMMINTRIN
100 #include <emmintrin.h>
101 #endif
102
103 #if _MSC_VER >= 1400 // VC8 or later
104 #include <intrin.h>
105 #endif
106
107 #if defined(JITASM_GCC)
108 #define JITASM_ATTRIBUTE_WEAK
109 // #define JITASM_ATTRIBUTE_WEAK __attribute__((weak))
110 // PF 20211013 remark, intentionally kept here:
111 // Do not use weak attribute! GCC Bug?
112 // With weak attributes mingw64 g++ 10.3 will miss a few initializations of structs during DLL load,
113 // for example these initializations will never be called(!):
114 // Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b = Reg8(R8B);
115 // YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8 = YmmReg(YMM8);
116 // (list not complete).
117 // But most horribly: after
118 // Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D);
119 // but before
120 // Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D);
121 // it will overwrite some other, already initialized variable areas at a totally different
122 // memory space, some hundred bytes before.
123 // Anyway, 'weak' is probably not needed, in ExprFilter use case we do not want a different
124 // implementations of these functions.
125 #elif defined(_MSC_VER)
126 #define JITASM_ATTRIBUTE_WEAK __declspec(selectany)
127 #else
128 #define JITASM_ATTRIBUTE_WEAK
129 #endif
130
131 #if defined(_MSC_VER)
132 #pragma warning( push )
133 #pragma warning( disable : 4127 ) // conditional expression is constant.
134 #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union
135 #endif
136
137 #if defined(JITASM_GCC)
138 #pragma GCC diagnostic ignored "-Wignored-attributes"
139 #endif
140
141 #ifdef ASSERT
142 #define JITASM_ASSERT ASSERT
143 #else
144 #include <assert.h>
145 #define JITASM_ASSERT assert
146 #endif
147
148 //#define JITASM_DEBUG_DUMP
149 #ifdef JITASM_DEBUG_DUMP
150 #include <stdio.h>
151 #if defined(JITASM_GCC)
152 #define JITASM_TRACE printf
153 #else
154 #define JITASM_TRACE jitasm::detail::Trace
155 #endif
156 #elif defined(JITASM_GCC)
157 #define JITASM_TRACE(...) ((void)0)
158 #else
159 #define JITASM_TRACE __noop
160 #endif
161
162 namespace jitasm
163 {
164
165 typedef signed char sint8;
166 typedef signed short sint16;
167 typedef signed int sint32;
168 typedef unsigned char uint8;
169 typedef unsigned short uint16;
170 typedef unsigned int uint32;
171 #if defined(JITASM_GCC)
172 typedef signed long long sint64;
173 typedef unsigned long long uint64;
174 #else
175 typedef signed __int64 sint64;
176 typedef unsigned __int64 uint64;
177 #endif
178
179 template<typename T> inline void avoid_unused_warn(const T&) {}
180
181 namespace detail
182 {
183 #if defined(JITASM_GCC)
184 inline long interlocked_increment(long *addend) { return __sync_add_and_fetch(addend, 1); }
185 inline long interlocked_decrement(long *addend) { return __sync_sub_and_fetch(addend, 1); }
186 inline long interlocked_exchange(long *target, long value) { return __sync_lock_test_and_set(target, value); }
187 #elif defined(JITASM_WIN)
188 inline long interlocked_increment(long *addend) { return _InterlockedIncrement(addend); }
189 inline long interlocked_decrement(long *addend) { return _InterlockedDecrement(addend); }
190 inline long interlocked_exchange(long *target, long value) { return _InterlockedExchange(target, value); }
191 #endif
192 } // namespace detail
193
194 /// Physical register ID
195 enum PhysicalRegID
196 {
197 INVALID=0x0FFFFFFF,
198 EAX=0, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D,
199 AL=0, CL, DL, BL, AH, CH, DH, BH, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B,
200 AX=0, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W,
201 RAX=0, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15,
202 ST0=0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
203 MM0=0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
204 XMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
205 YMM0=0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,
206 };
207
208 enum
209 {
210 /** \var NUM_OF_PHYSICAL_REG
211 * Number of physical register
212 */
213 /** \var SIZE_OF_GP_REG
214 * Size of general-purpose register
215 */
216 #ifdef JITASM64
217 NUM_OF_PHYSICAL_REG = 16,
218 SIZE_OF_GP_REG = 8
219 #else
220 NUM_OF_PHYSICAL_REG = 8,
221 SIZE_OF_GP_REG = 4
222 #endif
223 };
224
225 /// Register type
226 enum RegType
227 {
228 R_TYPE_GP, ///< General purpose register
229 R_TYPE_MMX, ///< MMX register
230 R_TYPE_XMM, ///< XMM register
231 R_TYPE_YMM, ///< YMM register
232 R_TYPE_FPU, ///< FPU register
233 R_TYPE_SYMBOLIC_GP, ///< Symbolic general purpose register
234 R_TYPE_SYMBOLIC_MMX, ///< Symbolic MMX register
235 R_TYPE_SYMBOLIC_XMM, ///< Symbolic XMM register
236 R_TYPE_SYMBOLIC_YMM ///< Symbolic YMM register
237 };
238
239 /// Register identifier
240 struct RegID
241 {
242 unsigned type : 4; // RegType
243 unsigned id : 28; ///< PhysicalRegID or symbolic register id
244
245 bool operator==(const RegID& rhs) const {return type == rhs.type && id == rhs.id;}
246 bool operator!=(const RegID& rhs) const {return !(*this == rhs);}
247 bool operator<(const RegID& rhs) const {return type != rhs.type ? type < rhs.type : id < rhs.id;}
248 bool IsInvalid() const {return type == R_TYPE_GP && id == INVALID;}
249 bool IsSymbolic() const {return type == R_TYPE_SYMBOLIC_GP || type == R_TYPE_SYMBOLIC_MMX || type == R_TYPE_SYMBOLIC_XMM || type == R_TYPE_SYMBOLIC_YMM;}
250 RegType GetType() const {return static_cast<RegType>(type);}
251
252 static RegID Invalid() {
253 RegID reg;
254 reg.type = R_TYPE_GP;
255 reg.id = INVALID;
256 return reg;
257 }
258 133800 static RegID CreatePhysicalRegID(RegType type_, PhysicalRegID id_) {
259 RegID reg;
260 133800 reg.type = type_;
261 133800 reg.id = id_;
262 133800 return reg;
263 }
264 static RegID CreateSymbolicRegID(RegType type_) {
265 static long s_id = 0;
266 RegID reg;
267 reg.type = type_;
268 reg.id = static_cast<unsigned>(detail::interlocked_increment(&s_id));
269 return reg;
270 }
271 };
272
273 /// Operand type
274 enum OpdType
275 {
276 O_TYPE_NONE,
277 O_TYPE_REG,
278 O_TYPE_MEM,
279 O_TYPE_IMM,
280 O_TYPE_TYPE_MASK = 0x03,
281
282 O_TYPE_DUMMY = 1 << 2, ///< The operand which has this flag is not encoded. This is for register allocator.
283 O_TYPE_READ = 1 << 3, ///< The operand is used for reading.
284 O_TYPE_WRITE = 1 << 4 ///< The operand is used for writing.
285 };
286
287 /// Operand size
288 enum OpdSize
289 {
290 O_SIZE_8,
291 O_SIZE_16,
292 O_SIZE_32,
293 O_SIZE_64,
294 O_SIZE_80,
295 O_SIZE_128,
296 O_SIZE_224,
297 O_SIZE_256,
298 O_SIZE_864,
299 O_SIZE_4096
300 };
301
302 namespace detail
303 {
304 #pragma pack(push, 1)
305
306 /// Operand base class
307 struct Opd
308 {
309 uint8 opdtype_; // OpdType
310 uint8 opdsize_; // OpdSize
311
312 union {
313 // REG
314 struct {
315 RegID reg_;
316 uint32 reg_assignable_;
317 };
318 // MEM
319 struct {
320 RegID base_;
321 RegID index_;
322 sint64 scale_;
323 sint64 disp_;
324 uint8 base_size_ : 4; // OpdSize
325 uint8 index_size_ : 4; // OpdSize
326 };
327 // IMM
328 sint64 imm_;
329 };
330
331 /// NONE
332 Opd() : opdtype_(O_TYPE_NONE) {}
333 /// REG
334 133800 Opd(OpdSize opdsize, const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : opdtype_(O_TYPE_REG), opdsize_(static_cast<uint8>(opdsize)), reg_(reg), reg_assignable_(reg_assignable) {}
335 /// MEM
336 Opd(OpdSize opdsize, OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp)
337 : opdtype_(O_TYPE_MEM), opdsize_(static_cast<uint8>(opdsize)), base_(base), index_(index), scale_(scale), disp_(disp), base_size_(static_cast<uint8>(base_size)), index_size_(static_cast<uint8>(index_size)) {}
338 protected:
339 /// IMM
340 explicit Opd(OpdSize opdsize, sint64 imm) : opdtype_(O_TYPE_IMM), opdsize_(static_cast<uint8>(opdsize)), imm_(imm) {}
341
342 public:
343 bool IsNone() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_NONE;}
344 bool IsReg() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_REG;}
345 bool IsGpReg() const {return IsReg() && (reg_.type == R_TYPE_GP || reg_.type == R_TYPE_SYMBOLIC_GP);}
346 bool IsFpuReg() const {return IsReg() && reg_.type == R_TYPE_FPU;}
347 bool IsMmxReg() const {return IsReg() && (reg_.type == R_TYPE_MMX || reg_.type == R_TYPE_SYMBOLIC_MMX);}
348 bool IsXmmReg() const {return IsReg() && (reg_.type == R_TYPE_XMM || reg_.type == R_TYPE_SYMBOLIC_XMM);}
349 bool IsYmmReg() const {return IsReg() && (reg_.type == R_TYPE_YMM || reg_.type == R_TYPE_SYMBOLIC_YMM);}
350 bool IsMem() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_MEM;}
351 bool IsImm() const {return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_IMM;}
352 bool IsDummy() const {return (opdtype_ & O_TYPE_DUMMY) != 0;}
353 bool IsRead() const {return (opdtype_ & O_TYPE_READ) != 0;}
354 bool IsWrite() const {return (opdtype_ & O_TYPE_WRITE) != 0;}
355
356 OpdType GetType() const {return static_cast<OpdType>(opdtype_);}
357 OpdSize GetSize() const {return static_cast<OpdSize>(opdsize_);}
358 OpdSize GetAddressBaseSize() const {return static_cast<OpdSize>(base_size_);}
359 OpdSize GetAddressIndexSize() const {return static_cast<OpdSize>(index_size_);}
360 RegID GetReg() const {JITASM_ASSERT(IsReg()); return reg_;}
361 RegID GetBase() const {JITASM_ASSERT(IsMem()); return base_;}
362 RegID GetIndex() const {JITASM_ASSERT(IsMem()); return index_;}
363 sint64 GetScale() const {JITASM_ASSERT(IsMem()); return scale_;}
364 sint64 GetDisp() const {JITASM_ASSERT(IsMem()); return disp_;}
365 sint64 GetImm() const {JITASM_ASSERT(IsImm()); return imm_;}
366
367 bool operator==(const Opd& rhs) const
368 {
369 if ((opdtype_ & O_TYPE_TYPE_MASK) != (rhs.opdtype_ & O_TYPE_TYPE_MASK) || opdsize_ != rhs.opdsize_) {return false;}
370 if (IsReg()) {return reg_ == rhs.reg_ && reg_assignable_ == rhs.reg_assignable_;}
371 if (IsMem()) {return base_ == rhs.base_ && index_ == rhs.index_ && scale_ == rhs.scale_ && disp_ == rhs.disp_ && base_size_ == rhs.base_size_ && index_size_ == rhs.index_size_;}
372 if (IsImm()) {return imm_ == rhs.imm_;}
373 return true;
374 }
375 bool operator!=(const Opd& rhs) const {return !(*this == rhs);}
376 };
377
378 #pragma pack(pop)
379
380 /// Add O_TYPE_DUMMY to the specified operand
381 inline Opd Dummy(const Opd& opd)
382 {
383 Opd o(opd);
384 o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY);
385 return o;
386 }
387
388 /// Add O_TYPE_DUMMY to the specified operand and constraint of register assignment
389 inline Opd Dummy(const Opd& opd, const Opd& constraint)
390 {
391 JITASM_ASSERT(opd.IsReg() && (opd.opdtype_ & O_TYPE_TYPE_MASK) == (constraint.opdtype_ & O_TYPE_TYPE_MASK) && !constraint.GetReg().IsSymbolic());
392 Opd o(opd);
393 o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY);
394 o.reg_assignable_ = (1 << constraint.reg_.id);
395 return o;
396 }
397
398 /// Add O_TYPE_READ to the specified operand
399 inline Opd R(const Opd& opd)
400 {
401 Opd o(opd);
402 o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ);
403 return o;
404 }
405
406 /// Add O_TYPE_WRITE to the specified operand
407 inline Opd W(const Opd& opd)
408 {
409 Opd o(opd);
410 o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_WRITE);
411 return o;
412 }
413
414 /// Add O_TYPE_READ | O_TYPE_WRITE to the specified operand
415 inline Opd RW(const Opd& opd)
416 {
417 Opd o(opd);
418 o.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ | O_TYPE_WRITE);
419 return o;
420 }
421
422 template<int Size> inline OpdSize ToOpdSize();
423 17840 template<> inline OpdSize ToOpdSize<8>() {return O_SIZE_8;}
424 17840 template<> inline OpdSize ToOpdSize<16>() {return O_SIZE_16;}
425 17840 template<> inline OpdSize ToOpdSize<32>() {return O_SIZE_32;}
426 35680 template<> inline OpdSize ToOpdSize<64>() {return O_SIZE_64;}
427 8920 template<> inline OpdSize ToOpdSize<80>() {return O_SIZE_80;}
428 17840 template<> inline OpdSize ToOpdSize<128>() {return O_SIZE_128;}
429 template<> inline OpdSize ToOpdSize<224>() {return O_SIZE_224;}
430 17840 template<> inline OpdSize ToOpdSize<256>() {return O_SIZE_256;}
431 template<> inline OpdSize ToOpdSize<864>() {return O_SIZE_864;}
432 template<> inline OpdSize ToOpdSize<4096>() {return O_SIZE_4096;}
433
434 template<int Size>
435 struct OpdT : Opd
436 {
437 /// NONE
438 OpdT() : Opd() {}
439 /// REG
440 133800 explicit OpdT(const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : Opd(ToOpdSize<Size>(), reg, reg_assignable) {}
441 /// MEM
442 OpdT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp)
443 : Opd(ToOpdSize<Size>(), base_size, index_size, base, index, scale, disp) {}
444 protected:
445 /// IMM
446 OpdT(sint64 imm) : Opd(ToOpdSize<Size>(), imm) {}
447 };
448
449 } // namespace detail
450
451 typedef detail::OpdT<8> Opd8;
452 typedef detail::OpdT<16> Opd16;
453 typedef detail::OpdT<32> Opd32;
454 typedef detail::OpdT<64> Opd64;
455 typedef detail::OpdT<80> Opd80;
456 typedef detail::OpdT<128> Opd128;
457 typedef detail::OpdT<224> Opd224; // FPU environment
458 typedef detail::OpdT<256> Opd256;
459 typedef detail::OpdT<864> Opd864; // FPU state
460 typedef detail::OpdT<4096> Opd4096; // FPU, MMX, XMM, MXCSR state
461
462 /// 8bit general purpose register
463 struct Reg8 : Opd8 {
464 Reg8() : Opd8(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP), 0xFFFFFF0F) {}
465 17840 explicit Reg8(PhysicalRegID id) : Opd8(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}
466 };
467 /// 16bit general purpose register
468 struct Reg16 : Opd16 {
469 Reg16() : Opd16(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}
470 17840 explicit Reg16(PhysicalRegID id) : Opd16(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}
471 };
472 /// 32bit general purpose register
473 struct Reg32 : Opd32 {
474 Reg32() : Opd32(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}
475 17840 explicit Reg32(PhysicalRegID id) : Opd32(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}
476 };
477 #ifdef JITASM64
478 /// 64bit general purpose register
479 struct Reg64 : Opd64 {
480 Reg64() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}
481 26760 explicit Reg64(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}
482 explicit Reg64(RegID reg_id) : Opd64(reg_id) {} // VS2017 /permissive-
483 };
484 typedef Reg64 Reg;
485 #else
486 typedef Reg32 Reg;
487 #endif
488 /// FPU register
489 struct FpuReg : Opd80 {
490 8920 explicit FpuReg(PhysicalRegID id) : Opd80(RegID::CreatePhysicalRegID(R_TYPE_FPU, id)) {}
491 };
492 /// MMX register
493 struct MmxReg : Opd64 {
494 MmxReg() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_MMX)) {}
495 8920 explicit MmxReg(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_MMX, id)) {}
496 };
497 /// XMM register
498 struct XmmReg : Opd128 {
499 XmmReg() : Opd128(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_XMM)) {}
500 17840 explicit XmmReg(PhysicalRegID id) : Opd128(RegID::CreatePhysicalRegID(R_TYPE_XMM, id)) {}
501 explicit XmmReg(RegID reg_id) : Opd128(reg_id) {} // VS2017 /permissive-
502 };
503 /// YMM register
504 struct YmmReg : Opd256 {
505 YmmReg() : Opd256(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_YMM)) {}
506 17840 explicit YmmReg(PhysicalRegID id) : Opd256(RegID::CreatePhysicalRegID(R_TYPE_YMM, id)) {}
507 XmmReg as128() const {
508 RegID id = reg_;
509 id.type = R_TYPE_SYMBOLIC_XMM;
510 return XmmReg(id);
511 }
512 };
513
514 1115 struct FpuReg_st0 : FpuReg {FpuReg_st0() : FpuReg(ST0) {}};
515
516 template<class OpdN>
517 struct MemT : OpdN
518 {
519 MemT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, index_size, base, index, scale, disp) {}
520 };
521 typedef MemT<Opd8> Mem8;
522 typedef MemT<Opd16> Mem16;
523 typedef MemT<Opd32> Mem32;
524 typedef MemT<Opd64> Mem64;
525 typedef MemT<Opd80> Mem80;
526 typedef MemT<Opd128> Mem128;
527 typedef MemT<Opd224> Mem224; // FPU environment
528 typedef MemT<Opd256> Mem256;
529 typedef MemT<Opd864> Mem864; // FPU state
530 typedef MemT<Opd4096> Mem4096; // FPU, MMX, XMM, MXCSR state
531
532 template<class OpdN, OpdSize IndexSize>
533 struct VecMemT : OpdN
534 {
535 VecMemT(OpdSize base_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, IndexSize, base, index, scale, disp) {}
536 };
537 typedef VecMemT<Opd32, O_SIZE_128> Mem32vxd;
538 typedef VecMemT<Opd32, O_SIZE_256> Mem32vyd;
539 typedef VecMemT<Opd32, O_SIZE_128> Mem64vxd;
540 typedef VecMemT<Opd32, O_SIZE_256> Mem64vyd;
541 typedef VecMemT<Opd64, O_SIZE_128> Mem32vxq;
542 typedef VecMemT<Opd64, O_SIZE_256> Mem32vyq;
543 typedef VecMemT<Opd64, O_SIZE_128> Mem64vxq;
544 typedef VecMemT<Opd64, O_SIZE_256> Mem64vyq;
545
546 struct MemOffset64
547 {
548 sint64 offset_;
549 explicit MemOffset64(sint64 offset) : offset_(offset) {}
550 sint64 GetOffset() const {return offset_;}
551 };
552
553 template<class OpdN, class U, class S>
554 struct ImmT : OpdN
555 {
556 ImmT(U imm) : OpdN((S) imm) {}
557 };
558 typedef ImmT<Opd8, uint8, sint8> Imm8; ///< 1 byte immediate
559 typedef ImmT<Opd16, uint16, sint16> Imm16; ///< 2 byte immediate
560 typedef ImmT<Opd32, uint32, sint32> Imm32; ///< 4 byte immediate
561 typedef ImmT<Opd64, uint64, sint64> Imm64; ///< 8 byte immediate
562
563 namespace detail
564 {
565 inline bool IsInt8(sint64 n) {return (sint8) n == n;}
566 inline bool IsInt16(sint64 n) {return (sint16) n == n;}
567 inline bool IsInt32(sint64 n) {return (sint32) n == n;}
568 inline Opd ImmXor8(const Imm16& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}
569 inline Opd ImmXor8(const Imm32& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}
570 inline Opd ImmXor8(const Imm64& imm) {return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}
571 } // namespace detail
572
573 /// 32bit address (base, displacement)
574 struct Addr32
575 {
576 RegID reg_;
577 sint64 disp_;
578 Addr32(const Reg32& obj) : reg_(obj.reg_), disp_(0) {} // implicit
579 Addr32(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {}
580 };
581 inline Addr32 operator+(const Reg32& lhs, sint64 rhs) {return Addr32(lhs.reg_, rhs);}
582 inline Addr32 operator+(sint64 lhs, const Reg32& rhs) {return rhs + lhs;}
583 inline Addr32 operator-(const Reg32& lhs, sint64 rhs) {return lhs + -rhs;}
584 inline Addr32 operator+(const Addr32& lhs, sint64 rhs) {return Addr32(lhs.reg_, lhs.disp_ + rhs);}
585 inline Addr32 operator+(sint64 lhs, const Addr32& rhs) {return rhs + lhs;}
586 inline Addr32 operator-(const Addr32& lhs, sint64 rhs) {return lhs + -rhs;}
587
588 /// 32bit address (base, index, displacement)
589 struct Addr32BI
590 {
591 RegID base_;
592 RegID index_;
593 sint64 disp_;
594 Addr32BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {}
595 };
596 inline Addr32BI operator+(const Addr32& lhs, const Addr32& rhs) {return Addr32BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);}
597 inline Addr32BI operator+(const Addr32BI& lhs, sint64 rhs) {return Addr32BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);}
598 inline Addr32BI operator+(sint64 lhs, const Addr32BI& rhs) {return rhs + lhs;}
599 inline Addr32BI operator-(const Addr32BI& lhs, sint64 rhs) {return lhs + -rhs;}
600
601 /// 32bit address (index, scale, displacement)
602 struct Addr32SI
603 {
604 RegID index_;
605 sint64 scale_;
606 sint64 disp_;
607 Addr32SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}
608 };
609 inline Addr32SI operator*(const Reg32& lhs, sint64 rhs) {return Addr32SI(lhs.reg_, rhs, 0);}
610 inline Addr32SI operator*(sint64 lhs, const Reg32& rhs) {return rhs * lhs;}
611 inline Addr32SI operator*(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}
612 inline Addr32SI operator*(sint64 lhs, const Addr32SI& rhs) {return rhs * lhs;}
613 inline Addr32SI operator+(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
614 inline Addr32SI operator+(sint64 lhs, const Addr32SI& rhs) {return rhs + lhs;}
615 inline Addr32SI operator-(const Addr32SI& lhs, sint64 rhs) {return lhs + -rhs;}
616
617 /// 32bit address (base, index, scale, displacement)
618 struct Addr32SIB
619 {
620 RegID base_;
621 RegID index_;
622 sint64 scale_;
623 sint64 disp_;
624 Addr32SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
625 };
626 inline Addr32SIB operator+(const Addr32& lhs, const Addr32SI& rhs) {return Addr32SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
627 inline Addr32SIB operator+(const Addr32SI& lhs, const Addr32& rhs) {return rhs + lhs;}
628 inline Addr32SIB operator+(const Addr32SIB& lhs, sint64 rhs) {return Addr32SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
629 inline Addr32SIB operator+(sint64 lhs, const Addr32SIB& rhs) {return rhs + lhs;}
630 inline Addr32SIB operator-(const Addr32SIB& lhs, sint64 rhs) {return lhs + -rhs;}
631
632 /// Address (xmm index, scale, displacement)
633 struct AddrXmmSI
634 {
635 RegID index_;
636 sint64 scale_;
637 sint64 disp_;
638 AddrXmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}
639 };
640 inline AddrXmmSI operator*(const XmmReg& lhs, sint64 rhs) {return AddrXmmSI(lhs.reg_, rhs, 0);}
641 inline AddrXmmSI operator*(sint64 lhs, const XmmReg& rhs) {return rhs * lhs;}
642 inline AddrXmmSI operator*(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}
643 inline AddrXmmSI operator*(sint64 lhs, const AddrXmmSI& rhs) {return rhs * lhs;}
644 inline AddrXmmSI operator+(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
645 inline AddrXmmSI operator+(sint64 lhs, const AddrXmmSI& rhs) {return rhs + lhs;}
646 inline AddrXmmSI operator-(const AddrXmmSI& lhs, sint64 rhs) {return lhs + -rhs;}
647
648 /// 32bit address (base, xmm index, scale, displacement)
649 struct Addr32XmmSIB
650 {
651 RegID base_;
652 RegID index_;
653 sint64 scale_;
654 sint64 disp_;
655 Addr32XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
656 };
657 inline Addr32XmmSIB operator+(const Addr32& lhs, const AddrXmmSI& rhs) {return Addr32XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
658 inline Addr32XmmSIB operator+(const AddrXmmSI& lhs, const Addr32& rhs) {return rhs + lhs;}
659 inline Addr32XmmSIB operator+(const Addr32XmmSIB& lhs, sint64 rhs) {return Addr32XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
660 inline Addr32XmmSIB operator+(sint64 lhs, const Addr32XmmSIB& rhs) {return rhs + lhs;}
661 inline Addr32XmmSIB operator-(const Addr32XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}
662
663 /// Address (ymm index, scale, displacement)
664 struct AddrYmmSI
665 {
666 RegID index_;
667 sint64 scale_;
668 sint64 disp_;
669 AddrYmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}
670 };
671 inline AddrYmmSI operator*(const YmmReg& lhs, sint64 rhs) {return AddrYmmSI(lhs.reg_, rhs, 0);}
672 inline AddrYmmSI operator*(sint64 lhs, const YmmReg& rhs) {return rhs * lhs;}
673 inline AddrYmmSI operator*(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}
674 inline AddrYmmSI operator*(sint64 lhs, const AddrYmmSI& rhs) {return rhs * lhs;}
675 inline AddrYmmSI operator+(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
676 inline AddrYmmSI operator+(sint64 lhs, const AddrYmmSI& rhs) {return rhs + lhs;}
677 inline AddrYmmSI operator-(const AddrYmmSI& lhs, sint64 rhs) {return lhs + -rhs;}
678
679 /// 32bit address (base, ymm index, scale, displacement)
680 struct Addr32YmmSIB
681 {
682 RegID base_;
683 RegID index_;
684 sint64 scale_;
685 sint64 disp_;
686 Addr32YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
687 };
688 inline Addr32YmmSIB operator+(const Addr32& lhs, const AddrYmmSI& rhs) {return Addr32YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
689 inline Addr32YmmSIB operator+(const AddrYmmSI& lhs, const Addr32& rhs) {return rhs + lhs;}
690 inline Addr32YmmSIB operator+(const Addr32YmmSIB& lhs, sint64 rhs) {return Addr32YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
691 inline Addr32YmmSIB operator+(sint64 lhs, const Addr32YmmSIB& rhs) {return rhs + lhs;}
692 inline Addr32YmmSIB operator-(const Addr32YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}
693
694 #ifdef JITASM64
695 /// 64bit address (base, displacement)
696 struct Addr64
697 {
698 RegID reg_;
699 sint64 disp_;
700 Addr64(const Reg64& obj) : reg_(obj.reg_), disp_(0) {} // implicit
701 Addr64(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {}
702 };
703 inline Addr64 operator+(const Reg64& lhs, sint64 rhs) {return Addr64(lhs.reg_, rhs);}
704 inline Addr64 operator+(sint64 lhs, const Reg64& rhs) {return rhs + lhs;}
705 inline Addr64 operator-(const Reg64& lhs, sint64 rhs) {return lhs + -rhs;}
706 inline Addr64 operator+(const Addr64& lhs, sint64 rhs) {return Addr64(lhs.reg_, lhs.disp_ + rhs);}
707 inline Addr64 operator+(sint64 lhs, const Addr64& rhs) {return rhs + lhs;}
708 inline Addr64 operator-(const Addr64& lhs, sint64 rhs) {return lhs + -rhs;}
709
710 /// 64bit address (base, index, displacement)
711 struct Addr64BI
712 {
713 RegID base_;
714 RegID index_;
715 sint64 disp_;
716 Addr64BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {}
717 };
718 inline Addr64BI operator+(const Addr64& lhs, const Addr64& rhs) {return Addr64BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);}
719 inline Addr64BI operator+(const Addr64BI& lhs, sint64 rhs) {return Addr64BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);}
720 inline Addr64BI operator+(sint64 lhs, const Addr64BI& rhs) {return rhs + lhs;}
721 inline Addr64BI operator-(const Addr64BI& lhs, sint64 rhs) {return lhs + -rhs;}
722
723 /// 64bit address (index, scale, displacement)
724 struct Addr64SI
725 {
726 RegID index_;
727 sint64 scale_;
728 sint64 disp_;
729 Addr64SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}
730 };
731 inline Addr64SI operator*(const Reg64& lhs, sint64 rhs) {return Addr64SI(lhs.reg_, rhs, 0);}
732 inline Addr64SI operator*(sint64 lhs, const Reg64& rhs) {return rhs * lhs;}
733 inline Addr64SI operator*(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}
734 inline Addr64SI operator*(sint64 lhs, const Addr64SI& rhs) {return rhs * lhs;}
735 inline Addr64SI operator+(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
736 inline Addr64SI operator+(sint64 lhs, const Addr64SI& rhs) {return rhs + lhs;}
737 inline Addr64SI operator-(const Addr64SI& lhs, sint64 rhs) {return lhs + -rhs;}
738
739 /// 64bit address (base, index, scale, displacement)
740 struct Addr64SIB
741 {
742 RegID base_;
743 RegID index_;
744 sint64 scale_;
745 sint64 disp_;
746 Addr64SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
747 };
748 inline Addr64SIB operator+(const Addr64& lhs, const Addr64SI& rhs) {return Addr64SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
749 inline Addr64SIB operator+(const Addr64SI& lhs, const Addr64& rhs) {return rhs + lhs;}
750 inline Addr64SIB operator+(const Addr64SIB& lhs, sint64 rhs) {return Addr64SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
751 inline Addr64SIB operator+(sint64 lhs, const Addr64SIB& rhs) {return rhs + lhs;}
752 inline Addr64SIB operator-(const Addr64SIB& lhs, sint64 rhs) {return lhs + -rhs;}
753
754 /// 64bit address (base, xmm index, scale, displacement)
755 struct Addr64XmmSIB
756 {
757 RegID base_;
758 RegID index_;
759 sint64 scale_;
760 sint64 disp_;
761 Addr64XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
762 };
763 inline Addr64XmmSIB operator+(const Addr64& lhs, const AddrXmmSI& rhs) {return Addr64XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
764 inline Addr64XmmSIB operator+(const AddrXmmSI& lhs, const Addr64& rhs) {return rhs + lhs;}
765 inline Addr64XmmSIB operator+(const Addr64XmmSIB& lhs, sint64 rhs) {return Addr64XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
766 inline Addr64XmmSIB operator+(sint64 lhs, const Addr64XmmSIB& rhs) {return rhs + lhs;}
767 inline Addr64XmmSIB operator-(const Addr64XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}
768
769 /// 64bit address (base, ymm index, scale, displacement)
770 struct Addr64YmmSIB
771 {
772 RegID base_;
773 RegID index_;
774 sint64 scale_;
775 sint64 disp_;
776 Addr64YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}
777 };
778 inline Addr64YmmSIB operator+(const Addr64& lhs, const AddrYmmSI& rhs) {return Addr64YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}
779 inline Addr64YmmSIB operator+(const AddrYmmSI& lhs, const Addr64& rhs) {return rhs + lhs;}
780 inline Addr64YmmSIB operator+(const Addr64YmmSIB& lhs, sint64 rhs) {return Addr64YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}
781 inline Addr64YmmSIB operator+(sint64 lhs, const Addr64YmmSIB& rhs) {return rhs + lhs;}
782 inline Addr64YmmSIB operator-(const Addr64YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}
783
784 typedef Addr64 Addr;
785 typedef Addr64BI AddrBI;
786 typedef Addr64SI AddrSI;
787 typedef Addr64SIB AddrSIB;
788 #else
789 typedef Addr32 Addr;
790 typedef Addr32BI AddrBI;
791 typedef Addr32SI AddrSI;
792 typedef Addr32SIB AddrSIB;
793 #endif
794
795 template<typename OpdN>
796 struct AddressingPtr
797 {
798 // 32bit-Addressing
799 MemT<OpdN> operator[](const Addr32& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.reg_, RegID::Invalid(), 0, obj.disp_);}
800 MemT<OpdN> operator[](const Addr32BI& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, 0, obj.disp_);}
801 MemT<OpdN> operator[](const Addr32SI& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);}
802 MemT<OpdN> operator[](const Addr32SIB& obj) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}
803 VecMemT<OpdN, O_SIZE_128> operator[](const Addr32XmmSIB& obj) {return VecMemT<OpdN, O_SIZE_128>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}
804 VecMemT<OpdN, O_SIZE_256> operator[](const Addr32YmmSIB& obj) {return VecMemT<OpdN, O_SIZE_256>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}
805
806 #ifdef JITASM64
807 // 64bit-Addressing
808 MemT<OpdN> operator[](const Addr64& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.reg_, RegID::Invalid(), 0, obj.disp_);}
809 MemT<OpdN> operator[](const Addr64BI& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, 0, obj.disp_);}
810 MemT<OpdN> operator[](const Addr64SI& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);}
811 MemT<OpdN> operator[](const Addr64SIB& obj) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}
812 MemOffset64 operator[](sint64 offset) {return MemOffset64(offset);}
813 MemOffset64 operator[](uint64 offset) {return MemOffset64((sint64) offset);}
814 VecMemT<OpdN, O_SIZE_128> operator[](const Addr64XmmSIB& obj) {return VecMemT<OpdN, O_SIZE_128>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}
815 VecMemT<OpdN, O_SIZE_256> operator[](const Addr64YmmSIB& obj) {return VecMemT<OpdN, O_SIZE_256>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}
816 #endif
817
818 #ifdef JITASM64
819 MemT<OpdN> operator[](sint32 disp) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, disp);}
820 MemT<OpdN> operator[](uint32 disp) {return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);}
821 #else
822 MemT<OpdN> operator[](sint32 disp) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, disp);}
823 MemT<OpdN> operator[](uint32 disp) {return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);}
824 #endif
825 };
826
827 /// Instruction ID
828 enum InstrID
829 {
830 I_ADC, I_ADD, I_AND,
831 I_BSF, I_BSR, I_BSWAP, I_BT, I_BTC, I_BTR, I_BTS,
832 I_CALL, I_CBW, I_CLC, I_CLD, I_CLI, I_CLTS, I_CMC, I_CMOVCC, I_CMP, I_CMPS_B, I_CMPS_W, I_CMPS_D, I_CMPS_Q, I_CMPXCHG,
833 I_CMPXCHG8B, I_CMPXCHG16B, I_CPUID, I_CWD, I_CDQ, I_CQO,
834 I_DEC, I_DIV,
835 I_ENTER,
836 I_HLT,
837 I_IDIV, I_IMUL, I_IN, I_INC, I_INS_B, I_INS_W, I_INS_D, I_INVD, I_INVLPG, I_INT3, I_INTN, I_INTO, I_IRET, I_IRETD, I_IRETQ,
838 I_JMP, I_JCC,
839 I_LAR, I_LEA, I_LEAVE, I_LLDT, I_LMSW, I_LSL, I_LTR, I_LODS_B, I_LODS_W, I_LODS_D, I_LODS_Q, I_LOOP,
840 I_MOV, I_MOVBE, I_MOVS_B, I_MOVS_W, I_MOVS_D, I_MOVS_Q, I_MOVZX, I_MOVSX, I_MOVSXD, I_MUL,
841 I_NEG, I_NOP, I_NOT,
842 I_OR, I_OUT, I_OUTS_B, I_OUTS_W, I_OUTS_D,
843 I_POP, I_POPAD, I_POPF, I_POPFD, I_POPFQ, I_PUSH, I_PUSHAD, I_PUSHF, I_PUSHFD, I_PUSHFQ,
844 I_RDMSR, I_RDPMC, I_RDTSC, I_RET, I_RCL, I_RCR, I_ROL, I_ROR, I_RSM,
845 I_SAR, I_SHL, I_SHR, I_SBB, I_SCAS_B, I_SCAS_W, I_SCAS_D, I_SCAS_Q, I_SETCC, I_SHLD, I_SHRD, I_SGDT, I_SIDT, I_SLDT, I_SMSW, I_STC, I_STD, I_STI,
846 I_STOS_B, I_STOS_W, I_STOS_D, I_STOS_Q, I_SUB, I_SWAPGS, I_SYSCALL, I_SYSENTER, I_SYSEXIT, I_SYSRET,
847 I_TEST,
848 I_UD2,
849 I_VERR, I_VERW,
850 I_WAIT, I_WBINVD, I_WRMSR,
851 I_XADD, I_XCHG, I_XGETBV, I_XLATB, I_XOR,
852
853 I_F2XM1, I_FABS, I_FADD, I_FADDP, I_FIADD,
854 I_FBLD, I_FBSTP, I_FCHS, I_FCLEX, I_FNCLEX, I_FCMOVCC, I_FCOM, I_FCOMP, I_FCOMPP, I_FCOMI, I_FCOMIP, I_FCOS,
855 I_FDECSTP, I_FDIV, I_FDIVP, I_FIDIV, I_FDIVR, I_FDIVRP, I_FIDIVR,
856 I_FFREE,
857 I_FICOM, I_FICOMP, I_FILD, I_FINCSTP, I_FINIT, I_FNINIT, I_FIST, I_FISTP,
858 I_FLD, I_FLD1, I_FLDCW, I_FLDENV, I_FLDL2E, I_FLDL2T, I_FLDLG2, I_FLDLN2, I_FLDPI, I_FLDZ,
859 I_FMUL, I_FMULP, I_FIMUL,
860 I_FNOP,
861 I_FPATAN, I_FPREM, I_FPREM1, I_FPTAN,
862 I_FRNDINT, I_FRSTOR,
863 I_FSAVE, I_FNSAVE, I_FSCALE, I_FSIN, I_FSINCOS, I_FSQRT, I_FST, I_FSTP, I_FSTCW, I_FNSTCW, I_FSTENV, I_FNSTENV, I_FSTSW, I_FNSTSW,
864 I_FSUB, I_FSUBP, I_FISUB, I_FSUBR, I_FSUBRP, I_FISUBR,
865 I_FTST,
866 I_FUCOM, I_FUCOMP, I_FUCOMPP, I_FUCOMI, I_FUCOMIP,
867 I_FXAM, I_FXCH, I_FXRSTOR, I_FXSAVE, I_FXTRACT,
868 I_FYL2X, I_FYL2XP1,
869
870 I_ADDPS, I_ADDSS, I_ADDPD, I_ADDSD, I_ADDSUBPS, I_ADDSUBPD, I_ANDPS, I_ANDPD, I_ANDNPS, I_ANDNPD,
871 I_BLENDPS, I_BLENDPD, I_BLENDVPS, I_BLENDVPD,
872 I_CLFLUSH, I_CMPPS, I_CMPSS, I_CMPPD, I_CMPSD, I_COMISS, I_COMISD, I_CRC32,
873 I_CVTDQ2PD, I_CVTDQ2PS, I_CVTPD2DQ, I_CVTPD2PI, I_CVTPD2PS, I_CVTPI2PD, I_CVTPI2PS, I_CVTPS2DQ, I_CVTPS2PD, I_CVTPS2PI, I_CVTSD2SI,
874 I_CVTSD2SS, I_CVTSI2SD, I_CVTSI2SS, I_CVTSS2SD, I_CVTSS2SI, I_CVTTPD2DQ, I_CVTTPD2PI, I_CVTTPS2DQ, I_CVTTPS2PI, I_CVTTSD2SI, I_CVTTSS2SI,
875 I_DIVPS, I_DIVSS, I_DIVPD, I_DIVSD, I_DPPS, I_DPPD,
876 I_EMMS, I_EXTRACTPS,
877 I_FISTTP,
878 I_HADDPS, I_HADDPD, I_HSUBPS, I_HSUBPD,
879 I_INSERTPS,
880 I_LDDQU, I_LDMXCSR, I_LFENCE,
881 I_MASKMOVDQU, I_MASKMOVQ, I_MAXPS, I_MAXSS, I_MAXPD, I_MAXSD, I_MFENCE, I_MINPS, I_MINSS, I_MINPD, I_MINSD, I_MONITOR,
882 I_MOVAPD, I_MOVAPS, I_MOVD, I_MOVDDUP, I_MOVDQA, I_MOVDQU, I_MOVDQ2Q, I_MOVHLPS, I_MOVLHPS, I_MOVHPS, I_MOVHPD, I_MOVLPS, I_MOVLPD,
883 I_MOVMSKPS, I_MOVMSKPD, I_MOVNTDQ, I_MOVNTDQA, I_MOVNTI, I_MOVNTPD, I_MOVNTPS, I_MOVNTQ, I_MOVQ, I_MOVQ2DQ, I_MOVSD, I_MOVSS,
884 I_MOVSHDUP, I_MOVSLDUP, I_MOVUPS, I_MOVUPD, I_MPSADBW, I_MULPS, I_MULSS, I_MULPD, I_MULSD, I_MWAIT,
885 I_ORPS, I_ORPD,
886 I_PABSB, I_PABSD, I_PABSW, I_PACKSSDW, I_PACKSSWB, I_PACKUSDW, I_PACKUSWB, I_PADDB, I_PADDD, I_PADDQ, I_PADDSB, I_PADDSW, I_PADDUSB,
887 I_PADDUSW, I_PADDW, I_PALIGNR, I_PAND, I_PANDN, I_PAUSE, I_PAVGB, I_PAVGW,
888 I_PBLENDVB, I_PBLENDW,
889 I_PCMPEQB, I_PCMPEQW, I_PCMPEQD, I_PCMPEQQ, I_PCMPESTRI, I_PCMPESTRM, I_PCMPISTRI, I_PCMPISTRM, I_PCMPGTB, I_PCMPGTW, I_PCMPGTD, I_PCMPGTQ,
890 I_PEXTRB, I_PEXTRW, I_PEXTRD, I_PEXTRQ,
891 I_PHADDW, I_PHADDD, I_PHADDSW, I_PHMINPOSUW, I_PHSUBW, I_PHSUBD, I_PHSUBSW,
892 I_PINSRB, I_PINSRW, I_PINSRD, I_PINSRQ,
893 I_PMADDUBSW, I_PMADDWD, I_PMAXSB, I_PMAXSW, I_PMAXSD, I_PMAXUB, I_PMAXUW, I_PMAXUD, I_PMINSB, I_PMINSW, I_PMINSD, I_PMINUB, I_PMINUW,
894 I_PMINUD, I_PMOVMSKB, I_PMOVSXBW, I_PMOVSXBD, I_PMOVSXBQ, I_PMOVSXWD, I_PMOVSXWQ, I_PMOVSXDQ, I_PMOVZXBW, I_PMOVZXBD, I_PMOVZXBQ, I_PMOVZXWD,
895 I_PMOVZXWQ, I_PMOVZXDQ, I_PMULDQ, I_PMULHRSW, I_PMULHUW, I_PMULHW, I_PMULLW, I_PMULLD, I_PMULUDQ,
896 I_POPCNT, I_POR,
897 I_PREFETCH,
898 I_PSADBW, I_PSHUFB, I_PSHUFD, I_PSHUFHW, I_PSHUFLW, I_PSHUFW, I_PSIGNB, I_PSIGNW, I_PSIGND, I_PSLLW, I_PSLLD, I_PSLLQ, I_PSLLDQ, I_PSRAW,
899 I_PSRAD, I_PSRLW, I_PSRLD, I_PSRLQ, I_PSRLDQ, I_PSUBB, I_PSUBW, I_PSUBD, I_PSUBQ, I_PSUBSB, I_PSUBSW, I_PSUBUSB, I_PSUBUSW,
900 I_PTEST,
901 I_PUNPCKHBW, I_PUNPCKHWD, I_PUNPCKHDQ, I_PUNPCKHQDQ, I_PUNPCKLBW, I_PUNPCKLWD, I_PUNPCKLDQ, I_PUNPCKLQDQ,
902 I_PXOR,
903 I_RCPPS, I_RCPSS, I_ROUNDPS, I_ROUNDPD, I_ROUNDSS, I_ROUNDSD, I_RSQRTPS, I_RSQRTSS,
904 I_SFENCE, I_SHUFPS, I_SHUFPD, I_SQRTPS, I_SQRTSS, I_SQRTPD, I_SQRTSD, I_STMXCSR, I_SUBPS, I_SUBSS, I_SUBPD, I_SUBSD,
905 I_UCOMISS, I_UCOMISD, I_UNPCKHPS, I_UNPCKHPD, I_UNPCKLPS, I_UNPCKLPD,
906 I_XORPS, I_XORPD,
907
908 I_VBROADCASTSS, I_VBROADCASTSD, I_VBROADCASTF128,
909 I_VEXTRACTF128,
910 I_VINSERTF128,
911 I_VMASKMOVPS, I_VMASKMOVPD,
912 I_VPERMILPD, I_VPERMILPS, I_VPERM2F128,
913 I_VTESTPS, I_VTESTPD,
914 I_VZEROALL, I_VZEROUPPER,
915
916 I_AESENC, I_AESENCLAST, I_AESDEC, I_AESDECLAST, I_AESIMC, I_AESKEYGENASSIST,
917 I_PCLMULQDQ,
918
919 // FMA
920 I_VFMADD132PD, I_VFMADD213PD, I_VFMADD231PD, I_VFMADD132PS, I_VFMADD213PS, I_VFMADD231PS,
921 I_VFMADD132SD, I_VFMADD213SD, I_VFMADD231SD, I_VFMADD132SS, I_VFMADD213SS, I_VFMADD231SS,
922 I_VFMADDSUB132PD, I_VFMADDSUB213PD, I_VFMADDSUB231PD, I_VFMADDSUB132PS, I_VFMADDSUB213PS, I_VFMADDSUB231PS,
923 I_VFMSUBADD132PD, I_VFMSUBADD213PD, I_VFMSUBADD231PD, I_VFMSUBADD132PS, I_VFMSUBADD213PS, I_VFMSUBADD231PS,
924 I_VFMSUB132PD, I_VFMSUB213PD, I_VFMSUB231PD, I_VFMSUB132PS, I_VFMSUB213PS, I_VFMSUB231PS,
925 I_VFMSUB132SD, I_VFMSUB213SD, I_VFMSUB231SD, I_VFMSUB132SS, I_VFMSUB213SS, I_VFMSUB231SS,
926 I_VFNMADD132PD, I_VFNMADD213PD, I_VFNMADD231PD, I_VFNMADD132PS, I_VFNMADD213PS, I_VFNMADD231PS,
927 I_VFNMADD132SD, I_VFNMADD213SD, I_VFNMADD231SD, I_VFNMADD132SS, I_VFNMADD213SS, I_VFNMADD231SS,
928 I_VFNMSUB132PD, I_VFNMSUB213PD, I_VFNMSUB231PD, I_VFNMSUB132PS, I_VFNMSUB213PS, I_VFNMSUB231PS,
929 I_VFNMSUB132SD, I_VFNMSUB213SD, I_VFNMSUB231SD, I_VFNMSUB132SS, I_VFNMSUB213SS, I_VFNMSUB231SS,
930
931 // F16C
932 I_RDFSBASE, I_RDGSBASE, I_RDRAND, I_WRFSBASE, I_WRGSBASE, I_VCVTPH2PS, I_VCVTPS2PH,
933
934 // BMI
935 I_ANDN, I_BEXTR, I_BLSI, I_BLSMSK, I_BLSR, I_BZHI, I_LZCNT, I_MULX, I_PDEP, I_PEXT, I_RORX, I_SARX, I_SHLX, I_SHRX, I_TZCNT, I_INVPCID,
936
937 // XOP
938 I_VFRCZPD, I_VFRCZPS, I_VFRCZSD, I_VFRCZSS,
939 I_VPCMOV, I_VPCOMB, I_VPCOMD, I_VPCOMQ, I_VPCOMUB, I_VPCOMUD, I_VPCOMUQ, I_VPCOMUW, I_VPCOMW, I_VPERMIL2PD, I_VPERMIL2PS,
940 I_VPHADDBD, I_VPHADDBQ, I_VPHADDBW, I_VPHADDDQ, I_VPHADDUBD, I_VPHADDUBQ, I_VPHADDUBW, I_VPHADDUDQ, I_VPHADDUWD, I_VPHADDUWQ,
941 I_VPHADDWD, I_VPHADDWQ, I_VPHSUBBW, I_VPHSUBDQ, I_VPHSUBWD,
942 I_VPMACSDD, I_VPMACSDQH, I_VPMACSDQL, I_VPMACSSDD, I_VPMACSSDQH, I_VPMACSSDQL, I_VPMACSSWD, I_VPMACSSWW, I_VPMACSWD, I_VPMACSWW,
943 I_VPMADCSSWD, I_VPMADCSWD,
944 I_VPPERM, I_VPROTB, I_VPROTD, I_VPROTQ, I_VPROTW, I_VPSHAB, I_VPSHAD, I_VPSHAQ, I_VPSHAW, I_VPSHLB, I_VPSHLD, I_VPSHLQ, I_VPSHLW,
945
946 // FMA4
947 I_VFMADDPD, I_VFMADDPS, I_VFMADDSD, I_VFMADDSS,
948 I_VFMADDSUBPD, I_VFMADDSUBPS,
949 I_VFMSUBADDPD, I_VFMSUBADDPS,
950 I_VFMSUBPD, I_VFMSUBPS, I_VFMSUBSD, I_VFMSUBSS,
951 I_VFNMADDPD, I_VFNMADDPS, I_VFNMADDSD, I_VFNMADDSS,
952 I_VFNMSUBPD, I_VFNMSUBPS, I_VFNMSUBSD, I_VFNMSUBSS,
953
954 // AVX2
955 I_VBROADCASTI128, I_VPBROADCASTB, I_VPBROADCASTW, I_VPBROADCASTD, I_VPBROADCASTQ,
956 I_PBLENDD, I_VPERMD, I_VPERMQ, I_VPERMPS, I_VPERMPD, I_VPERM2I128,
957 I_VEXTRACTI128, I_VINSERTI128, I_VMASKMOVD, I_VMASKMOVQ, I_VPSLLVD, I_VPSLLVQ, I_VPSRAVD, I_VPSRLVD, I_VPSRLVQ,
958 I_VGATHERDPS, I_VGATHERQPS, I_VGATHERDPD, I_VGATHERQPD, I_VPGATHERDD, I_VPGATHERQD, I_VPGATHERDQ, I_VPGATHERQQ,
959
960 // jitasm compiler instructions
961 I_COMPILER_DECLARE_REG_ARG, ///< Declare register argument
962 I_COMPILER_DECLARE_STACK_ARG, ///< Declare stack argument
963 I_COMPILER_DECLARE_RESULT_REG, ///< Declare result register (eax/rax/xmm0)
964 I_COMPILER_PROLOG, ///< Function prolog
965 I_COMPILER_EPILOG ///< Function epilog
966 };
967
968 enum JumpCondition
969 {
970 JCC_O, JCC_NO, JCC_B, JCC_AE, JCC_E, JCC_NE, JCC_BE, JCC_A, JCC_S, JCC_NS, JCC_P, JCC_NP, JCC_L, JCC_GE, JCC_LE, JCC_G,
971 JCC_CXZ, JCC_ECXZ, JCC_RCXZ,
972 };
973
974 enum EncodingFlags
975 {
976 E_SPECIAL = 1 << 0,
977 E_OPERAND_SIZE_PREFIX = 1 << 1, ///< Operand-size override prefix
978 E_REP_PREFIX = 1 << 2, ///< REP prefix
979 E_REXW_PREFIX = 1 << 3, ///< REX.W
980 E_MANDATORY_PREFIX_66 = 1 << 4, ///< Mandatory prefix 66
981 E_MANDATORY_PREFIX_F2 = 1 << 5, ///< Mandatory prefix F2
982 E_MANDATORY_PREFIX_F3 = 1 << 6, ///< Mandatory prefix F3
983 E_VEX = 1 << 7,
984 E_XOP = 1 << 8,
985 E_VEX_L = 1 << 9,
986 E_VEX_W = 1 << 10,
987 E_VEX_MMMMM_SHIFT = 11,
988 E_VEX_MMMMM_MASK = 0x1F << E_VEX_MMMMM_SHIFT,
989 E_VEX_0F = 1 << E_VEX_MMMMM_SHIFT,
990 E_VEX_0F38 = 2 << E_VEX_MMMMM_SHIFT,
991 E_VEX_0F3A = 3 << E_VEX_MMMMM_SHIFT,
992 E_XOP_M00011 = 3 << E_VEX_MMMMM_SHIFT,
993 E_XOP_M01000 = 8 << E_VEX_MMMMM_SHIFT,
994 E_XOP_M01001 = 9 << E_VEX_MMMMM_SHIFT,
995 E_VEX_PP_SHIFT = 16,
996 E_VEX_PP_MASK = 0x3 << E_VEX_PP_SHIFT,
997 E_VEX_66 = 1 << E_VEX_PP_SHIFT,
998 E_VEX_F3 = 2 << E_VEX_PP_SHIFT,
999 E_VEX_F2 = 3 << E_VEX_PP_SHIFT,
1000 E_XOP_P00 = 0 << E_VEX_PP_SHIFT,
1001 E_XOP_P01 = 1 << E_VEX_PP_SHIFT,
1002
1003 E_VEX_128 = E_VEX,
1004 E_VEX_256 = E_VEX | E_VEX_L,
1005 E_VEX_LIG = E_VEX,
1006 E_VEX_LZ = E_VEX,
1007 E_VEX_66_0F = E_VEX_66 | E_VEX_0F,
1008 E_VEX_66_0F38 = E_VEX_66 | E_VEX_0F38,
1009 E_VEX_66_0F3A = E_VEX_66 | E_VEX_0F3A,
1010 E_VEX_F2_0F = E_VEX_F2 | E_VEX_0F,
1011 E_VEX_F2_0F38 = E_VEX_F2 | E_VEX_0F38,
1012 E_VEX_F2_0F3A = E_VEX_F2 | E_VEX_0F3A,
1013 E_VEX_F3_0F = E_VEX_F3 | E_VEX_0F,
1014 E_VEX_F3_0F38 = E_VEX_F3 | E_VEX_0F38,
1015 E_VEX_F3_0F3A = E_VEX_F3 | E_VEX_0F3A,
1016 E_VEX_W0 = 0,
1017 E_VEX_W1 = E_VEX_W,
1018 E_VEX_WIG = 0,
1019 E_XOP_128 = E_XOP,
1020 E_XOP_256 = E_XOP | E_VEX_L,
1021 E_XOP_W0 = 0,
1022 E_XOP_W1 = E_VEX_W,
1023
1024 // Aliases
1025 E_VEX_128_0F_WIG = E_VEX_128 | E_VEX_0F | E_VEX_WIG,
1026 E_VEX_256_0F_WIG = E_VEX_256 | E_VEX_0F | E_VEX_WIG,
1027 E_VEX_128_66_0F_WIG = E_VEX_128 | E_VEX_66_0F | E_VEX_WIG,
1028 E_VEX_256_66_0F_WIG = E_VEX_256 | E_VEX_66_0F | E_VEX_WIG,
1029 E_VEX_128_66_0F38_WIG = E_VEX_128 | E_VEX_66_0F38 | E_VEX_WIG,
1030 E_VEX_256_66_0F38_WIG = E_VEX_256 | E_VEX_66_0F38 | E_VEX_WIG,
1031 E_VEX_128_66_0F38_W0 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W0,
1032 E_VEX_256_66_0F38_W0 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W0,
1033 E_VEX_128_66_0F38_W1 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W1,
1034 E_VEX_256_66_0F38_W1 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W1,
1035 E_VEX_128_66_0F3A_W0 = E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0,
1036 E_VEX_256_66_0F3A_W0 = E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0,
1037 };
1038
1039 /// Instruction
1040 struct Instr
1041 {
1042 static const size_t MAX_OPERAND_COUNT = 6;
1043
1044 InstrID id_; ///< Instruction ID
1045 uint32 opcode_; ///< Opcode
1046 uint32 encoding_flag_; ///< EncodingFlags
1047 detail::Opd opd_[MAX_OPERAND_COUNT]; ///< Operands
1048
1049 Instr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd())
1050 : id_(id), opcode_(opcode), encoding_flag_(encoding_flag) {opd_[0] = opd1, opd_[1] = opd2, opd_[2] = opd3, opd_[3] = opd4, opd_[4] = opd5, opd_[5] = opd6;}
1051
1052 InstrID GetID() const {return id_;}
1053 const detail::Opd& GetOpd(size_t index) const {return opd_[index];}
1054 detail::Opd& GetOpd(size_t index) {return opd_[index];}
1055 };
1056
1057 /// Assembler backend
1058 struct Backend
1059 {
1060 uint8* pbuff_;
1061 size_t buffsize_;
1062 size_t size_;
1063
1064 Backend(void* pbuff = NULL, size_t buffsize = 0) : pbuff_((uint8*) pbuff), buffsize_(buffsize), size_(0)
1065 {
1066 memset(pbuff, 0xCC, buffsize); // INT3
1067 }
1068
1069 size_t GetSize() const
1070 {
1071 return size_;
1072 }
1073
1074 void put_bytes(void* p, size_t n)
1075 {
1076 uint8* pb = (uint8*) p;
1077 while (n--) {
1078 if (pbuff_) {
1079 if (size_ == buffsize_) JITASM_ASSERT(0);
1080 pbuff_[size_] = *pb++;
1081 }
1082 size_++;
1083 }
1084 }
1085 void db(uint64 b) {put_bytes(&b, 1);}
1086 void dw(uint64 w) {put_bytes(&w, 2);}
1087 void dd(uint64 d) {put_bytes(&d, 4);}
1088 void dq(uint64 q) {put_bytes(&q, 8);}
1089
1090 uint8 GetWRXB(int w, const detail::Opd& reg, const detail::Opd& r_m)
1091 {
1092 uint8 wrxb = w ? 8 : 0;
1093 if (reg.IsReg()) {
1094 if (!reg.GetReg().IsInvalid() && reg.GetReg().id >= R8) wrxb |= 4;
1095 }
1096 if (r_m.IsReg()) {
1097 if (r_m.GetReg().id >= R8) wrxb |= 1;
1098 }
1099 if (r_m.IsMem()) {
1100 if (!r_m.GetIndex().IsInvalid() && r_m.GetIndex().id >= R8) wrxb |= 2;
1101 if (!r_m.GetBase().IsInvalid() && r_m.GetBase().id >= R8) wrxb |= 1;
1102 }
1103 return wrxb;
1104 }
1105
1106 void EncodePrefixes(uint32 flag, const detail::Opd& reg, const detail::Opd& r_m, const detail::Opd& vex)
1107 {
1108 if (flag & (E_VEX | E_XOP)) {
1109 // Encode VEX prefix
1110 #ifdef JITASM64
1111 if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);
1112 #endif
1113 uint8 vvvv = vex.IsReg() ? 0xF - (uint8) vex.GetReg().id : 0xF;
1114 uint8 mmmmm = (flag & E_VEX_MMMMM_MASK) >> E_VEX_MMMMM_SHIFT;
1115 uint8 pp = static_cast<uint8>((flag & E_VEX_PP_MASK) >> E_VEX_PP_SHIFT);
1116 uint8 wrxb = GetWRXB(flag & E_VEX_W, reg, r_m);
1117 if (flag & E_XOP) {
1118 db(0x8F);
1119 db((~wrxb & 7) << 5 | mmmmm);
1120 db((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);
1121 } else if (wrxb & 0xB || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F38 || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F3A) {
1122 db(0xC4);
1123 db((~wrxb & 7) << 5 | mmmmm);
1124 db((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);
1125 } else {
1126 db(0xC5);
1127 db((~wrxb & 4) << 5 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);
1128 }
1129 } else {
1130 uint8 wrxb = GetWRXB(flag & E_REXW_PREFIX, reg, r_m);
1131 if (wrxb) {
1132 // Encode REX prefix
1133 JITASM_ASSERT(!reg.IsReg() || reg.GetSize() != O_SIZE_8 || reg.GetReg().id < AH || reg.GetReg().id >= R8B); // AH, BH, CH, or DH may not be used with REX.
1134 JITASM_ASSERT(!r_m.IsReg() || r_m.GetSize() != O_SIZE_8 || r_m.GetReg().id < AH || r_m.GetReg().id >= R8B); // AH, BH, CH, or DH may not be used with REX.
1135
1136 if (flag & E_REP_PREFIX) db(0xF3);
1137 #ifdef JITASM64
1138 if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);
1139 #endif
1140 if (flag & E_OPERAND_SIZE_PREFIX) db(0x66);
1141
1142 if (flag & E_MANDATORY_PREFIX_66) db(0x66);
1143 else if (flag & E_MANDATORY_PREFIX_F2) db(0xF2);
1144 else if (flag & E_MANDATORY_PREFIX_F3) db(0xF3);
1145
1146 db(0x40 | wrxb);
1147 } else {
1148 if (flag & E_MANDATORY_PREFIX_66) db(0x66);
1149 else if (flag & E_MANDATORY_PREFIX_F2) db(0xF2);
1150 else if (flag & E_MANDATORY_PREFIX_F3) db(0xF3);
1151
1152 if (flag & E_REP_PREFIX) db(0xF3);
1153 #ifdef JITASM64
1154 if (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);
1155 #endif
1156 if (flag & E_OPERAND_SIZE_PREFIX) db(0x66);
1157 }
1158 }
1159 }
1160
1161 void EncodeModRM(uint8 reg, const detail::Opd& r_m)
1162 {
1163 reg &= 0x7;
1164
1165 if (r_m.IsReg()) {
1166 db(0xC0 | (reg << 3) | (r_m.GetReg().id & 0x7));
1167 } else if (r_m.IsMem()) {
1168 JITASM_ASSERT(r_m.GetBase().type == R_TYPE_GP && (r_m.GetIndex().type == R_TYPE_GP || r_m.GetIndex().type == R_TYPE_XMM || r_m.GetIndex().type == R_TYPE_YMM));
1169 int base = r_m.GetBase().id; if (base != INVALID) base &= 0x7;
1170 int index = r_m.GetIndex().id; if (index != INVALID) index &= 0x7;
1171
1172 if (base == INVALID && index == INVALID) {
1173 #ifdef JITASM64
1174 db(reg << 3 | 4);
1175 db(0x25);
1176 #else
1177 db(reg << 3 | 5);
1178 #endif
1179 dd(r_m.GetDisp());
1180 } else {
1181 JITASM_ASSERT(base != ESP || index != ESP);
1182 JITASM_ASSERT(index != ESP || r_m.GetScale() == 0);
1183
1184 if (index == ESP) {
1185 index = base;
1186 base = ESP;
1187 }
1188 bool sib = index != INVALID || r_m.GetScale() || base == ESP;
1189
1190 // ModR/M
1191 uint8 mod = 0;
1192 if (r_m.GetDisp() == 0 || (sib && base == INVALID)) mod = base != EBP ? 0 : 1;
1193 else if (detail::IsInt8(r_m.GetDisp())) mod = 1;
1194 else if (detail::IsInt32(r_m.GetDisp())) mod = 2;
1195 else JITASM_ASSERT(0);
1196 db(mod << 6 | reg << 3 | (sib ? 4 : base));
1197
1198 // SIB
1199 if (sib) {
1200 uint8 ss = 0;
1201 if (r_m.GetScale() == 0) ss = 0;
1202 else if (r_m.GetScale() == 2) ss = 1;
1203 else if (r_m.GetScale() == 4) ss = 2;
1204 else if (r_m.GetScale() == 8) ss = 3;
1205 else JITASM_ASSERT(0);
1206 if (index != INVALID && base != INVALID) {
1207 db(ss << 6 | index << 3 | base);
1208 } else if (base != INVALID) {
1209 db(ss << 6 | 4 << 3 | base);
1210 } else if (index != INVALID) {
1211 db(ss << 6 | index << 3 | 5);
1212 } else {
1213 JITASM_ASSERT(0);
1214 }
1215 }
1216
1217 // Displacement
1218 if (mod == 0 && sib && base == INVALID) dd(r_m.GetDisp());
1219 if (mod == 1) db(r_m.GetDisp());
1220 if (mod == 2) dd(r_m.GetDisp());
1221 }
1222 } else {
1223 JITASM_ASSERT(0);
1224 }
1225 }
1226
1227 void EncodeOpcode(uint32 opcode)
1228 {
1229 if (opcode & 0xFF000000) db((opcode >> 24) & 0xFF);
1230 if (opcode & 0xFFFF0000) db((opcode >> 16) & 0xFF);
1231 if (opcode & 0xFFFFFF00) db((opcode >> 8) & 0xFF);
1232 db(opcode & 0xFF);
1233 }
1234
1235 void EncodeImm(const detail::Opd& imm)
1236 {
1237 const OpdSize size = imm.GetSize();
1238 if (size == O_SIZE_8) db(imm.GetImm());
1239 else if (size == O_SIZE_16) dw(imm.GetImm());
1240 else if (size == O_SIZE_32) dd(imm.GetImm());
1241 else if (size == O_SIZE_64) dq(imm.GetImm());
1242 else JITASM_ASSERT(0);
1243 }
1244
1245 void Encode(const Instr& instr)
1246 {
1247 uint32 opcode = instr.opcode_;
1248
1249 const detail::Opd& opd1 = instr.GetOpd(0).IsDummy() ? detail::Opd() : instr.GetOpd(0); JITASM_ASSERT(!(opd1.IsReg() && opd1.GetReg().IsSymbolic()));
1250 const detail::Opd& opd2 = instr.GetOpd(1).IsDummy() ? detail::Opd() : instr.GetOpd(1); JITASM_ASSERT(!(opd2.IsReg() && opd2.GetReg().IsSymbolic()));
1251 const detail::Opd& opd3 = instr.GetOpd(2).IsDummy() ? detail::Opd() : instr.GetOpd(2); JITASM_ASSERT(!(opd3.IsReg() && opd3.GetReg().IsSymbolic()));
1252 const detail::Opd& opd4 = instr.GetOpd(3).IsDummy() ? detail::Opd() : instr.GetOpd(3); JITASM_ASSERT(!(opd4.IsReg() && opd4.GetReg().IsSymbolic()));
1253
1254 // +rb, +rw, +rd, +ro
1255 if (opd1.IsReg() && (opd2.IsNone() || opd2.IsImm())) {
1256 opcode += opd1.GetReg().id & 0x7;
1257 }
1258
1259 if ((opd1.IsImm() || opd1.IsReg()) && (opd2.IsReg() || opd2.IsMem())) { // ModR/M
1260 const detail::Opd& reg = opd1;
1261 const detail::Opd& r_m = opd2;
1262 const detail::Opd& vex = opd3;
1263 EncodePrefixes(instr.encoding_flag_, reg, r_m, vex);
1264 EncodeOpcode(opcode);
1265 EncodeModRM((uint8) (reg.IsImm() ? reg.GetImm() : reg.GetReg().id), r_m);
1266
1267 // /is4
1268 if (opd4.IsReg()) {
1269 EncodeImm(Imm8(static_cast<uint8>(opd4.GetReg().id << 4)));
1270 }
1271 } else {
1272 const detail::Opd& reg = detail::Opd();
1273 const detail::Opd& r_m = opd1.IsReg() ? opd1 : detail::Opd();
1274 const detail::Opd& vex = detail::Opd();
1275 EncodePrefixes(instr.encoding_flag_, reg, r_m, vex);
1276 EncodeOpcode(opcode);
1277 }
1278
1279 if (opd1.IsImm() && !opd2.IsReg() && !opd2.IsMem()) EncodeImm(opd1);
1280 if (opd2.IsImm()) EncodeImm(opd2);
1281 if (opd3.IsImm()) EncodeImm(opd3);
1282 if (opd4.IsImm()) EncodeImm(opd4);
1283 }
1284
1285 void EncodeALU(const Instr& instr, uint32 opcode)
1286 {
1287 const detail::Opd& reg = instr.GetOpd(1);
1288 const detail::Opd& imm = instr.GetOpd(2);
1289 JITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm());
1290
1291 if (reg.GetReg().id == EAX && (reg.GetSize() == O_SIZE_8 || !detail::IsInt8(imm.GetImm()))) {
1292 opcode |= (reg.GetSize() == O_SIZE_8 ? 0 : 1);
1293 Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm));
1294 } else {
1295 Encode(instr);
1296 }
1297 }
1298
1299 void EncodeJMP(const Instr& instr)
1300 {
1301 const detail::Opd& imm = instr.GetOpd(0);
1302 if (instr.GetID() == I_JMP) {
1303 Encode(Instr(instr.GetID(), imm.GetSize() == O_SIZE_8 ? 0xEB : 0xE9, instr.encoding_flag_, imm));
1304 } else if (instr.GetID() == I_JCC) {
1305 #ifndef JITASM64
1306 uint32 tttn = instr.opcode_;
1307 if (tttn == JCC_CXZ) Encode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm));
1308 else if (tttn == JCC_ECXZ) Encode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm));
1309 else Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm));
1310 #else
1311 uint32 tttn = instr.opcode_;
1312 if (tttn == JCC_ECXZ) Encode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm));
1313 else if (tttn == JCC_RCXZ) Encode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm));
1314 else Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm));
1315 #endif
1316 } else if (instr.GetID() == I_LOOP) {
1317 Encode(Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, imm));
1318 } else {
1319 JITASM_ASSERT(0);
1320 }
1321 }
1322
1323 void EncodeMOV(const Instr& instr)
1324 {
1325 #ifndef JITASM64
1326 const detail::Opd& reg = instr.GetOpd(0);
1327 const detail::Opd& mem = instr.GetOpd(1);
1328 JITASM_ASSERT(reg.IsReg() && mem.IsMem());
1329
1330 if (reg.GetReg().id == EAX && mem.GetBase().IsInvalid() && mem.GetIndex().IsInvalid()) {
1331 uint32 opcode = 0xA0 | (~instr.opcode_ & 0x2) | (instr.opcode_ & 1);
1332 Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, Imm32((sint32) mem.GetDisp())));
1333 } else {
1334 Encode(instr);
1335 }
1336 #else
1337 Encode(instr);
1338 #endif
1339 }
1340
1341 void EncodeTEST(const Instr& instr)
1342 {
1343 const detail::Opd& reg = instr.GetOpd(1);
1344 const detail::Opd& imm = instr.GetOpd(2);
1345 JITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm());
1346
1347 if (reg.GetReg().id == EAX) {
1348 uint32 opcode = 0xA8 | (reg.GetSize() == O_SIZE_8 ? 0 : 1);
1349 Encode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm));
1350 } else {
1351 Encode(instr);
1352 }
1353 }
1354
1355 void EncodeXCHG(const Instr& instr)
1356 {
1357 const detail::Opd& dst = instr.GetOpd(0);
1358 const detail::Opd& src = instr.GetOpd(1);
1359 JITASM_ASSERT(dst.IsReg() && src.IsReg());
1360
1361 if (dst.GetReg().id == EAX) {
1362 Encode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, src));
1363 } else if (src.GetReg().id == EAX) {
1364 Encode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, dst));
1365 } else {
1366 Encode(instr);
1367 }
1368 }
1369
1370 void Assemble(const Instr& instr)
1371 {
1372 if (instr.encoding_flag_ & E_SPECIAL) {
1373 switch (instr.GetID()) {
1374 case I_ADD: EncodeALU(instr, 0x04); break;
1375 case I_OR: EncodeALU(instr, 0x0C); break;
1376 case I_ADC: EncodeALU(instr, 0x14); break;
1377 case I_SBB: EncodeALU(instr, 0x1C); break;
1378 case I_AND: EncodeALU(instr, 0x24); break;
1379 case I_SUB: EncodeALU(instr, 0x2C); break;
1380 case I_XOR: EncodeALU(instr, 0x34); break;
1381 case I_CMP: EncodeALU(instr, 0x3C); break;
1382 case I_JMP: EncodeJMP(instr); break;
1383 case I_JCC: EncodeJMP(instr); break;
1384 case I_LOOP: EncodeJMP(instr); break;
1385 case I_MOV: EncodeMOV(instr); break;
1386 case I_TEST: EncodeTEST(instr); break;
1387 case I_XCHG: EncodeXCHG(instr); break;
1388 default: JITASM_ASSERT(0); break;
1389 }
1390 } else {
1391 Encode(instr);
1392 }
1393 }
1394
1395 static size_t GetInstrCodeSize(const Instr& instr)
1396 {
1397 Backend backend;
1398 backend.Assemble(instr);
1399 return backend.GetSize();
1400 }
1401 };
1402
1403 namespace detail
1404 {
1405 /// Counting 1-Bits
1406 inline uint32 Count1Bits(uint32 x)
1407 {
1408 x = x - ((x >> 1) & 0x55555555);
1409 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
1410 x = (x + (x >> 4)) & 0x0F0F0F0F;
1411 x = x + (x >> 8);
1412 x = x + (x >> 16);
1413 return x & 0x0000003F;
1414 }
1415
1416 /// The bit position of the first bit 1.
1417 inline uint32 bit_scan_forward(uint32 x)
1418 {
1419 JITASM_ASSERT(x != 0);
1420 #if defined(JITASM_GCC)
1421 return __builtin_ctz(x);
1422 #else
1423 unsigned long index;
1424 _BitScanForward(&index, x);
1425 return index;
1426 #endif
1427 }
1428
1429 /// The bit position of the last bit 1.
1430 inline uint32 bit_scan_reverse(uint32 x)
1431 {
1432 JITASM_ASSERT(x != 0);
1433 #if defined(JITASM_GCC)
1434 return 31 - __builtin_clz(x);
1435 #else
1436 unsigned long index;
1437 _BitScanReverse(&index, x);
1438 return index;
1439 #endif
1440 }
1441
1442 /// Prior iterator
1443 template<class It> It prior(const It &it) {
1444 It i = it;
1445 return --i;
1446 }
1447
1448 /// Next iterator
1449 template<class It> It next(const It &it) {
1450 It i = it;
1451 return ++i;
1452 }
1453
1454 /// Iterator range
1455 template<class T, class It = typename T::iterator> struct Range : std::pair<It, It> {
1456 typedef It Iterator;
1457 Range() : std::pair<It, It>() {}
1458 Range(const It& f, const It& s) : std::pair<It, It>(f, s) {}
1459 Range(T& container) : std::pair<It, It>(container.begin(), container.end()) {}
1460 bool empty() const {return this->first == this->second;}
1461 size_t size() const {return std::distance(this->first, this->second);}
1462 };
1463
1464 /// Const iterator range
1465 template<class T> struct ConstRange : Range<T, typename T::const_iterator> {
1466 ConstRange() : Range<T, typename T::const_iterator>() {}
1467 ConstRange(const typename T::const_iterator& f, const typename T::const_iterator& s) : Range<T, typename T::const_iterator>(f, s) {}
1468 ConstRange(const T& container) : Range<T, typename T::const_iterator>(container.begin(), container.end()) {}
1469 };
1470
1471 inline void append_num(std::string& str, size_t num)
1472 {
1473 if (num >= 10)
1474 append_num(str, num / 10);
1475 str.append(1, static_cast<char>('0' + num % 10));
1476 }
1477
1478 #if defined(JITASM_DEBUG_DUMP) && defined(JITASM_WIN)
1479 /// Debug trace
1480 inline void Trace(const char *format, ...)
1481 {
1482 char szBuf[256];
1483 va_list args;
1484 va_start(args, format);
1485 #if _MSC_VER >= 1400 // VC8 or later
1486 _vsnprintf_s(szBuf, sizeof(szBuf) / sizeof(char), format, args);
1487 #else
1488 vsnprintf(szBuf, sizeof(szBuf) / sizeof(char), format, args);
1489 #endif
1490 va_end(args);
1491 ::OutputDebugStringA(szBuf);
1492 }
1493 #endif
1494
1495 /// Executable code buffer
1496 class CodeBuffer
1497 {
1498 void* pbuff_;
1499 size_t codesize_;
1500 size_t buffsize_;
1501
1502 public:
1503 CodeBuffer() : pbuff_(NULL), codesize_(0), buffsize_(0) {}
1504 ~CodeBuffer() {Reset(0);}
1505
1506 void* GetPointer() const {return pbuff_;}
1507 size_t GetCodeSize() const {return codesize_;}
1508 size_t GetBufferSize() const {return buffsize_;}
1509
1510 bool Reset(size_t codesize)
1511 {
1512 if (pbuff_) {
1513 #if defined(JITASM_WIN)
1514 ::VirtualFree(pbuff_, 0, MEM_RELEASE);
1515 #else
1516 munmap(pbuff_, buffsize_);
1517 #endif
1518 pbuff_ = NULL;
1519 codesize_ = 0;
1520 buffsize_ = 0;
1521 }
1522 if (codesize) {
1523 #if defined(JITASM_WIN)
1524 void* pbuff = ::VirtualAlloc(NULL, codesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
1525 if (!pbuff) {
1526 JITASM_ASSERT(0);
1527 return false;
1528 }
1529 MEMORY_BASIC_INFORMATION info;
1530 ::VirtualQuery(pbuff, &info, sizeof(info));
1531 buffsize_ = info.RegionSize;
1532 #else
1533 int pagesize = getpagesize();
1534 size_t buffsize = (codesize + pagesize - 1) / pagesize * pagesize;
1535 void* pbuff = mmap(NULL, buffsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
1536 if (!pbuff) {
1537 JITASM_ASSERT(0);
1538 return false;
1539 }
1540 buffsize_ = buffsize;
1541 #endif
1542
1543 pbuff_ = pbuff;
1544 codesize_ = codesize;
1545 }
1546 return true;
1547 }
1548 };
1549
1550 /// Stack manager
1551 /**
1552 * <b>Stack layout</b>
1553 * \verbatim
1554 * +-----------------------+
1555 * | Caller return address |
1556 * +=======================+========
1557 * | ebp (rbp) |
1558 * +-----------------------+ <-- ebp (rbp)
1559 * | Saved gp registers |
1560 * +-----------------------+
1561 * | Padding for alignment |
1562 * +-----------------------+ <-- Stack base
1563 * | Spill slots and |
1564 * | local variable |
1565 * +-----------------------+ <-- esp (rsp)
1566 * \endverbatim
1567 */
1568 class StackManager
1569 {
1570 private:
1571 Addr stack_base_;
1572 uint32 stack_size_;
1573
1574 public:
1575 StackManager() : stack_base_(RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), 0), stack_size_(0) {}
1576
1577 /// Get allocated stack size
1578 uint32 GetSize() const {return (stack_size_ + 15) / 16 * 16; /* 16 bytes aligned*/}
1579
1580 /// Get stack base
1581 Addr GetStackBase() const {return stack_base_;}
1582
1583 /// Set stack base
1584 void SetStackBase(const Addr& stack_base) {stack_base_ = stack_base;}
1585
1586 /// Allocate stack
1587 Addr Alloc(uint32 size, uint32 alignment)
1588 {
1589 stack_size_ = (stack_size_ + alignment - 1) / alignment * alignment;
1590 stack_size_ += size;
1591 return stack_base_ - stack_size_;
1592 }
1593 };
1594
1595 /// Spin lock
1596 class SpinLock
1597 {
1598 long lock_;
1599 public:
1600 SpinLock() : lock_(0) {}
1601 void Lock() {while (interlocked_exchange(&lock_, 1));}
1602 void Unlock() {interlocked_exchange(&lock_, 0);}
1603 };
1604
1605 template<class Ty>
1606 class ScopedLock
1607 {
1608 Ty& lock_;
1609 ScopedLock<Ty>& operator=(const ScopedLock<Ty>&);
1610 public:
1611 ScopedLock(Ty& lock) : lock_(lock) {lock.Lock();}
1612 ~ScopedLock() {lock_.Unlock();}
1613 };
1614 } // namespace detail
1615
1616 // compiler prototype declaration
1617 struct Frontend;
1618 namespace compiler {
1619 void Compile(Frontend& f);
1620 }
1621
1622 /// jitasm frontend
1623 struct Frontend
1624 {
1625 typedef jitasm::Addr Addr;
1626 typedef jitasm::Reg Reg;
1627 typedef jitasm::Reg8 Reg8;
1628 typedef jitasm::Reg16 Reg16;
1629 typedef jitasm::Reg32 Reg32;
1630 #ifdef JITASM64
1631 typedef jitasm::Reg64 Reg64;
1632 #endif
1633 typedef jitasm::MmxReg MmxReg;
1634 typedef jitasm::XmmReg XmmReg;
1635 typedef jitasm::YmmReg YmmReg;
1636
1637 static Reg8 al, cl, dl, bl, ah, ch, dh, bh;
1638 static Reg16 ax, cx, dx, bx, sp, bp, si, di;
1639 static Reg32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
1640 static FpuReg_st0 st0;
1641 static FpuReg st1, st2, st3, st4, st5, st6, st7;
1642 static MmxReg mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
1643 static XmmReg xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
1644 static YmmReg ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7;
1645 #ifdef JITASM64
1646 static Reg8 r8b, r9b, r10b, r11b, r12b, r13b, r14b, r15b;
1647 static Reg16 r8w, r9w, r10w, r11w, r12w, r13w, r14w, r15w;
1648 static Reg32 r8d, r9d, r10d, r11d, r12d, r13d, r14d, r15d;
1649 static Reg64 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;
1650 static XmmReg xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
1651 static YmmReg ymm8, ymm9, ymm10, ymm11, ymm12, ymm13, ymm14, ymm15;
1652 #endif
1653
1654 AddressingPtr<Opd8> byte_ptr;
1655 AddressingPtr<Opd16> word_ptr;
1656 AddressingPtr<Opd32> dword_ptr;
1657 AddressingPtr<Opd64> qword_ptr;
1658 AddressingPtr<Opd64> mmword_ptr;
1659 AddressingPtr<Opd128> xmmword_ptr;
1660 AddressingPtr<Opd256> ymmword_ptr;
1661 AddressingPtr<Opd32> real4_ptr;
1662 AddressingPtr<Opd64> real8_ptr;
1663 AddressingPtr<Opd80> real10_ptr;
1664 AddressingPtr<Opd16> m2byte_ptr;
1665 AddressingPtr<Opd224> m28byte_ptr;
1666 AddressingPtr<Opd864> m108byte_ptr;
1667 AddressingPtr<Opd4096> m512byte_ptr;
1668
1669 static Reg zax, zcx, zdx, zbx, zsp, zbp, zsi, zdi;
1670 #ifdef JITASM64
1671 AddressingPtr<Opd64> ptr;
1672 #else
1673 AddressingPtr<Opd32> ptr;
1674 #endif
1675
1676 typedef std::vector<Instr> InstrList;
1677 InstrList instrs_;
1678 bool assembled_;
1679 bool avx_epilog_; // PF AVS+: avoid AVX transition penalties
1680 detail::CodeBuffer codebuff_;
1681 detail::SpinLock codelock_;
1682 detail::StackManager stack_manager_;
1683
1684 struct Label
1685 {
1686 std::string name;
1687 size_t instr_number;
1688 explicit Label(const std::string& name_) : name(name_), instr_number(0) {}
1689 };
1690 typedef std::deque<Label> LabelList;
1691 LabelList labels_;
1692
1693
1694 Frontend() : assembled_(false) {}
1695 virtual ~Frontend() {}
1696
1697 virtual void InternalMain() = 0;
1698
1699 /// Declare variable of the function argument on register
1700 void DeclareRegArg(const detail::Opd& var, const detail::Opd& arg, const detail::Opd& spill_slot = detail::Opd())
1701 {
1702 JITASM_ASSERT(var.IsReg() && arg.IsReg());
1703 // Insert special instruction after Prolog
1704 InstrList::iterator it = instrs_.begin();
1705 if (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it;
1706 // The arg is passed as register constraint of the var.
1707 instrs_.insert(it, Instr(I_COMPILER_DECLARE_REG_ARG, 0, E_SPECIAL, Dummy(W(var), arg), spill_slot));
1708 }
1709
1710 /// Declare variable of the function argument on stack
1711 void DeclareStackArg(const detail::Opd& var, const detail::Opd& arg)
1712 {
1713 JITASM_ASSERT(var.IsReg() && arg.IsMem());
1714 // Insert special instruction after Prolog
1715 InstrList::iterator it = instrs_.begin();
1716 if (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it;
1717 instrs_.insert(it, Instr(I_COMPILER_DECLARE_STACK_ARG, 0, E_SPECIAL, W(var), R(arg)));
1718 }
1719
1720 /// Declare variable of the function result on register
1721 void DeclareResultReg(const detail::Opd& var)
1722 {
1723 JITASM_ASSERT(var.IsReg());
1724 // The result register is passed as register constraint of the var.
1725 if (var.IsGpReg()) {
1726 AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), zax));
1727 } else if (var.IsMmxReg()) {
1728 AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), mm0));
1729 } else if (var.IsXmmReg()) {
1730 AppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), xmm0));
1731 }
1732 }
1733
1734 /// Function prolog
1735 void Prolog()
1736 {
1737 AppendInstr(I_COMPILER_PROLOG, 0, E_SPECIAL);
1738 }
1739
1740 /// Function epilog
1741 void Epilog()
1742 {
1743 AppendInstr(I_COMPILER_EPILOG, 0, E_SPECIAL);
1744 }
1745
1746 static bool IsJump(InstrID id)
1747 {
1748 return id == I_JMP || id == I_JCC || id == I_LOOP;
1749 }
1750
1751 size_t GetJumpTo(const Instr& instr) const
1752 {
1753 size_t label_id = (size_t) instr.GetOpd(0).GetImm();
1754 JITASM_ASSERT(labels_[label_id].instr_number != (size_t)-1); // invalid label
1755 return labels_[label_id].instr_number;
1756 }
1757
1758 // TODO: Return an error when there is no destination.
1759 void ResolveJump()
1760 {
1761 // Replace label indexes with instruncion numbers.
1762 for (InstrList::iterator it = instrs_.begin(); it != instrs_.end(); ++it) {
1763 Instr& instr = *it;
1764 if (IsJump(instr.GetID())) {
1765 instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8(0x7F), Imm64(GetJumpTo(instr))); // Opd(0) = max value in sint8, Opd(1) = instruction number
1766 }
1767 }
1768
1769 // Resolve operand sizes.
1770 std::vector<int> offsets;
1771 offsets.reserve(instrs_.size() + 1);
1772 bool retry;
1773 do {
1774 offsets.clear();
1775 offsets.push_back(0);
1776 Backend pre;
1777 for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {
1778 pre.Assemble(*it);
1779 offsets.push_back((int) pre.GetSize());
1780 }
1781
1782 retry = false;
1783 for (size_t i = 0; i < instrs_.size(); i++) {
1784 Instr& instr = instrs_[i];
1785 if (IsJump(instr.GetID())) {
1786 size_t d = (size_t) instr.GetOpd(1).GetImm();
1787 int rel = (int) offsets[d] - offsets[i + 1];
1788 OpdSize size = instr.GetOpd(0).GetSize();
1789 if (size == O_SIZE_8) {
1790 if (!detail::IsInt8(rel)) {
1791 // jrcxz, jcxz, jecxz, loop, loope, loopne are only for short jump
1792 uint32 tttn = instr.opcode_;
1793 if (instr.GetID() == I_JCC && (tttn == JCC_CXZ || tttn == JCC_ECXZ || tttn == JCC_RCXZ)) JITASM_ASSERT(0);
1794 if (instr.GetID() == I_LOOP) JITASM_ASSERT(0);
1795
1796 // Retry with immediate 32
1797 instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32(0x7FFFFFFF), Imm64(instr.GetOpd(1).GetImm()));
1798 retry = true;
1799 }
1800 } else if (size == O_SIZE_32) {
1801 JITASM_ASSERT(detail::IsInt32(rel)); // There is no jump instruction larger than immediate 32.
1802 }
1803 }
1804 }
1805 } while (retry);
1806
1807 // Resolve immediates
1808 for (size_t i = 0; i < instrs_.size(); i++) {
1809 Instr& instr = instrs_[i];
1810 if (IsJump(instr.GetID())) {
1811 size_t d = (size_t) instr.GetOpd(1).GetImm();
1812 int rel = (int) offsets[d] - offsets[i + 1];
1813 OpdSize size = instr.GetOpd(0).GetSize();
1814 if (size == O_SIZE_8) {
1815 JITASM_ASSERT(detail::IsInt8(rel));
1816 instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8((uint8) rel));
1817 } else if (size == O_SIZE_32) {
1818 JITASM_ASSERT(detail::IsInt32(rel));
1819 instr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32((uint32) rel));
1820 }
1821 }
1822 }
1823 }
1824
1825 /// Assemble
1826 void Assemble()
1827 {
1828 detail::ScopedLock<detail::SpinLock> lock(codelock_);
1829 if (assembled_) return;
1830
1831 instrs_.clear();
1832 labels_.clear();
1833 instrs_.reserve(128);
1834
1835 InternalMain();
1836 compiler::Compile(*this);
1837
1838 // Resolve jump instructions
1839 if (!labels_.empty()) {
1840 ResolveJump();
1841 }
1842
1843 // Count total size of machine code
1844 Backend pre;
1845 for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {
1846 pre.Assemble(*it);
1847 }
1848 size_t codesize = pre.GetSize();
1849
1850 // Write machine code to the buffer
1851 codebuff_.Reset(codesize);
1852 Backend backend(codebuff_.GetPointer(), codebuff_.GetBufferSize());
1853 for (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {
1854 backend.Assemble(*it);
1855 }
1856
1857 InstrList().swap(instrs_);
1858 LabelList().swap(labels_);
1859 assembled_ = true;
1860 }
1861
1862 /// Get assembled code
1863 void *GetCode(bool force_avx_epilog = false)
1864 {
1865 avx_epilog_ = force_avx_epilog; // PF AVS+: anti penalty
1866 if (!assembled_) {
1867 Assemble();
1868 }
1869 return codebuff_.GetPointer();
1870 }
1871
1872 /// Get total size of machine code
1873 size_t GetCodeSize() const
1874 {
1875 return codebuff_.GetCodeSize();
1876 }
1877
1878 void AppendInstr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd())
1879 {
1880 instrs_.push_back(Instr(id, opcode, encoding_flag, opd1, opd2, opd3, opd4, opd5, opd6));
1881 }
1882
1883 void AppendJmp(size_t label_id)
1884 {
1885 AppendInstr(I_JMP, 0, E_SPECIAL, Imm64(label_id));
1886 }
1887
1888 void AppendJcc(JumpCondition jcc, size_t label_id)
1889 {
1890 AppendInstr(I_JCC, jcc, E_SPECIAL, Imm64(label_id));
1891 }
1892
1893 /// Change label id of jump instruction
1894 static void ChangeLabelID(Instr& instr, size_t label_id)
1895 {
1896 JITASM_ASSERT(IsJump(instr.id_) && instr.GetOpd(0).IsImm());
1897 instr.GetOpd(0).imm_ = label_id;
1898 }
1899
1900 size_t NewLabelID(const std::string& label_name)
1901 {
1902 labels_.push_back(Label(label_name));
1903 return labels_.size() - 1;
1904 }
1905
1906 size_t GetLabelID(const std::string& label_name)
1907 {
1908 for (size_t i = 0; i < labels_.size(); i++) {
1909 if (labels_[i].name == label_name) {
1910 return i;
1911 }
1912 }
1913 return NewLabelID(label_name);
1914 }
1915
1916 void L(size_t label_id)
1917 {
1918 labels_[label_id].instr_number = instrs_.size(); // Label current instruction
1919 }
1920
1921 /// Label
1922 void L(const std::string& label_name)
1923 {
1924 JITASM_ASSERT(!label_name.empty());
1925 L(GetLabelID(label_name));
1926 }
1927
1928 // General-Purpose Instructions
1929 void adc(const Reg8& dst, const Imm8& imm) {AppendInstr(I_ADC, 0x80, E_SPECIAL, Imm8(2), RW(dst), imm);}
1930 void adc(const Mem8& dst, const Imm8& imm) {AppendInstr(I_ADC, 0x80, 0, Imm8(2), RW(dst), imm);}
1931 void adc(const Reg16& dst, const Imm16& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1932 void adc(const Mem16& dst, const Imm16& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1933 void adc(const Reg32& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1934 void adc(const Mem32& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1935 void adc(const Reg8& dst, const Reg8& src) {AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));}
1936 void adc(const Mem8& dst, const Reg8& src) {AppendInstr(I_ADC, 0x10, 0, R(src), RW(dst));}
1937 void adc(const Reg8& dst, const Mem8& src) {AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));}
1938 void adc(const Reg16& dst, const Reg16& src) {AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1939 void adc(const Mem16& dst, const Reg16& src) {AppendInstr(I_ADC, 0x11, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
1940 void adc(const Reg16& dst, const Mem16& src) {AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1941 void adc(const Reg32& dst, const Reg32& src) {AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));}
1942 void adc(const Mem32& dst, const Reg32& src) {AppendInstr(I_ADC, 0x11, 0, R(src), RW(dst));}
1943 void adc(const Reg32& dst, const Mem32& src) {AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));}
1944 #ifdef JITASM64
1945 void adc(const Reg64& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1946 void adc(const Mem64& dst, const Imm32& imm) {AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));}
1947 void adc(const Reg64& dst, const Reg64& src) {AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));}
1948 void adc(const Mem64& dst, const Reg64& src) {AppendInstr(I_ADC, 0x11, E_REXW_PREFIX, R(src), RW(dst));}
1949 void adc(const Reg64& dst, const Mem64& src) {AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));}
1950 #endif
1951 void add(const Reg8& dst, const Imm8& imm) {AppendInstr(I_ADD, 0x80, E_SPECIAL, Imm8(0), RW(dst), imm);}
1952 void add(const Mem8& dst, const Imm8& imm) {AppendInstr(I_ADD, 0x80, 0, Imm8(0), RW(dst), imm);}
1953 void add(const Reg16& dst, const Imm16& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1954 void add(const Mem16& dst, const Imm16& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1955 void add(const Reg32& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1956 void add(const Mem32& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1957 void add(const Reg8& dst, const Reg8& src) {AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));}
1958 void add(const Mem8& dst, const Reg8& src) {AppendInstr(I_ADD, 0x00, 0, R(src), RW(dst));}
1959 void add(const Reg8& dst, const Mem8& src) {AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));}
1960 void add(const Reg16& dst, const Reg16& src) {AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1961 void add(const Mem16& dst, const Reg16& src) {AppendInstr(I_ADD, 0x01, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
1962 void add(const Reg16& dst, const Mem16& src) {AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1963 void add(const Reg32& dst, const Reg32& src) {AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));}
1964 void add(const Mem32& dst, const Reg32& src) {AppendInstr(I_ADD, 0x01, 0, R(src), RW(dst));}
1965 void add(const Reg32& dst, const Mem32& src) {AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));}
1966 #ifdef JITASM64
1967 void add(const Reg64& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1968 void add(const Mem64& dst, const Imm32& imm) {AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));}
1969 void add(const Reg64& dst, const Reg64& src) {AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));}
1970 void add(const Mem64& dst, const Reg64& src) {AppendInstr(I_ADD, 0x01, E_REXW_PREFIX, R(src), RW(dst));}
1971 void add(const Reg64& dst, const Mem64& src) {AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));}
1972 #endif
1973 void and_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_AND, 0x80, E_SPECIAL, Imm8(4), RW(dst), imm);}
1974 void and_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_AND, 0x80, 0, Imm8(4), RW(dst), imm);}
1975 void and_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1976 void and_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1977 void and_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1978 void and_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1979 void and_(const Reg8& dst, const Reg8& src) {AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));}
1980 void and_(const Mem8& dst, const Reg8& src) {AppendInstr(I_AND, 0x20, 0, R(src), RW(dst));}
1981 void and_(const Reg8& dst, const Mem8& src) {AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));}
1982 void and_(const Reg16& dst, const Reg16& src) {AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1983 void and_(const Mem16& dst, const Reg16& src) {AppendInstr(I_AND, 0x21, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
1984 void and_(const Reg16& dst, const Mem16& src) {AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
1985 void and_(const Reg32& dst, const Reg32& src) {AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));}
1986 void and_(const Mem32& dst, const Reg32& src) {AppendInstr(I_AND, 0x21, 0, R(src), RW(dst));}
1987 void and_(const Reg32& dst, const Mem32& src) {AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));}
1988 #ifdef JITASM64
1989 // and with Imm32 is sign extended
1990 void and_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1991 void and_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));}
1992 void and_(const Reg64& dst, const Reg64& src) {AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));}
1993 void and_(const Mem64& dst, const Reg64& src) {AppendInstr(I_AND, 0x21, E_REXW_PREFIX, R(src), RW(dst));}
1994 void and_(const Reg64& dst, const Mem64& src) {AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));}
1995 #endif
1996 void bsf(const Reg16& dst, const Reg16& src) {AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
1997 void bsf(const Reg16& dst, const Mem16& src) {AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
1998 void bsf(const Reg32& dst, const Reg32& src) {AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));}
1999 void bsf(const Reg32& dst, const Mem32& src) {AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));}
2000 #ifdef JITASM64
2001 void bsf(const Reg64& dst, const Reg64& src) {AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));}
2002 void bsf(const Reg64& dst, const Mem64& src) {AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));}
2003 #endif
2004 void bsr(const Reg16& dst, const Reg16& src) {AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2005 void bsr(const Reg16& dst, const Mem16& src) {AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2006 void bsr(const Reg32& dst, const Reg32& src) {AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));}
2007 void bsr(const Reg32& dst, const Mem32& src) {AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));}
2008 #ifdef JITASM64
2009 void bsr(const Reg64& dst, const Reg64& src) {AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));}
2010 void bsr(const Reg64& dst, const Mem64& src) {AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));}
2011 #endif
2012 void bswap(const Reg32& dst) {AppendInstr(I_BSWAP, 0x0FC8, 0, RW(dst));}
2013 #ifdef JITASM64
2014 void bswap(const Reg64& dst) {AppendInstr(I_BSWAP, 0x0FC8, E_REXW_PREFIX, RW(dst));}
2015 #endif
2016 void bt(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));}
2017 void bt(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));}
2018 void bt(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));}
2019 void bt(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));}
2020 void bt(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);}
2021 void bt(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);}
2022 void bt(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);}
2023 void bt(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);}
2024 #ifdef JITASM64
2025 void bt(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));}
2026 void bt(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));}
2027 void bt(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);}
2028 void bt(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);}
2029 #endif
2030 void btc(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2031 void btc(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2032 void btc(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));}
2033 void btc(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));}
2034 void btc(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);}
2035 void btc(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);}
2036 void btc(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);}
2037 void btc(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);}
2038 #ifdef JITASM64
2039 void btc(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2040 void btc(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2041 void btc(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);}
2042 void btc(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);}
2043 #endif
2044 void btr(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2045 void btr(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2046 void btr(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));}
2047 void btr(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));}
2048 void btr(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);}
2049 void btr(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);}
2050 void btr(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);}
2051 void btr(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);}
2052 #ifdef JITASM64
2053 void btr(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2054 void btr(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2055 void btr(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);}
2056 void btr(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);}
2057 #endif
2058 void bts(const Reg16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2059 void bts(const Mem16& bitbase, const Reg16& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}
2060 void bts(const Reg32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));}
2061 void bts(const Mem32& bitbase, const Reg32& bitoffset) {AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));}
2062 void bts(const Reg16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);}
2063 void bts(const Mem16& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);}
2064 void bts(const Reg32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);}
2065 void bts(const Mem32& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);}
2066 #ifdef JITASM64
2067 void bts(const Reg64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2068 void bts(const Mem64& bitbase, const Reg64& bitoffset) {AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}
2069 void bts(const Reg64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);}
2070 void bts(const Mem64& bitbase, const Imm8& bitoffset) {AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);}
2071 #endif
2072 #ifndef JITASM64
2073 void call(const Reg16& dst) {AppendInstr(I_CALL, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(2), R(dst));}
2074 void call(const Reg32& dst) {AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));}
2075 #else
2076 void call(const Reg64& dst) {AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));}
2077 #endif
2078 void cbw() {AppendInstr(I_CBW, 0x98, E_OPERAND_SIZE_PREFIX, Dummy(RW(eax)));}
2079 void cwde() {AppendInstr(I_CBW, 0x98, 0, Dummy(RW(eax)));}
2080 #ifdef JITASM64
2081 void cdqe() {AppendInstr(I_CBW, 0x98, E_REXW_PREFIX, Dummy(RW(eax)));}
2082 #endif
2083 void clc() {AppendInstr(I_CLC, 0xF8, 0);}
2084 void cld() {AppendInstr(I_CLD, 0xFC, 0);}
2085 void cli() {AppendInstr(I_CLI, 0xFA, 0);}
2086 #ifdef JITASM64
2087 void clts() {AppendInstr(I_CLTS, 0x0F06, 0);}
2088 #endif
2089 void cmc() {AppendInstr(I_CMC, 0xF5, 0);}
2090 void cmova(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2091 void cmova(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2092 void cmovae(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2093 void cmovae(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2094 void cmovb(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2095 void cmovb(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2096 void cmovbe(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2097 void cmovbe(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2098 void cmovc(const Reg16& dst, const Reg16& src) {cmovb(dst, src);}
2099 void cmovc(const Reg16& dst, const Mem16& src) {cmovb(dst, src);}
2100 void cmove(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2101 void cmove(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2102 void cmovg(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2103 void cmovg(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2104 void cmovge(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2105 void cmovge(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2106 void cmovl(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2107 void cmovl(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2108 void cmovle(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2109 void cmovle(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2110 void cmovna(const Reg16& dst, const Reg16& src) {cmovbe(dst, src);}
2111 void cmovna(const Reg16& dst, const Mem16& src) {cmovbe(dst, src);}
2112 void cmovnae(const Reg16& dst, const Reg16& src) {cmovb(dst, src);}
2113 void cmovnae(const Reg16& dst, const Mem16& src) {cmovb(dst, src);}
2114 void cmovnb(const Reg16& dst, const Reg16& src) {cmovae(dst, src);}
2115 void cmovnb(const Reg16& dst, const Mem16& src) {cmovae(dst, src);}
2116 void cmovnbe(const Reg16& dst, const Reg16& src) {cmova(dst, src);}
2117 void cmovnbe(const Reg16& dst, const Mem16& src) {cmova(dst, src);}
2118 void cmovnc(const Reg16& dst, const Reg16& src) {cmovae(dst, src);}
2119 void cmovnc(const Reg16& dst, const Mem16& src) {cmovae(dst, src);}
2120 void cmovne(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2121 void cmovne(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2122 void cmovng(const Reg16& dst, const Reg16& src) {cmovle(dst, src);}
2123 void cmovng(const Reg16& dst, const Mem16& src) {cmovle(dst, src);}
2124 void cmovnge(const Reg16& dst, const Reg16& src) {cmovl(dst, src);}
2125 void cmovnge(const Reg16& dst, const Mem16& src) {cmovl(dst, src);}
2126 void cmovnl(const Reg16& dst, const Reg16& src) {cmovge(dst, src);}
2127 void cmovnl(const Reg16& dst, const Mem16& src) {cmovge(dst, src);}
2128 void cmovnle(const Reg16& dst, const Reg16& src) {cmovg(dst, src);}
2129 void cmovnle(const Reg16& dst, const Mem16& src) {cmovg(dst, src);}
2130 void cmovno(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2131 void cmovno(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2132 void cmovnp(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2133 void cmovnp(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2134 void cmovns(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2135 void cmovns(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2136 void cmovnz(const Reg16& dst, const Reg16& src) {cmovne(dst, src);}
2137 void cmovnz(const Reg16& dst, const Mem16& src) {cmovne(dst, src);}
2138 void cmovo(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2139 void cmovo(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2140 void cmovp(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2141 void cmovp(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2142 void cmovpe(const Reg16& dst, const Reg16& src) {cmovp(dst, src);}
2143 void cmovpe(const Reg16& dst, const Mem16& src) {cmovp(dst, src);}
2144 void cmovpo(const Reg16& dst, const Reg16& src) {cmovnp(dst, src);}
2145 void cmovpo(const Reg16& dst, const Mem16& src) {cmovnp(dst, src);}
2146 void cmovs(const Reg16& dst, const Reg16& src) {AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2147 void cmovs(const Reg16& dst, const Mem16& src) {AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2148 void cmovz(const Reg16& dst, const Reg16& src) {cmove(dst, src);}
2149 void cmovz(const Reg16& dst, const Mem16& src) {cmove(dst, src);}
2150 void cmova(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));}
2151 void cmova(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));}
2152 void cmovae(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));}
2153 void cmovae(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));}
2154 void cmovb(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));}
2155 void cmovb(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));}
2156 void cmovbe(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));}
2157 void cmovbe(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));}
2158 void cmovc(const Reg32& dst, const Reg32& src) {cmovb(dst, src);}
2159 void cmovc(const Reg32& dst, const Mem32& src) {cmovb(dst, src);}
2160 void cmove(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));}
2161 void cmove(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));}
2162 void cmovg(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));}
2163 void cmovg(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));}
2164 void cmovge(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));}
2165 void cmovge(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));}
2166 void cmovl(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));}
2167 void cmovl(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));}
2168 void cmovle(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));}
2169 void cmovle(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));}
2170 void cmovna(const Reg32& dst, const Reg32& src) {cmovbe(dst, src);}
2171 void cmovna(const Reg32& dst, const Mem32& src) {cmovbe(dst, src);}
2172 void cmovnae(const Reg32& dst, const Reg32& src) {cmovb(dst, src);}
2173 void cmovnae(const Reg32& dst, const Mem32& src) {cmovb(dst, src);}
2174 void cmovnb(const Reg32& dst, const Reg32& src) {cmovae(dst, src);}
2175 void cmovnb(const Reg32& dst, const Mem32& src) {cmovae(dst, src);}
2176 void cmovnbe(const Reg32& dst, const Reg32& src) {cmova(dst, src);}
2177 void cmovnbe(const Reg32& dst, const Mem32& src) {cmova(dst, src);}
2178 void cmovnc(const Reg32& dst, const Reg32& src) {cmovae(dst, src);}
2179 void cmovnc(const Reg32& dst, const Mem32& src) {cmovae(dst, src);}
2180 void cmovne(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));}
2181 void cmovne(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));}
2182 void cmovng(const Reg32& dst, const Reg32& src) {cmovle(dst, src);}
2183 void cmovng(const Reg32& dst, const Mem32& src) {cmovle(dst, src);}
2184 void cmovnge(const Reg32& dst, const Reg32& src) {cmovl(dst, src);}
2185 void cmovnge(const Reg32& dst, const Mem32& src) {cmovl(dst, src);}
2186 void cmovnl(const Reg32& dst, const Reg32& src) {cmovge(dst, src);}
2187 void cmovnl(const Reg32& dst, const Mem32& src) {cmovge(dst, src);}
2188 void cmovnle(const Reg32& dst, const Reg32& src) {cmovg(dst, src);}
2189 void cmovnle(const Reg32& dst, const Mem32& src) {cmovg(dst, src);}
2190 void cmovno(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));}
2191 void cmovno(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));}
2192 void cmovnp(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));}
2193 void cmovnp(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));}
2194 void cmovns(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));}
2195 void cmovns(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));}
2196 void cmovnz(const Reg32& dst, const Reg32& src) {cmovne(dst, src);}
2197 void cmovnz(const Reg32& dst, const Mem32& src) {cmovne(dst, src);}
2198 void cmovo(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));}
2199 void cmovo(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));}
2200 void cmovp(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));}
2201 void cmovp(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));}
2202 void cmovpe(const Reg32& dst, const Reg32& src) {cmovp(dst, src);}
2203 void cmovpe(const Reg32& dst, const Mem32& src) {cmovp(dst, src);}
2204 void cmovpo(const Reg32& dst, const Reg32& src) {cmovnp(dst, src);}
2205 void cmovpo(const Reg32& dst, const Mem32& src) {cmovnp(dst, src);}
2206 void cmovs(const Reg32& dst, const Reg32& src) {AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));}
2207 void cmovs(const Reg32& dst, const Mem32& src) {AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));}
2208 void cmovz(const Reg32& dst, const Reg32& src) {cmove(dst, src);}
2209 void cmovz(const Reg32& dst, const Mem32& src) {cmove(dst, src);}
2210 #ifdef JITASM64
2211 void cmova(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));}
2212 void cmova(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));}
2213 void cmovae(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));}
2214 void cmovae(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));}
2215 void cmovb(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));}
2216 void cmovb(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));}
2217 void cmovbe(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));}
2218 void cmovbe(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));}
2219 void cmovc(const Reg64& dst, const Reg64& src) {cmovb(dst, src);}
2220 void cmovc(const Reg64& dst, const Mem64& src) {cmovb(dst, src);}
2221 void cmove(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));}
2222 void cmove(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));}
2223 void cmovg(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));}
2224 void cmovg(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));}
2225 void cmovge(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));}
2226 void cmovge(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));}
2227 void cmovl(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));}
2228 void cmovl(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));}
2229 void cmovle(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));}
2230 void cmovle(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));}
2231 void cmovna(const Reg64& dst, const Reg64& src) {cmovbe(dst, src);}
2232 void cmovna(const Reg64& dst, const Mem64& src) {cmovbe(dst, src);}
2233 void cmovnae(const Reg64& dst, const Reg64& src) {cmovb(dst, src);}
2234 void cmovnae(const Reg64& dst, const Mem64& src) {cmovb(dst, src);}
2235 void cmovnb(const Reg64& dst, const Reg64& src) {cmovae(dst, src);}
2236 void cmovnb(const Reg64& dst, const Mem64& src) {cmovae(dst, src);}
2237 void cmovnbe(const Reg64& dst, const Reg64& src) {cmova(dst, src);}
2238 void cmovnbe(const Reg64& dst, const Mem64& src) {cmova(dst, src);}
2239 void cmovnc(const Reg64& dst, const Reg64& src) {cmovae(dst, src);}
2240 void cmovnc(const Reg64& dst, const Mem64& src) {cmovae(dst, src);}
2241 void cmovne(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));}
2242 void cmovne(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));}
2243 void cmovng(const Reg64& dst, const Reg64& src) {cmovle(dst, src);}
2244 void cmovng(const Reg64& dst, const Mem64& src) {cmovle(dst, src);}
2245 void cmovnge(const Reg64& dst, const Reg64& src) {cmovl(dst, src);}
2246 void cmovnge(const Reg64& dst, const Mem64& src) {cmovl(dst, src);}
2247 void cmovnl(const Reg64& dst, const Reg64& src) {cmovge(dst, src);}
2248 void cmovnl(const Reg64& dst, const Mem64& src) {cmovge(dst, src);}
2249 void cmovnle(const Reg64& dst, const Reg64& src) {cmovg(dst, src);}
2250 void cmovnle(const Reg64& dst, const Mem64& src) {cmovg(dst, src);}
2251 void cmovno(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));}
2252 void cmovno(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));}
2253 void cmovnp(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));}
2254 void cmovnp(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));}
2255 void cmovns(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));}
2256 void cmovns(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));}
2257 void cmovnz(const Reg64& dst, const Reg64& src) {cmovne(dst, src);}
2258 void cmovnz(const Reg64& dst, const Mem64& src) {cmovne(dst, src);}
2259 void cmovo(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));}
2260 void cmovo(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));}
2261 void cmovp(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));}
2262 void cmovp(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));}
2263 void cmovpe(const Reg64& dst, const Reg64& src) {cmovp(dst, src);}
2264 void cmovpe(const Reg64& dst, const Mem64& src) {cmovp(dst, src);}
2265 void cmovpo(const Reg64& dst, const Reg64& src) {cmovnp(dst, src);}
2266 void cmovpo(const Reg64& dst, const Mem64& src) {cmovnp(dst, src);}
2267 void cmovs(const Reg64& dst, const Reg64& src) {AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));}
2268 void cmovs(const Reg64& dst, const Mem64& src) {AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));}
2269 void cmovz(const Reg64& dst, const Reg64& src) {cmove(dst, src);}
2270 void cmovz(const Reg64& dst, const Mem64& src) {cmove(dst, src);}
2271 #endif
2272 void cmp(const Reg8& lhs, const Imm8& imm) {AppendInstr(I_CMP, 0x80, E_SPECIAL, Imm8(7), R(lhs), imm);}
2273 void cmp(const Mem8& lhs, const Imm8& imm) {AppendInstr(I_CMP, 0x80, 0, Imm8(7), R(lhs), imm);}
2274 void cmp(const Reg16& lhs, const Imm16& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2275 void cmp(const Mem16& lhs, const Imm16& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2276 void cmp(const Reg32& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2277 void cmp(const Mem32& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2278 void cmp(const Reg8& lhs, const Reg8& rhs) {AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));}
2279 void cmp(const Mem8& lhs, const Reg8& rhs) {AppendInstr(I_CMP, 0x38, 0, R(rhs), R(lhs));}
2280 void cmp(const Reg8& lhs, const Mem8& rhs) {AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));}
2281 void cmp(const Reg16& lhs, const Reg16& rhs) {AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));}
2282 void cmp(const Mem16& lhs, const Reg16& rhs) {AppendInstr(I_CMP, 0x39, E_OPERAND_SIZE_PREFIX, R(rhs), R(lhs));}
2283 void cmp(const Reg16& lhs, const Mem16& rhs) {AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));}
2284 void cmp(const Reg32& lhs, const Reg32& rhs) {AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));}
2285 void cmp(const Mem32& lhs, const Reg32& rhs) {AppendInstr(I_CMP, 0x39, 0, R(rhs), R(lhs));}
2286 void cmp(const Reg32& lhs, const Mem32& rhs) {AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));}
2287 #ifdef JITASM64
2288 void cmp(const Reg64& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2289 void cmp(const Mem64& lhs, const Imm32& imm) {AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));}
2290 void cmp(const Reg64& lhs, const Reg64& rhs) {AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));}
2291 void cmp(const Mem64& lhs, const Reg64& rhs) {AppendInstr(I_CMP, 0x39, E_REXW_PREFIX, R(rhs), R(lhs));}
2292 void cmp(const Reg64& lhs, const Mem64& rhs) {AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));}
2293 #endif
2294 void cmpsb() {AppendInstr(I_CMPS_B, 0xA6, 0, Dummy(RW(edi)), Dummy(RW(esi)));}
2295 void cmpsw() {AppendInstr(I_CMPS_W, 0xA7, E_OPERAND_SIZE_PREFIX, Dummy(RW(edi)), Dummy(RW(esi)));}
2296 void cmpsd() {AppendInstr(I_CMPS_D, 0xA7, 0, Dummy(RW(edi)), Dummy(RW(esi)));}
2297 #ifdef JITASM64
2298 void cmpsq() {AppendInstr(I_CMPS_Q, 0xA7, E_REXW_PREFIX, Dummy(RW(rdi)), Dummy(RW(rsi)));}
2299 #endif
2300 void cmpxchg(const Reg8& dst, const Reg8& src, const Reg8& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));}
2301 void cmpxchg(const Mem8& dst, const Reg8& src, const Reg8& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));}
2302 void cmpxchg(const Reg16& dst, const Reg16& src, const Reg16& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));}
2303 void cmpxchg(const Mem16& dst, const Reg16& src, const Reg16& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));}
2304 void cmpxchg(const Reg32& dst, const Reg32& src, const Reg32& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));}
2305 void cmpxchg(const Mem32& dst, const Reg32& src, const Reg32& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));}
2306 #ifdef JITASM64
2307 void cmpxchg(const Reg64& dst, const Reg64& src, const Reg64& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));}
2308 void cmpxchg(const Mem64& dst, const Reg64& src, const Reg64& cmpx) {AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));}
2309 #endif
2310 void cmpxchg8b(const Mem64& dst) {AppendInstr(I_CMPXCHG8B, 0x0FC7, 0, Imm8(1), RW(dst), Dummy(RW(edx)), Dummy(RW(eax)), Dummy(R(ecx)), Dummy(R(ebx)));}
2311 #ifdef JITASM64
2312 void cmpxchg16b(const Mem128& dst) {AppendInstr(I_CMPXCHG16B, 0x0FC7, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(RW(rdx)), Dummy(RW(rax)), Dummy(R(rcx)), Dummy(R(rbx)));}
2313 #endif
2314 void cpuid() {AppendInstr(I_CPUID, 0x0FA2, 0, Dummy(RW(eax)), Dummy(RW(ecx)), Dummy(W(ebx)), Dummy(W(edx)));}
2315 void cwd() {AppendInstr(I_CWD, 0x99, E_OPERAND_SIZE_PREFIX, Dummy(W(dx)), Dummy(R(ax)));}
2316 void cdq() {AppendInstr(I_CDQ, 0x99, 0, Dummy(W(edx)), Dummy(R(eax)));}
2317 #ifdef JITASM64
2318 void cqo() {AppendInstr(I_CQO, 0x99, E_REXW_PREFIX, Dummy(W(rdx)), Dummy(R(rax)));}
2319 #endif
2320 void dec(const Reg8& dst) {AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));}
2321 void dec(const Mem8& dst) {AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));}
2322 void dec(const Mem16& dst) {AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));}
2323 void dec(const Mem32& dst) {AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));}
2324 #ifndef JITASM64
2325 void dec(const Reg16& dst) {AppendInstr(I_DEC, 0x48, E_OPERAND_SIZE_PREFIX, RW(dst));}
2326 void dec(const Reg32& dst) {AppendInstr(I_DEC, 0x48, 0, RW(dst));}
2327 #else
2328 void dec(const Reg16& dst) {AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));}
2329 void dec(const Reg32& dst) {AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));}
2330 void dec(const Reg64& dst) {AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));}
2331 void dec(const Mem64& dst) {AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));}
2332 #endif
2333 void div(const Reg8& src) {AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));}
2334 void div(const Mem8& src) {AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));}
2335 void div(const Reg16& src) {AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}
2336 void div(const Mem16& src) {AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}
2337 void div(const Reg32& src) {AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}
2338 void div(const Mem32& src) {AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}
2339 #ifdef JITASM64
2340 void div(const Reg64& src) {AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}
2341 void div(const Mem64& src) {AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}
2342 #endif
2343 void enter(const Imm16& imm16, const Imm8& imm8) {AppendInstr(I_ENTER, 0xC8, 0, imm16, imm8, Dummy(RW(esp)), Dummy(RW(ebp)));}
2344 void hlt() {AppendInstr(I_HLT, 0xF4, 0);}
2345 void idiv(const Reg8& src) {AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));}
2346 void idiv(const Mem8& src) {AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));}
2347 void idiv(const Reg16& src) {AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}
2348 void idiv(const Mem16& src) {AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}
2349 void idiv(const Reg32& src) {AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}
2350 void idiv(const Mem32& src) {AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}
2351 #ifdef JITASM64
2352 void idiv(const Reg64& src) {AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}
2353 void idiv(const Mem64& src) {AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}
2354 #endif
2355 void imul(const Reg8& src) {AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));}
2356 void imul(const Mem8& src) {AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));}
2357 void imul(const Reg16& src) {AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));}
2358 void imul(const Mem16& src) {AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));}
2359 void imul(const Reg32& src) {AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));}
2360 void imul(const Mem32& src) {AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));}
2361 void imul(const Reg16& dst, const Reg16& src) {AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2362 void imul(const Reg16& dst, const Mem16& src) {AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2363 void imul(const Reg32& dst, const Reg32& src) {AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));}
2364 void imul(const Reg32& dst, const Mem32& src) {AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));}
2365 void imul(const Reg16& dst, const Reg16& src, const Imm16& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}
2366 void imul(const Reg16& dst, const Mem16& src, const Imm16& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}
2367 void imul(const Reg32& dst, const Reg32& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));}
2368 void imul(const Reg32& dst, const Mem32& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));}
2369 void imul(const Reg16& dst, const Imm16& imm) {imul(dst, dst, imm);}
2370 void imul(const Reg32& dst, const Imm32& imm) {imul(dst, dst, imm);}
2371 #ifdef JITASM64
2372 void imul(const Reg64& src) {AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}
2373 void imul(const Mem64& src) {AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}
2374 void imul(const Reg64& dst, const Reg64& src) {AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));}
2375 void imul(const Reg64& dst, const Mem64& src) {AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));}
2376 void imul(const Reg64& dst, const Reg64& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}
2377 void imul(const Reg64& dst, const Mem64& src, const Imm32& imm) {AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}
2378 void imul(const Reg64& dst, const Imm32& imm) {imul(dst, dst, imm);}
2379 #endif
2380 void in(const Reg8& dst, const Imm8& src) {AppendInstr(I_IN, 0xE4, 0, src, Dummy(W(dst),al));}
2381 void in(const Reg16& dst, const Imm8& src) {AppendInstr(I_IN, 0xE5, E_OPERAND_SIZE_PREFIX, src, Dummy(W(dst),ax));}
2382 void in(const Reg32& dst, const Imm8& src) {AppendInstr(I_IN, 0xE5, 0, src, Dummy(W(dst),eax));}
2383 void in(const Reg8& dst, const Reg16& src) {AppendInstr(I_IN, 0xEC, 0, Dummy(R(src),dx), Dummy(W(dst),al));}
2384 void in(const Reg16& dst, const Reg16& src) {AppendInstr(I_IN, 0xED, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(W(dst),ax));}
2385 void in(const Reg32& dst, const Reg16& src) {AppendInstr(I_IN, 0xED, 0, Dummy(R(src),dx), Dummy(W(dst),eax));}
2386 void inc(const Reg8& dst) {AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));}
2387 void inc(const Mem8& dst) {AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));}
2388 void inc(const Mem16& dst) {AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));}
2389 void inc(const Mem32& dst) {AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));}
2390 #ifndef JITASM64
2391 void inc(const Reg16& dst) {AppendInstr(I_INC, 0x40, E_OPERAND_SIZE_PREFIX, RW(dst));}
2392 void inc(const Reg32& dst) {AppendInstr(I_INC, 0x40, 0, RW(dst));}
2393 #else
2394 void inc(const Reg16& dst) {AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));}
2395 void inc(const Reg32& dst) {AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));}
2396 void inc(const Reg64& dst) {AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));}
2397 void inc(const Mem64& dst) {AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));}
2398 #endif
2399 void insb(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_B, 0x6C, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));}
2400 void insw(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_W, 0x6D, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi));}
2401 void insd(const Reg& dst, const Reg16& src) {AppendInstr(I_INS_D, 0x6D, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));}
2402 void rep_insb(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_B, 0x6C, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}
2403 void rep_insw(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_W, 0x6D, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}
2404 void rep_insd(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_INS_D, 0x6D, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}
2405 void int3() {AppendInstr(I_INT3, 0xCC, 0);}
2406 void intn(const Imm8& n) {AppendInstr(I_INTN, 0xCD, 0, n);}
2407 #ifndef JITASM64
2408 void into() {AppendInstr(I_INTO, 0xCE, 0);}
2409 #endif
2410 void invd() {AppendInstr(I_INVD, 0x0F08, 0);}
2411 template<class Ty> void invlpg(const MemT<Ty>& dst) {AppendInstr(I_INVLPG, 0x0F01, 0, Imm8(7), R(dst));}
2412 void iret() {AppendInstr(I_IRET, 0xCF, E_OPERAND_SIZE_PREFIX);}
2413 void iretd() {AppendInstr(I_IRETD, 0xCF, 0);}
2414 #ifdef JITASM64
2415 void iretq() {AppendInstr(I_IRETQ, 0xCF, E_REXW_PREFIX);}
2416 #endif
2417 void jmp(const std::string& label_name) {AppendJmp(GetLabelID(label_name));}
2418 void ja(const std::string& label_name) {AppendJcc(JCC_A, GetLabelID(label_name));}
2419 void jae(const std::string& label_name) {AppendJcc(JCC_AE, GetLabelID(label_name));}
2420 void jb(const std::string& label_name) {AppendJcc(JCC_B, GetLabelID(label_name));}
2421 void jbe(const std::string& label_name) {AppendJcc(JCC_BE, GetLabelID(label_name));}
2422 void jc(const std::string& label_name) {jb(label_name);}
2423 #ifdef JITASM64
2424 void jecxz(const std::string& label_name) {AppendJcc(JCC_ECXZ, GetLabelID(label_name));} // short jump only
2425 void jrcxz (const std::string& label_name) {AppendJcc(JCC_RCXZ, GetLabelID(label_name));} // short jump only
2426 #else
2427 void jcxz(const std::string& label_name) {AppendJcc(JCC_CXZ, GetLabelID(label_name));} // short jump only
2428 void jecxz(const std::string& label_name) {AppendJcc(JCC_ECXZ, GetLabelID(label_name));} // short jump only
2429 #endif
2430 void je(const std::string& label_name) {AppendJcc(JCC_E, GetLabelID(label_name));}
2431 void jg(const std::string& label_name) {AppendJcc(JCC_G, GetLabelID(label_name));}
2432 void jge(const std::string& label_name) {AppendJcc(JCC_GE, GetLabelID(label_name));}
2433 void jl(const std::string& label_name) {AppendJcc(JCC_L, GetLabelID(label_name));}
2434 void jle(const std::string& label_name) {AppendJcc(JCC_LE, GetLabelID(label_name));}
2435 void jna(const std::string& label_name) {jbe(label_name);}
2436 void jnae(const std::string& label_name) {jb(label_name);}
2437 void jnb(const std::string& label_name) {jae(label_name);}
2438 void jnbe(const std::string& label_name) {ja(label_name);}
2439 void jnc(const std::string& label_name) {jae(label_name);}
2440 void jne(const std::string& label_name) {AppendJcc(JCC_NE, GetLabelID(label_name));}
2441 void jng(const std::string& label_name) {jle(label_name);}
2442 void jnge(const std::string& label_name) {jl(label_name);}
2443 void jnl(const std::string& label_name) {jge(label_name);}
2444 void jnle(const std::string& label_name) {jg(label_name);}
2445 void jno(const std::string& label_name) {AppendJcc(JCC_NO, GetLabelID(label_name));}
2446 void jnp(const std::string& label_name) {AppendJcc(JCC_NP, GetLabelID(label_name));}
2447 void jns(const std::string& label_name) {AppendJcc(JCC_NS, GetLabelID(label_name));}
2448 void jnz(const std::string& label_name) {jne(label_name);}
2449 void jo(const std::string& label_name) {AppendJcc(JCC_O, GetLabelID(label_name));}
2450 void jp(const std::string& label_name) {AppendJcc(JCC_P, GetLabelID(label_name));}
2451 void jpe(const std::string& label_name) {jp(label_name);}
2452 void jpo(const std::string& label_name) {jnp(label_name);}
2453 void js(const std::string& label_name) {AppendJcc(JCC_S, GetLabelID(label_name));}
2454 void jz(const std::string& label_name) {je(label_name);}
2455 void lar(const Reg16& dst, const Reg16& src) {AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2456 void lar(const Reg16& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2457 void lar(const Reg32& dst, const Reg32& src) {AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));}
2458 void lar(const Reg32& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));}
2459 #ifdef JITASM64
2460 void lar(const Reg64& dst, const Reg64& src) {AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));}
2461 void lar(const Reg64& dst, const Mem16& src) {AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));}
2462 #endif
2463 template<class Ty> void lea(const Reg16& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2464 template<class Ty> void lea(const Reg32& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, 0, W(dst), R(src));}
2465 #ifdef JITASM64
2466 template<class Ty> void lea(const Reg64& dst, const MemT<Ty>& src) {AppendInstr(I_LEA, 0x8D, E_REXW_PREFIX, W(dst), R(src));}
2467 #endif
2468 void leave() {AppendInstr(I_LEAVE, 0xC9, 0, Dummy(W(esp)), Dummy(RW(ebp)));}
2469 //lgdt
2470 //lidt
2471 void lldt(const Reg16& src) {AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));}
2472 void lldt(const Mem16& src) {AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));}
2473 void lmsw(const Reg16& src) {AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));}
2474 void lmsw(const Mem16& src) {AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));}
2475 void lodsb(const Reg8& dst, const Reg& src) {AppendInstr(I_LODS_B, 0xAC, 0, Dummy(W(dst),al), Dummy(RW(src),zsi));}
2476 void lodsw(const Reg16& dst, const Reg& src) {AppendInstr(I_LODS_W, 0xAD, E_OPERAND_SIZE_PREFIX, Dummy(W(dst),ax), Dummy(RW(src),zsi));}
2477 void lodsd(const Reg32& dst, const Reg& src) {AppendInstr(I_LODS_D, 0xAD, 0, Dummy(W(dst),eax), Dummy(RW(src),zsi));}
2478 #ifdef JITASM64
2479 void lodsq(const Reg64& dst, const Reg& src) {AppendInstr(I_LODS_Q, 0xAD, E_REXW_PREFIX, Dummy(W(dst),rax), Dummy(RW(src),rsi));}
2480 #endif
2481 void rep_lodsb(const Reg8& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_B, 0xAC, E_REP_PREFIX, Dummy(RW(dst),al), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0
2482 void rep_lodsw(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_W, 0xAD, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst),ax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0
2483 void rep_lodsd(const Reg32& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_D, 0xAD, E_REP_PREFIX, Dummy(RW(dst),eax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));} // dst is RW because of ecx == 0
2484 #ifdef JITASM64
2485 void rep_lodsq(const Reg64& dst, const Reg& src, const Reg& count) {AppendInstr(I_LODS_Q, 0xAD, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst),rax), Dummy(RW(src),rsi), Dummy(RW(count),rcx));} // dst is RW because of ecx == 0
2486 #endif
2487 void loop(const std::string& label_name) {AppendInstr(I_LOOP, 0xE2, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only
2488 void loope(const std::string& label_name) {AppendInstr(I_LOOP, 0xE1, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only
2489 void loopne(const std::string& label_name) {AppendInstr(I_LOOP, 0xE0, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));} // short jump only
2490 void lsl(const Reg16& dst, const Reg16& src) {AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2491 void lsl(const Reg16& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2492 void lsl(const Reg32& dst, const Reg32& src) {AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));}
2493 void lsl(const Reg32& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));}
2494 #ifdef JITASM64
2495 void lsl(const Reg64& dst, const Reg32& src) {AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));}
2496 void lsl(const Reg64& dst, const Mem16& src) {AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));}
2497 #endif
2498 void ltr(const Reg16& src) {AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));}
2499 void ltr(const Mem16& src) {AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));}
2500 void mov(const Reg8& dst, const Reg8& src) {AppendInstr(I_MOV, 0x8A, 0, W(dst), R(src));}
2501 void mov(const Mem8& dst, const Reg8& src) {AppendInstr(I_MOV, 0x88, E_SPECIAL, R(src), W(dst));}
2502 void mov(const Reg16& dst, const Reg16& src) {AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2503 void mov(const Mem16& dst, const Reg16& src) {AppendInstr(I_MOV, 0x89, E_OPERAND_SIZE_PREFIX | E_SPECIAL, R(src), W(dst));}
2504 void mov(const Reg32& dst, const Reg32& src) {AppendInstr(I_MOV, 0x8B, 0, W(dst), R(src));}
2505 void mov(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOV, 0x89, E_SPECIAL, R(src), W(dst));}
2506 void mov(const Reg8& dst, const Mem8& src) {AppendInstr(I_MOV, 0x8A, E_SPECIAL, W(dst), R(src));}
2507 void mov(const Reg16& dst, const Mem16& src) {AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX | E_SPECIAL, W(dst), R(src));}
2508 void mov(const Reg32& dst, const Mem32& src) {AppendInstr(I_MOV, 0x8B, E_SPECIAL, W(dst), R(src));}
2509 void mov(const Reg8& dst, const Imm8& imm) {AppendInstr(I_MOV, 0xB0, 0, W(dst), imm);}
2510 void mov(const Reg16& dst, const Imm16& imm) {AppendInstr(I_MOV, 0xB8, E_OPERAND_SIZE_PREFIX, W(dst), imm);}
2511 void mov(const Reg32& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xB8, 0, W(dst), imm);}
2512 void mov(const Mem8& dst, const Imm8& imm) {AppendInstr(I_MOV, 0xC6, 0, Imm8(0), W(dst), imm);}
2513 void mov(const Mem16& dst, const Imm16& imm) {AppendInstr(I_MOV, 0xC7, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst), imm);}
2514 void mov(const Mem32& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xC7, 0, Imm8(0), W(dst), imm);}
2515 #ifdef JITASM64
2516 void mov(const Reg64& dst, const Reg64& src) {AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));}
2517 void mov(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOV, 0x89, E_REXW_PREFIX, R(src), W(dst));}
2518 void mov(const Reg64& dst, const Mem64& src) {AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));}
2519 void mov(const Reg64& dst, const Imm64& imm) {detail::IsInt32(imm.GetImm()) ? AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), Imm32((sint32) imm.GetImm())) : AppendInstr(I_MOV, 0xB8, E_REXW_PREFIX, W(dst), imm);}
2520 void mov(const Mem64& dst, const Imm32& imm) {AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), imm);}
2521 void mov(const Reg64& dst, const MemOffset64& src) {AppendInstr(I_MOV, 0xA1, E_REXW_PREFIX, Imm64(src.GetOffset()), Dummy(W(dst), rax));}
2522 void mov(const MemOffset64& dst, const Reg64& src) {AppendInstr(I_MOV, 0xA3, E_REXW_PREFIX, Imm64(dst.GetOffset()), Dummy(R(src), rax));}
2523 #endif
2524 void movbe(const Reg16& dst, const Mem16& src) {AppendInstr(I_MOVBE, 0x0F38F0, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2525 void movbe(const Reg32& dst, const Mem32& src) {AppendInstr(I_MOVBE, 0x0F38F0, 0, W(dst), R(src));}
2526 void movbe(const Mem16& dst, const Reg16& src) {AppendInstr(I_MOVBE, 0x0F38F1, E_OPERAND_SIZE_PREFIX, R(src), W(dst));}
2527 void movbe(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOVBE, 0x0F38F1, 0, R(src), W(dst));}
2528 #ifdef JITASM64
2529 void movbe(const Reg64& dst, const Mem64& src) {AppendInstr(I_MOVBE, 0x0F38F0, E_REXW_PREFIX, W(dst), R(src));}
2530 void movbe(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOVBE, 0x0F38F1, E_REXW_PREFIX, R(src), W(dst));}
2531 #endif
2532 void movsb(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_B, 0xA4, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}
2533 void movsw(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_W, 0xA5, E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}
2534 void movsd(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_D, 0xA5, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}
2535 #ifdef JITASM64
2536 void movsq(const Reg& dst, const Reg& src) {AppendInstr(I_MOVS_Q, 0xA5, E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi));}
2537 #endif
2538 void rep_movsb() {rep_movsb(zdi, zsi, zcx);}
2539 void rep_movsw() {rep_movsw(zdi, zsi, zcx);}
2540 void rep_movsd() {rep_movsd(zdi, zsi, zcx);}
2541 void rep_movsb(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_B, 0xA4, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}
2542 void rep_movsw(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_W, 0xA5, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}
2543 void rep_movsd(const Reg& dst, const Reg& src, const Reg& count) {AppendInstr(I_MOVS_D, 0xA5, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}
2544 #ifdef JITASM64
2545 void rep_movsq() {rep_movsq(rdi, rsi, rcx);}
2546 void rep_movsq(const Reg64& dst, const Reg64& src, const Reg64& count) {AppendInstr(I_MOVS_Q, 0xA5, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi), Dummy(RW(count), rcx));}
2547 #endif
2548 void movsx(const Reg16& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2549 void movsx(const Reg16& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2550 void movsx(const Reg32& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));}
2551 void movsx(const Reg32& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));}
2552 void movsx(const Reg32& dst, const Reg16& src) {AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));}
2553 void movsx(const Reg32& dst, const Mem16& src) {AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));}
2554 #ifdef JITASM64
2555 void movsx(const Reg64& dst, const Reg8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));}
2556 void movsx(const Reg64& dst, const Mem8& src) {AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));}
2557 void movsx(const Reg64& dst, const Reg16& src) {AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));}
2558 void movsx(const Reg64& dst, const Mem16& src) {AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));}
2559 void movsxd(const Reg64& dst, const Reg32& src) {AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));}
2560 void movsxd(const Reg64& dst, const Mem32& src) {AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));}
2561 #endif
2562 void movzx(const Reg16& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2563 void movzx(const Reg16& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
2564 void movzx(const Reg32& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));}
2565 void movzx(const Reg32& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));}
2566 void movzx(const Reg32& dst, const Reg16& src) {AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));}
2567 void movzx(const Reg32& dst, const Mem16& src) {AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));}
2568 #ifdef JITASM64
2569 void movzx(const Reg64& dst, const Reg8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));}
2570 void movzx(const Reg64& dst, const Mem8& src) {AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));}
2571 void movzx(const Reg64& dst, const Reg16& src) {AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));}
2572 void movzx(const Reg64& dst, const Mem16& src) {AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));}
2573 #endif
2574 void mul(const Reg8& src) {AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));}
2575 void mul(const Mem8& src) {AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));}
2576 void mul(const Reg16& src) {AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));}
2577 void mul(const Mem16& src) {AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));}
2578 void mul(const Reg32& src) {AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));}
2579 void mul(const Mem32& src) {AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));}
2580 #ifdef JITASM64
2581 void mul(const Reg64& src) {AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}
2582 void mul(const Mem64& src) {AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}
2583 #endif
2584 void neg(const Reg8& dst) {AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));}
2585 void neg(const Mem8& dst) {AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));}
2586 void neg(const Reg16& dst) {AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));}
2587 void neg(const Mem16& dst) {AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));}
2588 void neg(const Reg32& dst) {AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));}
2589 void neg(const Mem32& dst) {AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));}
2590 #ifdef JITASM64
2591 void neg(const Reg64& dst) {AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));}
2592 void neg(const Mem64& dst) {AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));}
2593 #endif
2594 void nop() {AppendInstr(I_NOP, 0x90, 0);}
2595 void not_(const Reg8& dst) {AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));}
2596 void not_(const Mem8& dst) {AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));}
2597 void not_(const Reg16& dst) {AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));}
2598 void not_(const Mem16& dst) {AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));}
2599 void not_(const Reg32& dst) {AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));}
2600 void not_(const Mem32& dst) {AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));}
2601 #ifdef JITASM64
2602 void not_(const Reg64& dst) {AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));}
2603 void not_(const Mem64& dst) {AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));}
2604 #endif
2605 void or_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_OR, 0x80, E_SPECIAL, Imm8(1), RW(dst), imm);}
2606 void or_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_OR, 0x80, 0, Imm8(1), RW(dst), imm);}
2607 void or_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2608 void or_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2609 void or_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2610 void or_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2611 void or_(const Reg8& dst, const Reg8& src) {AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));}
2612 void or_(const Mem8& dst, const Reg8& src) {AppendInstr(I_OR, 0x08, 0, R(src), RW(dst));}
2613 void or_(const Reg8& dst, const Mem8& src) {AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));}
2614 void or_(const Reg16& dst, const Reg16& src) {AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2615 void or_(const Mem16& dst, const Reg16& src) {AppendInstr(I_OR, 0x09, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
2616 void or_(const Reg16& dst, const Mem16& src) {AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2617 void or_(const Reg32& dst, const Reg32& src) {AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));}
2618 void or_(const Mem32& dst, const Reg32& src) {AppendInstr(I_OR, 0x09, 0, R(src), RW(dst));}
2619 void or_(const Reg32& dst, const Mem32& src) {AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));}
2620 #ifdef JITASM64
2621 void or_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2622 void or_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));}
2623 void or_(const Reg64& dst, const Reg64& src) {AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));}
2624 void or_(const Mem64& dst, const Reg64& src) {AppendInstr(I_OR, 0x09, E_REXW_PREFIX, R(src), RW(dst));}
2625 void or_(const Reg64& dst, const Mem64& src) {AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));}
2626 #endif
2627 void out(const Imm8& dst, const Reg8& src) {AppendInstr(I_OUT, 0xE6, 0, dst, Dummy(R(src),al));}
2628 void out(const Imm8& dst, const Reg16& src) {AppendInstr(I_OUT, 0xE7, E_OPERAND_SIZE_PREFIX, dst, Dummy(R(src),ax));}
2629 void out(const Imm8& dst, const Reg32& src) {AppendInstr(I_OUT, 0xE7, 0, dst, Dummy(R(src),eax));}
2630 void out(const Reg16& dst, const Reg8& src) {AppendInstr(I_OUT, 0xEE, 0, Dummy(R(dst),dx), Dummy(R(src),al));}
2631 void out(const Reg16& dst, const Reg16& src) {AppendInstr(I_OUT, 0xEF, E_OPERAND_SIZE_PREFIX, Dummy(R(dst),dx), Dummy(R(src),ax));}
2632 void out(const Reg16& dst, const Reg32& src) {AppendInstr(I_OUT, 0xEF, 0, Dummy(R(dst),dx), Dummy(R(src),eax));}
2633 void outsb(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_B, 0x6E, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));}
2634 void outsw(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_W, 0x6F, E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx));}
2635 void outsd(const Reg16& dst, const Reg& src) {AppendInstr(I_OUTS_D, 0x6F, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));}
2636 void rep_outsb(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_B, 0x6E, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}
2637 void rep_outsw(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_W, 0x6F, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}
2638 void rep_outsd(const Reg16& dst, const Reg& src, const Reg& count) {AppendInstr(I_OUTS_D, 0x6F, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}
2639 void pop(const Reg16& dst) {AppendInstr(I_POP, 0x58, E_OPERAND_SIZE_PREFIX, W(dst));}
2640 void pop(const Mem16& dst) {AppendInstr(I_POP, 0x8F, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));}
2641 #ifndef JITASM64
2642 void pop(const Reg32& dst) {AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));}
2643 void pop(const Mem32& dst) {AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));}
2644 #else
2645 void pop(const Reg64& dst) {AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));}
2646 void pop(const Mem64& dst) {AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));}
2647 #endif
2648 #ifndef JITASM64
2649 void popa() {popad();}
2650 void popad() {AppendInstr(I_POPAD, 0x61, 0, Dummy(RW(esp)));}
2651 #endif
2652 #ifndef JITASM64
2653 void popf() {AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}
2654 void popfd() {AppendInstr(I_POPFD, 0x9D, 0, Dummy(RW(esp)));}
2655 #else
2656 void popf() {AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}
2657 void popfq() {AppendInstr(I_POPFQ, 0x9D, 0, Dummy(RW(esp)));}
2658 #endif
2659 void push(const Reg16& src) {AppendInstr(I_PUSH, 0x50, E_OPERAND_SIZE_PREFIX, R(src), Dummy(RW(esp)));}
2660 void push(const Mem16& src) {AppendInstr(I_PUSH, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(esp)));}
2661 #ifndef JITASM64
2662 void push(const Reg32& src) {AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));}
2663 void push(const Mem32& src) {AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));}
2664 #else
2665 void push(const Reg64& src) {AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));}
2666 void push(const Mem64& src) {AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));}
2667 #endif
2668 void push(const Imm32& imm) {AppendInstr(I_PUSH, detail::IsInt8(imm.GetImm()) ? 0x6A : 0x68, 0, detail::ImmXor8(imm), Dummy(RW(esp)));}
2669 #ifndef JITASM64
2670 void pusha() {pushad();}
2671 void pushad() {AppendInstr(I_PUSHAD, 0x60, 0, Dummy(RW(esp)));}
2672 #endif
2673 void pushf() {AppendInstr(I_PUSHF, 0x9C, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}
2674 #ifndef JITASM64
2675 void pushfd() {AppendInstr(I_PUSHFD, 0x9C, 0, Dummy(RW(esp)));}
2676 #else
2677 void pushfq() {AppendInstr(I_PUSHFQ, 0x9C, 0, Dummy(RW(esp)));}
2678 #endif
2679 void rcl(const Reg8& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2680 void rcl(const Mem8& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2681 void rcl(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);}
2682 void rcl(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);}
2683 void rcr(const Reg8& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2684 void rcr(const Mem8& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2685 void rcr(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);}
2686 void rcr(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);}
2687 void rol(const Reg8& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2688 void rol(const Mem8& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2689 void rol(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);}
2690 void rol(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);}
2691 void ror(const Reg8& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2692 void ror(const Mem8& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2693 void ror(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);}
2694 void ror(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);}
2695 void rcl(const Reg16& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2696 void rcl(const Mem16& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2697 void rcl(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);}
2698 void rcl(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);}
2699 void rcr(const Reg16& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2700 void rcr(const Mem16& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2701 void rcr(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);}
2702 void rcr(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);}
2703 void rol(const Reg16& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2704 void rol(const Mem16& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2705 void rol(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);}
2706 void rol(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);}
2707 void ror(const Reg16& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2708 void ror(const Mem16& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2709 void ror(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);}
2710 void ror(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);}
2711 void rcl(const Reg32& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2712 void rcl(const Mem32& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2713 void rcl(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);}
2714 void rcl(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);}
2715 void rcr(const Reg32& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2716 void rcr(const Mem32& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2717 void rcr(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);}
2718 void rcr(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);}
2719 void rol(const Reg32& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2720 void rol(const Mem32& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2721 void rol(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);}
2722 void rol(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);}
2723 void ror(const Reg32& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2724 void ror(const Mem32& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2725 void ror(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);}
2726 void ror(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);}
2727 #ifdef JITASM64
2728 void rcl(const Reg64& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2729 void rcl(const Mem64& dst, const Reg8& shift) {AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}
2730 void rcl(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);}
2731 void rcl(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);}
2732 void rcr(const Reg64& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2733 void rcr(const Mem64& dst, const Reg8& shift) {AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}
2734 void rcr(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);}
2735 void rcr(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);}
2736 void rol(const Reg64& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2737 void rol(const Mem64& dst, const Reg8& shift) {AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}
2738 void rol(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);}
2739 void rol(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);}
2740 void ror(const Reg64& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2741 void ror(const Mem64& dst, const Reg8& shift) {AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}
2742 void ror(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);}
2743 void ror(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);}
2744 #endif
2745 void rdmsr() {AppendInstr(I_RDMSR, 0x0F32, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}
2746 void rdpmc() {AppendInstr(I_RDMSR, 0x0F33, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}
2747 void rdtsc() {AppendInstr(I_RDPMC, 0x0F31, 0, Dummy(W(edx)), Dummy(W(eax)), Dummy(W(ecx)));}
2748 void ret() {AppendInstr(I_RET, 0xC3, 0, Dummy(RW(esp)));}
2749 void ret(const Imm16& imm) {AppendInstr(I_RET, 0xC2, 0, imm, Dummy(RW(esp)));}
2750 void rsm() {AppendInstr(I_RSM, 0x0FAA, 0);}
2751 void sal(const Reg8& dst, const Reg8& shift) {shl(dst, shift);}
2752 void sal(const Mem8& dst, const Reg8& shift) {shl(dst, shift);}
2753 void sal(const Reg8& dst, const Imm8& shift) {shl(dst, shift);}
2754 void sal(const Mem8& dst, const Imm8& shift) {shl(dst, shift);}
2755 void sar(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2756 void sar(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2757 void sar(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);}
2758 void sar(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);}
2759 void shl(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2760 void shl(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2761 void shl(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);}
2762 void shl(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);}
2763 void shr(const Reg8& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2764 void shr(const Mem8& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2765 void shr(const Reg8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);}
2766 void shr(const Mem8& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);}
2767 void sal(const Reg16& dst, const Reg8& shift) {shl(dst, shift);}
2768 void sal(const Mem16& dst, const Reg8& shift) {shl(dst, shift);}
2769 void sal(const Reg16& dst, const Imm8& shift) {shl(dst, shift);}
2770 void sal(const Mem16& dst, const Imm8& shift) {shl(dst, shift);}
2771 void sar(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2772 void sar(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2773 void sar(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);}
2774 void sar(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);}
2775 void shl(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2776 void shl(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2777 void shl(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);}
2778 void shl(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);}
2779 void shr(const Reg16& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2780 void shr(const Mem16& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2781 void shr(const Reg16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);}
2782 void shr(const Mem16& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);}
2783 void sal(const Reg32& dst, const Reg8& shift) {shl(dst, shift);}
2784 void sal(const Mem32& dst, const Reg8& shift) {shl(dst, shift);}
2785 void sal(const Reg32& dst, const Imm8& shift) {shl(dst, shift);}
2786 void sal(const Mem32& dst, const Imm8& shift) {shl(dst, shift);}
2787 void sar(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2788 void sar(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2789 void sar(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);}
2790 void sar(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);}
2791 void shl(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2792 void shl(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2793 void shl(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);}
2794 void shl(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);}
2795 void shr(const Reg32& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2796 void shr(const Mem32& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2797 void shr(const Reg32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);}
2798 void shr(const Mem32& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);}
2799 #ifdef JITASM64
2800 void sal(const Reg64& dst, const Reg8& shift) {shl(dst, shift);}
2801 void sal(const Mem64& dst, const Reg8& shift) {shl(dst, shift);}
2802 void sal(const Reg64& dst, const Imm8& shift) {shl(dst, shift);}
2803 void sal(const Mem64& dst, const Imm8& shift) {shl(dst, shift);}
2804 void sar(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2805 void sar(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}
2806 void sar(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);}
2807 void sar(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);}
2808 void shl(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2809 void shl(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}
2810 void shl(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);}
2811 void shl(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);}
2812 void shr(const Reg64& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2813 void shr(const Mem64& dst, const Reg8& shift) {AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}
2814 void shr(const Reg64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);}
2815 void shr(const Mem64& dst, const Imm8& shift) {shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);}
2816 #endif
2817 void sbb(const Reg8& dst, const Imm8& imm) {AppendInstr(I_SBB, 0x80, E_SPECIAL, Imm8(3), RW(dst), imm);}
2818 void sbb(const Mem8& dst, const Imm8& imm) {AppendInstr(I_SBB, 0x80, 0, Imm8(3), RW(dst), imm);}
2819 void sbb(const Reg16& dst, const Imm16& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2820 void sbb(const Mem16& dst, const Imm16& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2821 void sbb(const Reg32& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2822 void sbb(const Mem32& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2823 void sbb(const Reg8& dst, const Reg8& src) {AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));}
2824 void sbb(const Mem8& dst, const Reg8& src) {AppendInstr(I_SBB, 0x18, 0, R(src), RW(dst));}
2825 void sbb(const Reg8& dst, const Mem8& src) {AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));}
2826 void sbb(const Reg16& dst, const Reg16& src) {AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2827 void sbb(const Mem16& dst, const Reg16& src) {AppendInstr(I_SBB, 0x19, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
2828 void sbb(const Reg16& dst, const Mem16& src) {AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2829 void sbb(const Reg32& dst, const Reg32& src) {AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));}
2830 void sbb(const Mem32& dst, const Reg32& src) {AppendInstr(I_SBB, 0x19, 0, R(src), RW(dst));}
2831 void sbb(const Reg32& dst, const Mem32& src) {AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));}
2832 #ifdef JITASM64
2833 void sbb(const Reg64& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2834 void sbb(const Mem64& dst, const Imm32& imm) {AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));}
2835 void sbb(const Reg64& dst, const Reg64& src) {AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));}
2836 void sbb(const Mem64& dst, const Reg64& src) {AppendInstr(I_SBB, 0x19, E_REXW_PREFIX, R(src), RW(dst));}
2837 void sbb(const Reg64& dst, const Mem64& src) {AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));}
2838 #endif
2839 void scasb() {AppendInstr(I_SCAS_B, 0xAE, 0, Dummy(R(al)), Dummy(RW(edi)));}
2840 void scasw() {AppendInstr(I_SCAS_W, 0xAF, E_OPERAND_SIZE_PREFIX, Dummy(R(ax)), Dummy(RW(edi)));}
2841 void scasd() {AppendInstr(I_SCAS_D, 0xAF, 0, Dummy(R(eax)), Dummy(RW(edi)));}
2842 #ifdef JITASM64
2843 void scasq() {AppendInstr(I_SCAS_Q, 0xAF, E_REXW_PREFIX, Dummy(R(rax)), Dummy(RW(rdi)));}
2844 #endif
2845 void seta(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));}
2846 void seta(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));}
2847 void setae(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));}
2848 void setae(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));}
2849 void setb(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));}
2850 void setb(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));}
2851 void setbe(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));}
2852 void setbe(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));}
2853 void setc(const Reg8& dst) {setb(dst);}
2854 void setc(const Mem8& dst) {setb(dst);}
2855 void sete(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));}
2856 void sete(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));}
2857 void setg(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));}
2858 void setg(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));}
2859 void setge(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));}
2860 void setge(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));}
2861 void setl(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));}
2862 void setl(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));}
2863 void setle(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));}
2864 void setle(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));}
2865 void setna(const Reg8& dst) {setbe(dst);}
2866 void setna(const Mem8& dst) {setbe(dst);}
2867 void setnae(const Reg8& dst) {setb(dst);}
2868 void setnae(const Mem8& dst) {setb(dst);}
2869 void setnb(const Reg8& dst) {setae(dst);}
2870 void setnb(const Mem8& dst) {setae(dst);}
2871 void setnbe(const Reg8& dst) {seta(dst);}
2872 void setnbe(const Mem8& dst) {seta(dst);}
2873 void setnc(const Reg8& dst) {setae(dst);}
2874 void setnc(const Mem8& dst) {setae(dst);}
2875 void setne(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));}
2876 void setne(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));}
2877 void setng(const Reg8& dst) {setle(dst);}
2878 void setng(const Mem8& dst) {setle(dst);}
2879 void setnge(const Reg8& dst) {setl(dst);}
2880 void setnge(const Mem8& dst) {setl(dst);}
2881 void setnl(const Reg8& dst) {setge(dst);}
2882 void setnl(const Mem8& dst) {setge(dst);}
2883 void setnle(const Reg8& dst) {setg(dst);}
2884 void setnle(const Mem8& dst) {setg(dst);}
2885 void setno(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));}
2886 void setno(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));}
2887 void setnp(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));}
2888 void setnp(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));}
2889 void setns(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));}
2890 void setns(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));}
2891 void setnz(const Reg8& dst) {setne(dst);}
2892 void setnz(const Mem8& dst) {setne(dst);}
2893 void seto(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));}
2894 void seto(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));}
2895 void setp(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));}
2896 void setp(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));}
2897 void setpe(const Reg8& dst) {setp(dst);}
2898 void setpe(const Mem8& dst) {setp(dst);}
2899 void setpo(const Reg8& dst) {setnp(dst);}
2900 void setpo(const Mem8& dst) {setnp(dst);}
2901 void sets(const Reg8& dst) {AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));}
2902 void sets(const Mem8& dst) {AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));}
2903 void setz(const Reg8& dst) {sete(dst);}
2904 void setz(const Mem8& dst) {sete(dst);}
2905 void shld(const Reg16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}
2906 void shld(const Mem16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}
2907 void shld(const Reg16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2908 void shld(const Mem16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2909 void shld(const Reg32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);}
2910 void shld(const Mem32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);}
2911 void shld(const Reg32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));}
2912 void shld(const Mem32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));}
2913 #ifdef JITASM64
2914 void shld(const Reg64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);}
2915 void shld(const Mem64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);}
2916 void shld(const Reg64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2917 void shld(const Mem64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2918 #endif
2919 void shrd(const Reg16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}
2920 void shrd(const Mem16& dst, const Reg16& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}
2921 void shrd(const Reg16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2922 void shrd(const Mem16& dst, const Reg16& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2923 void shrd(const Reg32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);}
2924 void shrd(const Mem32& dst, const Reg32& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);}
2925 void shrd(const Reg32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));}
2926 void shrd(const Mem32& dst, const Reg32& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));}
2927 #ifdef JITASM64
2928 void shrd(const Reg64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);}
2929 void shrd(const Mem64& dst, const Reg64& src, const Imm8& place) {AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);}
2930 void shrd(const Reg64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2931 void shrd(const Mem64& dst, const Reg64& src, const Reg8& place) {AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}
2932 #endif
2933 template<class Ty> void sgdt(const MemT<Ty>& dst) {AppendInstr(I_SGDT, 0x0F01, 0, Imm8(0), W(dst));}
2934 template<class Ty> void sidt(const MemT<Ty>& dst) {AppendInstr(I_SIDT, 0x0F01, 0, Imm8(1), W(dst));}
2935 void sldt(const Reg16& dst) {AppendInstr(I_SLDT, 0x0F00, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));}
2936 void sldt(const Mem16& dst) {AppendInstr(I_SLDT, 0x0F00, 0, Imm8(0), W(dst));}
2937 #ifdef JITASM64
2938 void sldt(const Reg64& dst) {AppendInstr(I_SLDT, 0x0F00, E_REXW_PREFIX, Imm8(0), W(dst));}
2939 #endif
2940 void smsw(const Reg16& dst) {AppendInstr(I_SMSW, 0x0F01, E_OPERAND_SIZE_PREFIX, Imm8(4), W(dst));}
2941 void smsw(const Mem16& dst) {AppendInstr(I_SMSW, 0x0F01, 0, Imm8(4), W(dst));}
2942 #ifdef JITASM64
2943 void smsw(const Reg64& dst) {AppendInstr(I_SMSW, 0x0F01, E_REXW_PREFIX, Imm8(4), W(dst));}
2944 #endif
2945 void stc() {AppendInstr(I_STC, 0xF9, 0);}
2946 void std() {AppendInstr(I_STD, 0xFD, 0);}
2947 void sti() {AppendInstr(I_STI, 0xFB, 0);}
2948 void stosb(const Reg& dst, const Reg8& src) {AppendInstr(I_STOS_B, 0xAA, 0, Dummy(R(src),al), Dummy(RW(dst),zdi));}
2949 void stosw(const Reg& dst, const Reg16& src) {AppendInstr(I_STOS_W, 0xAB, E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi));}
2950 void stosd(const Reg& dst, const Reg32& src) {AppendInstr(I_STOS_D, 0xAB, 0, Dummy(R(src),eax), Dummy(RW(dst),zdi));}
2951 #ifdef JITASM64
2952 void stosq(const Reg& dst, const Reg64& src) {AppendInstr(I_STOS_Q, 0xAB, E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi));}
2953 #endif
2954 void rep_stosb(const Reg& dst, const Reg8& src, const Reg& count) {AppendInstr(I_STOS_B, 0xAA, E_REP_PREFIX, Dummy(R(src),al), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}
2955 void rep_stosw(const Reg& dst, const Reg16& src, const Reg& count) {AppendInstr(I_STOS_W, 0xAB, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}
2956 void rep_stosd(const Reg& dst, const Reg32& src, const Reg& count) {AppendInstr(I_STOS_D, 0xAB, E_REP_PREFIX, Dummy(R(src),eax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}
2957 #ifdef JITASM64
2958 void rep_stosq(const Reg& dst, const Reg64& src, const Reg& count) {AppendInstr(I_STOS_Q, 0xAB, E_REP_PREFIX | E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}
2959 #endif
2960 void sub(const Reg8& dst, const Imm8& imm) {AppendInstr(I_SUB, 0x80, E_SPECIAL, Imm8(5), RW(dst), imm);}
2961 void sub(const Mem8& dst, const Imm8& imm) {AppendInstr(I_SUB, 0x80, 0, Imm8(5), RW(dst), imm);}
2962 void sub(const Reg16& dst, const Imm16& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2963 void sub(const Mem16& dst, const Imm16& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2964 void sub(const Reg32& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2965 void sub(const Mem32& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2966 void sub(const Reg8& dst, const Reg8& src) {AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));}
2967 void sub(const Mem8& dst, const Reg8& src) {AppendInstr(I_SUB, 0x28, 0, R(src), RW(dst));}
2968 void sub(const Reg8& dst, const Mem8& src) {AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));}
2969 void sub(const Reg16& dst, const Reg16& src) {AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2970 void sub(const Mem16& dst, const Reg16& src) {AppendInstr(I_SUB, 0x29, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
2971 void sub(const Reg16& dst, const Mem16& src) {AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
2972 void sub(const Reg32& dst, const Reg32& src) {AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));}
2973 void sub(const Mem32& dst, const Reg32& src) {AppendInstr(I_SUB, 0x29, 0, R(src), RW(dst));}
2974 void sub(const Reg32& dst, const Mem32& src) {AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));}
2975 #ifdef JITASM64
2976 void sub(const Reg64& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2977 void sub(const Mem64& dst, const Imm32& imm) {AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));}
2978 void sub(const Reg64& dst, const Reg64& src) {AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));}
2979 void sub(const Mem64& dst, const Reg64& src) {AppendInstr(I_SUB, 0x29, E_REXW_PREFIX, R(src), RW(dst));}
2980 void sub(const Reg64& dst, const Mem64& src) {AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));}
2981 #endif
2982 #ifndef JITASM64
2983 void sysenter() {AppendInstr(I_SYSENTER, 0x0F34, 0);}
2984 void sysexit() {AppendInstr(I_SYSEXIT, 0x0F35, 0);}
2985 #else
2986 void swapgs() {AppendInstr(I_SWAPGS, 0x0F01F8, 0);} // 0F 01 /7
2987 void syscall() {AppendInstr(I_SYSCALL, 0x0F05, 0);}
2988 void sysret() {AppendInstr(I_SYSRET, 0x0F07, 0);}
2989 #endif
2990 void test(const Reg8& src1, const Imm8& src2) {AppendInstr(I_TEST, 0xF6, E_SPECIAL, Imm8(0), R(src1), R(src2));}
2991 void test(const Mem8& src1, const Imm8& src2) {AppendInstr(I_TEST, 0xF6, 0, Imm8(0), R(src1), R(src2));}
2992 void test(const Reg16& src1, const Imm16& src2) {AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));}
2993 void test(const Mem16& src1, const Imm16& src2) {AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(0), R(src1), R(src2));}
2994 void test(const Reg32& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_SPECIAL, Imm8(0), R(src1), R(src2));}
2995 void test(const Mem32& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, 0, Imm8(0), R(src1), R(src2));}
2996 void test(const Reg8& src1, const Reg8& src2) {AppendInstr(I_TEST, 0x84, 0, R(src1), R(src2));}
2997 void test(const Mem8& src1, const Reg8& src2) {AppendInstr(I_TEST, 0x84, 0, R(src2), R(src1));}
2998 void test(const Reg16& src1, const Reg16& src2) {AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src1), R(src2));}
2999 void test(const Mem16& src1, const Reg16& src2) {AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src2), R(src1));}
3000 void test(const Reg32& src1, const Reg32& src2) {AppendInstr(I_TEST, 0x85, 0, R(src1), R(src2));}
3001 void test(const Mem32& src1, const Reg32& src2) {AppendInstr(I_TEST, 0x85, 0, R(src2), R(src1));}
3002 #ifdef JITASM64
3003 void test(const Reg64& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));}
3004 void test(const Mem64& src1, const Imm32& src2) {AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX, Imm8(0), R(src1), R(src2));}
3005 void test(const Reg64& src1, const Reg64& src2) {AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src1), R(src2));}
3006 void test(const Mem64& src1, const Reg64& src2) {AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src2), R(src1));}
3007 #endif
3008 void ud2() {AppendInstr(I_UD2, 0x0F0B, 0);}
3009 void verr(const Reg16& src) {AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));}
3010 void verr(const Mem16& src) {AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));}
3011 void verw(const Reg16& src) {AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));}
3012 void verw(const Mem16& src) {AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));}
3013 void wait() {AppendInstr(I_WAIT, 0x9B, 0);}
3014 void wbinvd() {AppendInstr(I_WBINVD, 0x0F09, 0);}
3015 void wrmsr() {AppendInstr(I_WRMSR, 0x0F30, 0, Dummy(R(ecx)), Dummy(R(edx)), Dummy(R(eax)));}
3016 void xadd(const Reg8& dst, const Reg8& src) {AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));}
3017 void xadd(const Mem8& dst, const Reg8& src) {AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));}
3018 void xadd(const Reg16& dst, const Reg16& src) {AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}
3019 void xadd(const Mem16& dst, const Reg16& src) {AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}
3020 void xadd(const Reg32& dst, const Reg32& src) {AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));}
3021 void xadd(const Mem32& dst, const Reg32& src) {AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));}
3022 #ifdef JITASM64
3023 void xadd(const Reg64& dst, const Reg64& src) {AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));}
3024 void xadd(const Mem64& dst, const Reg64& src) {AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));}
3025 #endif
3026 void xchg(const Reg8& dst, const Reg8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));}
3027 void xchg(const Mem8& dst, const Reg8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(src), RW(dst));}
3028 void xchg(const Reg8& dst, const Mem8& src) {AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));}
3029 void xchg(const Reg16& dst, const Reg16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX | E_SPECIAL, RW(dst), RW(src));}
3030 void xchg(const Mem16& dst, const Reg16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}
3031 void xchg(const Reg16& dst, const Mem16& src) {AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(dst), RW(src));}
3032 void xchg(const Reg32& dst, const Reg32& src) {AppendInstr(I_XCHG, 0x87, E_SPECIAL, RW(dst), RW(src));}
3033 void xchg(const Mem32& dst, const Reg32& src) {AppendInstr(I_XCHG, 0x87, 0, RW(src), RW(dst));}
3034 void xchg(const Reg32& dst, const Mem32& src) {AppendInstr(I_XCHG, 0x87, 0, RW(dst), RW(src));}
3035 #ifdef JITASM64
3036 void xchg(const Reg64& dst, const Reg64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX | E_SPECIAL, RW(dst), RW(src));}
3037 void xchg(const Mem64& dst, const Reg64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(src), RW(dst));}
3038 void xchg(const Reg64& dst, const Mem64& src) {AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(dst), RW(src));}
3039 #endif
3040 void xgetbv() {AppendInstr(I_XGETBV, 0x0F01D0, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}
3041 void xlatb() {AppendInstr(I_XLATB, 0xD7, 0, Dummy(RW(al)), Dummy(R(ebx)));}
3042 void xor_(const Reg8& dst, const Imm8& imm) {AppendInstr(I_XOR, 0x80, E_SPECIAL, Imm8(6), RW(dst), imm);}
3043 void xor_(const Mem8& dst, const Imm8& imm) {AppendInstr(I_XOR, 0x80, 0, Imm8(6), RW(dst), imm);}
3044 void xor_(const Reg16& dst, const Imm16& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3045 void xor_(const Mem16& dst, const Imm16& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3046 void xor_(const Reg32& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3047 void xor_(const Mem32& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3048 void xor_(const Reg8& dst, const Reg8& src) {AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));}
3049 void xor_(const Mem8& dst, const Reg8& src) {AppendInstr(I_XOR, 0x30, 0, R(src), RW(dst));}
3050 void xor_(const Reg8& dst, const Mem8& src) {AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));}
3051 void xor_(const Reg16& dst, const Reg16& src) {AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
3052 void xor_(const Mem16& dst, const Reg16& src) {AppendInstr(I_XOR, 0x31, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}
3053 void xor_(const Reg16& dst, const Mem16& src) {AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
3054 void xor_(const Reg32& dst, const Reg32& src) {AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));}
3055 void xor_(const Mem32& dst, const Reg32& src) {AppendInstr(I_XOR, 0x31, 0, R(src), RW(dst));}
3056 void xor_(const Reg32& dst, const Mem32& src) {AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));}
3057 #ifdef JITASM64
3058 void xor_(const Reg64& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3059 void xor_(const Mem64& dst, const Imm32& imm) {AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));}
3060 void xor_(const Reg64& dst, const Reg64& src) {AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));}
3061 void xor_(const Mem64& dst, const Reg64& src) {AppendInstr(I_XOR, 0x31, E_REXW_PREFIX, R(src), RW(dst));}
3062 void xor_(const Reg64& dst, const Mem64& src) {AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));}
3063 #endif
3064
3065 // x87 Floating-Point Instructions
3066 void f2xm1() {AppendInstr(I_F2XM1, 0xD9F0, 0);}
3067 void fabs() {AppendInstr(I_FABS, 0xD9E1, 0);}
3068 void fadd(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FADD, 0xD8C0, 0, src); avoid_unused_warn(dst);}
3069 void fadd(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FADD, 0xDCC0, 0, dst); avoid_unused_warn(src);}
3070 void fadd(const Mem32& dst) {AppendInstr(I_FADD, 0xD8, 0, Imm8(0), dst);}
3071 void fadd(const Mem64& dst) {AppendInstr(I_FADD, 0xDC, 0, Imm8(0), dst);}
3072 void faddp() {AppendInstr(I_FADDP, 0xDEC1, 0);}
3073 void faddp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FADDP, 0xDEC0, 0, dst); avoid_unused_warn(src);}
3074 void fiadd(const Mem16& dst) {AppendInstr(I_FIADD, 0xDE, 0, Imm8(0), dst);}
3075 void fiadd(const Mem32& dst) {AppendInstr(I_FIADD, 0xDA, 0, Imm8(0), dst);}
3076 void fbld(const Mem80& dst) {AppendInstr(I_FBLD, 0xDF, 0, Imm8(4), dst);}
3077 void fbstp(const Mem80& dst) {AppendInstr(I_FBSTP, 0xDF, 0, Imm8(6), dst);}
3078 void fchs() {AppendInstr(I_FCHS, 0xD9E0, 0);}
3079 void fclex() {AppendInstr(I_FCLEX, 0x9BDBE2, 0);}
3080 void fnclex() {AppendInstr(I_FNCLEX, 0xDBE2, 0);}
3081 void fcmovb(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAC0, 0, src); avoid_unused_warn(dst);}
3082 void fcmovbe(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAD0, 0, src); avoid_unused_warn(dst);}
3083 void fcmove(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAC8, 0, src); avoid_unused_warn(dst);}
3084 void fcmovnb(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBC0, 0, src); avoid_unused_warn(dst);}
3085 void fcmovnbe(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBD0, 0, src); avoid_unused_warn(dst);}
3086 void fcmovne(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBC8, 0, src); avoid_unused_warn(dst);}
3087 void fcmovnu(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDBD8, 0, src); avoid_unused_warn(dst);}
3088 void fcmovu(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCMOVCC, 0xDAD8, 0, src); avoid_unused_warn(dst);}
3089 void fcom() {AppendInstr(I_FCOM, 0xD8D1, 0);}
3090 void fcom(const FpuReg& dst) {AppendInstr(I_FCOM, 0xD8D0, 0, dst);}
3091 void fcom(const Mem32& dst) {AppendInstr(I_FCOM, 0xD8, 0, Imm8(2), dst);}
3092 void fcom(const Mem64& dst) {AppendInstr(I_FCOM, 0xDC, 0, Imm8(2), dst);}
3093 void fcomp() {AppendInstr(I_FCOMP, 0xD8D9, 0);}
3094 void fcomp(const FpuReg& dst) {AppendInstr(I_FCOMP, 0xD8D8, 0, dst);}
3095 void fcomp(const Mem32& dst) {AppendInstr(I_FCOMP, 0xD8, 0, Imm8(3), dst);}
3096 void fcomp(const Mem64& dst) {AppendInstr(I_FCOMP, 0xDC, 0, Imm8(3), dst);}
3097 void fcompp() {AppendInstr(I_FCOMPP, 0xDED9, 0);}
3098 void fcomi(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCOMI, 0xDBF0, 0, src); avoid_unused_warn(dst);}
3099 void fcomip(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FCOMIP, 0xDFF0, 0, src); avoid_unused_warn(dst);}
3100 void fcos() {AppendInstr(I_FCOS, 0xD9FF, 0);}
3101 void fdecstp() {AppendInstr(I_FDECSTP, 0xD9F6, 0);}
3102 void fdiv(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FDIV, 0xD8F0, 0, src); avoid_unused_warn(dst);}
3103 void fdiv(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIV, 0xDCF8, 0, dst); avoid_unused_warn(src);}
3104 void fdiv(const Mem32& dst) {AppendInstr(I_FDIV, 0xD8, 0, Imm8(6), dst);}
3105 void fdiv(const Mem64& dst) {AppendInstr(I_FDIV, 0xDC, 0, Imm8(6), dst);}
3106 void fdivp() {AppendInstr(I_FDIVP, 0xDEF9, 0);}
3107 void fdivp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVP, 0xDEF8, 0, dst); avoid_unused_warn(src);}
3108 void fidiv(const Mem16& dst) {AppendInstr(I_FIDIV, 0xDE, 0, Imm8(6), dst);}
3109 void fidiv(const Mem32& dst) {AppendInstr(I_FIDIV, 0xDA, 0, Imm8(6), dst);}
3110 void fdivr(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FDIVR, 0xD8F8, 0, src); avoid_unused_warn(dst);}
3111 void fdivr(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVR, 0xDCF0, 0, dst); avoid_unused_warn(src);}
3112 void fdivr(const Mem32& dst) {AppendInstr(I_FDIVR, 0xD8, 0, Imm8(7), dst);}
3113 void fdivr(const Mem64& dst) {AppendInstr(I_FDIVR, 0xDC, 0, Imm8(7), dst);}
3114 void fdivrp() {AppendInstr(I_FDIVRP, 0xDEF1, 0);}
3115 void fdivrp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FDIVRP, 0xDEF0, 0, dst); avoid_unused_warn(src);}
3116 void fidivr(const Mem16& dst) {AppendInstr(I_FIDIVR, 0xDE, 0, Imm8(7), dst);}
3117 void fidivr(const Mem32& dst) {AppendInstr(I_FIDIVR, 0xDA, 0, Imm8(7), dst);}
3118 void ffree(const FpuReg& dst) {AppendInstr(I_FFREE, 0xDDC0, 0, dst);}
3119 void ficom(const Mem16& dst) {AppendInstr(I_FICOM, 0xDE, 0, Imm8(2), dst);}
3120 void ficom(const Mem32& dst) {AppendInstr(I_FICOM, 0xDA, 0, Imm8(2), dst);}
3121 void ficomp(const Mem16& dst) {AppendInstr(I_FICOMP, 0xDE, 0, Imm8(3), dst);}
3122 void ficomp(const Mem32& dst) {AppendInstr(I_FICOMP, 0xDA, 0, Imm8(3), dst);}
3123 void fild(const Mem16& dst) {AppendInstr(I_FILD, 0xDF, 0, Imm8(0), dst);}
3124 void fild(const Mem32& dst) {AppendInstr(I_FILD, 0xDB, 0, Imm8(0), dst);}
3125 void fild(const Mem64& dst) {AppendInstr(I_FILD, 0xDF, 0, Imm8(5), dst);}
3126 void fincstp() {AppendInstr(I_FINCSTP, 0xD9F7, 0);}
3127 void finit() {AppendInstr(I_FINIT, 0x9BDBE3, 0);}
3128 void fninit() {AppendInstr(I_FNINIT, 0xDBE3, 0);}
3129 void fist(const Mem16& dst) {AppendInstr(I_FIST, 0xDF, 0, Imm8(2), dst);}
3130 void fist(const Mem32& dst) {AppendInstr(I_FIST, 0xDB, 0, Imm8(2), dst);}
3131 void fistp(const Mem16& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(3), dst);}
3132 void fistp(const Mem32& dst) {AppendInstr(I_FISTP, 0xDB, 0, Imm8(3), dst);}
3133 void fistp(const Mem64& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(7), dst);}
3134 void fisttp(const Mem16& dst) {AppendInstr(I_FISTP, 0xDF, 0, Imm8(1), dst);}
3135 void fisttp(const Mem32& dst) {AppendInstr(I_FISTP, 0xDB, 0, Imm8(1), dst);}
3136 void fisttp(const Mem64& dst) {AppendInstr(I_FISTP, 0xDD, 0, Imm8(1), dst);}
3137 void fld(const Mem32& src) {AppendInstr(I_FLD, 0xD9, 0, Imm8(0), src);}
3138 void fld(const Mem64& src) {AppendInstr(I_FLD, 0xDD, 0, Imm8(0), src);}
3139 void fld(const Mem80& src) {AppendInstr(I_FLD, 0xDB, 0, Imm8(5), src);}
3140 void fld(const FpuReg& src) {AppendInstr(I_FLD, 0xD9C0, 0, src);}
3141 void fld1() {AppendInstr(I_FLD1, 0xD9E8, 0);}
3142 void fldcw(const Mem16& src) {AppendInstr(I_FLDCW, 0xD9, 0, Imm8(5), src);}
3143 void fldenv(const Mem224& src) {AppendInstr(I_FLDENV, 0xD9, 0, Imm8(4), src);}
3144 void fldl2e() {AppendInstr(I_FLDL2E, 0xD9EA, 0);}
3145 void fldl2t() {AppendInstr(I_FLDL2T, 0xD9E9, 0);}
3146 void fldlg2() {AppendInstr(I_FLDLG2, 0xD9EC, 0);}
3147 void fldln2() {AppendInstr(I_FLDLN2, 0xD9ED, 0);}
3148 void fldpi() {AppendInstr(I_FLDPI, 0xD9EB, 0);}
3149 void fldz() {AppendInstr(I_FLDZ, 0xD9EE, 0);}
3150 void fmul(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FMUL, 0xD8C8, 0, src); avoid_unused_warn(dst);}
3151 void fmul(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FMUL, 0xDCC8, 0, dst); avoid_unused_warn(src);}
3152 void fmul(const Mem32& dst) {AppendInstr(I_FMUL, 0xD8, 0, Imm8(1), dst);}
3153 void fmul(const Mem64& dst) {AppendInstr(I_FMUL, 0xDC, 0, Imm8(1), dst);}
3154 void fmulp() {AppendInstr(I_FMULP, 0xDEC9, 0);}
3155 void fmulp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FMULP, 0xDEC8, 0, dst); avoid_unused_warn(src);}
3156 void fimul(const Mem16& dst) {AppendInstr(I_FIMUL, 0xDE, 0, Imm8(1), dst);}
3157 void fimul(const Mem32& dst) {AppendInstr(I_FIMUL, 0xDA, 0, Imm8(1), dst);}
3158 void fnop() {AppendInstr(I_FNOP, 0xD9D0, 0);}
3159 void fpatan() {AppendInstr(I_FPATAN, 0xD9F3, 0);}
3160 void fprem() {AppendInstr(I_FPREM, 0xD9F8, 0);}
3161 void fprem1() {AppendInstr(I_FPREM1, 0xD9F5, 0);}
3162 void fptan() {AppendInstr(I_FPTAN, 0xD9F2, 0);}
3163 void frndint() {AppendInstr(I_FRNDINT, 0xD9FC, 0);}
3164 void frstor(const Mem864& src) {AppendInstr(I_FRSTOR, 0xDD, 0, Imm8(4), src);}
3165 void fsave(const Mem864& dst) {AppendInstr(I_FSAVE, 0x9BDD, 0, Imm8(6), dst);}
3166 void fnsave(const Mem864& dst) {AppendInstr(I_FNSAVE, 0xDD, 0, Imm8(6), dst);}
3167 void fscale() {AppendInstr(I_FSCALE, 0xD9FD, 0);}
3168 void fsin() {AppendInstr(I_FSIN, 0xD9FE, 0);}
3169 void fsincos() {AppendInstr(I_FSINCOS, 0xD9FB, 0);}
3170 void fsqrt() {AppendInstr(I_FSQRT, 0xD9FA, 0);}
3171 void fst(const Mem32& dst) {AppendInstr(I_FST, 0xD9, 0, Imm8(2), dst);}
3172 void fst(const Mem64& dst) {AppendInstr(I_FST, 0xDD, 0, Imm8(2), dst);}
3173 void fst(const FpuReg& dst) {AppendInstr(I_FST, 0xDDD0, 0, dst);}
3174 void fstp(const FpuReg& dst) {AppendInstr(I_FSTP, 0xDDD8, 0, dst);}
3175 void fstp(const Mem32& dst) {AppendInstr(I_FSTP, 0xD9, 0, Imm8(3), dst);}
3176 void fstp(const Mem64& dst) {AppendInstr(I_FSTP, 0xDD, 0, Imm8(3), dst);}
3177 void fstp(const Mem80& dst) {AppendInstr(I_FSTP, 0xDB, 0, Imm8(7), dst);}
3178 void fstcw(const Mem16& dst) {AppendInstr(I_FSTCW, 0x9BD9, 0, Imm8(7), dst);}
3179 void fnstcw(const Mem16& dst) {AppendInstr(I_FNSTCW, 0xD9, 0, Imm8(7), dst);}
3180 void fstenv(const Mem224& dst) {AppendInstr(I_FSTENV, 0x9BD9, 0, Imm8(6), dst);}
3181 void fnstenv(const Mem224& dst) {AppendInstr(I_FNSTENV, 0xD9, 0, Imm8(6), dst);}
3182 void fstsw(const Mem16& dst) {AppendInstr(I_FSTSW, 0x9BDD, 0, Imm8(7), dst);}
3183 void fstsw(const Reg16& dst) {AppendInstr(I_FSTSW, 0x9BDFE0, 0, Dummy(W(dst), ax));}
3184 void fnstsw(const Mem16& dst) {AppendInstr(I_FNSTSW, 0xDD, 0, Imm8(7), dst);}
3185 void fnstsw(const Reg16& dst) {AppendInstr(I_FNSTSW, 0xDFE0, 0, Dummy(W(dst), ax));}
3186 void fsub(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FSUB, 0xD8E0, 0, src); avoid_unused_warn(dst);}
3187 void fsub(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUB, 0xDCE8, 0, dst); avoid_unused_warn(src);}
3188 void fsub(const Mem32& dst) {AppendInstr(I_FSUB, 0xD8, 0, Imm8(4), dst);}
3189 void fsub(const Mem64& dst) {AppendInstr(I_FSUB, 0xDC, 0, Imm8(4), dst);}
3190 void fsubp() {AppendInstr(I_FSUBP, 0xDEE9, 0);}
3191 void fsubp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBP, 0xDEE8, 0, dst); avoid_unused_warn(src);}
3192 void fisub(const Mem16& dst) {AppendInstr(I_FISUB, 0xDE, 0, Imm8(4), dst);}
3193 void fisub(const Mem32& dst) {AppendInstr(I_FISUB, 0xDA, 0, Imm8(4), dst);}
3194 void fsubr(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FSUBR, 0xD8E8, 0, src); avoid_unused_warn(dst);}
3195 void fsubr(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBR, 0xDCE0, 0, dst); avoid_unused_warn(src);}
3196 void fsubr(const Mem32& dst) {AppendInstr(I_FSUBR, 0xD8, 0, Imm8(5), dst);}
3197 void fsubr(const Mem64& dst) {AppendInstr(I_FSUBR, 0xDC, 0, Imm8(5), dst);}
3198 void fsubrp() {AppendInstr(I_FSUBRP, 0xDEE1, 0);}
3199 void fsubrp(const FpuReg& dst, const FpuReg_st0& src) {AppendInstr(I_FSUBRP, 0xDEE0, 0, dst); avoid_unused_warn(src);}
3200 void fisubr(const Mem16& dst) {AppendInstr(I_FISUBR, 0xDE, 0, Imm8(5), dst);}
3201 void fisubr(const Mem32& dst) {AppendInstr(I_FISUBR, 0xDA, 0, Imm8(5), dst);}
3202 void ftst() {AppendInstr(I_FTST, 0xD9E4, 0);}
3203 void fucom() {AppendInstr(I_FUCOM, 0xDDE1, 0);}
3204 void fucom(const FpuReg& dst) {AppendInstr(I_FUCOM, 0xDDE0, 0, dst);}
3205 void fucomp() {AppendInstr(I_FUCOMP, 0xDDE9, 0);}
3206 void fucomp(const FpuReg& dst) {AppendInstr(I_FUCOMP, 0xDDE8, 0, dst);}
3207 void fucompp() {AppendInstr(I_FUCOMPP, 0xDAE9, 0);}
3208 void fucomi(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FUCOMI, 0xDBE8, 0, src); avoid_unused_warn(dst);}
3209 void fucomip(const FpuReg_st0& dst, const FpuReg& src) {AppendInstr(I_FUCOMIP, 0xDFE8, 0, src); avoid_unused_warn(dst);}
3210 void fwait() {wait();}
3211 void fxam() {AppendInstr(I_FXAM, 0xD9E5, 0);}
3212 void fxch() {AppendInstr(I_FXCH, 0xD9C9, 0);}
3213 void fxch(const FpuReg& dst) {AppendInstr(I_FXCH, 0xD9C8, 0, dst);}
3214 void fxrstor(const Mem4096& src) {AppendInstr(I_FXRSTOR, 0x0FAE, 0, Imm8(1), src);}
3215 void fxsave(const Mem4096& dst) {AppendInstr(I_FXSAVE, 0x0FAE, 0, Imm8(0), dst);}
3216 void fxtract() {AppendInstr(I_FXTRACT, 0xD9F4, 0);}
3217 void fyl2x() {AppendInstr(I_FYL2X, 0xD9F1, 0);}
3218 void fyl2xp1() {AppendInstr(I_FYL2XP1, 0xD9F9, 0);}
3219
3220 // MMX
3221 void emms() {AppendInstr(I_EMMS, 0x0F77, 0);}
3222 void movd(const MmxReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));}
3223 void movd(const MmxReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));}
3224 void movd(const Reg32& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));}
3225 void movd(const Mem32& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));}
3226 #ifdef JITASM64
3227 void movd(const MmxReg& dst, const Reg64& src) {AppendInstr(I_MOVD, 0x0F6E, E_REXW_PREFIX, W(dst), R(src));}
3228 void movd(const Reg64& dst, const MmxReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_REXW_PREFIX, R(src), W(dst));}
3229 #endif
3230 void movq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x0F6F, 0, W(dst), R(src));}
3231 void movq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));}
3232 void movq(const Mem64& dst, const MmxReg& src) {AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));}
3233 #ifdef JITASM64
3234 void movq(const MmxReg& dst, const Reg64& src) {movd(dst, src);}
3235 void movq(const Reg64& dst, const MmxReg& src) {movd(dst, src);}
3236 #endif
3237 void packsswb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));}
3238 void packsswb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));}
3239 void packssdw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));}
3240 void packssdw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));}
3241 void packuswb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));}
3242 void packuswb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));}
3243 void paddb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDB, 0x0FFC, 0, RW(dst), R(src));}
3244 void paddb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDB, 0x0FFC, 0, RW(dst), R(src));}
3245 void paddw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDW, 0x0FFD, 0, RW(dst), R(src));}
3246 void paddw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDW, 0x0FFD, 0, RW(dst), R(src));}
3247 void paddd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDD, 0x0FFE, 0, RW(dst), R(src));}
3248 void paddd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDD, 0x0FFE, 0, RW(dst), R(src));}
3249 void paddsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDSB, 0x0FEC, 0, RW(dst), R(src));}
3250 void paddsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDSB, 0x0FEC, 0, RW(dst), R(src));}
3251 void paddsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDSW, 0x0FED, 0, RW(dst), R(src));}
3252 void paddsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDSW, 0x0FED, 0, RW(dst), R(src));}
3253 void paddusb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDUSB, 0x0FDC, 0, RW(dst), R(src));}
3254 void paddusb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDUSB, 0x0FDC, 0, RW(dst), R(src));}
3255 void paddusw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDUSW, 0x0FDD, 0, RW(dst), R(src));}
3256 void paddusw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDUSW, 0x0FDD, 0, RW(dst), R(src));}
3257 void pand(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAND, 0x0FDB, 0, RW(dst), R(src));}
3258 void pand(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAND, 0x0FDB, 0, RW(dst), R(src));}
3259 void pandn(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PANDN, 0x0FDF, 0, RW(dst), R(src));}
3260 void pandn(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PANDN, 0x0FDF, 0, RW(dst), R(src));}
3261 void pcmpeqb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQB, 0x0F74, 0, RW(dst), R(src));}
3262 void pcmpeqb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQB, 0x0F74, 0, RW(dst), R(src));}
3263 void pcmpeqw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQW, 0x0F75, 0, RW(dst), R(src));}
3264 void pcmpeqw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQW, 0x0F75, 0, RW(dst), R(src));}
3265 void pcmpeqd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPEQD, 0x0F76, 0, RW(dst), R(src));}
3266 void pcmpeqd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPEQD, 0x0F76, 0, RW(dst), R(src));}
3267 void pcmpgtb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTB, 0x0F64, 0, RW(dst), R(src));}
3268 void pcmpgtb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTB, 0x0F64, 0, RW(dst), R(src));}
3269 void pcmpgtw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTW, 0x0F65, 0, RW(dst), R(src));}
3270 void pcmpgtw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTW, 0x0F65, 0, RW(dst), R(src));}
3271 void pcmpgtd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PCMPGTD, 0x0F66, 0, RW(dst), R(src));}
3272 void pcmpgtd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PCMPGTD, 0x0F66, 0, RW(dst), R(src));}
3273 void pmaddwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMADDWD, 0x0FF5, 0, RW(dst), R(src));}
3274 void pmaddwd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMADDWD, 0x0FF5, 0, RW(dst), R(src));}
3275 void pmulhw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHW, 0x0FE5, 0, RW(dst), R(src));}
3276 void pmulhw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHW, 0x0FE5, 0, RW(dst), R(src));}
3277 void pmullw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULLW, 0x0FD5, 0, RW(dst), R(src));}
3278 void pmullw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULLW, 0x0FD5, 0, RW(dst), R(src));}
3279 void por(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_POR, 0x0FEB, 0, RW(dst), R(src));}
3280 void por(const MmxReg& dst, const Mem64& src) {AppendInstr(I_POR, 0x0FEB, 0, RW(dst), R(src));}
3281 void psllw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLW, 0x0FF1, 0, RW(dst), R(count));}
3282 void psllw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLW, 0x0FF1, 0, RW(dst), R(count));}
3283 void psllw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLW, 0x0F71, 0, Imm8(6), RW(dst), count);}
3284 void pslld(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLD, 0x0FF2, 0, RW(dst), R(count));}
3285 void pslld(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLD, 0x0FF2, 0, RW(dst), R(count));}
3286 void pslld(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLD, 0x0F72, 0, Imm8(6), RW(dst), count);}
3287 void psllq(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSLLQ, 0x0FF3, 0, RW(dst), R(count));}
3288 void psllq(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSLLQ, 0x0FF3, 0, RW(dst), R(count));}
3289 void psllq(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSLLQ, 0x0F73, 0, Imm8(6), RW(dst), count);}
3290 void psraw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRAW, 0x0FE1, 0, RW(dst), R(count));}
3291 void psraw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRAW, 0x0FE1, 0, RW(dst), R(count));}
3292 void psraw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRAW, 0x0F71, 0, Imm8(4), RW(dst), count);}
3293 void psrad(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRAD, 0x0FE2, 0, RW(dst), R(count));}
3294 void psrad(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRAD, 0x0FE2, 0, RW(dst), R(count));}
3295 void psrad(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRAD, 0x0F72, 0, Imm8(4), RW(dst), count);}
3296 void psrlw(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLW, 0x0FD1, 0, RW(dst), R(count));}
3297 void psrlw(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLW, 0x0FD1, 0, RW(dst), R(count));}
3298 void psrlw(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLW, 0x0F71, 0, Imm8(2), RW(dst), count);}
3299 void psrld(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLD, 0x0FD2, 0, RW(dst), R(count));}
3300 void psrld(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLD, 0x0FD2, 0, RW(dst), R(count));}
3301 void psrld(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLD, 0x0F72, 0, Imm8(2), RW(dst), count);}
3302 void psrlq(const MmxReg& dst, const MmxReg& count) {AppendInstr(I_PSRLQ, 0x0FD3, 0, RW(dst), R(count));}
3303 void psrlq(const MmxReg& dst, const Mem64& count) {AppendInstr(I_PSRLQ, 0x0FD3, 0, RW(dst), R(count));}
3304 void psrlq(const MmxReg& dst, const Imm8& count) {AppendInstr(I_PSRLQ, 0x0F73, 0, Imm8(2), RW(dst), count);}
3305 void psubb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBB, 0x0FF8, 0, RW(dst), R(src));}
3306 void psubb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBB, 0x0FF8, 0, RW(dst), R(src));}
3307 void psubw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBW, 0x0FF9, 0, RW(dst), R(src));}
3308 void psubw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBW, 0x0FF9, 0, RW(dst), R(src));}
3309 void psubd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBD, 0x0FFA, 0, RW(dst), R(src));}
3310 void psubd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBD, 0x0FFA, 0, RW(dst), R(src));}
3311 void psubsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBSB, 0x0FE8, 0, RW(dst), R(src));}
3312 void psubsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBSB, 0x0FE8, 0, RW(dst), R(src));}
3313 void psubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBSW, 0x0FE9, 0, RW(dst), R(src));}
3314 void psubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBSW, 0x0FE9, 0, RW(dst), R(src));}
3315 void psubusb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBUSB, 0x0FD8, 0, RW(dst), R(src));}
3316 void psubusb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBUSB, 0x0FD8, 0, RW(dst), R(src));}
3317 void psubusw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBUSW, 0x0FD9, 0, RW(dst), R(src));}
3318 void psubusw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBUSW, 0x0FD9, 0, RW(dst), R(src));}
3319 void punpckhbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));}
3320 void punpckhbw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));}
3321 void punpckhwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));}
3322 void punpckhwd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));}
3323 void punpckhdq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));}
3324 void punpckhdq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));}
3325 void punpcklbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));}
3326 void punpcklbw(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));}
3327 void punpcklwd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));}
3328 void punpcklwd(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));}
3329 void punpckldq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));}
3330 void punpckldq(const MmxReg& dst, const Mem32& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));}
3331 void pxor(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));}
3332 void pxor(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));}
3333
3334 // MMX2
3335 void pavgb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));}
3336 void pavgb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));}
3337 void pavgw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));}
3338 void pavgw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));}
3339 void pextrw(const Reg32& dst, const MmxReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, 0, W(dst), R(src), i);}
3340 #ifdef JITASM64
3341 void pextrw(const Reg64& dst, const MmxReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_REXW_PREFIX, W(dst), R(src), i);}
3342 #endif
3343 void pinsrw(const MmxReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);}
3344 void pinsrw(const MmxReg& dst, const Mem16& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);}
3345 #ifdef JITASM64
3346 void pinsrw(const MmxReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_REXW_PREFIX, RW(dst), R(src), i);}
3347 #endif
3348 void pmaxsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMAXSW, 0x0FEE, 0, RW(dst), R(src));}
3349 void pmaxsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMAXSW, 0x0FEE, 0, RW(dst), R(src));}
3350 void pmaxub(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMAXUB, 0x0FDE, 0, RW(dst), R(src));}
3351 void pmaxub(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMAXUB, 0x0FDE, 0, RW(dst), R(src));}
3352 void pminsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMINSW, 0x0FEA, 0, RW(dst), R(src));}
3353 void pminsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMINSW, 0x0FEA, 0, RW(dst), R(src));}
3354 void pminub(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMINUB, 0x0FDA, 0, RW(dst), R(src));}
3355 void pminub(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMINUB, 0x0FDA, 0, RW(dst), R(src));}
3356 void pmovmskb(const Reg32& dst, const MmxReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, 0, W(dst), R(src));}
3357 #ifdef JITASM64
3358 void pmovmskb(const Reg64& dst, const MmxReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_REXW_PREFIX, W(dst), R(src));}
3359 #endif
3360 void pmulhuw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHUW, 0x0FE4, 0, RW(dst), R(src));}
3361 void pmulhuw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHUW, 0x0FE4, 0, RW(dst), R(src));}
3362 void psadbw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSADBW, 0x0FF6, 0, RW(dst), R(src));}
3363 void psadbw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSADBW, 0x0FF6, 0, RW(dst), R(src));}
3364 void pshufw(const MmxReg& dst, const MmxReg& src, const Imm8& order) {AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);}
3365 void pshufw(const MmxReg& dst, const Mem64& src, const Imm8& order) {AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);}
3366
3367 // SSE
3368 void addps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDPS, 0x0F58, 0, RW(dst), R(src));}
3369 void addps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDPS, 0x0F58, 0, RW(dst), R(src));}
3370 void addss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSS, 0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3371 void addss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_ADDSS, 0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3372 void andps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDPS, 0x0F54, 0, RW(dst), R(src));}
3373 void andps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDPS, 0x0F54, 0, RW(dst), R(src));}
3374 void andnps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDNPS, 0x0F55, 0, RW(dst), R(src));}
3375 void andnps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDNPS, 0x0F55, 0, RW(dst), R(src));}
3376 void cmpps(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);}
3377 void cmpps(const XmmReg& dst, const Mem128& src, const Imm8& opd3) {AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);}
3378 void cmpeqps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 0);}
3379 void cmpeqps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 0);}
3380 void cmpltps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 1);}
3381 void cmpltps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 1);}
3382 void cmpleps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 2);}
3383 void cmpleps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 2);}
3384 void cmpunordps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 3);}
3385 void cmpunordps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 3);}
3386 void cmpneqps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 4);}
3387 void cmpneqps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 4);}
3388 void cmpnltps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 5);}
3389 void cmpnltps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 5);}
3390 void cmpnleps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 6);}
3391 void cmpnleps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 6);}
3392 void cmpordps(const XmmReg& dst, const XmmReg& src) {cmpps(dst, src, 7);}
3393 void cmpordps(const XmmReg& dst, const Mem128& src) {cmpps(dst, src, 7);}
3394 void cmpss(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);}
3395 void cmpss(const XmmReg& dst, const Mem32& src, const Imm8& opd3) {AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);}
3396 void cmpeqss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 0);}
3397 void cmpeqss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 0);}
3398 void cmpltss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 1);}
3399 void cmpltss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 1);}
3400 void cmpless(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 2);}
3401 void cmpless(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 2);}
3402 void cmpunordss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 3);}
3403 void cmpunordss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 3);}
3404 void cmpneqss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 4);}
3405 void cmpneqss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 4);}
3406 void cmpnltss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 5);}
3407 void cmpnltss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 5);}
3408 void cmpnless(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 6);}
3409 void cmpnless(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 6);}
3410 void cmpordss(const XmmReg& dst, const XmmReg& src) {cmpss(dst, src, 7);}
3411 void cmpordss(const XmmReg& dst, const Mem32& src) {cmpss(dst, src, 7);}
3412 void comiss(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_COMISS, 0x0F2F, 0, R(src1), R(src2));}
3413 void comiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_COMISS, 0x0F2F, 0, R(src1), R(src2));}
3414 void cvtpi2ps(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));}
3415 void cvtpi2ps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));}
3416 void cvtps2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));}
3417 void cvtps2pi(const MmxReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));}
3418 void cvtsi2ss(const XmmReg& dst, const Reg32& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3419 void cvtsi2ss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3420 void cvtss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3421 void cvtss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3422 void cvttps2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));}
3423 void cvttps2pi(const MmxReg& dst, const Mem64& src) {AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));}
3424 void cvttss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3425 void cvttss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3426 #ifdef JITASM64
3427 void cvtsi2ss(const XmmReg& dst, const Reg64& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));}
3428 void cvtsi2ss(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));}
3429 void cvtss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
3430 void cvtss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
3431 void cvttss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
3432 void cvttss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
3433 #endif
3434 void divps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVPS, 0x0F5E, 0, RW(dst), R(src));}
3435 void divps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_DIVPS, 0x0F5E, 0, RW(dst), R(src));}
3436 void divss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVSS, 0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3437 void divss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_DIVSS, 0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3438 void ldmxcsr(const Mem32& src) {AppendInstr(I_LDMXCSR, 0x0FAE, 0, Imm8(2), R(src));}
3439 void maskmovq(const MmxReg& src, const MmxReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVQ, 0x0FF7, 0, R(src), R(mask), Dummy(R(dstptr),zdi));}
3440 void maxps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXPS, 0x0F5F, 0, RW(dst), R(src));}
3441 void maxps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MAXPS, 0x0F5F, 0, RW(dst), R(src));}
3442 void maxss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXSS, 0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3443 void maxss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MAXSS, 0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3444 void minps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINPS, 0x0F5D, 0, RW(dst), R(src));}
3445 void minps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MINPS, 0x0F5D, 0, RW(dst), R(src));}
3446 void minss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINSS, 0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3447 void minss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MINSS, 0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3448 void movaps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x0F28, 0, W(dst), R(src));}
3449 void movaps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPS, 0x0F28, 0, W(dst), R(src));}
3450 void movaps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x0F29, 0, R(src), W(dst));}
3451 void movhlps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVHLPS, 0x0F12, 0, RW(dst), R(src));}
3452 void movhps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVHPS, 0x0F16, 0, RW(dst), R(src));}
3453 void movhps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPS, 0x0F17, 0, R(src), W(dst));}
3454 void movlhps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVLHPS, 0x0F16, 0, RW(dst), R(src));}
3455 void movlps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVLPS, 0x0F12, 0, RW(dst), R(src));}
3456 void movlps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPS, 0x0F13, 0, R(src), W(dst));}
3457 void movmskps(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x0F50, 0, W(dst), R(src));}
3458 #ifdef JITASM64
3459 void movmskps(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x0F50, E_REXW_PREFIX, W(dst), R(src));}
3460 #endif
3461 void movntps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPS, 0x0F2B, 0, R(src), W(dst));}
3462 void movntq(const Mem64& dst, const MmxReg& src) {AppendInstr(I_MOVNTQ, 0x0FE7, 0, R(src), W(dst));}
3463 void movss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x0F10, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3464 void movss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVSS, 0x0F10, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3465 void movss(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x0F11, E_MANDATORY_PREFIX_F3, R(src), W(dst));}
3466 void movups(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x0F10, 0, W(dst), R(src));}
3467 void movups(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPS, 0x0F10, 0, W(dst), R(src));}
3468 void movups(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x0F11, 0, R(src), W(dst));}
3469 void mulps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULPS, 0x0F59, 0, RW(dst), R(src));}
3470 void mulps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MULPS, 0x0F59, 0, RW(dst), R(src));}
3471 void mulss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULSS, 0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3472 void mulss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MULSS, 0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3473 void orps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ORPS, 0x0F56, 0, RW(dst), R(src));}
3474 void orps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ORPS, 0x0F56, 0, RW(dst), R(src));}
3475 void prefetcht0(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(1), R(mem));}
3476 void prefetcht1(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(2), R(mem));}
3477 void prefetcht2(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(3), R(mem));}
3478 void prefetchnta(const Mem8& mem) {AppendInstr(I_PREFETCH, 0x0F18, 0, Imm8(0), R(mem));}
3479 void rcpps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPPS, 0x0F53, 0, W(dst), R(src));}
3480 void rcpps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RCPPS, 0x0F53, 0, W(dst), R(src));}
3481 void rcpss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPSS, 0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3482 void rcpss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_RCPSS, 0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3483 void rsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTPS, 0x0F52, 0, W(dst), R(src));}
3484 void rsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RSQRTPS, 0x0F52, 0, W(dst), R(src));}
3485 void rsqrtss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTSS, 0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3486 void rsqrtss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_RSQRTSS, 0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3487 void sfence() {AppendInstr(I_SFENCE, 0x0FAEF8, 0);}
3488 void shufps(const XmmReg& dst, const XmmReg& src, const Imm8& sel) {AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);}
3489 void shufps(const XmmReg& dst, const Mem128& src, const Imm8& sel) {AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);}
3490 void sqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPS, 0x0F51, 0, W(dst), R(src));}
3491 void sqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPS, 0x0F51, 0, W(dst), R(src));}
3492 void sqrtss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTSS, 0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3493 void sqrtss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_SQRTSS, 0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3494 void stmxcsr(const Mem32& dst) {AppendInstr(I_STMXCSR, 0x0FAE, 0, Imm8(3), W(dst));}
3495 void subps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBPS, 0x0F5C, 0, RW(dst), R(src));}
3496 void subps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SUBPS, 0x0F5C, 0, RW(dst), R(src));}
3497 void subss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBSS, 0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3498 void subss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_SUBSS, 0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3499 void ucomiss(const XmmReg& src1, const XmmReg& src2){AppendInstr(I_UCOMISS, 0x0F2E, 0, R(src1), R(src2));}
3500 void ucomiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_UCOMISS, 0x0F2E, 0, R(src1), R(src2));}
3501 void unpckhps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));}
3502 void unpckhps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));}
3503 void unpcklps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));}
3504 void unpcklps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));}
3505 void xorps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_XORPS, 0x0F57, 0, RW(dst), R(src));}
3506 void xorps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_XORPS, 0x0F57, 0, RW(dst), R(src));}
3507
3508 // SSE2
3509 void addpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDPD, 0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3510 void addpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDPD, 0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3511 void addsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSD, 0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3512 void addsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_ADDSD, 0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3513 void andpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDPD, 0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3514 void andpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDPD, 0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3515 void andnpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ANDNPD, 0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3516 void andnpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ANDNPD, 0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3517 void clflush(const Mem8& src) {AppendInstr(I_CLFLUSH, 0x0FAE, 0, Imm8(7), R(src));}
3518 void cmppd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);}
3519 void cmppd(const XmmReg& dst, const Mem128& src, const Imm8& opd3) {AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);}
3520 void cmpeqpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 0);}
3521 void cmpeqpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 0);}
3522 void cmpltpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 1);}
3523 void cmpltpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 1);}
3524 void cmplepd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 2);}
3525 void cmplepd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 2);}
3526 void cmpunordpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 3);}
3527 void cmpunordpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 3);}
3528 void cmpneqpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 4);}
3529 void cmpneqpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 4);}
3530 void cmpnltpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 5);}
3531 void cmpnltpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 5);}
3532 void cmpnlepd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 6);}
3533 void cmpnlepd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 6);}
3534 void cmpordpd(const XmmReg& dst, const XmmReg& src) {cmppd(dst, src, 7);}
3535 void cmpordpd(const XmmReg& dst, const Mem128& src) {cmppd(dst, src, 7);}
3536 void cmpsd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3) {AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);}
3537 void cmpsd(const XmmReg& dst, const Mem64& src, const Imm8& opd3) {AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);}
3538 void cmpeqsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 0);}
3539 void cmpeqsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 0);}
3540 void cmpltsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 1);}
3541 void cmpltsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 1);}
3542 void cmplesd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 2);}
3543 void cmplesd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 2);}
3544 void cmpunordsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 3);}
3545 void cmpunordsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 3);}
3546 void cmpneqsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 4);}
3547 void cmpneqsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 4);}
3548 void cmpnltsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 5);}
3549 void cmpnltsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 5);}
3550 void cmpnlesd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 6);}
3551 void cmpnlesd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 6);}
3552 void cmpordsd(const XmmReg& dst, const XmmReg& src) {cmpsd(dst, src, 7);}
3553 void cmpordsd(const XmmReg& dst, const Mem64& src) {cmpsd(dst, src, 7);}
3554 void comisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_COMISD, 0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
3555 void comisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_COMISD, 0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
3556 void cvtdq2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3557 void cvtdq2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3558 void cvtpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3559 void cvtpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3560 void cvtpd2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3561 void cvtpd2pi(const MmxReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3562 void cvtpd2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3563 void cvtpd2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3564 void cvtpi2pd(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3565 void cvtpi2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3566 void cvtps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3567 void cvtps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3568 void cvtdq2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));}
3569 void cvtdq2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));}
3570 void cvtps2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));}
3571 void cvtps2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));}
3572 void cvtsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3573 void cvtsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3574 #ifdef JITASM64
3575 void cvtsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}
3576 void cvtsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}
3577 #endif
3578 void cvtsd2ss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3579 void cvtsd2ss(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3580 void cvtsi2sd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3581 void cvtsi2sd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3582 #ifdef JITASM64
3583 void cvtsi2sd(const XmmReg& dst, const Reg64& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
3584 void cvtsi2sd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
3585 #endif
3586 void cvtss2sd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SD, 0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3587 void cvtss2sd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_CVTSS2SD, 0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}
3588 void cvttpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3589 void cvttpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3590 void cvttpd2pi(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3591 void cvttpd2pi(const MmxReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3592 void cvttps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3593 void cvttps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3594 void cvttsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3595 void cvttsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3596 #ifdef JITASM64
3597 void cvttsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}
3598 void cvttsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}
3599 #endif
3600 void divpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVPD, 0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3601 void divpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_DIVPD, 0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3602 void divsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_DIVSD, 0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3603 void divsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_DIVSD, 0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3604 void lfence() {AppendInstr(I_LFENCE, 0x0FAEE8, 0);}
3605 void maskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVDQU, 0x0FF7, E_MANDATORY_PREFIX_66, R(src), R(mask), Dummy(R(dstptr), zdi));}
3606 void maxpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXPD, 0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3607 void maxpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MAXPD, 0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3608 void maxsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MAXSD, 0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3609 void maxsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MAXSD, 0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3610 void mfence() {AppendInstr(I_MFENCE, 0x0FAEF0, 0);}
3611 void minpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINPD, 0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3612 void minpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MINPD, 0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3613 void minsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MINSD, 0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3614 void minsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MINSD, 0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3615 void movapd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3616 void movapd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPD, 0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3617 void movapd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x0F29, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3618 void movd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3619 void movd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3620 void movd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3621 void movd(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3622 #ifdef JITASM64
3623 void movd(const XmmReg& dst, const Reg64& src) {AppendInstr(I_MOVD, 0x0F6E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}
3624 void movd(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x0F7E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst));}
3625 #endif
3626 void movdqa(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3627 void movdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQA, 0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3628 void movdqa(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x0F7F, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3629 void movdqu(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3630 void movdqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQU, 0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3631 void movdqu(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x0F7F, E_MANDATORY_PREFIX_F3, R(src), W(dst));}
3632 void movdq2q(const MmxReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQ2Q, 0x0FD6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3633 void movhpd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVHPD, 0x0F16, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3634 void movhpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPD, 0x0F17, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3635 void movlpd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVLPD, 0x0F12, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3636 void movlpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPD, 0x0F13, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3637 void movmskpd(const Reg32& dst, XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3638 #ifdef JITASM64
3639 void movmskpd(const Reg64& dst, XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}
3640 #endif
3641 void movntdq(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTDQ, 0x0FE7, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3642 void movnti(const Mem32& dst, const Reg32& src) {AppendInstr(I_MOVNTI, 0x0FC3, 0, R(src), W(dst));}
3643 #ifdef JITASM64
3644 void movnti(const Mem64& dst, const Reg64& src) {AppendInstr(I_MOVNTI, 0x0FC3, E_REXW_PREFIX, R(src), W(dst));}
3645 #endif
3646 void movntpd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPD, 0x0F2B, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3647 void movq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3648 void movq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3649 void movq(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x0FD6, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3650 #ifdef JITASM64
3651 void movq(const XmmReg& dst, const Reg64& src) {movd(dst, src);}
3652 void movq(const Reg64& dst, const XmmReg& src) {movd(dst, src);}
3653 #endif
3654 void movq2dq(const XmmReg& dst, const MmxReg& src) {AppendInstr(I_MOVQ2DQ, 0x0FD6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3655 void movsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x0F10, E_MANDATORY_PREFIX_F2, RW(dst), R(src));} // 64~127bits are unchanged
3656 void movsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVSD, 0x0F10, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3657 void movsd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x0F11, E_MANDATORY_PREFIX_F2, R(src), W(dst));}
3658 void movupd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3659 void movupd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPD, 0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3660 void movupd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x0F11, E_MANDATORY_PREFIX_66, R(src), W(dst));}
3661 void mulpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULPD, 0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3662 void mulpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MULPD, 0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3663 void mulsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MULSD, 0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3664 void mulsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MULSD, 0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3665 void orpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ORPD, 0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3666 void orpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ORPD, 0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3667 void packsswb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3668 void packsswb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3669 void packssdw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3670 void packssdw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3671 void packuswb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3672 void packuswb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3673 void paddb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDB, 0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3674 void paddb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDB, 0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3675 void paddw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDW, 0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3676 void paddw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDW, 0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3677 void paddd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDD, 0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3678 void paddd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDD, 0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3679 void paddq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PADDQ, 0x0FD4, 0, RW(dst), R(src));}
3680 void paddq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PADDQ, 0x0FD4, 0, RW(dst), R(src));}
3681 void paddq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDQ, 0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3682 void paddq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDQ, 0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3683 void paddsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDSB, 0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3684 void paddsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDSB, 0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3685 void paddsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDSW, 0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3686 void paddsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDSW, 0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3687 void paddusb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDUSB, 0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3688 void paddusb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDUSB, 0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3689 void paddusw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PADDUSW, 0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3690 void paddusw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PADDUSW, 0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3691 void pand(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAND, 0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3692 void pand(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAND, 0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3693 void pandn(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PANDN, 0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3694 void pandn(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PANDN, 0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3695 void pause() {AppendInstr(I_PAUSE, 0xF390, 0);}
3696 void pavgb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAVGB, 0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3697 void pavgb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAVGB, 0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3698 void pavgw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PAVGW, 0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3699 void pavgw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PAVGW, 0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3700 void pcmpeqb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQB, 0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3701 void pcmpeqb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQB, 0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3702 void pcmpeqw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQW, 0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3703 void pcmpeqw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQW, 0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3704 void pcmpeqd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQD, 0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3705 void pcmpeqd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQD, 0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3706 void pcmpgtb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTB, 0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3707 void pcmpgtb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTB, 0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3708 void pcmpgtw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTW, 0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3709 void pcmpgtw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTW, 0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3710 void pcmpgtd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTD, 0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3711 void pcmpgtd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTD, 0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3712 void pextrw(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66, W(dst), R(src), i);}
3713 #ifdef JITASM64
3714 void pextrw(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src), i);}
3715 #endif
3716 void pinsrw(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3717 void pinsrw(const XmmReg& dst, const Mem16& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3718 #ifdef JITASM64
3719 void pinsrw(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}
3720 #endif
3721 void pmaddwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMADDWD, 0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3722 void pmaddwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMADDWD, 0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3723 void pmaxsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSW, 0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3724 void pmaxsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSW, 0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3725 void pmaxub(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUB, 0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3726 void pmaxub(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUB, 0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3727 void pminsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSW, 0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3728 void pminsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSW, 0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3729 void pminub(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUB, 0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3730 void pminub(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUB, 0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3731 void pmovmskb(const Reg32& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3732 #ifdef JITASM64
3733 void pmovmskb(const Reg64& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}
3734 #endif
3735 void pmulhuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHUW, 0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3736 void pmulhuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHUW, 0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3737 void pmulhw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHW, 0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3738 void pmulhw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHW, 0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3739 void pmullw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULLW, 0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3740 void pmullw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULLW, 0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3741 void pmuludq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULUDQ, 0x0FF4, 0, RW(dst), R(src));}
3742 void pmuludq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULUDQ, 0x0FF4, 0, RW(dst), R(src));}
3743 void pmuludq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULUDQ, 0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3744 void pmuludq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULUDQ, 0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3745 void por(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_POR, 0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3746 void por(const XmmReg& dst, const Mem128& src) {AppendInstr(I_POR, 0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3747 void psadbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSADBW, 0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3748 void psadbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSADBW, 0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3749 void pshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);}
3750 void pshufd(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);}
3751 void pshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);}
3752 void pshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);}
3753 void pshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);}
3754 void pshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);}
3755 void psllw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLW, 0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3756 void psllw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLW, 0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3757 void psllw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}
3758 void pslld(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLD, 0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3759 void pslld(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLD, 0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3760 void pslld(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}
3761 void psllq(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSLLQ, 0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3762 void psllq(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSLLQ, 0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3763 void psllq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}
3764 void pslldq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(7), RW(dst), count);}
3765 void psraw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRAW, 0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3766 void psraw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRAW, 0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3767 void psraw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRAW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);}
3768 void psrad(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRAD, 0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3769 void psrad(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRAD, 0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3770 void psrad(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRAD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);}
3771 void psrlw(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLW, 0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3772 void psrlw(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLW, 0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3773 void psrlw(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLW, 0x0F71, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}
3774 void psrld(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLD, 0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3775 void psrld(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLD, 0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3776 void psrld(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLD, 0x0F72, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}
3777 void psrlq(const XmmReg& dst, const XmmReg& count) {AppendInstr(I_PSRLQ, 0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3778 void psrlq(const XmmReg& dst, const Mem128& count) {AppendInstr(I_PSRLQ, 0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}
3779 void psrlq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}
3780 void psrldq(const XmmReg& dst, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x0F73, E_MANDATORY_PREFIX_66, Imm8(3), RW(dst), count);}
3781 void psubb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBB, 0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3782 void psubb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBB, 0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3783 void psubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBW, 0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3784 void psubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBW, 0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3785 void psubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBD, 0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3786 void psubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBD, 0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3787 void psubq(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSUBQ, 0x0FFB, 0, RW(dst), R(src));}
3788 void psubq(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSUBQ, 0x0FFB, 0, RW(dst), R(src));}
3789 void psubq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBQ, 0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3790 void psubq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBQ, 0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3791 void psubsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBSB, 0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3792 void psubsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBSB, 0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3793 void psubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBSW, 0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3794 void psubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBSW, 0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3795 void psubusb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBUSB, 0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3796 void psubusb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBUSB, 0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3797 void psubusw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSUBUSW, 0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3798 void psubusw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSUBUSW, 0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3799 void punpckhbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3800 void punpckhbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHBW, 0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3801 void punpckhwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3802 void punpckhwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHWD, 0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3803 void punpckhdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3804 void punpckhdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHDQ, 0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3805 void punpckhqdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKHQDQ, 0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3806 void punpckhqdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKHQDQ, 0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3807 void punpcklbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3808 void punpcklbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLBW, 0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3809 void punpcklwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3810 void punpcklwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLWD, 0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3811 void punpckldq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3812 void punpckldq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLDQ, 0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3813 void punpcklqdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PUNPCKLQDQ, 0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3814 void punpcklqdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PUNPCKLQDQ, 0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3815 void pxor(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PXOR, 0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3816 void pxor(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PXOR, 0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3817 void shufpd(const XmmReg& dst, const XmmReg& src, const Imm8& sel) {AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);}
3818 void shufpd(const XmmReg& dst, const Mem128& src, const Imm8& sel) {AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);}
3819 void sqrtpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPD, 0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3820 void sqrtpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPD, 0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3821 void sqrtsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTSD, 0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3822 void sqrtsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_SQRTSD, 0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3823 void subpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBPD, 0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3824 void subpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SUBPD, 0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3825 void subsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SUBSD, 0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3826 void subsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_SUBSD, 0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3827 void ucomisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISD, 0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
3828 void ucomisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_UCOMISD, 0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
3829 void unpckhpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3830 void unpckhpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3831 void unpcklpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3832 void unpcklpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3833 void xorpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_XORPD, 0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3834 void xorpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_XORPD, 0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3835
3836 // SSE3
3837 void addsubps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3838 void addsubps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3839 void addsubpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3840 void addsubpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3841 void haddps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HADDPS, 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3842 void haddps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HADDPS, 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3843 void haddpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HADDPD, 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3844 void haddpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HADDPD, 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3845 void hsubps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HSUBPS, 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3846 void hsubps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HSUBPS, 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
3847 void hsubpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_HSUBPD, 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3848 void hsubpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_HSUBPD, 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3849 void lddqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_LDDQU, 0x0FF0, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3850 void monitor() {AppendInstr(I_MONITOR, 0x0F01C8, 0);}
3851 void movddup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDDUP, 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3852 void movddup(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVDDUP, 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));}
3853 void movshdup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3854 void movshdup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3855 void movsldup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3856 void movsldup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
3857 void mwait() {AppendInstr(I_MWAIT, 0x0F01C9, 0);}
3858
3859 // SSSE3
3860 void pabsb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSB, 0x0F381C, 0, RW(dst), R(src));}
3861 void pabsb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSB, 0x0F381C, 0, RW(dst), R(src));}
3862 void pabsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSB, 0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3863 void pabsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSB, 0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3864 void pabsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSW, 0x0F381D, 0, RW(dst), R(src));}
3865 void pabsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSW, 0x0F381D, 0, RW(dst), R(src));}
3866 void pabsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSW, 0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3867 void pabsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSW, 0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3868 void pabsd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PABSD, 0x0F381E, 0, RW(dst), R(src));}
3869 void pabsd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PABSD, 0x0F381E, 0, RW(dst), R(src));}
3870 void pabsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSD, 0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3871 void pabsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSD, 0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3872 void palignr(const MmxReg& dst, const MmxReg& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);}
3873 void palignr(const MmxReg& dst, const Mem64& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);}
3874 void palignr(const XmmReg& dst, const XmmReg& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);}
3875 void palignr(const XmmReg& dst, const Mem128& src, const Imm8& n) {AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);}
3876 void phaddw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDW, 0x0F3801, 0, RW(dst), R(src));}
3877 void phaddw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDW, 0x0F3801, 0, RW(dst), R(src));}
3878 void phaddw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDW, 0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3879 void phaddw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDW, 0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3880 void phaddd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDD, 0x0F3802, 0, RW(dst), R(src));}
3881 void phaddd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDD, 0x0F3802, 0, RW(dst), R(src));}
3882 void phaddd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDD, 0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3883 void phaddd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDD, 0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3884 void phaddsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHADDSW, 0x0F3803, 0, RW(dst), R(src));}
3885 void phaddsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHADDSW, 0x0F3803, 0, RW(dst), R(src));}
3886 void phaddsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHADDSW, 0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3887 void phaddsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHADDSW, 0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3888 void phsubw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBW, 0x0F3805, 0, RW(dst), R(src));}
3889 void phsubw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBW, 0x0F3805, 0, RW(dst), R(src));}
3890 void phsubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBW, 0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3891 void phsubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBW, 0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3892 void phsubd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBD, 0x0F3806, 0, RW(dst), R(src));}
3893 void phsubd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBD, 0x0F3806, 0, RW(dst), R(src));}
3894 void phsubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBD, 0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3895 void phsubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBD, 0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3896 void phsubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PHSUBSW, 0x0F3807, 0, RW(dst), R(src));}
3897 void phsubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PHSUBSW, 0x0F3807, 0, RW(dst), R(src));}
3898 void phsubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHSUBSW, 0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3899 void phsubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHSUBSW, 0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3900 void pmaddubsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));}
3901 void pmaddubsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));}
3902 void pmaddubsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3903 void pmaddubsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3904 void pmulhrsw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PMULHRSW, 0x0F380B, 0, RW(dst), R(src));}
3905 void pmulhrsw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PMULHRSW, 0x0F380B, 0, RW(dst), R(src));}
3906 void pmulhrsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULHRSW, 0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3907 void pmulhrsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULHRSW, 0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3908 void pshufb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSHUFB, 0x0F3800, 0, RW(dst), R(src));}
3909 void pshufb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSHUFB, 0x0F3800, 0, RW(dst), R(src));}
3910 void pshufb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSHUFB, 0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3911 void pshufb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSHUFB, 0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3912 void psignb(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGNB, 0x0F3808, 0, RW(dst), R(src));}
3913 void psignb(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGNB, 0x0F3808, 0, RW(dst), R(src));}
3914 void psignb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGNB, 0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3915 void psignb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGNB, 0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3916 void psignw(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGNW, 0x0F3809, 0, RW(dst), R(src));}
3917 void psignw(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGNW, 0x0F3809, 0, RW(dst), R(src));}
3918 void psignw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGNW, 0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3919 void psignw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGNW, 0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3920 void psignd(const MmxReg& dst, const MmxReg& src) {AppendInstr(I_PSIGND, 0x0F380A, 0, RW(dst), R(src));}
3921 void psignd(const MmxReg& dst, const Mem64& src) {AppendInstr(I_PSIGND, 0x0F380A, 0, RW(dst), R(src));}
3922 void psignd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PSIGND, 0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3923 void psignd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PSIGND, 0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3924
3925 // SSE4.1
3926 void blendps(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3927 void blendps(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3928 void blendpd(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3929 void blendpd(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3930 void blendvps(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3931 void blendvps(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3932 void blendvpd(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3933 void blendvpd(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3934 void dpps(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_DPPS, 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3935 void dpps(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_DPPS, 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3936 void dppd(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_DPPD, 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3937 void dppd(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_DPPD, 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3938 void extractps(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3939 void extractps(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3940 #ifdef JITASM64
3941 void extractps(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}
3942 #endif
3943 void insertps(const XmmReg& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3944 void insertps(const XmmReg& dst, const Mem32& src, const Imm8& i) {AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3945 void movntdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVNTDQA, 0x0F382A, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3946 void mpsadbw(const XmmReg& dst, const XmmReg& src, const Imm8& offsets) {AppendInstr(I_MPSADBW, 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);}
3947 void mpsadbw(const XmmReg& dst, const Mem128& src, const Imm8& offsets) {AppendInstr(I_MPSADBW, 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);}
3948 void packusdw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3949 void packusdw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3950 void pblendvb(const XmmReg& dst, const XmmReg& src, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3951 void pblendvb(const XmmReg& dst, const Mem128& src, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}
3952 void pblendw(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3953 void pblendw(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
3954 void pcmpeqq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPEQQ, 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3955 void pcmpeqq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPEQQ, 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3956 void pextrb(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3957 void pextrb(const Mem8& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3958 void pextrw(const Mem16& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x0F3A15, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3959 void pextrd(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3960 void pextrd(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3961 #ifdef JITASM64
3962 void pextrb(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x0F3A14, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}
3963 void pextrd(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}
3964 void pextrq(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}
3965 void pextrq(const Mem64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}
3966 #endif
3967 void phminposuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3968 void phminposuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3969 void pinsrb(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3970 void pinsrb(const XmmReg& dst, const Mem8& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3971 void pinsrd(const XmmReg& dst, const Reg32& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3972 void pinsrd(const XmmReg& dst, const Mem32& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3973 #ifdef JITASM64
3974 void pinsrb(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3975 void pinsrd(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}
3976 void pinsrq(const XmmReg& dst, const Reg64& src, const Imm8& i) {AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}
3977 void pinsrq(const XmmReg& dst, const Mem64& src, const Imm8& i) {AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}
3978 #endif
3979 void pmaxsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3980 void pmaxsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3981 void pmaxsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3982 void pmaxsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3983 void pmaxuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3984 void pmaxuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3985 void pmaxud(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3986 void pmaxud(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3987 void pminsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3988 void pminsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3989 void pminsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3990 void pminsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3991 void pminuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3992 void pminuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3993 void pminud(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3994 void pminud(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
3995 void pmovsxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3996 void pmovsxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3997 void pmovsxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3998 void pmovsxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));}
3999 void pmovsxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4000 void pmovsxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4001 void pmovsxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4002 void pmovsxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4003 void pmovsxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4004 void pmovsxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4005 void pmovsxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4006 void pmovsxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4007 void pmovzxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4008 void pmovzxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4009 void pmovzxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4010 void pmovzxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4011 void pmovzxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4012 void pmovzxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4013 void pmovzxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4014 void pmovzxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4015 void pmovzxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4016 void pmovzxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4017 void pmovzxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4018 void pmovzxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4019 void pmuldq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULDQ, 0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4020 void pmuldq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULDQ, 0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4021 void pmulld(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMULLD, 0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4022 void pmulld(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PMULLD, 0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4023 void ptest(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PTEST, 0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
4024 void ptest(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PTEST, 0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));}
4025 void roundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}
4026 void roundps(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}
4027 void roundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}
4028 void roundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}
4029 void roundss(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}
4030 void roundss(const XmmReg& dst, const Mem32& src, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}
4031 void roundsd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}
4032 void roundsd(const XmmReg& dst, const Mem64& src, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}
4033
4034 // SSE4.2
4035 void crc32(const Reg32& dst, const Reg8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
4036 void crc32(const Reg32& dst, const Mem8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
4037 void crc32(const Reg32& dst, const Reg16& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
4038 void crc32(const Reg32& dst, const Mem16& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}
4039 void crc32(const Reg32& dst, const Reg32& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
4040 void crc32(const Reg32& dst, const Mem32& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}
4041 #ifdef JITASM64
4042 void crc32(const Reg64& dst, const Reg8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
4043 void crc32(const Reg64& dst, const Mem8& src) {AppendInstr(I_CRC32, 0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
4044 void crc32(const Reg64& dst, const Reg64& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
4045 void crc32(const Reg64& dst, const Mem64& src) {AppendInstr(I_CRC32, 0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}
4046 #endif
4047 void pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4048 void pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4049 void pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM, 0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4050 void pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM, 0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4051 void pcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));}
4052 void pcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));}
4053 void pcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));}
4054 void pcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));}
4055 void pcmpgtq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PCMPGTQ, 0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4056 void pcmpgtq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PCMPGTQ, 0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));}
4057 void popcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
4058 void popcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
4059 void popcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
4060 void popcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
4061 #ifdef JITASM64
4062 void popcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
4063 void popcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
4064 #endif
4065
4066 // AVX
4067 void vaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4068 void vaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4069 void vaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4070 void vaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4071 void vaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4072 void vaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4073 void vaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4074 void vaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4075 void vaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4076 void vaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4077 void vaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4078 void vaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4079 void vaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4080 void vaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4081 void vaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4082 void vaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4083 void vaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4084 void vaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4085 void vaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4086 void vaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4087 void aesenc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4088 void aesenc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4089 void vaesenc(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4090 void vaesenc(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4091 void aesenclast(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4092 void aesenclast(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4093 void vaesenclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4094 void vaesenclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4095 void aesdec(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4096 void aesdec(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4097 void vaesdec(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4098 void vaesdec(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4099 void aesdeclast(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4100 void aesdeclast(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4101 void vaesdeclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4102 void vaesdeclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4103 void aesimc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4104 void aesimc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));}
4105 void vaesimc(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4106 void vaesimc(const XmmReg& dst, const Mem128& src) {AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4107 void aeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);}
4108 void aeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);}
4109 void vaeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);}
4110 void vaeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm) {AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);}
4111 void vandpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4112 void vandpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4113 void vandpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4114 void vandpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4115 void vandps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4116 void vandps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4117 void vandps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4118 void vandps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4119 void vandnpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4120 void vandnpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4121 void vandnpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4122 void vandnpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4123 void vandnps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4124 void vandnps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4125 void vandnps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4126 void vandnps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4127 void vblendpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4128 void vblendpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4129 void vblendpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4130 void vblendpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4131 void vblendps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4132 void vblendps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4133 void vblendps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4134 void vblendps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4135 void vblendvpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4136 void vblendvpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4137 void vblendvpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4138 void vblendvpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4139 void vblendvps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4140 void vblendvps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4141 void vblendvps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4142 void vblendvps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}
4143 void vbroadcastss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));}
4144 void vbroadcastss(const YmmReg& dst, const Mem32& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));}
4145 void vbroadcastsd(const YmmReg& dst, const Mem64 src) {AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));}
4146 void vbroadcastf128(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VBROADCASTF128, 0x1A, E_VEX_256_66_0F38_W0, W(dst), R(src));}
4147 void vcmppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);}
4148 void vcmppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);}
4149 void vcmppd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);}
4150 void vcmppd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm) {AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);}
4151 void vcmpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);}
4152 void vcmpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);}
4153 void vcmpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);}
4154 void vcmpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm) {AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);}
4155 void vcmpsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);}
4156 void vcmpsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& imm) {AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);}
4157 void vcmpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm) {AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);}
4158 void vcmpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& imm) {AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);}
4159 void vcomisd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4160 void vcomisd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4161 void vcomiss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));}
4162 void vcomiss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));}
4163 void vcvtdq2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}
4164 void vcvtdq2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}
4165 void vcvtdq2pd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}
4166 void vcvtdq2pd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}
4167 void vcvtdq2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));}
4168 void vcvtdq2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));}
4169 void vcvtdq2ps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));}
4170 void vcvtdq2ps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));}
4171 void vcvtpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}
4172 void vcvtpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}
4173 void vcvtpd2dq(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}
4174 void vcvtpd2dq(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}
4175 void vcvtpd2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4176 void vcvtpd2ps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4177 void vcvtpd2ps(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4178 void vcvtpd2ps(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4179 void vcvtps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4180 void vcvtps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4181 void vcvtps2dq(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4182 void vcvtps2dq(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4183 void vcvtps2pd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));}
4184 void vcvtps2pd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));}
4185 void vcvtps2pd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));}
4186 void vcvtps2pd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));}
4187 void vcvtsd2si(const Reg32 dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}
4188 void vcvtsd2si(const Reg32 dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}
4189 #ifdef JITASM64
4190 void vcvtsd2si(const Reg64 dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}
4191 void vcvtsd2si(const Reg64 dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}
4192 #endif
4193 void vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4194 void vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4195 void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg32& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));}
4196 void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));}
4197 #ifdef JITASM64
4198 void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg64& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));}
4199 void vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));}
4200 #endif
4201 void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg32& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));}
4202 void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));}
4203 #ifdef JITASM64
4204 void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg64& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));}
4205 void vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));}
4206 #endif
4207 void vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4208 void vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4209 void vcvtss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}
4210 void vcvtss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}
4211 #ifdef JITASM64
4212 void vcvtss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}
4213 void vcvtss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}
4214 #endif
4215 void vcvttpd2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4216 void vcvttpd2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4217 void vcvttpd2dq(const XmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4218 void vcvttpd2dq(const XmmReg& dst, const Mem256& src) {AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4219 void vcvttps2dq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}
4220 void vcvttps2dq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}
4221 void vcvttps2dq(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}
4222 void vcvttps2dq(const YmmReg& dst, const Mem256& src) {AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}
4223 void vcvttsd2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}
4224 void vcvttsd2si(const Reg32& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}
4225 #ifdef JITASM64
4226 void vcvttsd2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}
4227 void vcvttsd2si(const Reg64& dst, const Mem64& src) {AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}
4228 #endif
4229 void vcvttss2si(const Reg32& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}
4230 void vcvttss2si(const Reg32& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}
4231 #ifdef JITASM64
4232 void vcvttss2si(const Reg64& dst, const XmmReg& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}
4233 void vcvttss2si(const Reg64& dst, const Mem32& src) {AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}
4234 #endif
4235 void vdivpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4236 void vdivpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4237 void vdivpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4238 void vdivpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4239 void vdivps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4240 void vdivps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4241 void vdivps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4242 void vdivps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4243 void vdivsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4244 void vdivsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4245 void vdivss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4246 void vdivss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4247 void vdppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4248 void vdppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4249 void vdpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4250 void vdpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4251 void vdpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4252 void vdpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4253 void vextractf128(const XmmReg& dst, const YmmReg& src, const Imm8& i) {AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4254 void vextractf128(const Mem128& dst, const YmmReg& src, const Imm8& i) {AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4255 void vextractps(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);}
4256 void vextractps(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);}
4257 void vhaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4258 void vhaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4259 void vhaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4260 void vhaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4261 void vhaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4262 void vhaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4263 void vhaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4264 void vhaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4265 void vhsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4266 void vhsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4267 void vhsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4268 void vhsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4269 void vhsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4270 void vhsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4271 void vhsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4272 void vhsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4273 void vinsertf128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4274 void vinsertf128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4275 void vinsertps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4276 void vinsertps(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& i) {AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4277 void vlddqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_LDDQU, 0xF0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}
4278 void vlddqu(const YmmReg& dst, const Mem256& src) {AppendInstr(I_LDDQU, 0xF0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}
4279 void vldmxcsr(const Mem32& src) {AppendInstr(I_LDMXCSR, 0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(2), R(src));}
4280 void vmaskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr) {AppendInstr(I_MASKMOVDQU, 0xF7, E_VEX_128_66_0F_WIG, R(src), R(mask), Dummy(R(dstptr), zdi));}
4281 void vmaskmovps(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}
4282 void vmaskmovps(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}
4283 void vmaskmovpd(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}
4284 void vmaskmovpd(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}
4285 void vmaskmovps(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}
4286 void vmaskmovps(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}
4287 void vmaskmovpd(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}
4288 void vmaskmovpd(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}
4289 void vmaxpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4290 void vmaxpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4291 void vmaxpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4292 void vmaxpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4293 void vmaxps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4294 void vmaxps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4295 void vmaxps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4296 void vmaxps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4297 void vmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4298 void vmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4299 void vmaxss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4300 void vmaxss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4301 void vminpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4302 void vminpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4303 void vminpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4304 void vminpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4305 void vminps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4306 void vminps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4307 void vminps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4308 void vminps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4309 void vminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4310 void vminsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}
4311 void vminss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4312 void vminss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}
4313 void vmovapd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4314 void vmovapd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4315 void vmovapd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPD, 0x29, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4316 void vmovapd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4317 void vmovapd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4318 void vmovapd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVAPD, 0x29, E_VEX_256_66_0F_WIG, R(src), W(dst));}
4319 void vmovaps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));}
4320 void vmovaps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));}
4321 void vmovaps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVAPS, 0x29, E_VEX_128_0F_WIG, R(src), W(dst));}
4322 void vmovaps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));}
4323 void vmovaps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));}
4324 void vmovaps(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVAPS, 0x29, E_VEX_256_0F_WIG, R(src), W(dst));}
4325 void vmovd(const XmmReg& dst, const Reg32& src) {AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));}
4326 void vmovd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));}
4327 void vmovd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));}
4328 void vmovd(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));}
4329 void vmovq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4330 void vmovq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4331 void vmovq(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0xD6, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4332 #ifdef JITASM64
4333 void vmovq(const XmmReg& dst, const Reg64& src) {AppendInstr(I_MOVQ, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, W(dst), R(src));}
4334 void vmovq(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, R(src), W(dst));}
4335 #endif
4336 void vmovddup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}
4337 void vmovddup(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}
4338 void vmovddup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}
4339 void vmovddup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}
4340 void vmovdqa(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4341 void vmovdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4342 void vmovdqa(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQA, 0x7F, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4343 void vmovdqa(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4344 void vmovdqa(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4345 void vmovdqa(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVDQA, 0x7F, E_VEX_256_66_0F_WIG, R(src), W(dst));}
4346 void vmovdqu(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4347 void vmovdqu(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4348 void vmovdqu(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVDQU, 0x7F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}
4349 void vmovdqu(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4350 void vmovdqu(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4351 void vmovdqu(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVDQU, 0x7F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}
4352 void vmovhlps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVHLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4353 void vmovhpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVHPD, 0x16, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4354 void vmovhpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPD, 0x17, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4355 void vmovhps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVHPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4356 void vmovhps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVHPS, 0x17, E_VEX_128_0F_WIG, R(src), W(dst));}
4357 void vmovlhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVHLPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4358 void vmovlpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVLPD, 0x12, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4359 void vmovlpd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPD, 0x13, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4360 void vmovlps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MOVLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4361 void vmovlps(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVLPS, 0x13, E_VEX_128_0F_WIG, R(src), W(dst));}
4362 void vmovmskpd(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4363 void vmovmskpd(const Reg32& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4364 #ifdef JITASM64
4365 void vmovmskpd(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4366 void vmovmskpd(const Reg64& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4367 #endif
4368 void vmovmskps(const Reg32& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));}
4369 void vmovmskps(const Reg32& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));}
4370 #ifdef JITASM64
4371 void vmovmskps(const Reg64& dst, const XmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));}
4372 void vmovmskps(const Reg64& dst, const YmmReg& src) {AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));}
4373 #endif
4374 void vmovntdq(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4375 void vmovntdq(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_256_66_0F_WIG, R(src), W(dst));}
4376 void vmovntdqa(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4377 void vmovntpd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPD, 0x2B, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4378 void vmovntpd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTPD, 0x2B, E_VEX_256_66_0F_WIG, R(src), W(dst));}
4379 void vmovntps(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVNTPS, 0x2B, E_VEX_128_0F_WIG, R(src), W(dst));}
4380 void vmovntps(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVNTPS, 0x2B, E_VEX_256_0F_WIG, R(src), W(dst));}
4381 void vmovsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4382 void vmovsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}
4383 void vmovsd(const Mem64& dst, const XmmReg& src) {AppendInstr(I_MOVSD, 0x11, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, R(src), W(dst));}
4384 void vmovshdup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4385 void vmovshdup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4386 void vmovshdup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4387 void vmovshdup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4388 void vmovsldup(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4389 void vmovsldup(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4390 void vmovsldup(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4391 void vmovsldup(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4392 void vmovss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4393 void vmovss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}
4394 void vmovss(const Mem32& dst, const XmmReg& src) {AppendInstr(I_MOVSS, 0x11, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}
4395 void vmovupd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4396 void vmovupd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4397 void vmovupd(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPD, 0x11, E_VEX_128_66_0F_WIG, R(src), W(dst));}
4398 void vmovupd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4399 void vmovupd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4400 void vmovupd(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVUPD, 0x11, E_VEX_256_66_0F_WIG, R(src), W(dst));}
4401 void vmovups(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));}
4402 void vmovups(const XmmReg& dst, const Mem128& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));}
4403 void vmovups(const Mem128& dst, const XmmReg& src) {AppendInstr(I_MOVUPS, 0x11, E_VEX_128_0F_WIG, R(src), W(dst));}
4404 void vmovups(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));}
4405 void vmovups(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));}
4406 void vmovups(const Mem256& dst, const YmmReg& src) {AppendInstr(I_MOVUPS, 0x11, E_VEX_256_0F_WIG, R(src), W(dst));}
4407 void vmpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}
4408 void vmpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}
4409 void vmulpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4410 void vmulpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4411 void vmulpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4412 void vmulpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4413 void vmulps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4414 void vmulps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4415 void vmulps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4416 void vmulps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4417 void vmulsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4418 void vmulsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4419 void vmulss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4420 void vmulss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4421 void vorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4422 void vorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4423 void vorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4424 void vorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4425 void vorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4426 void vorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4427 void vorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4428 void vorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4429 void vpabsb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4430 void vpabsb(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4431 void vpabsw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4432 void vpabsw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4433 void vpabsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4434 void vpabsd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4435 void vpacksswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4436 void vpacksswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4437 void vpackssdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4438 void vpackssdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4439 void vpackuswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4440 void vpackuswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4441 void vpackusdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4442 void vpackusdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4443 void vpaddb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4444 void vpaddb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4445 void vpaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4446 void vpaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4447 void vpaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4448 void vpaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4449 void vpaddq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4450 void vpaddq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4451 void vpaddsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4452 void vpaddsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4453 void vpaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4454 void vpaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4455 void vpaddusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4456 void vpaddusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4457 void vpaddusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4458 void vpaddusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4459 void vpalignr(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4460 void vpalignr(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
4461 void vpand(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4462 void vpand(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4463 void vpandn(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4464 void vpandn(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4465 void vpavgb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4466 void vpavgb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4467 void vpavgw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4468 void vpavgw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4469 void vpblendvb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}
4470 void vpblendvb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}
4471 void vpblendw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4472 void vpblendw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4473 void pclmulqdq(const XmmReg& dst, const XmmReg& src, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
4474 void pclmulqdq(const XmmReg& dst, const Mem128& src, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}
4475 void vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4476 void vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
4477 void vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4478 void vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4479 void vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4480 void vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4481 void vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4482 void vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4483 void vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4484 void vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4485 void vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4486 void vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4487 void vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4488 void vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4489 void vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4490 void vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4491 void vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4492 void vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4493 void vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4494 void vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4495 void vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4496 void vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode) {AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}
4497 void vpcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));}
4498 void vpcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));}
4499 void vpcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));}
4500 void vpcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode) {AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));}
4501 void vpermilpd(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}
4502 void vpermilpd(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}
4503 void vpermilpd(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}
4504 void vpermilpd(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl) {AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}
4505 void vpermilpd(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4506 void vpermilpd(const XmmReg& dst, const Mem128& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4507 void vpermilpd(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4508 void vpermilpd(const YmmReg& dst, const Mem256& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4509 void vpermilps(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}
4510 void vpermilps(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}
4511 void vpermilps(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}
4512 void vpermilps(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl) {AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}
4513 void vpermilps(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4514 void vpermilps(const XmmReg& dst, const Mem128& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4515 void vpermilps(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4516 void vpermilps(const YmmReg& dst, const Mem256& src, const Imm8& ctrl) {AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}
4517 void vperm2f128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& ctrl) {AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);}
4518 void vperm2f128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& ctrl) {AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);}
4519 void vpextrb(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4520 void vpextrb(const Mem8& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4521 void vpextrw(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);}
4522 void vpextrw(const Mem16& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0x15, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4523 void vpextrd(const Reg32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4524 void vpextrd(const Mem32& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4525 #ifdef JITASM64
4526 void vpextrb(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRB, 0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4527 void vpextrw(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRW, 0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);}
4528 void vpextrd(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRD, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}
4529 void vpextrq(const Reg64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);}
4530 void vpextrq(const Mem64& dst, const XmmReg& src, const Imm8& i) {AppendInstr(I_PEXTRQ, 0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);}
4531 #endif
4532 void vphaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4533 void vphaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4534 void vphaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4535 void vphaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4536 void vphaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4537 void vphaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4538 void vphminposuw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4539 void vphminposuw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4540 void vphsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4541 void vphsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4542 void vphsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4543 void vphsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4544 void vphsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4545 void vphsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4546 void vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4547 void vpinsrb(const XmmReg& dst, const XmmReg& src, const Mem8& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4548 void vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}
4549 void vpinsrw(const XmmReg& dst, const XmmReg& src, const Mem16& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}
4550 void vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4551 void vpinsrd(const XmmReg& dst, const XmmReg& src, const Mem32& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4552 #ifdef JITASM64
4553 void vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4554 void vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}
4555 void vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}
4556 void vpinsrq(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i) {AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);}
4557 void vpinsrq(const XmmReg& dst, const XmmReg& src, const Mem64& val, const Imm8& i) {AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);}
4558 #endif
4559 void vpmaddwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4560 void vpmaddwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4561 void vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4562 void vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4563 void vpmaxsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4564 void vpmaxsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4565 void vpmaxsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4566 void vpmaxsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4567 void vpmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4568 void vpmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4569 void vpmaxub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4570 void vpmaxub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4571 void vpmaxuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4572 void vpmaxuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4573 void vpmaxud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4574 void vpmaxud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4575 void vpminsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4576 void vpminsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4577 void vpminsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4578 void vpminsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4579 void vpminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4580 void vpminsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4581 void vpminub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4582 void vpminub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4583 void vpminuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4584 void vpminuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4585 void vpminud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4586 void vpminud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4587 void vpmovmskb(const Reg32& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4588 #ifdef JITASM64
4589 void vpmovmskb(const Reg64& dst, const XmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4590 #endif
4591 void vpmovsxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4592 void vpmovsxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4593 void vpmovsxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4594 void vpmovsxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4595 void vpmovsxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4596 void vpmovsxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4597 void vpmovsxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4598 void vpmovsxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4599 void vpmovsxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4600 void vpmovsxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4601 void vpmovsxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4602 void vpmovsxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4603 void vpmovzxbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4604 void vpmovzxbw(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4605 void vpmovzxbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4606 void vpmovzxbd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4607 void vpmovzxbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4608 void vpmovzxbq(const XmmReg& dst, const Mem16& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4609 void vpmovzxwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4610 void vpmovzxwd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4611 void vpmovzxwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4612 void vpmovzxwq(const XmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4613 void vpmovzxdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4614 void vpmovzxdq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));}
4615 void vpmulhuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHUW, 0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4616 void vpmulhuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHUW, 0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4617 void vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4618 void vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4619 void vpmulhw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4620 void vpmulhw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4621 void vpmullw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4622 void vpmullw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4623 void vpmulld(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4624 void vpmulld(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4625 void vpmuludq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULUDQ, 0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4626 void vpmuludq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULUDQ, 0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4627 void vpmuldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4628 void vpmuldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4629 void vpor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_POR, 0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4630 void vpor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_POR, 0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4631 void vpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4632 void vpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4633 void vpshufb(const XmmReg& dst, const XmmReg& src, const XmmReg& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));}
4634 void vpshufb(const XmmReg& dst, const XmmReg& src, const Mem128& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));}
4635 void vpshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);}
4636 void vpshufd(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);}
4637 void vpshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}
4638 void vpshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}
4639 void vpshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}
4640 void vpshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}
4641 void vpsignb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4642 void vpsignb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4643 void vpsignw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4644 void vpsignw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4645 void vpsignd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4646 void vpsignd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}
4647 void vpsllw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4648 void vpsllw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4649 void vpsllw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLW, 0x71, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
4650 void vpslld(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4651 void vpslld(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4652 void vpslld(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLD, 0x72, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
4653 void vpsllq(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4654 void vpsllq(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4655 void vpsllq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
4656 void vpslldq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(7), R(src), W(dst), count);}
4657 void vpsraw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4658 void vpsraw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4659 void vpsraw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRAW, 0x71, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);}
4660 void vpsrad(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4661 void vpsrad(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4662 void vpsrad(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRAD, 0x72, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);}
4663 void vpsrlw(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4664 void vpsrlw(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4665 void vpsrlw(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLW, 0x71, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
4666 void vpsrld(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4667 void vpsrld(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4668 void vpsrld(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLD, 0x72, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
4669 void vpsrlq(const XmmReg& dst, const XmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4670 void vpsrlq(const XmmReg& dst, const XmmReg& src, const Mem128& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}
4671 void vpsrlq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
4672 void vpsrldq(const XmmReg& dst, const XmmReg& src, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x73, E_VEX_128_66_0F_WIG, Imm8(3), R(src), W(dst), count);}
4673 void vptest(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));}
4674 void vptest(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));}
4675 void vptest(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));}
4676 void vptest(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PTEST, 0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));}
4677 void vtestps(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));}
4678 void vtestps(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));}
4679 void vtestps(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));}
4680 void vtestps(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VTESTPS, 0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));}
4681 void vtestpd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));}
4682 void vtestpd(const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));}
4683 void vtestpd(const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));}
4684 void vtestpd(const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VTESTPD, 0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));}
4685 void vpsubb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4686 void vpsubb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4687 void vpsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4688 void vpsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4689 void vpsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4690 void vpsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4691 void vpsubq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4692 void vpsubq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4693 void vpsubsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4694 void vpsubsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4695 void vpsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4696 void vpsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4697 void vpsubusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4698 void vpsubusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4699 void vpsubusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4700 void vpsubusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4701 void vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4702 void vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4703 void vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4704 void vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4705 void vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4706 void vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4707 void vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4708 void vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4709 void vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4710 void vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4711 void vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4712 void vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4713 void vpunpckldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4714 void vpunpckldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4715 void vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4716 void vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4717 void vpxor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4718 void vpxor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4719 void vrcpps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_128_0F_WIG, W(dst), R(src));}
4720 void vrcpps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_128_0F_WIG, W(dst), R(src));}
4721 void vrcpps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_256_0F_WIG, W(dst), R(src));}
4722 void vrcpps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_RCPPS, 0x53, E_VEX_256_0F_WIG, W(dst), R(src));}
4723 void vrcpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_RCPSS, 0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4724 void vrcpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_RCPSS, 0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4725 void vrsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_128_0F_WIG, W(dst), R(src));}
4726 void vrsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_128_0F_WIG, W(dst), R(src));}
4727 void vrsqrtps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_256_0F_WIG, W(dst), R(src));}
4728 void vrsqrtps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_RSQRTPS, 0x52, E_VEX_256_0F_WIG, W(dst), R(src));}
4729 void vrsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_RSQRTSS, 0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4730 void vrsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_RSQRTSS, 0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4731 void vroundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4732 void vroundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4733 void vroundpd(const YmmReg& dst, const YmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4734 void vroundpd(const YmmReg& dst, const Mem256& src, const Imm8& mode) {AppendInstr(I_ROUNDPD, 0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4735 void vroundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4736 void vroundps(const XmmReg& dst, const Mem128& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4737 void vroundps(const YmmReg& dst, const YmmReg& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4738 void vroundps(const YmmReg& dst, const Mem256& src, const Imm8& mode) {AppendInstr(I_ROUNDPS, 0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}
4739 void vroundsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}
4740 void vroundsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& mode) {AppendInstr(I_ROUNDSD, 0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}
4741 void vroundss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}
4742 void vroundss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& mode) {AppendInstr(I_ROUNDSS, 0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}
4743 void vshufpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);}
4744 void vshufpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);}
4745 void vshufpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);}
4746 void vshufpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel) {AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);}
4747 void vshufps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);}
4748 void vshufps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);}
4749 void vshufps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);}
4750 void vshufps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel) {AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);}
4751 void vsqrtpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4752 void vsqrtpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));}
4753 void vsqrtpd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4754 void vsqrtpd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));}
4755 void vsqrtps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));}
4756 void vsqrtps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));}
4757 void vsqrtps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));}
4758 void vsqrtps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));}
4759 void vsqrtsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4760 void vsqrtsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4761 void vsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4762 void vsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4763 void vstmxcsr(const Mem32& dst) {AppendInstr(I_STMXCSR, 0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(3), W(dst));}
4764 void vsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4765 void vsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4766 void vsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4767 void vsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4768 void vsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4769 void vsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4770 void vsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4771 void vsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4772 void vsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4773 void vsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4774 void vsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4775 void vsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2) {AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}
4776 void vucomisd(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));}
4777 void vucomisd(const XmmReg& src1, const Mem64& src2) {AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));}
4778 void vucomiss(const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));}
4779 void vucomiss(const XmmReg& src1, const Mem32& src2) {AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));}
4780 void vunpckhpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4781 void vunpckhpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4782 void vunpckhpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4783 void vunpckhpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4784 void vunpckhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4785 void vunpckhps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4786 void vunpckhps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4787 void vunpckhps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4788 void vunpcklpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4789 void vunpcklpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4790 void vunpcklpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4791 void vunpcklpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4792 void vunpcklps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4793 void vunpcklps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4794 void vunpcklps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4795 void vunpcklps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4796 void vxorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4797 void vxorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}
4798 void vxorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4799 void vxorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
4800 void vxorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4801 void vxorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}
4802 void vxorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4803 void vxorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}
4804 void vzeroall() {AppendInstr(I_VZEROUPPER, 0x77, E_VEX_256_0F_WIG);}
4805 void vzeroupper() {AppendInstr(I_VZEROUPPER, 0x77, E_VEX_128_0F_WIG);}
4806
4807 // FMA
4808 void vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4809 void vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4810 void vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4811 void vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4812 void vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4813 void vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4814 void vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4815 void vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4816 void vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4817 void vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4818 void vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4819 void vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4820 void vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4821 void vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4822 void vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4823 void vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4824 void vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4825 void vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4826 void vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4827 void vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4828 void vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4829 void vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4830 void vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4831 void vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4832 void vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4833 void vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4834 void vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4835 void vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4836 void vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4837 void vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4838 void vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4839 void vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4840 void vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4841 void vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4842 void vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4843 void vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4844 void vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4845 void vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4846 void vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4847 void vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4848 void vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4849 void vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4850 void vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4851 void vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4852 void vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4853 void vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4854 void vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4855 void vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4856 void vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4857 void vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4858 void vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4859 void vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4860 void vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4861 void vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4862 void vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4863 void vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4864 void vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4865 void vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4866 void vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4867 void vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4868 void vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4869 void vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4870 void vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4871 void vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4872 void vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4873 void vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4874 void vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4875 void vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4876 void vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4877 void vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4878 void vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4879 void vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4880 void vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4881 void vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4882 void vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4883 void vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4884 void vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4885 void vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4886 void vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4887 void vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4888 void vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4889 void vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4890 void vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4891 void vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4892 void vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4893 void vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4894 void vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4895 void vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4896 void vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4897 void vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4898 void vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4899 void vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4900 void vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4901 void vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4902 void vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4903 void vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4904 void vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4905 void vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4906 void vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4907 void vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4908 void vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4909 void vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4910 void vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4911 void vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4912 void vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4913 void vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4914 void vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4915 void vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4916 void vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4917 void vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4918 void vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4919 void vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4920 void vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4921 void vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4922 void vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4923 void vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4924 void vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4925 void vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4926 void vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4927 void vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4928 void vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4929 void vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4930 void vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4931 void vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4932 void vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4933 void vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4934 void vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4935 void vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4936 void vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4937 void vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4938 void vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4939 void vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4940 void vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4941 void vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4942 void vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4943 void vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4944 void vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4945 void vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4946 void vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4947 void vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4948 void vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4949 void vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4950 void vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4951 void vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4952 void vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4953 void vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4954 void vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4955 void vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4956 void vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4957 void vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4958 void vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4959 void vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4960 void vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4961 void vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4962 void vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4963 void vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4964 void vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4965 void vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4966 void vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4967 void vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4968 void vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4969 void vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4970 void vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4971 void vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4972 void vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4973 void vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4974 void vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4975 void vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}
4976 void vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4977 void vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4978 void vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4979 void vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4980 void vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4981 void vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4982 void vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4983 void vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4984 void vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4985 void vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4986 void vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4987 void vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}
4988 void vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4989 void vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4990 void vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4991 void vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4992 void vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4993 void vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}
4994 void vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4995 void vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4996 void vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4997 void vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4998 void vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) {AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
4999 void vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2) {AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}
5000
5001 // F16C
5002 #ifdef JITASM64
5003 void rdfsbase(const Reg32& dst) {AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(0), W(dst));}
5004 void rdfsbase(const Reg64& dst) {AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(0), W(dst));}
5005 void rdgsbase(const Reg32& dst) {AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(1), W(dst));}
5006 void rdgsbase(const Reg64& dst) {AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(1), W(dst));}
5007 #endif
5008 void rdrand(const Reg16& dst) {AppendInstr(I_RDRAND, 0x0FC7, E_OPERAND_SIZE_PREFIX, Imm8(6), W(dst));}
5009 void rdrand(const Reg32& dst) {AppendInstr(I_RDRAND, 0x0FC7, 0, Imm8(6), W(dst));}
5010 #ifdef JITASM64
5011 void rdrand(const Reg64& dst) {AppendInstr(I_RDRAND, 0x0FC7, E_REXW_PREFIX, Imm8(6), W(dst));}
5012 #endif
5013 #ifdef JITASM64
5014 void wrfsbase(const Reg32& src) {AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(2), R(src));}
5015 void wrfsbase(const Reg64& src) {AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(2), R(src));}
5016 void wrgsbase(const Reg32& src) {AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(3), R(src));}
5017 void wrgsbase(const Reg64& src) {AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(3), R(src));}
5018 #endif
5019 void vcvtph2ps(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5020 void vcvtph2ps(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5021 void vcvtph2ps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5022 void vcvtph2ps(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5023 void vcvtps2ph(const XmmReg& dst, const YmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);}
5024 void vcvtps2ph(const Mem128& dst, const YmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);}
5025 void vcvtps2ph(const XmmReg& dst, const XmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);}
5026 void vcvtps2ph(const Mem64& dst, const XmmReg& src, const Imm8& rc) {AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);}
5027
5028 // BMI2
5029 void andn(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5030 void andn(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5031 #ifdef JITASM64
5032 void andn(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5033 void andn(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5034 #endif
5035 void bextr(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5036 void bextr(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5037 #ifdef JITASM64
5038 void bextr(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5039 void bextr(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5040 #endif
5041 void blsi(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));}
5042 void blsi(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));}
5043 #ifdef JITASM64
5044 void blsi(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));}
5045 void blsi(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));}
5046 #endif
5047 void blsmsk(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));}
5048 void blsmsk(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));}
5049 #ifdef JITASM64
5050 void blsmsk(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));}
5051 void blsmsk(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));}
5052 #endif
5053 void blsr(const Reg32& dst, const Reg32& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));}
5054 void blsr(const Reg32& dst, const Mem32& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));}
5055 #ifdef JITASM64
5056 void blsr(const Reg64& dst, const Reg64& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));}
5057 void blsr(const Reg64& dst, const Mem64& src) {AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));}
5058 #endif
5059 void bzhi(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5060 void bzhi(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5061 #ifdef JITASM64
5062 void bzhi(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5063 void bzhi(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5064 #endif
5065 void lzcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
5066 void lzcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
5067 void lzcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
5068 void lzcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
5069 #ifdef JITASM64
5070 void lzcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
5071 void lzcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
5072 #endif
5073 void mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Reg32& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));}
5074 void mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Mem32& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));}
5075 #ifdef JITASM64
5076 void mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Reg64& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));}
5077 void mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Mem64& src2) {AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));}
5078 #endif
5079 void pdep(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5080 void pdep(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5081 #ifdef JITASM64
5082 void pdep(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5083 void pdep(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5084 #endif
5085 void pext(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5086 void pext(const Reg32& dst, const Reg32& src1, const Mem32& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}
5087 #ifdef JITASM64
5088 void pext(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5089 void pext(const Reg64& dst, const Reg64& src1, const Mem64& src2) {AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}
5090 #endif
5091 void rorx(const Reg32& dst, const Reg32& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);}
5092 void rorx(const Reg32& dst, const Mem32& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);}
5093 #ifdef JITASM64
5094 void rorx(const Reg64& dst, const Reg64& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);}
5095 void rorx(const Reg64& dst, const Mem64& src, const Imm8& shift) {AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);}
5096 #endif
5097 void sarx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5098 void sarx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5099 #ifdef JITASM64
5100 void sarx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5101 void sarx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5102 #endif
5103 void shlx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5104 void shlx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5105 #ifdef JITASM64
5106 void shlx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5107 void shlx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5108 #endif
5109 void shrx(const Reg32& dst, const Reg32& src1, const Reg32& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5110 void shrx(const Reg32& dst, const Mem32& src1, const Reg32& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}
5111 #ifdef JITASM64
5112 void shrx(const Reg64& dst, const Reg64& src1, const Reg64& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5113 void shrx(const Reg64& dst, const Mem64& src1, const Reg64& src2) {AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}
5114 #endif
5115 void tzcnt(const Reg16& dst, const Reg16& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
5116 void tzcnt(const Reg16& dst, const Mem16& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}
5117 void tzcnt(const Reg32& dst, const Reg32& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
5118 void tzcnt(const Reg32& dst, const Mem32& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));}
5119 #ifdef JITASM64
5120 void tzcnt(const Reg64& dst, const Reg64& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
5121 void tzcnt(const Reg64& dst, const Mem64& src) {AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}
5122 #endif
5123 #ifndef JITASM64
5124 void invpcid(const Reg32& type, const Mem128& desc) {AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));}
5125 #else
5126 void invpcid(const Reg64& type, const Mem128& desc) {AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));}
5127 #endif
5128
5129 // XOP
5130 void vfrczpd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5131 void vfrczpd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5132 void vfrczpd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5133 void vfrczpd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5134 void vfrczps(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5135 void vfrczps(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5136 void vfrczps(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5137 void vfrczps(const YmmReg& dst, const Mem256& src) {AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5138 void vfrczsd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5139 void vfrczsd(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5140 void vfrczss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5141 void vfrczss(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5142 void vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5143 void vpcmov(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5144 void vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}
5145 void vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5146 void vpcmov(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5147 void vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}
5148 void vpcomb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5149 void vpcomb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5150 void vpcomd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5151 void vpcomd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5152 void vpcomq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5153 void vpcomq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5154 //void vpcomub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5155 //void vpcomub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5156 //void vpcomud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5157 //void vpcomud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5158 //void vpcomuq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5159 //void vpcomuq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5160 //void vpcomuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5161 //void vpcomuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5162 //void vpcomw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type) {AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5163 //void vpcomw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type) {AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}
5164 //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5165 //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5166 //void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}
5167 //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5168 //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5169 //void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}
5170 //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5171 //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5172 //void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}
5173 //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5174 //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}
5175 //void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}
5176 void vphaddbd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5177 void vphaddbd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5178 void vphaddbq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5179 void vphaddbq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5180 void vphaddbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5181 void vphaddbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5182 void vphadddq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5183 void vphadddq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5184 void vphaddubd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5185 void vphaddubd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5186 void vphaddubq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5187 void vphaddubq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5188 void vphaddubw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5189 void vphaddubw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5190 //void vphaddudq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5191 //void vphaddudq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5192 void vphadduwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5193 void vphadduwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5194 void vphadduwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5195 void vphadduwq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5196 void vphaddwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5197 void vphaddwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5198 void vphaddwq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5199 void vphaddwq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5200 void vphsubbw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5201 void vphsubbw(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5202 //void vphsubdq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5203 //void vphsubdq(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5204 void vphsubwd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5205 void vphsubwd(const XmmReg& dst, const Mem128& src) {AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}
5206 void vpmacsdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5207 void vpmacsdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5208 void vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5209 void vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5210 void vpmacsdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5211 void vpmacsdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5212 void vpmacssdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5213 void vpmacssdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5214 void vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5215 void vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5216 void vpmacssdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5217 void vpmacssdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5218 void vpmacsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5219 void vpmacsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5220 void vpmacssww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5221 void vpmacssww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5222 void vpmacswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5223 void vpmacswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5224 void vpmacsww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5225 void vpmacsww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5226 void vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5227 void vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5228 void vpmadcswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5229 void vpmadcswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5230 void vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5231 void vpperm(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}
5232 void vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}
5233 void vprotb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5234 void vprotb(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5235 void vprotb(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5236 void vprotb(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5237 void vprotb(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5238 void vprotd(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5239 void vprotd(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5240 void vprotd(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5241 void vprotd(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5242 void vprotd(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5243 void vprotq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5244 void vprotq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5245 void vprotq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5246 void vprotq(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5247 void vprotq(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5248 void vprotw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5249 void vprotw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5250 void vprotw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5251 void vprotw(const XmmReg& dst, const XmmReg& src1, const Imm8& count) {AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5252 void vprotw(const XmmReg& dst, const Mem128& src1, const Imm8& count) {AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}
5253 void vpshab(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5254 void vpshab(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5255 void vpshab(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5256 void vpshad(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5257 void vpshad(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5258 void vpshad(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5259 void vpshaq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5260 void vpshaq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5261 void vpshaq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5262 void vpshaw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5263 void vpshaw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5264 void vpshaw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5265 void vpshlb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5266 void vpshlb(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5267 void vpshlb(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5268 void vpshld(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5269 void vpshld(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5270 void vpshld(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5271 void vpshlq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5272 void vpshlq(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5273 void vpshlq(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5274 void vpshlw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5275 void vpshlw(const XmmReg& dst, const Mem128& src1, const XmmReg& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}
5276 void vpshlw(const XmmReg& dst, const XmmReg& src1, const Mem128& count) {AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}
5277
5278 // FMA4
5279 void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5280 void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5281 void vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5282 void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5283 void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5284 void vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5285 void vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5286 void vfmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5287 void vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5288 void vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5289 void vfmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5290 void vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5291 void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5292 void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5293 void vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5294 void vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5295 void vfmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5296 void vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5297 void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5298 void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5299 void vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5300 void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5301 void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5302 void vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5303 void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5304 void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5305 void vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5306 void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5307 void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5308 void vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5309 void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5310 void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5311 void vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5312 void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5313 void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5314 void vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5315 void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5316 void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5317 void vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5318 void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5319 void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5320 void vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5321 void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5322 void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5323 void vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5324 void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5325 void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5326 void vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5327 void vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5328 void vfmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5329 void vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5330 void vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5331 void vfmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5332 void vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5333 void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5334 void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5335 void vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5336 void vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5337 void vfmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5338 void vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5339 void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5340 void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5341 void vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5342 void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5343 void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5344 void vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5345 void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5346 void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5347 void vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5348 void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5349 void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5350 void vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5351 void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5352 void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5353 void vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5354 void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5355 void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5356 void vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5357 void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5358 void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5359 void vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5360 void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5361 void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5362 void vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5363 void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5364 void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5365 void vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5366 void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5367 void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5368 void vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3) {AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5369 void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5370 void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5371 void vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3) {AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5372 void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5373 void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}
5374 void vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3) {AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}
5375
5376 // AVX2
5377 void vbroadcastss(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5378 void vbroadcastss(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5379 void vbroadcastsd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5380 void vbroadcasti128(const YmmReg& dst, const Mem128& src) {AppendInstr(I_VBROADCASTI128, 0x5A, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5381 void vextracti128(const XmmReg& dst, const YmmReg& src, const Imm8& offset) {AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);}
5382 void vextracti128(const Mem128& dst, const YmmReg& src, const Imm8& offset) {AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);}
5383 void vgatherdps(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask) {AppendInstr(I_VGATHERDPS, 0x92, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}
5384 void vgatherdps(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask) {AppendInstr(I_VGATHERDPS, 0x92, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}
5385 void vgatherqps(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPS, 0x93, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}
5386 void vgatherqps(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPS, 0x93, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}
5387 void vgatherdpd(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask) {AppendInstr(I_VGATHERDPD, 0x92, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}
5388 void vgatherdpd(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask) {AppendInstr(I_VGATHERDPD, 0x92, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}
5389 void vgatherqpd(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask) {AppendInstr(I_VGATHERQPD, 0x93, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}
5390 void vgatherqpd(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask) {AppendInstr(I_VGATHERQPD, 0x93, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}
5391 void vinserti128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& offset) {AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);}
5392 void vinserti128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& offset) {AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);}
5393 void vmovntdqa(const YmmReg& dst, const Mem256& src) {AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5394 void vmpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}
5395 void vmpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i) {AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}
5396 void vpabsb(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5397 void vpabsb(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5398 void vpabsw(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5399 void vpabsw(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5400 void vpabsd(const YmmReg& dst, const YmmReg& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5401 void vpabsd(const YmmReg& dst, const Mem256& src) {AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5402 void vpacksswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5403 void vpacksswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5404 void vpackssdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5405 void vpackssdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5406 void vpackuswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5407 void vpackuswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5408 void vpackusdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5409 void vpackusdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5410 void vpaddb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5411 void vpaddb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5412 void vpaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5413 void vpaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5414 void vpaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5415 void vpaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5416 void vpaddq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5417 void vpaddq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5418 void vpaddsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5419 void vpaddsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5420 void vpaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5421 void vpaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5422 void vpaddusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5423 void vpaddusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5424 void vpaddusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5425 void vpaddusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5426 void vpalignr(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
5427 void vpalignr(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}
5428 void vpand(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5429 void vpand(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5430 void vpandn(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5431 void vpandn(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5432 void vpavgb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5433 void vpavgb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5434 void vpavgw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5435 void vpavgw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5436 void vpblendvb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}
5437 void vpblendvb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) {AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}
5438 void vpblendw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
5439 void vpblendw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}
5440 void vpblendd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}
5441 void vpblendd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}
5442 void vpblendd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}
5443 void vpblendd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) {AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}
5444 void vpbroadcastb(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5445 void vpbroadcastb(const XmmReg& dst, const Mem8& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5446 void vpbroadcastb(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5447 void vpbroadcastb(const YmmReg& dst, const Mem8& src) {AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5448 void vpbroadcastw(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5449 void vpbroadcastw(const XmmReg& dst, const Mem16& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5450 void vpbroadcastw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5451 void vpbroadcastw(const YmmReg& dst, const Mem16& src) {AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5452 void vpbroadcastd(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5453 void vpbroadcastd(const XmmReg& dst, const Mem32& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5454 void vpbroadcastd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5455 void vpbroadcastd(const YmmReg& dst, const Mem32& src) {AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5456 void vpbroadcastq(const XmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5457 void vpbroadcastq(const XmmReg& dst, const Mem64& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));}
5458 void vpbroadcastq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5459 void vpbroadcastq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));}
5460 void vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5461 void vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQB, 0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5462 void vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5463 void vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQW, 0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5464 void vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5465 void vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQD, 0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5466 void vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5467 void vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPEQQ, 0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5468 void vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5469 void vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTB, 0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5470 void vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5471 void vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTW, 0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5472 void vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5473 void vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTD, 0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5474 void vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5475 void vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PCMPGTQ, 0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5476 void vpermd(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src) {AppendInstr(I_VPERMD, 0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}
5477 void vpermd(const YmmReg& dst, const YmmReg& offsets, const Mem256& src) {AppendInstr(I_VPERMD, 0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}
5478 void vpermq(const YmmReg& dst, const YmmReg& src, const Imm8& control) {AppendInstr(I_VPERMQ, 0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}
5479 void vpermq(const YmmReg& dst, const Mem256& src, const Imm8& control) {AppendInstr(I_VPERMQ, 0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}
5480 void vpermps(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src) {AppendInstr(I_VPERMPS, 0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}
5481 void vpermps(const YmmReg& dst, const YmmReg& offsets, const Mem256& src) {AppendInstr(I_VPERMPS, 0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}
5482 void vpermpd(const YmmReg& dst, const YmmReg& src, const Imm8& control) {AppendInstr(I_VPERMPD, 0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}
5483 void vpermpd(const YmmReg& dst, const Mem256& src, const Imm8& control) {AppendInstr(I_VPERMPD, 0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}
5484 void vperm2i128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& control) {AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);}
5485 void vperm2i128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& control) {AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);}
5486 void vpgatherdd(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERDD, 0x90, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}
5487 void vpgatherdd(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask) {AppendInstr(I_VPGATHERDD, 0x90, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}
5488 void vpgatherqd(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQD, 0x91, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}
5489 void vpgatherqd(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQD, 0x91, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}
5490 void vpgatherdq(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask) {AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}
5491 void vpgatherdq(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask) {AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}
5492 void vpgatherqq(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask) {AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}
5493 void vpgatherqq(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask) {AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}
5494 void vphaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5495 void vphaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDW, 0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5496 void vphaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5497 void vphaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDD, 0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5498 void vphaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5499 void vphaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHADDSW, 0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5500 void vphsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5501 void vphsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBW, 0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5502 void vphsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5503 void vphsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBD, 0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5504 void vphsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5505 void vphsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PHSUBSW, 0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5506 void vpmaddwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5507 void vpmaddwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMADDWD, 0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5508 void vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5509 void vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5510 void vpmaskmovd(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}
5511 void vpmaskmovd(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}
5512 void vpmaskmovq(const XmmReg& dst, const XmmReg& mask, const Mem128& src) {AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_128_66_0F38_W1, W(dst), R(src), R(mask));}
5513 void vpmaskmovq(const YmmReg& dst, const YmmReg& mask, const Mem256& src) {AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_256_66_0F38_W1, W(dst), R(src), R(mask));}
5514 void vpmaskmovd(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}
5515 void vpmaskmovd(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}
5516 void vpmaskmovq(const Mem128& dst, const XmmReg& mask, const XmmReg& src) {AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_128_66_0F38_W1, R(src), W(dst), R(mask));}
5517 void vpmaskmovq(const Mem256& dst, const YmmReg& mask, const YmmReg& src) {AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_256_66_0F38_W1, R(src), W(dst), R(mask));}
5518 void vpmaxsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5519 void vpmaxsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5520 void vpmaxsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5521 void vpmaxsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5522 void vpmaxsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5523 void vpmaxsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5524 void vpmaxub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5525 void vpmaxub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5526 void vpmaxuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5527 void vpmaxuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5528 void vpmaxud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5529 void vpmaxud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5530 void vpminsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5531 void vpminsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5532 void vpminsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5533 void vpminsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5534 void vpminsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5535 void vpminsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5536 void vpminub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5537 void vpminub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5538 void vpminuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5539 void vpminuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5540 void vpminud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5541 void vpminud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5542 void vpmovmskb(const Reg32& dst, const YmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));}
5543 #ifdef JITASM64
5544 void vpmovmskb(const Reg64& dst, const YmmReg& src) {AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));}
5545 #endif
5546 void vpmovsxbw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5547 void vpmovsxbw(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5548 void vpmovsxbd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5549 void vpmovsxbd(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5550 void vpmovsxbq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5551 void vpmovsxbq(const YmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5552 void vpmovsxwd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5553 void vpmovsxwd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5554 void vpmovsxwq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5555 void vpmovsxwq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5556 void vpmovsxdq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5557 void vpmovsxdq(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5558 void vpmovzxbw(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5559 void vpmovzxbw(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5560 void vpmovzxbd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5561 void vpmovzxbd(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5562 void vpmovzxbq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5563 void vpmovzxbq(const YmmReg& dst, const Mem32& src) {AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5564 void vpmovzxwd(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5565 void vpmovzxwd(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5566 void vpmovzxwq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5567 void vpmovzxwq(const YmmReg& dst, const Mem64& src) {AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5568 void vpmovzxdq(const YmmReg& dst, const XmmReg& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5569 void vpmovzxdq(const YmmReg& dst, const Mem128& src) {AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));}
5570 void vpmulhuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHUW, 0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5571 void vpmulhuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHUW, 0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5572 void vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5573 void vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5574 void vpmulhw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5575 void vpmulhw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULHW, 0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5576 void vpmullw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5577 void vpmullw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULLW, 0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5578 void vpmulld(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5579 void vpmulld(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULLD, 0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5580 void vpmuludq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULUDQ, 0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5581 void vpmuludq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULUDQ, 0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5582 void vpmuldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5583 void vpmuldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PMULDQ, 0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5584 void vpor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_POR, 0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5585 void vpor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_POR, 0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5586 void vpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5587 void vpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSADBW, 0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5588 void vpshufb(const YmmReg& dst, const YmmReg& src, const YmmReg& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));}
5589 void vpshufb(const YmmReg& dst, const YmmReg& src, const Mem256& order) {AppendInstr(I_PSHUFB, 0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));}
5590 void vpshufd(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);}
5591 void vpshufd(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFD, 0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);}
5592 void vpshufhw(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}
5593 void vpshufhw(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFHW, 0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}
5594 void vpshuflw(const YmmReg& dst, const YmmReg& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}
5595 void vpshuflw(const YmmReg& dst, const Mem256& src, const Imm8& order) {AppendInstr(I_PSHUFLW, 0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}
5596 void vpsignb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5597 void vpsignb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGNB, 0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5598 void vpsignw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5599 void vpsignw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGNW, 0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5600 void vpsignd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5601 void vpsignd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSIGND, 0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}
5602 void vpsllw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5603 void vpsllw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLW, 0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5604 void vpsllw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLW, 0x71, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
5605 void vpslld(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5606 void vpslld(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLD, 0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5607 void vpslld(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLD, 0x72, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
5608 void vpsllq(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5609 void vpsllq(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSLLQ, 0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5610 void vpsllq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}
5611 void vpslldq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSLLDQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(7), R(src), W(dst), count);}
5612 void vpsllvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5613 void vpsllvd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5614 void vpsllvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5615 void vpsllvd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSLLVD, 0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5616 void vpsllvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}
5617 void vpsllvq(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}
5618 void vpsllvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}
5619 void vpsllvq(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSLLVQ, 0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}
5620 void vpsraw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5621 void vpsraw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRAW, 0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5622 void vpsraw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRAW, 0x71, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);}
5623 void vpsrad(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5624 void vpsrad(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRAD, 0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5625 void vpsrad(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRAD, 0x72, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);}
5626 void vpsravd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5627 void vpsravd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5628 void vpsravd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5629 void vpsravd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRAVD, 0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5630 void vpsrlw(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5631 void vpsrlw(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLW, 0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5632 void vpsrlw(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLW, 0x71, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
5633 void vpsrld(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5634 void vpsrld(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLD, 0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5635 void vpsrld(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLD, 0x72, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
5636 void vpsrlq(const YmmReg& dst, const YmmReg& src, const XmmReg& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5637 void vpsrlq(const YmmReg& dst, const YmmReg& src, const Mem128& count) {AppendInstr(I_PSRLQ, 0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}
5638 void vpsrlq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}
5639 void vpsrldq(const YmmReg& dst, const YmmReg& src, const Imm8& count) {AppendInstr(I_PSRLDQ, 0x73, E_VEX_256_66_0F_WIG, Imm8(3), R(src), W(dst), count);}
5640 void vpsrlvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5641 void vpsrlvd(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}
5642 void vpsrlvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5643 void vpsrlvd(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRLVD, 0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}
5644 void vpsrlvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}
5645 void vpsrlvq(const XmmReg& dst, const XmmReg& count, const Mem128& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}
5646 void vpsrlvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}
5647 void vpsrlvq(const YmmReg& dst, const YmmReg& count, const Mem256& src) {AppendInstr(I_VPSRLVQ, 0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}
5648 void vpsubb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5649 void vpsubb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBB, 0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5650 void vpsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5651 void vpsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBW, 0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5652 void vpsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5653 void vpsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBD, 0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5654 void vpsubq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5655 void vpsubq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBQ, 0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5656 void vpsubsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5657 void vpsubsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBSB, 0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5658 void vpsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5659 void vpsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBSW, 0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5660 void vpsubusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5661 void vpsubusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBUSB, 0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5662 void vpsubusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5663 void vpsubusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PSUBUSW, 0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5664 void vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5665 void vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHBW, 0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5666 void vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5667 void vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHWD, 0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5668 void vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5669 void vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHDQ, 0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5670 void vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5671 void vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKHQDQ, 0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5672 void vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5673 void vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLBW, 0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5674 void vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5675 void vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLWD, 0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5676 void vpunpckldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5677 void vpunpckldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLDQ, 0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5678 void vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5679 void vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PUNPCKLQDQ, 0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5680 void vpxor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5681 void vpxor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) {AppendInstr(I_PXOR, 0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}
5682
5683
5684 struct ControlState
5685 {
5686 size_t label1;
5687 size_t label2;
5688 };
5689 ControlState ctrl_state_;
5690 std::deque<ControlState> ctrl_state_stack_;
5691
5692 // Repeat, Until
5693 void Repeat()
5694 {
5695 ctrl_state_stack_.push_back(ctrl_state_);
5696 ctrl_state_.label1 = NewLabelID(""); // begin
5697 ctrl_state_.label2 = 0;
5698
5699 L(ctrl_state_.label1);
5700 }
5701 template<class Ty>
5702 void Until(const Ty& expr)
5703 {
5704 size_t label = NewLabelID("");
5705 expr(*this, ctrl_state_.label1, label);
5706 L(label);
5707
5708 ctrl_state_ = *ctrl_state_stack_.rbegin();
5709 ctrl_state_stack_.pop_back();
5710 }
5711
5712 // While, EndW
5713 template<class Ty>
5714 void While(const Ty& expr)
5715 {
5716 ctrl_state_stack_.push_back(ctrl_state_);
5717 ctrl_state_.label1 = NewLabelID(""); // begin
5718 ctrl_state_.label2 = NewLabelID(""); // end
5719
5720 size_t label = NewLabelID("");
5721 L(ctrl_state_.label1);
5722 expr(*this, label, ctrl_state_.label2);
5723 L(label);
5724 }
5725 void EndW()
5726 {
5727 AppendJmp(ctrl_state_.label1);
5728 L(ctrl_state_.label2);
5729
5730 ctrl_state_ = *ctrl_state_stack_.rbegin();
5731 ctrl_state_stack_.pop_back();
5732 }
5733
5734 // If, ElseIf, Else, EndIf
5735 template<class Ty>
5736 void If(const Ty& expr)
5737 {
5738 ctrl_state_stack_.push_back(ctrl_state_);
5739 ctrl_state_.label1 = NewLabelID(""); // else
5740 ctrl_state_.label2 = NewLabelID(""); // end
5741
5742 size_t label = NewLabelID("");
5743 expr(*this, label, ctrl_state_.label1);
5744 L(label);
5745 }
5746 template<class Ty>
5747 void ElseIf(const Ty& expr)
5748 {
5749 Else();
5750
5751 size_t label = NewLabelID("");
5752 expr(*this, label, ctrl_state_.label1);
5753 L(label);
5754 }
5755 void Else()
5756 {
5757 AppendJmp(ctrl_state_.label2);
5758 L(ctrl_state_.label1);
5759 ctrl_state_.label1 = NewLabelID("");
5760 }
5761 void EndIf()
5762 {
5763 L(ctrl_state_.label1);
5764 L(ctrl_state_.label2);
5765
5766 ctrl_state_ = *ctrl_state_stack_.rbegin();
5767 ctrl_state_stack_.pop_back();
5768 }
5769 };
5770
5771 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::al = Reg8(AL);
5772 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::cl = Reg8(CL);
5773 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::dl = Reg8(DL);
5774 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::bl = Reg8(BL);
5775 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::ah = Reg8(AH);
5776 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::ch = Reg8(CH);
5777 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::dh = Reg8(DH);
5778 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::bh = Reg8(BH);
5779 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::ax = Reg16(AX);
5780 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::cx = Reg16(CX);
5781 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::dx = Reg16(DX);
5782 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::bx = Reg16(BX);
5783 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::sp = Reg16(SP);
5784 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::bp = Reg16(BP);
5785 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::si = Reg16(SI);
5786 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::di = Reg16(DI);
5787 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::eax = Reg32(EAX);
5788 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ecx = Reg32(ECX);
5789 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::edx = Reg32(EDX);
5790 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ebx = Reg32(EBX);
5791 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::esp = Reg32(ESP);
5792 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::ebp = Reg32(EBP);
5793 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::esi = Reg32(ESI);
5794 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::edi = Reg32(EDI);
5795 FpuReg_st0 JITASM_ATTRIBUTE_WEAK Frontend::st0;
5796 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st1 = FpuReg(ST1);
5797 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st2 = FpuReg(ST2);
5798 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st3 = FpuReg(ST3);
5799 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st4 = FpuReg(ST4);
5800 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st5 = FpuReg(ST5);
5801 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st6 = FpuReg(ST6);
5802 FpuReg JITASM_ATTRIBUTE_WEAK Frontend::st7 = FpuReg(ST7);
5803 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm0 = MmxReg(MM0);
5804 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm1 = MmxReg(MM1);
5805 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm2 = MmxReg(MM2);
5806 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm3 = MmxReg(MM3);
5807 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm4 = MmxReg(MM4);
5808 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm5 = MmxReg(MM5);
5809 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm6 = MmxReg(MM6);
5810 MmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm7 = MmxReg(MM7);
5811 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm0 = XmmReg(XMM0);
5812 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm1 = XmmReg(XMM1);
5813 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm2 = XmmReg(XMM2);
5814 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm3 = XmmReg(XMM3);
5815 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm4 = XmmReg(XMM4);
5816 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm5 = XmmReg(XMM5);
5817 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm6 = XmmReg(XMM6);
5818 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm7 = XmmReg(XMM7);
5819 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm0 = YmmReg(YMM0);
5820 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm1 = YmmReg(YMM1);
5821 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm2 = YmmReg(YMM2);
5822 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm3 = YmmReg(YMM3);
5823 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm4 = YmmReg(YMM4);
5824 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm5 = YmmReg(YMM5);
5825 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm6 = YmmReg(YMM6);
5826 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm7 = YmmReg(YMM7);
5827 #ifdef JITASM64
5828 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b = Reg8(R8B);
5829 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r9b = Reg8(R9B);
5830 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r10b = Reg8(R10B);
5831 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r11b = Reg8(R11B);
5832 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r12b = Reg8(R12B);
5833 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r13b = Reg8(R13B);
5834 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r14b = Reg8(R14B);
5835 Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r15b = Reg8(R15B);
5836 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r8w = Reg16(R8W);
5837 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r9w = Reg16(R9W);
5838 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r10w = Reg16(R10W);
5839 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r11w = Reg16(R11W);
5840 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r12w = Reg16(R12W);
5841 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r13w = Reg16(R13W);
5842 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r14w = Reg16(R14W);
5843 Reg16 JITASM_ATTRIBUTE_WEAK Frontend::r15w = Reg16(R15W);
5844 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r8d = Reg32(R8D);
5845 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r9d = Reg32(R9D);
5846 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r10d = Reg32(R10D);
5847 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r11d = Reg32(R11D);
5848 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r12d = Reg32(R12D);
5849 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D);
5850 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D);
5851 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r15d = Reg32(R15D);
5852 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rax = Reg64(RAX);
5853 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rcx = Reg64(RCX);
5854 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rdx = Reg64(RDX);
5855 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rbx = Reg64(RBX);
5856 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rsp = Reg64(RSP);
5857 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rbp = Reg64(RBP);
5858 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rsi = Reg64(RSI);
5859 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::rdi = Reg64(RDI);
5860 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r8 = Reg64(R8);
5861 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r9 = Reg64(R9);
5862 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r10 = Reg64(R10);
5863 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r11 = Reg64(R11);
5864 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r12 = Reg64(R12);
5865 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r13 = Reg64(R13);
5866 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r14 = Reg64(R14);
5867 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::r15 = Reg64(R15);
5868 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm8 = XmmReg(XMM8);
5869 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm9 = XmmReg(XMM9);
5870 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm10 = XmmReg(XMM10);
5871 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm11 = XmmReg(XMM11);
5872 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm12 = XmmReg(XMM12);
5873 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm13 = XmmReg(XMM13);
5874 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm14 = XmmReg(XMM14);
5875 XmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm15 = XmmReg(XMM15);
5876 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8 = YmmReg(YMM8);
5877 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm9 = YmmReg(YMM9);
5878 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm10 = YmmReg(YMM10);
5879 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm11 = YmmReg(YMM11);
5880 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm12 = YmmReg(YMM12);
5881 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm13 = YmmReg(YMM13);
5882 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm14 = YmmReg(YMM14);
5883 YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm15 = YmmReg(YMM15);
5884 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg64(RAX);
5885 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg64(RCX);
5886 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg64(RDX);
5887 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg64(RBX);
5888 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg64(RSP);
5889 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg64(RBP);
5890 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg64(RSI);
5891 Reg64 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg64(RDI);
5892 #else
5893 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg32(EAX);
5894 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg32(ECX);
5895 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg32(EDX);
5896 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg32(EBX);
5897 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg32(ESP);
5898 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg32(EBP);
5899 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg32(ESI);
5900 Reg32 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg32(EDI);
5901 #endif
5902
5903
5904 namespace compiler
5905 {
5906 struct BitVector : std::vector<uint32>
5907 {
5908 size_t size_bit() const { return size() * 32; }
5909
5910 bool get_bit(size_t idx) const
5911 {
5912 const size_t i = idx / 32;
5913 return i < size() && (at(i) & (1 << (idx % 32))) != 0;
5914 }
5915
5916 void set_bit(size_t idx, bool b)
5917 {
5918 const size_t i = idx / 32;
5919 const uint32 mask = (1 << (idx % 32));
5920 if (i >= size()) resize(i + 1);
5921 if (b) at(i) |= mask;
5922 else at(i) &= ~mask;
5923 }
5924
5925 bool is_equal(const BitVector& rhs) const
5926 {
5927 const size_t min_size = size() < rhs.size() ? size() : rhs.size();
5928 for (size_t i = 0; i < min_size; ++i) {
5929 if (at(i) != rhs[i]) return false;
5930 }
5931
5932 const BitVector& larger = size() < rhs.size() ? rhs : *this;
5933 for (size_t i = min_size; i < larger.size(); ++i) {
5934 if (larger[i] != 0) return false;
5935 }
5936
5937 return true;
5938 }
5939
5940 size_t count_bit() const
5941 {
5942 size_t count = 0;
5943 for (size_t i = 0; i < size(); ++i) {
5944 count += detail::Count1Bits(at(i));
5945 }
5946 return count;
5947 }
5948
5949 void get_bit_indexes(std::vector<size_t>& indexes) const
5950 {
5951 indexes.clear();
5952 for (size_t i = 0; i < size(); ++i) {
5953 uint32 m = at(i);
5954 while (m != 0) {
5955 uint32 index = detail::bit_scan_forward(m);
5956 indexes.push_back(static_cast<uint32>(i * 32) + index);
5957 m &= ~(1 << index);
5958 }
5959 }
5960 }
5961
5962 template<class Fn>
5963 void query_bit_indexes(Fn& fn) const
5964 {
5965 for (size_t i = 0; i < size(); ++i) {
5966 uint32 m = at(i);
5967 while (m != 0) {
5968 uint32 index = detail::bit_scan_forward(m);
5969 fn(i * 32 + index);
5970 m &= ~(1 << index);
5971 }
5972 }
5973 }
5974
5975 void set_union(const BitVector& rhs)
5976 {
5977 if (size() < rhs.size()) resize(rhs.size());
5978 for (size_t i = 0; i < rhs.size(); ++i) {
5979 at(i) |= rhs[i];
5980 }
5981 }
5982
5983 void set_subtract(const BitVector& rhs)
5984 {
5985 const size_t min_size = size() < rhs.size() ? size() : rhs.size();
5986 for (size_t i = 0; i < min_size; ++i) {
5987 at(i) &= ~rhs[i];
5988 }
5989 }
5990 };
5991
5992 template<class T, size_t N>
5993 class FixedArray
5994 {
5995 private:
5996 T data_[N];
5997 size_t size_;
5998
5999 public:
6000 FixedArray() : size_(0) {}
6001 bool empty() const {return size_ == 0;}
6002 size_t size() const {return size_;}
6003 void clear() {size_ = 0;}
6004
6005 void push_back(const T& v) {data_[size_++] = v;}
6006 void pop_back() {--size_;}
6007
6008 const T& operator[](size_t i) const {return data_[i];}
6009 T& operator[](size_t i) {return data_[i];}
6010
6011 const T& back() const {return data_[size_ - 1];}
6012 T& back() {return data_[size_ - 1];}
6013 };
6014
6015 /// Register family
6016 inline size_t GetRegFamily(RegType type)
6017 {
6018 switch (type) {
6019 case R_TYPE_GP: return 0;
6020 case R_TYPE_MMX: return 1;
6021 case R_TYPE_XMM: return 2;
6022 case R_TYPE_YMM: return 2;
6023 case R_TYPE_SYMBOLIC_GP: return 0;
6024 case R_TYPE_SYMBOLIC_MMX: return 1;
6025 case R_TYPE_SYMBOLIC_XMM: return 2;
6026 case R_TYPE_SYMBOLIC_YMM: return 2;
6027 case R_TYPE_FPU:
6028 default:
6029 JITASM_ASSERT(0);
6030 return 0x7FFFFFFF;
6031 }
6032 }
6033
6034 inline std::string GetRegName(RegType type, size_t reg_idx)
6035 {
6036 #ifdef JITASM64
6037 const static std::string s_gp_reg_name[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
6038 #else
6039 const static std::string s_gp_reg_name[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
6040 #endif
6041 std::string name;
6042 if (type == R_TYPE_GP) {return s_gp_reg_name[reg_idx];}
6043 else if (type == R_TYPE_MMX) {name.assign("mm");}
6044 else if (type == R_TYPE_XMM) {name.assign("xmm");}
6045 else if (type == R_TYPE_YMM) {name.assign("ymm");}
6046 else if (type == R_TYPE_SYMBOLIC_GP) {name.assign("gpsym"); reg_idx -= NUM_OF_PHYSICAL_REG;}
6047 else if (type == R_TYPE_SYMBOLIC_MMX) {name.assign("mmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;}
6048 else if (type == R_TYPE_SYMBOLIC_XMM) {name.assign("xmmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;}
6049 else if (type == R_TYPE_SYMBOLIC_YMM) {name.assign("ymmsym"); reg_idx -= NUM_OF_PHYSICAL_REG;}
6050 detail::append_num(name, reg_idx);
6051 return name;
6052 }
6053
6054 /// Variable attribute
6055 struct VarAttribute
6056 {
6057 unsigned size : 7; // OpdSize
6058 unsigned spill : 1; // bool
6059 Addr stack_slot;
6060 VarAttribute() : size(0), spill(0/*false*/), stack_slot(RegID::Invalid(), 0) {}
6061 };
6062
6063 /// Variable manager
6064 class VariableManager
6065 {
6066 private:
6067 std::vector<VarAttribute> attributes_[3]; // GP, MMX, XMM/YMM
6068
6069 public:
6070 std::vector<VarAttribute>& GetAttributes(size_t reg_family) {return attributes_[reg_family];}
6071 const std::vector<VarAttribute>& GetAttributes(size_t reg_family) const {return attributes_[reg_family];}
6072
6073 /// Get variable size
6074 OpdSize GetVarSize(size_t reg_family, int var) const
6075 {
6076 return static_cast<OpdSize>(attributes_[reg_family][var].size);
6077 }
6078
6079 /// Update variable size
6080 void UpdateVarSize(RegType reg_type, int var, OpdSize size)
6081 {
6082 const size_t reg_family = GetRegFamily(reg_type);
6083 if (static_cast<size_t>(var) >= attributes_[reg_family].size()) {
6084 attributes_[reg_family].resize(var + 1);
6085 }
6086
6087 if (attributes_[reg_family][var].size < static_cast<unsigned>(size)) {
6088 attributes_[reg_family][var].size = static_cast<unsigned>(size);
6089 }
6090 }
6091
6092 /// Get stack slot for spill register
6093 Addr GetSpillSlot(size_t reg_family, int var) const
6094 {
6095 return attributes_[reg_family][var].stack_slot;
6096 }
6097
6098 /// Set stack slot for spill register
6099 void SetSpillSlot(RegType reg_type, int var, const Addr& stack_slot)
6100 {
6101 const size_t reg_family = GetRegFamily(reg_type);
6102 if (static_cast<size_t>(var) >= attributes_[reg_family].size()) {
6103 attributes_[reg_family].resize(var + 1);
6104 }
6105 attributes_[reg_family][var].stack_slot = stack_slot;
6106 }
6107
6108 /// Allocate stack of spill slots
6109 void AllocSpillSlots(detail::StackManager& stack_manager)
6110 {
6111 // YMM
6112 for (size_t i = 0; i < attributes_[2].size(); ++i) {
6113 if (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_256 && attributes_[2][i].stack_slot.reg_.IsInvalid()) {
6114 attributes_[2][i].stack_slot = stack_manager.Alloc(256 / 8, 32); // 32 bytes aligned! 16->32 171108
6115 }
6116 }
6117
6118 // XMM
6119 for (size_t i = 0; i < attributes_[2].size(); ++i) {
6120 if (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_128 && attributes_[2][i].stack_slot.reg_.IsInvalid()) {
6121 attributes_[2][i].stack_slot = stack_manager.Alloc(128 / 8, 16);
6122 }
6123 }
6124
6125 // MMX
6126 for (size_t i = 0; i < attributes_[1].size(); ++i) {
6127 if (attributes_[1][i].spill && attributes_[1][i].stack_slot.reg_.IsInvalid()) {
6128 attributes_[1][i].stack_slot = stack_manager.Alloc(64 / 8, 8);
6129 }
6130 }
6131
6132 // GP
6133 for (size_t i = 0; i < attributes_[0].size(); ++i) {
6134 if (attributes_[0][i].spill && attributes_[0][i].stack_slot.reg_.IsInvalid()) {
6135 #ifdef JITASM64
6136 attributes_[0][i].stack_slot = stack_manager.Alloc(64 / 8, 8);
6137 #else
6138 attributes_[0][i].stack_slot = stack_manager.Alloc(32 / 8, 4);
6139 #endif
6140 }
6141 }
6142 }
6143 };
6144
6145 /// Register use point
6146 struct RegUsePoint
6147 {
6148 size_t instr_idx; ///< Instruction index offset from basic block start point
6149 OpdType type; ///< Operand type
6150 uint32 reg_assignable; ///< Register assignment constraint
6151
6152 RegUsePoint(size_t idx, OpdType t, uint32 assignable) : instr_idx(idx), type(t), reg_assignable(assignable) {}
6153
6154 bool operator<(const RegUsePoint& rhs) const {
6155 if (instr_idx == rhs.instr_idx) {
6156 // R < RW < W
6157 const int lhs_type = (type & O_TYPE_READ ? -1 : 0) + (type & O_TYPE_WRITE ? 1 : 0);
6158 const int rhs_type = (rhs.type & O_TYPE_READ ? -1 : 0) + (rhs.type & O_TYPE_WRITE ? 1 : 0);
6159 return lhs_type < rhs_type;
6160 }
6161 return instr_idx < rhs.instr_idx;
6162 }
6163 };
6164
6165 /// Variable lifetime
6166 struct Lifetime
6167 {
6168 typedef detail::Range< std::vector<RegUsePoint> > RegUsePointRange;
6169 typedef detail::ConstRange< std::vector<RegUsePoint> > ConstRegUsePointRange;
6170
6171 struct Interval
6172 {
6173 size_t instr_idx_offset; ///< Instruction index offset from basic block start point
6174 BitVector liveness; ///< The set of live variables
6175 BitVector use; ///< The set of used variables in this interval
6176 BitVector spill; ///< The set of spilled variables
6177 std::vector<uint32> reg_assignables; ///< The constraints of register allocation
6178 std::vector<int> assignment_table; ///< Register assignment table
6179
6180 Interval(size_t instr_idx, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), reg_assignables(assignables) {}
6181 Interval(size_t instr_idx, const BitVector& l, const BitVector& s, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), liveness(l), spill(s), reg_assignables(assignables) {}
6182
6183 void UpdateUse(size_t var, RegUsePointRange& range, const Interval *next_interval)
6184 {
6185 // step range
6186 while (!range.empty() && range.first->instr_idx < instr_idx_offset) {++range.first;}
6187
6188 // check if variables used in this interval
6189 const bool used = !range.empty() && (!next_interval || range.first->instr_idx < next_interval->instr_idx_offset);
6190 use.set_bit(var, used);
6191 }
6192
6193 void Dump(bool dump_assigned_reg) const
6194 {
6195 std::vector<char> liveness_str;
6196 for (size_t v = 0; v < liveness.size_bit(); ++v) {
6197 if (liveness.get_bit(v)) {
6198 const bool used = use.get_bit(v);
6199 char c;
6200 if (spill.get_bit(v)) {
6201 c = used ? 'S' : 's';
6202 } else if (dump_assigned_reg) {
6203 int reg = assignment_table[v];
6204 c = static_cast<char>(reg < 0xA ? '0' + reg : 'A' + reg);
6205 } else {
6206 c = used ? 'R' : 'r';
6207 }
6208 liveness_str.push_back(c);
6209 } else {
6210 liveness_str.push_back('.');
6211 }
6212 }
6213 liveness_str.push_back('\0');
6214 JITASM_TRACE("[%03d] %s\n", instr_idx_offset, &liveness_str[0]);
6215 }
6216 };
6217
6218 // 0 ~ NUM_OF_PHYSICAL_REG-1 : Physical register
6219 // NUM_OF_PHYSICAL_REG ~ : Symbolic register
6220 std::vector< std::vector<RegUsePoint> > use_points;
6221 BitVector gen; ///< The set of variables used before any assignment
6222 BitVector kill; ///< The set of variables assigned a value before any use
6223 BitVector live_in; ///< The set of live variables at the start of this block
6224 BitVector live_out; ///< The set of live variables at the end of this block
6225 bool dirty_live_out; ///< The dirty flag of live_out
6226 std::vector<Interval> intervals; ///< Lifetime intervals
6227
6228 static const int SpillCost_Read = 2;
6229 static const int SpillCost_Write = 3;
6230
6231 Lifetime() : use_points(NUM_OF_PHYSICAL_REG), dirty_live_out(true) {}
6232
6233 /// Add register use point
6234 void AddUsePoint(size_t instr_idx, const RegID& reg, OpdType opd_type, OpdSize opd_size, uint32 reg_assignable)
6235 {
6236 if (use_points.size() <= static_cast<size_t>(reg.id)) {
6237 use_points.resize(reg.id + 1);
6238 }
6239
6240 // add read attribute when writing to 8/16bit register because it is partial write
6241 if ((opd_type & O_TYPE_WRITE) && (opd_size == O_SIZE_8 || opd_size == O_SIZE_16)) {
6242 opd_type = static_cast<OpdType>(static_cast<int>(opd_type) | O_TYPE_READ);
6243 }
6244
6245 RegUsePoint use_point(instr_idx, opd_type, reg_assignable);
6246 std::vector<RegUsePoint>::reverse_iterator it = use_points[reg.id].rbegin();
6247 while (it != use_points[reg.id].rend() && use_point < *it) {++it;}
6248 use_points[reg.id].insert(it.base(), use_point);
6249 }
6250
6251 void GetSpillCost(int freq, std::vector<int>& spill_cost) const
6252 {
6253 if (spill_cost.size() < use_points.size()) {
6254 spill_cost.resize(use_points.size()); // expand
6255 }
6256 for(size_t i = 0; i < use_points.size(); ++i) {
6257 int cost = 0;
6258 for (std::vector<RegUsePoint>::const_iterator it = use_points[i].begin(); it != use_points[i].end(); ++it) {
6259 if (it->type & O_TYPE_READ) cost += SpillCost_Read;
6260 if (it->type & O_TYPE_WRITE) cost += SpillCost_Write;
6261 }
6262 spill_cost[i] += cost * freq;
6263 }
6264 }
6265
6266 void BuildIntervals()
6267 {
6268 // initialize use_points ranges
6269 std::vector<RegUsePointRange> use_points_ranges;
6270 use_points_ranges.reserve(use_points.size());
6271 for (size_t i = 0; i < use_points.size(); ++i) {
6272 use_points_ranges.push_back(RegUsePointRange(use_points[i]));
6273 }
6274
6275 // build interval
6276 BitVector *last_liveness = NULL;
6277 std::vector<uint32> reg_assignables;
6278 bool last_reg_constraints = false;
6279 bool last_stack_vars = false;
6280 const size_t num_of_variables = live_in.size_bit() < use_points.size() ? use_points.size() : live_in.size_bit();
6281 size_t instr_idx = 0;
6282 size_t end_count;
6283 do {
6284 BitVector liveness = live_in;
6285 BitVector stack_vars;
6286 end_count = 0;
6287 reg_assignables.clear();
6288 size_t min_instr_idx = (size_t)-1;
6289 for (size_t i = 0; i < use_points_ranges.size(); ++i) {
6290 if (use_points_ranges[i].empty()) {
6291 liveness.set_bit(i, live_out.get_bit(i));
6292 ++end_count;
6293 } else {
6294 if (use_points_ranges[i].first->instr_idx < min_instr_idx) {
6295 min_instr_idx = use_points_ranges[i].first->instr_idx;
6296 }
6297
6298 if (use_points_ranges[i].first->instr_idx == instr_idx) {
6299 for (; !use_points_ranges[i].empty() && use_points_ranges[i].first->instr_idx == instr_idx; ++use_points_ranges[i].first) {
6300 // Check the constraints of register allocation
6301 if (use_points_ranges[i].first->reg_assignable != 0xFFFFFFFF) {
6302 reg_assignables.resize(num_of_variables, 0xFFFFFFFF);
6303 reg_assignables[i] &= use_points_ranges[i].first->reg_assignable;
6304 }
6305
6306 // Check the stack variable
6307 if (use_points_ranges[i].first->type & O_TYPE_MEM) {
6308 stack_vars.set_bit(i, true);
6309 }
6310 }
6311 liveness.set_bit(i, true);
6312 } else if (use_points_ranges[i].first->type & O_TYPE_READ) {
6313 liveness.set_bit(i, true);
6314 } else if (use_points_ranges[i].first->type & O_TYPE_WRITE) {
6315 liveness.set_bit(i, false);
6316 } else {
6317 JITASM_ASSERT(0);
6318 }
6319 }
6320 }
6321
6322 // Split interval in the following case:
6323 // - The liveness is changed.
6324 // - Current or last instruction has any constraints of register allocation.
6325 // - Last instruction is I_COMPILER_DECLARE_STACK_ARG
6326 if (!reg_assignables.empty() || last_reg_constraints || last_stack_vars || !last_liveness || !last_liveness->is_equal(liveness)) {
6327 intervals.push_back(Interval(instr_idx, liveness, stack_vars, reg_assignables));
6328 last_liveness = &intervals.back().liveness;
6329 }
6330
6331 last_reg_constraints = !reg_assignables.empty();
6332 last_stack_vars = !stack_vars.empty();
6333 instr_idx = min_instr_idx == instr_idx ? instr_idx + 1 : min_instr_idx;
6334 } while (end_count < use_points_ranges.size());
6335
6336 // check use
6337 for (size_t v = 0; v < use_points.size(); ++v) {
6338 RegUsePointRange range(use_points[v]);
6339 for (size_t i = 0; i < intervals.size(); ++i) {
6340 const Interval *next_interval = i + 1 < intervals.size() ? &intervals[i + 1] : NULL;
6341 intervals[i].UpdateUse(v, range, next_interval);
6342 }
6343 }
6344 }
6345
6346 /// Split interval
6347 void SplitInterval(size_t instr_idx, size_t interval_idx)
6348 {
6349 std::vector<Interval>::iterator it = intervals.insert(intervals.begin() + interval_idx + 1, intervals[interval_idx]);
6350 it->instr_idx_offset = instr_idx;
6351
6352 // update use
6353 for (size_t v = 0; v < use_points.size(); ++v) {
6354 RegUsePointRange range(use_points[v]);
6355 for (size_t i = interval_idx; i < interval_idx + 2; ++i) {
6356 const Interval *next_interval = i + 1 < intervals.size() ? &intervals[i + 1] : NULL;
6357 intervals[i].UpdateUse(v, range, next_interval);
6358 }
6359 }
6360 }
6361
6362 struct LessCost {
6363 const std::vector<int> *cost_;
6364 LessCost(const std::vector<int> *cost) : cost_(cost) {}
6365 int get_cost(size_t i) const {return i < cost_->size() ? cost_->at(i) : 0;}
6366 bool operator()(size_t lhs, size_t rhs) const {return get_cost(lhs) < get_cost(rhs);}
6367 };
6368
6369 /// Spill identification
6370 void SpillIdentification(uint32 available_reg_count, const std::vector<int>& total_spill_cost, int freq, const Interval *last_interval, std::vector<VarAttribute>& var_attrs)
6371 {
6372 // initialize use_points ranges
6373 std::vector<RegUsePointRange> interval_use_points;
6374 interval_use_points.reserve(use_points.size());
6375 for (size_t i = 0; i < use_points.size(); ++i) {
6376 interval_use_points.push_back(RegUsePointRange(use_points[i]));
6377 }
6378
6379 std::vector<size_t> live_vars;
6380 std::vector<int> cur_spill_cost;
6381 for (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) {
6382 const Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval;
6383 Interval *cur_interval = &intervals[interval_idx];
6384
6385 if (cur_interval->liveness.count_bit() > available_reg_count) {
6386 cur_interval->liveness.get_bit_indexes(live_vars);
6387
6388 const size_t max_var = live_vars.back();
6389 if (var_attrs.size() < max_var + 1) {
6390 var_attrs.resize(max_var + 1); // expand var_attrs
6391 }
6392
6393 cur_spill_cost.resize(max_var + 1);
6394 for (size_t i = 0; i < live_vars.size(); ++i) {
6395 const size_t var = live_vars[i];
6396
6397 // step interval_use_points
6398 if (var < interval_use_points.size()) {
6399 while (!interval_use_points[var].empty() && interval_use_points[var].first->instr_idx < cur_interval->instr_idx_offset) {++interval_use_points[var].first;}
6400 }
6401
6402 // calculate spill cost of this interval
6403 if (cur_interval->use.get_bit(var) && (interval_use_points[var].first->type & O_TYPE_MEM)) {
6404 // special low spill cost if this variable on stack (function arguemnt)
6405 cur_spill_cost[var] = -1;
6406 } else if (cur_interval->use.get_bit(var) && interval_use_points[var].first->instr_idx == cur_interval->instr_idx_offset) {
6407 // special high spill cost if this variable is used at first instruction of this interval
6408 // because it must not be spilled.
6409 cur_spill_cost[var] = 0x7FFFFFFF;
6410 } else {
6411 cur_spill_cost[var] = total_spill_cost[var];
6412 if (prior_interval && !prior_interval->spill.get_bit(var)) {
6413 cur_spill_cost[var] += (SpillCost_Read + SpillCost_Write) * freq;
6414 }
6415 }
6416 }
6417
6418 // Spill from the smallest cost
6419 std::sort(live_vars.begin(), live_vars.end(), LessCost(&cur_spill_cost));
6420
6421 // Mark spilled variable.
6422 // Split interval if spilled variable is used in this interval.
6423 // Find first instruction index using the spilled variable.
6424 size_t split_interval_instr = (size_t)-1;
6425 for (size_t i = 0; i < live_vars.size(); ++i) {
6426 const size_t var = live_vars[i];
6427 const bool stack_var = (cur_spill_cost[var] < 0); // It may be function argument on stack
6428 const bool spill = (i + available_reg_count < live_vars.size() || stack_var);
6429 cur_interval->spill.set_bit(var, spill);
6430 if (spill) {
6431 var_attrs[var].spill = 1;
6432 }
6433 if (stack_var) {
6434 // Split at next of using stack variable
6435 if (interval_use_points[var].first->instr_idx + 1 < split_interval_instr) {
6436 split_interval_instr = interval_use_points[var].first->instr_idx + 1;
6437 }
6438 } else if (spill && cur_interval->use.get_bit(var)) {
6439 // Split if spilled variable is used in this interval.
6440 if (interval_use_points[var].first->instr_idx < split_interval_instr) {
6441 split_interval_instr = interval_use_points[var].first->instr_idx;
6442 }
6443 }
6444 }
6445
6446 if (split_interval_instr != (size_t)-1) {
6447 SplitInterval(split_interval_instr, interval_idx);
6448 }
6449 }
6450 }
6451 }
6452
6453 struct LessAssignOrder {
6454 Interval *interval;
6455 const Interval *prior_interval;
6456 LessAssignOrder(Interval *cur, const Interval *prior) : interval(cur), prior_interval(prior) {}
6457 bool has_constraints(size_t v) const {return v < interval->reg_assignables.size() ? interval->reg_assignables[v] != 0xFFFFFFFF : false;}
6458 uint32 num_of_assignable(size_t v) const {return v < interval->reg_assignables.size() ? detail::Count1Bits(interval->reg_assignables[v]) : 32;}
6459 bool operator()(size_t lhs, size_t rhs) const {
6460 // is there any register constraints or not
6461 const bool lhs_has_constraints = has_constraints(lhs);
6462 const bool rhs_has_constraints = has_constraints(rhs);
6463 if (lhs_has_constraints != rhs_has_constraints) {
6464 return lhs_has_constraints;
6465 }
6466
6467 if (lhs_has_constraints) {
6468 // is the register which has constraints used in this interval or not
6469 const bool lhs_used = interval->use.get_bit(lhs);
6470 const bool rhs_used = interval->use.get_bit(rhs);
6471 if (lhs_used != rhs_used) {
6472 return lhs_used;
6473 }
6474
6475 // compare number of assignable registers
6476 const uint32 lhs_num_of_assignable = num_of_assignable(lhs);
6477 const uint32 rhs_num_of_assignable = num_of_assignable(rhs);
6478 if (lhs_num_of_assignable != rhs_num_of_assignable) {
6479 return lhs_num_of_assignable < rhs_num_of_assignable;
6480 }
6481 }
6482
6483 // physical register or symbolic register
6484 const int lhs_sym_reg = (lhs < NUM_OF_PHYSICAL_REG ? 0 : 1);
6485 const int rhs_sym_reg = (rhs < NUM_OF_PHYSICAL_REG ? 0 : 1);
6486 if (lhs_sym_reg != rhs_sym_reg) {
6487 return lhs_sym_reg < rhs_sym_reg;
6488 }
6489
6490 if (prior_interval) {
6491 // is the variable assigned register in prior interval or not
6492 const bool lhs_prior_reg = !prior_interval->spill.get_bit(lhs) && prior_interval->liveness.get_bit(lhs);
6493 const bool rhs_prior_reg = !prior_interval->spill.get_bit(rhs) && prior_interval->liveness.get_bit(rhs);
6494 if (lhs_prior_reg != rhs_prior_reg) {
6495 return lhs_prior_reg;
6496 }
6497 }
6498
6499 // compare register id
6500 return lhs < rhs;
6501 }
6502 };
6503
6504 /// Assign register in basic block
6505 /**
6506 * \param[in] available_reg Available physical register mask
6507 * \param[in] last_interval Last Interval as the hint of assignment
6508 * \return Used physical register mask
6509 */
6510 uint32 AssignRegister(uint32 available_reg, const Interval *last_interval)
6511 {
6512 uint32 used_reg = 0;
6513 std::vector<size_t> live_vars;
6514 for (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) {
6515 const Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval;
6516 Interval *cur_interval = &intervals[interval_idx];
6517
6518 // enum variables to assign register
6519 live_vars.clear();
6520 for (size_t i = 0; i < cur_interval->liveness.size(); ++i) {
6521 uint32 s = i < cur_interval->spill.size() ? cur_interval->spill[i] : 0;
6522 uint32 l = cur_interval->liveness[i] & ~s;
6523 while (l != 0) {
6524 uint32 index = detail::bit_scan_forward(l);
6525 live_vars.push_back(static_cast<uint32>(i * 32) + index);
6526 l &= ~(1 << index);
6527 }
6528 }
6529
6530 if (!live_vars.empty()) {
6531 cur_interval->assignment_table.resize(live_vars.back() + 1, -1);
6532
6533 // sort into assignment order
6534 std::sort(live_vars.begin(), live_vars.end(), LessAssignOrder(cur_interval, prior_interval));
6535 }
6536
6537 // Assign register
6538 uint32 cur_avail = available_reg;
6539 const size_t num_of_live_vars = live_vars.size();
6540 for (size_t i = 0; i < live_vars.size(); ++i) {
6541 const size_t var = live_vars[i];
6542 const bool first_try = (i < num_of_live_vars); // Try to assign for the first time
6543 const uint32 reg_assignable = first_try && var < cur_interval->reg_assignables.size() ? cur_interval->reg_assignables[var] : 0xFFFFFFFF; // Ignore constraint if it is retried
6544 JITASM_ASSERT((cur_avail & reg_assignable) != 0);
6545 int assigned_reg = -1;
6546 if (var < NUM_OF_PHYSICAL_REG && first_try) {
6547 // Physical register
6548 if (cur_avail & reg_assignable & (1 << var)) {
6549 assigned_reg = static_cast<int>(var);
6550 } else if (((1 << var) & available_reg) && !cur_interval->use.get_bit(var)) {
6551 // Try to assign another physical register if it is not used in this interval. But assign later.
6552 live_vars.push_back(var);
6553 } else if (reg_assignable != 0xFFFFFFFF && (cur_avail & reg_assignable) && cur_interval->use.get_bit(var)) {
6554 // This physical register violates the register constraint.
6555 // Assign another physical register which satisfy the constraint.
6556 assigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable);
6557 } else {
6558 // This may be out of assignment register (ESP, EBP and so on...)
6559 JITASM_ASSERT(((1 << var) & available_reg) == 0); // false assignment!?
6560 assigned_reg = static_cast<int>(var);
6561 }
6562 } else {
6563 // Symbolic register or retried physical register
6564 const int last_assigned = prior_interval && var < prior_interval->assignment_table.size() ? prior_interval->assignment_table[var] : -1;
6565 if (last_assigned != -1 && (cur_avail & reg_assignable & (1 << last_assigned))) {
6566 // select last assigned register
6567 assigned_reg = last_assigned;
6568 } else if (cur_avail & reg_assignable) {
6569 assigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable);
6570 } else if (reg_assignable != 0xFFFFFFFF && !cur_interval->use.get_bit(var)) {
6571 // Try to assign register ignoring constraint if it is not used in this interval. But assign later.
6572 live_vars.push_back(var);
6573 } else {
6574 JITASM_ASSERT(0);
6575 }
6576 }
6577
6578 if (assigned_reg >= 0) {
6579 cur_interval->assignment_table[var] = assigned_reg;
6580 cur_avail &= ~(1 << assigned_reg);
6581 }
6582 }
6583
6584 used_reg |= ~cur_avail & available_reg;
6585 }
6586
6587 return used_reg;
6588 }
6589
6590 void DumpIntervals(size_t block_id, bool dump_assigned_reg) const
6591 {
6592 avoid_unused_warn(block_id);
6593 JITASM_TRACE("---- Block%d ----\n", block_id);
6594 for (size_t i = 0; i < intervals.size(); ++i) {
6595 intervals[i].Dump(dump_assigned_reg);
6596 }
6597 }
6598 };
6599
6600 /// Basic block
6601 struct BasicBlock
6602 {
6603 BasicBlock *successor[2];
6604 std::vector<BasicBlock *> predecessor;
6605 size_t instr_begin; ///< Begin instruction index of the basic block (inclusive)
6606 size_t instr_end; ///< End instruction index of the basic block (exclusive)
6607 size_t depth; ///< Depth-first order of Control flow
6608 BasicBlock *dfs_parent; ///< Depth-first search tree parent
6609 BasicBlock *immediate_dominator; ///< Immediate dominator
6610 size_t loop_depth; ///< Loop nesting depth
6611 Lifetime lifetime[3]; ///< Variable lifetime (0: GP, 1: MMX, 2: XMM/YMM)
6612
6613 BasicBlock(size_t instr_begin_, size_t instr_end_, BasicBlock *successor0 = NULL, BasicBlock *successor1 = NULL) : instr_begin(instr_begin_), instr_end(instr_end_), depth((size_t)-1), dfs_parent(NULL), immediate_dominator(NULL), loop_depth(0) {
6614 successor[0] = successor0;
6615 successor[1] = successor1;
6616 }
6617
6618 bool operator<(const BasicBlock& rhs) const { return instr_begin < rhs.instr_begin; }
6619
6620 /// Remove predecessor
6621 void RemovePredecessor(BasicBlock *block) {
6622 std::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), block);
6623 if (it != predecessor.end()) {
6624 predecessor.erase(it);
6625 }
6626 }
6627
6628 /// Replace predecessor
6629 bool ReplacePredecessor(BasicBlock *old_pred, BasicBlock *new_pred) {
6630 std::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), old_pred);
6631 if (it != predecessor.end()) {
6632 *it = new_pred;
6633 return true;
6634 }
6635 return false;
6636 }
6637
6638 /// Check if the specified block is dominator of this block
6639 bool IsDominated(BasicBlock *block) const {
6640 if (block == this) {return true;}
6641 return immediate_dominator ? immediate_dominator->IsDominated(block) : false;
6642 }
6643
6644 /// Get estimated frequency of basic block
6645 int GetFrequency() const {
6646 const static int freq[] = {1, 100, 10000, 40000, 160000, 640000};
6647 return freq[loop_depth < sizeof(freq) / sizeof(int) ? loop_depth : sizeof(freq) / sizeof(int) - 1];
6648 }
6649
6650 /// Get variable lifetime
6651 Lifetime& GetLifetime(RegType type) {return lifetime[GetRegFamily(type)];}
6652 /// Get variable lifetime
6653 const Lifetime& GetLifetime(RegType type) const {return lifetime[GetRegFamily(type)];}
6654
6655 struct less
6656 {
6657 bool operator()(BasicBlock *lhs, BasicBlock *rhs) { return lhs->instr_begin < rhs->instr_begin; }
6658 bool operator()(BasicBlock *lhs, size_t rhs) { return lhs->instr_begin < rhs; }
6659 bool operator()(size_t lhs, BasicBlock *rhs) { return lhs < rhs->instr_begin; }
6660 };
6661 };
6662
6663 /**
6664 * The Lengauer-Tarjan algorithm
6665 */
6666 class DominatorFinder
6667 {
6668 private:
6669 std::vector<size_t> sdom_; // semidominator
6670 std::vector<size_t> ancestor_;
6671 std::vector<size_t> best_;
6672
6673 void Link(size_t v, size_t w)
6674 {
6675 ancestor_[w] = v;
6676 }
6677
6678 size_t Eval(size_t v)
6679 {
6680 if (ancestor_[v] == 0) return v;
6681 Compress(v);
6682 return best_[v];
6683 }
6684
6685 void Compress(size_t v)
6686 {
6687 size_t a = ancestor_[v];
6688 if (ancestor_[a] == 0)
6689 return;
6690
6691 Compress(a);
6692
6693 if (sdom_[best_[v]] > sdom_[best_[a]])
6694 best_[v] = best_[a];
6695
6696 ancestor_[v] = ancestor_[a];
6697 }
6698
6699 public:
6700 void operator()(std::deque<BasicBlock *>& depth_first_blocks)
6701 {
6702 const size_t num_of_nodes = depth_first_blocks.size();
6703 if (num_of_nodes == 0) return;
6704
6705 // initialize
6706 sdom_.resize(num_of_nodes); // semidominator
6707 ancestor_.clear();
6708 ancestor_.resize(num_of_nodes);
6709 best_.resize(num_of_nodes);
6710 std::vector< std::vector<size_t> > bucket(num_of_nodes);
6711 std::vector<size_t> dom(num_of_nodes);
6712 for (size_t i = 0; i < num_of_nodes; ++i) {
6713 sdom_[i] = i;
6714 best_[i] = i;
6715 }
6716
6717 for (size_t w = num_of_nodes - 1; w > 0; --w) {
6718 BasicBlock *wb = depth_first_blocks[w];
6719 size_t p = wb->dfs_parent->depth;
6720
6721 // Compute the semidominator
6722 for (std::vector<BasicBlock *>::iterator v = wb->predecessor.begin(); v != wb->predecessor.end(); ++v) {
6723 if ((*v)->depth != (size_t)-1) { // skip out of DFS tree
6724 size_t u = Eval((*v)->depth);
6725 if (sdom_[u] < sdom_[w])
6726 sdom_[w] = sdom_[u];
6727 }
6728 }
6729 bucket[sdom_[w]].push_back(w);
6730 Link(p, w);
6731
6732 // Implicity compute immediate dominator
6733 for (std::vector<size_t>::iterator v = bucket[p].begin(); v != bucket[p].end(); ++v) {
6734 size_t u = Eval(*v);
6735 dom[*v] = sdom_[u] < sdom_[*v] ? u : p;
6736 }
6737 bucket[p].clear();
6738 }
6739
6740 // Explicity compute immediate dominator
6741 for (size_t w = 1; w < num_of_nodes; ++w) {
6742 if (dom[w] != sdom_[w])
6743 dom[w] = dom[dom[w]];
6744 depth_first_blocks[w]->immediate_dominator = depth_first_blocks[dom[w]];
6745 }
6746 depth_first_blocks[0]->immediate_dominator = NULL;
6747 }
6748 };
6749
6750 /// Control flow graph
6751 class ControlFlowGraph
6752 {
6753 public:
6754 typedef std::deque<BasicBlock *> BlockList;
6755
6756 private:
6757 BlockList blocks_;
6758 BlockList depth_first_blocks_;
6759
6760 void MakeDepthFirstBlocks(BasicBlock *block)
6761 {
6762 block->depth = 0; // mark "visited"
6763 for (size_t i = 0; i < 2; ++i) {
6764 BasicBlock *s = block->successor[i];
6765 if (s && s->depth != 0) {
6766 s->dfs_parent = block;
6767 MakeDepthFirstBlocks(s);
6768 }
6769 }
6770 depth_first_blocks_.push_front(block);
6771 }
6772
6773 struct sort_backedge {
6774 bool operator()(const std::pair<size_t, size_t>& lhs, const std::pair<size_t, size_t>& rhs) const {
6775 if (lhs.second < rhs.second) return true; // smaller depth loop header first
6776 if (lhs.second == rhs.second) return lhs.first > rhs.first; // larger depth of end of loop first if same loop header
6777 return false;
6778 }
6779 };
6780
6781 void DetectLoops()
6782 {
6783 // Make dominator tree
6784 DominatorFinder dom_finder;
6785 dom_finder(depth_first_blocks_);
6786
6787 // Identify backedges
6788 std::vector< std::pair<size_t, size_t> > backedges;
6789 for (size_t i = 0; i < depth_first_blocks_.size(); ++i) {
6790 BasicBlock *block = depth_first_blocks_[i];
6791 for (size_t j = 0; j < 2; ++j) {
6792 if (block->successor[j] && block->depth >= block->successor[j]->depth) { // retreating edge
6793 if (block->IsDominated(block->successor[j])) {
6794 backedges.push_back(std::make_pair(block->depth, block->successor[j]->depth));
6795 }
6796 }
6797 }
6798 }
6799
6800 // Merge loops with the same loop header
6801 std::sort(backedges.begin(), backedges.end(), sort_backedge());
6802 if (backedges.size() >= 2) {
6803 std::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin() + 1;
6804 while (it != backedges.end()) {
6805 if (detail::prior(it)->second == it->second) {
6806 // erase backedge of smaller loop
6807 it = backedges.erase(it);
6808 } else {
6809 ++it;
6810 }
6811 }
6812 }
6813
6814 // Set loop depth
6815 for (std::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin(); it != backedges.end(); ++it) {
6816 for (size_t i = it->second; i <= it->first; ++i) {
6817 depth_first_blocks_[i]->loop_depth++;
6818 }
6819 }
6820 }
6821
6822 BlockList::iterator initialize(size_t num_of_instructions) {
6823 clear();
6824 blocks_.resize(num_of_instructions > 0 ? 2 : 1);
6825 BasicBlock *enter_block = new BasicBlock(0, num_of_instructions);
6826 blocks_[0] = enter_block;
6827 if (num_of_instructions > 0) {
6828 // exit block
6829 BasicBlock *exit_block = new BasicBlock(num_of_instructions, num_of_instructions);
6830 blocks_[1] = exit_block;
6831 enter_block->successor[0] = exit_block;
6832 exit_block->predecessor.push_back(enter_block);
6833 }
6834 return blocks_.begin();
6835 }
6836
6837 /// Split basic block
6838 BlockList::iterator split(BlockList::iterator target_block_it, size_t instr_idx) {
6839 BasicBlock *target_block = *target_block_it;
6840 if (target_block->instr_begin == instr_idx)
6841 return target_block_it;
6842
6843 BasicBlock *new_block = new BasicBlock(instr_idx, target_block->instr_end);
6844 new_block->successor[0] = target_block->successor[0];
6845 new_block->successor[1] = target_block->successor[1];
6846 new_block->predecessor.push_back(target_block);
6847 target_block->successor[0] = new_block;
6848 target_block->successor[1] = NULL;
6849 target_block->instr_end = instr_idx;
6850
6851 // replace predecessor of successors
6852 if (new_block->successor[0]) new_block->successor[0]->ReplacePredecessor(target_block, new_block);
6853 if (new_block->successor[1]) new_block->successor[1]->ReplacePredecessor(target_block, new_block);
6854
6855 return blocks_.insert(detail::next(target_block_it), new_block);
6856 }
6857
6858 public:
6859 ~ControlFlowGraph()
6860 {
6861 clear();
6862 }
6863
6864 BlockList::iterator get_block(size_t instr_idx) {
6865 BlockList::iterator it = std::upper_bound(blocks_.begin(), blocks_.end(), instr_idx, BasicBlock::less());
6866 return it != blocks_.begin() ? --it : blocks_.end();
6867 }
6868
6869 BlockList::iterator get_exit_block() {
6870 return detail::prior(blocks_.end());
6871 }
6872
6873 size_t size() { return blocks_.size(); }
6874
6875 void clear()
6876 {
6877 for (BlockList::iterator it = blocks_.begin(); it != blocks_.end(); ++it) {
6878 delete *it;
6879 }
6880 blocks_.clear();
6881 depth_first_blocks_.clear();
6882 }
6883
6884 BlockList::iterator begin() { return blocks_.begin(); }
6885 BlockList::iterator end() { return blocks_.end(); }
6886 BlockList::const_iterator begin() const { return blocks_.begin(); }
6887 BlockList::const_iterator end() const { return blocks_.end(); }
6888 BlockList::iterator dfs_begin() { return depth_first_blocks_.begin(); }
6889 BlockList::iterator dfs_end() { return depth_first_blocks_.end(); }
6890
6891 void DumpDot() const
6892 {
6893 JITASM_TRACE("digraph CFG {\n");
6894 JITASM_TRACE("\tnode[shape=box];\n");
6895 for (BlockList::const_iterator it = blocks_.begin(); it != blocks_.end(); ++it) {
6896 BasicBlock *block = *it;
6897 std::string live_in = "live in:";
6898 std::string live_out = "live out:";
6899 for (size_t reg_family = 0; reg_family < 3; ++reg_family) {
6900 for (size_t i = 0; i < block->lifetime[reg_family].live_in.size_bit(); ++i) {
6901 if (block->lifetime[reg_family].live_in.get_bit(i)) {
6902 live_in.append(" ");
6903 live_in.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i));
6904 }
6905 }
6906 for (size_t i = 0; i < block->lifetime[reg_family].live_out.size_bit(); ++i) {
6907 if (block->lifetime[reg_family].live_out.get_bit(i)) {
6908 live_out.append(" ");
6909 live_out.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i));
6910 }
6911 }
6912 }
6913 JITASM_TRACE("\tnode%d[label=\"Block%d\\ninstruction %d - %d\\nloop depth %d\\n%s\\n%s\"];\n", block->instr_begin, block->depth, block->instr_begin, block->instr_end - 1, block->loop_depth, live_in.c_str(), live_out.c_str());
6914 int constraint = 0; avoid_unused_warn(constraint);
6915 if (block->successor[0]) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=%s];\n", block->instr_begin, block->successor[0]->instr_begin, constraint == 0 ? "true" : "false");
6916 if (block->successor[1]) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=%s];\n", block->instr_begin, block->successor[1]->instr_begin, constraint == 0 ? "true" : "false");
6917 //if (block->dfs_parent) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [color=\"#ff0000\"];\n", block->instr_begin, block->dfs_parent->instr_begin);
6918 //if (block->immediate_dominator) JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=false, color=\"#0000ff\"];\n", block->instr_begin, block->immediate_dominator->instr_begin);
6919 //for (size_t i = 0; i < block->predecessor.size(); ++i) {
6920 // JITASM_TRACE("\t\"node%d\" -> \"node%d\" [constraint=false, color=\"#808080\"];\n", block->instr_begin, block->predecessor[i]->instr_begin);
6921 //}
6922 }
6923 JITASM_TRACE("}\n");
6924 }
6925
6926 /// Build control flow graph from instruction list
6927 void Build(const Frontend& f)
6928 {
6929 initialize(f.instrs_.size());
6930 size_t block_idx = 0;
6931 for (size_t instr_idx = 0; instr_idx < f.instrs_.size(); ++instr_idx) {
6932 InstrID instr_id = f.instrs_[instr_idx].GetID();
6933 if (Frontend::IsJump(instr_id) || instr_id == I_RET || instr_id == I_IRET) {
6934 while (blocks_[block_idx]->instr_end <= instr_idx) {
6935 ++block_idx;
6936 }
6937 BasicBlock *cur_block = blocks_[block_idx];
6938 JITASM_ASSERT(block_idx == std::distance(blocks_.begin(), get_block(instr_idx)));
6939
6940 // Jump instruction always terminate basic block
6941 if (instr_idx + 1 < cur_block->instr_end) {
6942 // Split basic block
6943 split(blocks_.begin() + block_idx, instr_idx + 1);
6944 }
6945
6946 // Set successors of current block
6947 if (instr_id == I_RET || instr_id == I_IRET) {
6948 if (cur_block->successor[0])
6949 cur_block->successor[0]->RemovePredecessor(cur_block);
6950 cur_block->successor[0] = *get_exit_block();
6951 (*get_exit_block())->predecessor.push_back(cur_block);
6952 } else {
6953 const size_t jump_to = f.GetJumpTo(f.instrs_[instr_idx]); // jump target instruction index
6954 BasicBlock *jump_target = *split(get_block(jump_to), jump_to);
6955
6956 // Update cur_block if split cur_block
6957 if (jump_target->instr_begin <= instr_idx && instr_idx < jump_target->instr_end) {
6958 cur_block = jump_target;
6959 }
6960
6961 if (instr_id == I_JMP) {
6962 if (cur_block->successor[0])
6963 cur_block->successor[0]->RemovePredecessor(cur_block);
6964 cur_block->successor[0] = jump_target;
6965 jump_target->predecessor.push_back(cur_block);
6966 } else {
6967 JITASM_ASSERT(instr_id == I_JCC || instr_id == I_LOOP);
6968 if (cur_block->successor[1])
6969 cur_block->successor[1]->RemovePredecessor(cur_block);
6970 cur_block->successor[1] = jump_target;
6971 jump_target->predecessor.push_back(cur_block);
6972 }
6973 }
6974 }
6975 }
6976
6977 // Make depth first orderd list
6978 MakeDepthFirstBlocks(*get_block(0));
6979
6980 // Numbering depth
6981 for (size_t i = 0; i < depth_first_blocks_.size(); ++i) {
6982 depth_first_blocks_[i]->depth = i;
6983 }
6984
6985 // Detect loops
6986 DetectLoops();
6987 }
6988
6989 /// Build dummy control flow graph which has enter and exit blocks.
6990 void BuildDummy(const Frontend& f)
6991 {
6992 BasicBlock *enter_block = *initialize(f.instrs_.size());
6993 BasicBlock *exit_block = enter_block->successor[0];
6994
6995 enter_block->depth = 0;
6996 depth_first_blocks_.push_back(enter_block);
6997 if (exit_block) {
6998 exit_block->depth = 1;
6999 exit_block->dfs_parent = enter_block;
7000 exit_block->immediate_dominator = enter_block;
7001 depth_first_blocks_.push_back(exit_block);
7002 }
7003 }
7004 };
7005
7006 /// Prepare compile
7007 /**
7008 * - Re-number symbolic register ID.
7009 * - Check if register allocation is needed or not.
7010 * - Look over physical register use.
7011 *
7012 * \param[in,out] instrs Instruction list
7013 * \param[out] modified_physical_reg Modified physical register mask
7014 * \param[out] need_reg_alloc Register allocation is needed or not
7015 * \return There is any compile process if it is true.
7016 */
7017 inline bool PrepareCompile(Frontend::InstrList& instrs, uint32 (&modified_physical_reg)[3], bool (&need_reg_alloc)[3])
7018 {
7019 struct RegIDMap {
7020 int next_id_;
7021 std::map<int, int> id_map_;
7022 RegIDMap() : next_id_(NUM_OF_PHYSICAL_REG) {}
7023 int GetNormalizedID(int id) {
7024 std::map<int, int>::iterator it = id_map_.find(id);
7025 if (it != id_map_.end()) {return it->second;}
7026 int new_id = next_id_++;
7027 id_map_.insert(std::pair<int, int>(id, new_id));
7028 return new_id;
7029 }
7030 };
7031 RegIDMap reg_id_map[3]; // GP, MMX, XMM/YMM
7032 modified_physical_reg[0] = modified_physical_reg[1] = modified_physical_reg[2] = 0;
7033 need_reg_alloc[0] = need_reg_alloc[1] = need_reg_alloc[2] = false;
7034 bool compile_process = false;
7035
7036 for (Frontend::InstrList::iterator it = instrs.begin(); it != instrs.end(); ++it) {
7037 const InstrID instr_id = it->GetID();
7038 if (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG || instr_id == I_COMPILER_PROLOG || instr_id == I_COMPILER_EPILOG) {
7039 compile_process = true;
7040 }
7041
7042 for (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) {
7043 detail::Opd& opd = it->GetOpd(i);
7044 if (opd.IsReg() && !opd.IsFpuReg()) {
7045 const RegID& reg = opd.GetReg();
7046 const size_t reg_family = GetRegFamily(reg.GetType());
7047 if (reg.IsSymbolic()) {
7048 opd.reg_.id = reg_id_map[reg_family].GetNormalizedID(reg.id);
7049 } else {
7050 if (opd.IsWrite()) {
7051 // This physical register is modified
7052 modified_physical_reg[reg_family] |= (1 << reg.id);
7053 }
7054
7055 if ((opd.reg_assignable_ & (1 << reg.id)) == 0) {
7056 // Specified physical register does not fit the instruction.
7057 // Let's try to assign optimal physical register by register allocation.
7058 need_reg_alloc[reg_family] = true;
7059 }
7060 }
7061 } else if (opd.IsMem()) {
7062 const RegID& base = opd.GetBase();
7063 if (base.IsSymbolic()) {
7064 opd.base_.id = reg_id_map[0].GetNormalizedID(base.id);
7065 }
7066
7067 const RegID& index = opd.GetIndex();
7068 if (index.IsSymbolic()) {
7069 opd.index_.id = reg_id_map[GetRegFamily(index.GetType())].GetNormalizedID(index.id);
7070 }
7071 }
7072 }
7073 }
7074
7075 for (size_t i = 0; i < 3; ++i) {
7076 if (!need_reg_alloc[i] && reg_id_map[i].next_id_ > NUM_OF_PHYSICAL_REG) {
7077 need_reg_alloc[i] = true;
7078 }
7079 }
7080
7081 return compile_process || need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2];
7082 }
7083
7084 /// Check the instruction if it break register dependence
7085 inline bool IsBreakDependenceInstr(const Instr& instr)
7086 {
7087 // Instructions
7088 // SUB, SBB, XOR, PXOR, XORPS, XORPD, PANDN, PSUBxx, PCMPxx
7089 const InstrID id = instr.GetID();
7090 if (id == I_SUB || id == I_SBB || id == I_XOR || id == I_PXOR || id == I_XORPS || id == I_XORPD || id == I_PANDN ||
7091 id == I_PSUBB || id == I_PSUBW || id == I_PSUBD || id == I_PSUBQ || id == I_PSUBSB || id == I_PSUBSW || id == I_PSUBUSB || id == I_PSUBUSW ||
7092 id == I_PCMPEQB || id == I_PCMPEQW || id == I_PCMPEQD || id == I_PCMPEQQ || id == I_PCMPGTB || id == I_PCMPGTW || id == I_PCMPGTD || id == I_PCMPGTQ) {
7093 // source and destination operands are the same register.
7094 // 8bit or 16bit register cannot break dependence.
7095 const detail::Opd& opd0 = instr.GetOpd(0);
7096 const detail::Opd& opd1 = instr.GetOpd(1);
7097 const OpdSize opdsize = opd0.GetSize();
7098 if (opd0 == opd1 && opd0.IsReg() && opdsize != O_SIZE_8 && opdsize != O_SIZE_16) {
7099 return true;
7100 }
7101 }
7102 return false;
7103 }
7104
7105 /// Live Variable Analysis
7106 inline void LiveVariableAnalysis(const Frontend& f, ControlFlowGraph& cfg, VariableManager& var_manager)
7107 {
7108 std::vector<BasicBlock *> update_target;
7109 update_target.reserve(cfg.size());
7110
7111 for (ControlFlowGraph::BlockList::iterator it = cfg.begin(); it != cfg.end(); ++it) {
7112 BasicBlock *block = *it;
7113 // Scanning instructions of basic block and make register lifetime table
7114 for (size_t i = block->instr_begin; i != block->instr_end; ++i) {
7115 const size_t instr_offset = i - block->instr_begin;
7116 const Instr& instr = f.instrs_[i];
7117 if (instr.GetID() == I_COMPILER_DECLARE_REG_ARG) {
7118 // Declare function argument on register
7119 const detail::Opd& opd0 = instr.GetOpd(0);
7120 const RegID& reg = opd0.GetReg();
7121 // Avoid passing operand size 8 or 16 to AddUsePoint
7122 // because they are treated as partial access register and cause miss assignment of register.
7123 OpdSize opd_size = opd0.GetSize();
7124 if (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) {
7125 opd_size = O_SIZE_32;
7126 }
7127 const detail::Opd& opd1 = instr.GetOpd(1);
7128 block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd_size, opd0.reg_assignable_);
7129 if (opd1.IsMem()) {
7130 var_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp()));
7131 }
7132 } else if (instr.GetID() == I_COMPILER_DECLARE_STACK_ARG) {
7133 // Declare function argument on stack
7134 // The register variable starts "spill" state by O_TYPE_MEM of AddUsePoint
7135 const detail::Opd& opd0 = instr.GetOpd(0); // Register variable.
7136 const RegID& reg = opd0.GetReg();
7137 // Avoid passing operand size 8 or 16 to AddUsePoint
7138 // because they are treated as partial access register and cause miss assignment of register.
7139 OpdSize opd_size = opd0.GetSize();
7140 if (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) {
7141 opd_size = O_SIZE_32;
7142 }
7143 const detail::Opd& opd1 = instr.GetOpd(1); // Argument
7144 block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_MEM | O_TYPE_WRITE), opd_size, opd0.reg_assignable_);
7145 var_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp()));
7146 } else if (instr.GetID() == I_COMPILER_DECLARE_RESULT_REG) {
7147 // Declare function result on register
7148 const detail::Opd& opd0 = instr.GetOpd(0);
7149 const RegID& reg = opd0.GetReg();
7150 block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd0.GetSize(), opd0.reg_assignable_);
7151 } else if (IsBreakDependenceInstr(instr)) {
7152 // Add only 1 use point if the instruction that break register dependence
7153 const detail::Opd& opd = instr.GetOpd(0);
7154 const RegID& reg = opd.GetReg();
7155 block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_REG | O_TYPE_WRITE), opd.GetSize(), opd.reg_assignable_);
7156 var_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize());
7157 } else if (instr.GetID() == I_PUSHAD || instr.GetID() == I_POPAD) {
7158 // Add use point of pushad/popad
7159 const OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_PUSHAD ? O_TYPE_READ : O_TYPE_WRITE));
7160 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EAX), type, O_SIZE_32, 0xFFFFFFFF);
7161 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ECX), type, O_SIZE_32, 0xFFFFFFFF);
7162 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDX), type, O_SIZE_32, 0xFFFFFFFF);
7163 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), type, O_SIZE_32, 0xFFFFFFFF);
7164 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), type, O_SIZE_32, 0xFFFFFFFF);
7165 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESI), type, O_SIZE_32, 0xFFFFFFFF);
7166 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDI), type, O_SIZE_32, 0xFFFFFFFF);
7167 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESP), static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ | O_TYPE_WRITE), O_SIZE_32, 0xFFFFFFFF);
7168 } else if (instr.GetID() == I_VZEROALL || instr.GetID() == I_VZEROUPPER) {
7169 // Add use point of vzeroall/vzeroupper
7170 const OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_VZEROALL ? O_TYPE_WRITE : O_TYPE_READ | O_TYPE_WRITE));
7171 for (int j = 0; j < NUM_OF_PHYSICAL_REG; ++j) {
7172 block->GetLifetime(R_TYPE_YMM).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_YMM, static_cast<PhysicalRegID>(YMM0 + j)), type, O_SIZE_256, 0xFFFFFFFF);
7173 }
7174 } else {
7175 // Add each use point of all operands
7176 for (size_t j = 0; j < Instr::MAX_OPERAND_COUNT; ++j) {
7177 const detail::Opd& opd = instr.GetOpd(j);
7178 if (opd.IsGpReg() || opd.IsMmxReg() || opd.IsXmmReg() || opd.IsYmmReg()) {
7179 // Register operand
7180 const RegID& reg = opd.GetReg();
7181 block->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd.GetType(), opd.GetSize(), opd.reg_assignable_);
7182 var_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize());
7183 } else if (opd.IsMem()) {
7184 // Memory operand
7185 const RegID& base = opd.GetBase();
7186 if (!base.IsInvalid()) {
7187 block->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, base, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressBaseSize(), 0xFFFFFFFF);
7188 var_manager.UpdateVarSize(R_TYPE_GP, base.id, opd.GetAddressBaseSize());
7189 }
7190 const RegID& index = opd.GetIndex();
7191 if (!index.IsInvalid()) {
7192 block->GetLifetime(index.GetType()).AddUsePoint(instr_offset, index, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressIndexSize(), 0xFFFFFFFF);
7193 var_manager.UpdateVarSize(index.GetType(), index.id, opd.GetAddressIndexSize());
7194 }
7195 }
7196 }
7197 }
7198 }
7199
7200 // Make GEN and KILL set
7201 for (size_t reg_family = 0; reg_family < 3; ++reg_family) {
7202 Lifetime& lifetime = block->lifetime[reg_family];
7203 const size_t num_of_used_reg = lifetime.use_points.size();
7204 for (size_t i = 0; i < num_of_used_reg; ++i) {
7205 if (!lifetime.use_points[i].empty()) {
7206 OpdType type = lifetime.use_points[i][0].type;
7207 if (type & O_TYPE_READ) {
7208 lifetime.gen.set_bit(i, true); // GEN
7209 } else {
7210 JITASM_ASSERT(type & O_TYPE_WRITE);
7211 lifetime.kill.set_bit(i, true); // KILL
7212 }
7213 }
7214 }
7215 }
7216
7217 update_target.push_back(block);
7218 }
7219
7220 while (!update_target.empty()) {
7221 BasicBlock *block = update_target.back();
7222 update_target.pop_back();
7223 for (size_t reg_family = 0; reg_family < 3; ++reg_family) {
7224 Lifetime& lifetime = block->lifetime[reg_family];
7225 if (lifetime.dirty_live_out) {
7226 // live_out is the union of the live_in of the successors
7227 for (size_t i = 0; i < 2; ++i) {
7228 if (block->successor[i]) {
7229 lifetime.live_out.set_union(block->successor[i]->lifetime[reg_family].live_in);
7230 }
7231 }
7232 lifetime.dirty_live_out = false;
7233
7234 // live_in = gen OR (live_out - kill)
7235 BitVector new_live_in = lifetime.live_out;
7236 new_live_in.set_subtract(lifetime.kill);
7237 new_live_in.set_union(lifetime.gen);
7238
7239 if (!lifetime.live_in.is_equal(new_live_in)) {
7240 lifetime.live_in.swap(new_live_in);
7241
7242 for (size_t i = 0; i < block->predecessor.size(); ++i) {
7243 block->predecessor[i]->lifetime[reg_family].dirty_live_out = true;
7244 update_target.push_back(block->predecessor[i]);
7245 }
7246 }
7247 }
7248 }
7249 }
7250 }
7251
7252 /// Linear scan register allocation
7253 /**
7254 * \param[in,out] cfg Control flow graph and additional information
7255 * \param[in] reg_family Register family
7256 * \param[in] available_reg Available physical register mask
7257 * \param[out] var_attrs Variable attributes
7258 * \return Used physical register mask
7259 */
7260 inline uint32 LinearScanRegisterAlloc(ControlFlowGraph& cfg, size_t reg_family, uint32 available_reg, std::vector<VarAttribute>& var_attrs)
7261 {
7262 const uint32 available_reg_count = detail::Count1Bits(available_reg);
7263
7264 std::vector<int> total_spill_cost;
7265 for (ControlFlowGraph::BlockList::iterator block = cfg.begin(); block != cfg.end(); ++block) {
7266 (*block)->lifetime[reg_family].BuildIntervals();
7267 (*block)->lifetime[reg_family].GetSpillCost((*block)->GetFrequency(), total_spill_cost);
7268 }
7269
7270 uint32 used_reg = 0;
7271 const Lifetime::Interval *last_interval = NULL;
7272 size_t last_loop_depth = 0;
7273 for (ControlFlowGraph::BlockList::iterator block = cfg.dfs_begin(); block != cfg.dfs_end(); ++block) {
7274 Lifetime& lifetime = (*block)->lifetime[reg_family];
7275 const size_t loop_depth = (*block)->loop_depth;
7276
7277 // Spill identification
7278 lifetime.SpillIdentification(available_reg_count, total_spill_cost, (*block)->GetFrequency(), last_loop_depth == loop_depth ? last_interval : NULL, var_attrs);
7279
7280 // Register assignment
7281 used_reg |= lifetime.AssignRegister(available_reg, last_interval);
7282
7283 #ifdef JITASM_DEBUG_DUMP
7284 lifetime.DumpIntervals((*block)->depth, true);
7285 #endif
7286 if (!lifetime.intervals.empty()) {
7287 last_interval = &lifetime.intervals.back();
7288 last_loop_depth = loop_depth;
7289 }
7290 }
7291
7292 return used_reg;
7293 }
7294
7295 /// General purpose register operator
7296 struct GpRegOperator
7297 {
7298 Frontend *f_;
7299 const VariableManager *var_manager_;
7300
7301 GpRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}
7302
7303 void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/)
7304 {
7305 f_->mov(Reg(dst_reg), Reg(src_reg));
7306 }
7307
7308 void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/)
7309 {
7310 f_->xchg(Reg(reg1), Reg(reg2));
7311 }
7312
7313 void Load(PhysicalRegID dst_reg, int var)
7314 {
7315 f_->mov(Reg(dst_reg), f_->ptr[var_manager_->GetSpillSlot(0, var)]);
7316 }
7317
7318 void Store(int var, PhysicalRegID src_reg)
7319 {
7320 f_->mov(f_->ptr[var_manager_->GetSpillSlot(0, var)], Reg(src_reg));
7321 }
7322 };
7323
7324 /// MMX register operator
7325 struct MmxRegOperator
7326 {
7327 Frontend *f_;
7328 const VariableManager *var_manager_;
7329
7330 MmxRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}
7331
7332 void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/)
7333 {
7334 f_->movq(MmxReg(dst_reg), MmxReg(src_reg));
7335 }
7336
7337 void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/)
7338 {
7339 f_->pxor(MmxReg(reg1), MmxReg(reg2));
7340 f_->pxor(MmxReg(reg2), MmxReg(reg1));
7341 f_->pxor(MmxReg(reg1), MmxReg(reg2));
7342 }
7343
7344 void Load(PhysicalRegID dst_reg, int var)
7345 {
7346 f_->movq(MmxReg(dst_reg), f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)]);
7347 }
7348
7349 void Store(int var, PhysicalRegID src_reg)
7350 {
7351 f_->movq(f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)], MmxReg(src_reg));
7352 }
7353 };
7354
7355 /// XMM/YMM register operator
7356 struct XmmRegOperator
7357 {
7358 Frontend *f_;
7359 const VariableManager *var_manager_;
7360
7361 XmmRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}
7362
7363 void Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize size)
7364 {
7365 if (size == O_SIZE_128) {
7366 if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty
7367 f_->vmovaps(XmmReg(dst_reg), XmmReg(src_reg));
7368 else
7369 f_->movaps(XmmReg(dst_reg), XmmReg(src_reg));
7370 } else if (size == O_SIZE_256) {
7371 f_->vmovaps(YmmReg(dst_reg), YmmReg(src_reg));
7372 } else {
7373 JITASM_ASSERT(0);
7374 }
7375 }
7376
7377 void Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize size)
7378 {
7379 if (size == O_SIZE_128) {
7380 if (f_->avx_epilog_) { // PF AVS+ anti AVX-SSE2 penalty
7381 f_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2));
7382 f_->vxorps(XmmReg(reg2), XmmReg(reg2), XmmReg(reg1));
7383 f_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2));
7384 } else {
7385 f_->xorps(XmmReg(reg1), XmmReg(reg2));
7386 f_->xorps(XmmReg(reg2), XmmReg(reg1));
7387 f_->xorps(XmmReg(reg1), XmmReg(reg2));
7388 }
7389 } else if (size == O_SIZE_256) {
7390 f_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2));
7391 f_->vxorps(YmmReg(reg2), YmmReg(reg1), YmmReg(reg2));
7392 f_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2));
7393 } else {
7394 JITASM_ASSERT(0);
7395 }
7396 }
7397
7398 void Load(PhysicalRegID dst_reg, int var)
7399 {
7400 const OpdSize size = var_manager_->GetVarSize(2, var);
7401 if (size == O_SIZE_128) {
7402 if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty
7403 f_->vmovaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]);
7404 else
7405 f_->movaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]);
7406 } else if (size == O_SIZE_256) {
7407 f_->vmovaps(YmmReg(dst_reg), f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)]);
7408 } else {
7409 JITASM_ASSERT(0);
7410 }
7411 }
7412
7413 void Store(int var, PhysicalRegID src_reg)
7414 {
7415 const OpdSize size = var_manager_->GetVarSize(2, var);
7416 if (size == O_SIZE_128) {
7417 if (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty
7418 f_->vmovaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg));
7419 else
7420 f_->movaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg));
7421 } else if (size == O_SIZE_256) {
7422 f_->vmovaps(f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)], YmmReg(src_reg));
7423 } else {
7424 JITASM_ASSERT(0);
7425 }
7426 }
7427 };
7428
7429 /// Strongly connected components finder
7430 /**
7431 * Tarjan's algorithm
7432 */
7433 class SCCFinder {
7434 private:
7435 struct Node {
7436 int index;
7437 int lowlink;
7438 Node() : index(-1) {}
7439 };
7440 Node nodes_[NUM_OF_PHYSICAL_REG];
7441 int *successors_;
7442 int index;
7443 FixedArray<int, NUM_OF_PHYSICAL_REG> scc_;
7444
7445 /// Is v in scc_?
7446 bool IsInsideSCC(int v) const
7447 {
7448 for (size_t i = 0; i < scc_.size(); ++i) {
7449 if (scc_[i] == v) {return true;}
7450 }
7451 return false;
7452 }
7453
7454 template<class Fn> void Find(int v, Fn& fn)
7455 {
7456 nodes_[v].index = index;
7457 nodes_[v].lowlink = index;
7458 ++index;
7459 scc_.push_back(v);
7460 const int w = successors_[v];
7461 if (w != -1) {
7462 if (nodes_[w].index == -1) {
7463 // successor w has not been visited yet
7464 Find(w, fn);
7465 if (nodes_[w].lowlink < nodes_[v].lowlink) {
7466 nodes_[v].lowlink = nodes_[w].lowlink;
7467 }
7468 } else if (IsInsideSCC(w)) {
7469 // successor w is in scc_
7470 if (nodes_[w].index < nodes_[v].lowlink) {
7471 nodes_[v].lowlink = nodes_[w].index;
7472 }
7473 }
7474 }
7475 if (nodes_[v].lowlink == nodes_[v].index && !scc_.empty()) {
7476 // v is the root of scc_
7477 size_t i = 0;
7478 while (scc_[i] != v) {++i;}
7479 fn(&scc_[i], scc_.size() - i);
7480 while (i < scc_.size()) {scc_.pop_back();}
7481 }
7482 }
7483
7484 public:
7485 SCCFinder(int *successors) : successors_(successors), index(0) {}
7486
7487 template<class Fn> void operator()(Fn fn)
7488 {
7489 for (int v = 0; v < NUM_OF_PHYSICAL_REG; ++v) {
7490 if (successors_[v] != -1 && nodes_[v].index == -1) {
7491 Find(v, fn);
7492 }
7493 }
7494 }
7495 };
7496
7497 struct Operations {
7498 int move[NUM_OF_PHYSICAL_REG];
7499 int load[NUM_OF_PHYSICAL_REG];
7500 int store[NUM_OF_PHYSICAL_REG];
7501 OpdSize size[NUM_OF_PHYSICAL_REG];
7502 std::pair<const Lifetime::Interval *, const Lifetime::Interval *> interval;
7503 const std::vector<VarAttribute> *var_attrs;
7504
7505 Operations(const Lifetime::Interval *first, const Lifetime::Interval *second, const std::vector<VarAttribute> *vattrs) : interval(first, second), var_attrs(vattrs) {
7506 for (size_t i = 0; i < NUM_OF_PHYSICAL_REG; ++i) {move[i] = load[i] = store[i] = -1;}
7507 }
7508
7509 void operator()(size_t var) {
7510 if (interval.second->liveness.get_bit(var)) {
7511 const bool first_spill = interval.first->spill.get_bit(var);
7512 const bool second_spill = interval.second->spill.get_bit(var);
7513 if (!first_spill) {
7514 const int first_reg = interval.first->assignment_table[var];
7515 if (!second_spill) {
7516 // register -> register
7517 move[first_reg] = interval.second->assignment_table[var];
7518 size[first_reg] = static_cast<OpdSize>(var_attrs->at(var).size);
7519 } else {
7520 // register -> stack
7521 store[first_reg] = static_cast<int>(var);
7522 }
7523 } else {
7524 if (!second_spill) {
7525 // stack -> register
7526 load[interval.second->assignment_table[var]] = static_cast<int>(var);
7527 } else {
7528 // stack -> stack
7529 // do nothing
7530 }
7531 }
7532 }
7533 }
7534 };
7535
7536
7537 template<class RegOp>
7538 struct MoveGenerator {
7539 int *moves_;
7540 OpdSize *sizes_;
7541 RegOp *reg_operator_;
7542 MoveGenerator(int *moves, OpdSize *sizes, RegOp *reg_operator) : moves_(moves), sizes_(sizes), reg_operator_(reg_operator) {}
7543 void operator()(const int *scc, size_t count) {
7544 if (count > 1) {
7545 std::vector<std::pair<int, int>> real_moves; // PF 20171210 track real register usage
7546 for (size_t i = 0; i < count - 1; ++i) {
7547 const int r = scc[i];
7548 JITASM_ASSERT(r != moves_[r] && moves_[r] != -1); // sanity check: cannot move to itself, cannot move to undefined
7549 /*
7550 PF 20171210 track real register usage
7551 Old: reg_operator_->Swap(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]);
7552 results in wrong code for multiple xchg: does not take into account previous exchanges
7553 xchg edi, ecx
7554 xchg esi, edi
7555 xchg edx, esi
7556 new code:
7557 xchg edi,ecx (-> edi = _ecx, ecx = _edi)
7558 xchg esi,ecx (-> esi = ecx (esi = _edi), ecx = _esi)
7559 xchg edx,ecx (-> edx = ecx (edx = _esi), ecx = _edx)
7560 */
7561
7562 // When swapping registers, all register exchanges which took role in swap should be renamed
7563 int _this1 = moves_[r];
7564 int _this2 = r;
7565 for (size_t j = 0; j < real_moves.size(); j++) {
7566 int _test_this1 = real_moves[j].first;
7567 int _test_this2 = real_moves[j].second;
7568 if (_this1 == _test_this1)
7569 _this1 = _test_this2;
7570 else if (_this1 == _test_this2)
7571 _this1 = _test_this1;
7572 if (_this2 == _test_this1)
7573 _this2 = _test_this2;
7574 else if (_this2 == _test_this2)
7575 _this2 = _test_this1;
7576 }
7577 real_moves.push_back(std::make_pair(_this1, _this2));
7578 reg_operator_->Swap(static_cast<PhysicalRegID>(_this1), static_cast<PhysicalRegID>(_this2), sizes_[_this2]);
7579
7580 JITASM_TRACE("Swap%d %d <-> %d\n", sizes_[r], moves_[r], r);
7581 }
7582 } else if (moves_[scc[0]] != scc[0] && moves_[scc[0]] != -1) {
7583 const int r = scc[0];
7584 reg_operator_->Move(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]);
7585 JITASM_TRACE("Move%d %d -> %d\n", sizes_[r], r, moves_[r]);
7586 }
7587 }
7588 };
7589
7590 /// Generate inter-interval instructions
7591 /**
7592 * - Move register
7593 * - Load from stack slot
7594 * - Store to stack slot
7595 */
7596 template<class RegOp>
7597 inline void GenerateInterIntervalInstr(const Lifetime::Interval& first_interval, const Lifetime::Interval& second_interval, const std::vector<VarAttribute>& var_attrs, RegOp reg_operator)
7598 {
7599 #ifdef JITASM_DEBUG_DUMP
7600 first_interval.Dump(true);
7601 #endif
7602
7603 Operations ops(&first_interval, &second_interval, &var_attrs);
7604 first_interval.liveness.query_bit_indexes(ops);
7605
7606 // Store instructions
7607 for (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) {
7608 if (ops.store[r] != -1) {
7609 reg_operator.Store(ops.store[r], static_cast<PhysicalRegID>(r));
7610 JITASM_TRACE("Store %d (physical reg %d)\n", ops.store[r], r);
7611 }
7612 }
7613
7614 // Move instructions
7615 SCCFinder scc_finder(ops.move);
7616 scc_finder(MoveGenerator<RegOp>(ops.move, ops.size, &reg_operator));
7617
7618 // Load instructions
7619 for (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) {
7620 if (ops.load[r] != -1) {
7621 reg_operator.Load(static_cast<PhysicalRegID>(r), ops.load[r]);
7622 JITASM_TRACE("Load %d (physical reg %d)\n", ops.load[r], r);
7623 }
7624 }
7625
7626 #ifdef JITASM_DEBUG_DUMP
7627 second_interval.Dump(true);
7628 #endif
7629 }
7630
7631 /// Generate inter-block instructions
7632 inline void GenerateInterBlockInstr(const BasicBlock *first_block, const BasicBlock *second_block, Frontend& f, const VariableManager& var_manager)
7633 {
7634 if (!first_block->lifetime[0].intervals.empty() && !second_block->lifetime[0].intervals.empty()) {
7635 JITASM_TRACE("---- General purpose register ----\n");
7636 GenerateInterIntervalInstr(first_block->lifetime[0].intervals.back(), second_block->lifetime[0].intervals.front(), var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager));
7637 }
7638 if (!first_block->lifetime[1].intervals.empty() && !second_block->lifetime[1].intervals.empty()) {
7639 JITASM_TRACE("---- MMX register ----\n");
7640 GenerateInterIntervalInstr(first_block->lifetime[1].intervals.back(), second_block->lifetime[1].intervals.front(), var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager));
7641 }
7642 if (!first_block->lifetime[2].intervals.empty() && !second_block->lifetime[2].intervals.empty()) {
7643 JITASM_TRACE("---- XMM/YMM register ----\n");
7644 GenerateInterIntervalInstr(first_block->lifetime[2].intervals.back(), second_block->lifetime[2].intervals.front(), var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager));
7645 }
7646 }
7647
7648 /// Generate prolog instructions
7649 inline void GenerateProlog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)
7650 {
7651 avoid_unused_warn(preserved_reg_stack);
7652
7653 // Save & Make frame pointer
7654 f.push(f.zbp);
7655 f.mov(f.zbp, f.zsp);
7656
7657 size_t stack_size = f.stack_manager_.GetSize();
7658
7659 // Save general-purpose registers
7660 size_t num_of_preserved_gp_reg = 0;
7661 for (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ++num_of_preserved_gp_reg) {
7662 uint32 reg_id = detail::bit_scan_forward(reg_mask);
7663 f.push(Reg(static_cast<PhysicalRegID>(reg_id)));
7664 reg_mask &= ~(1 << reg_id);
7665 }
7666
7667 #ifdef JITASM64
7668 // rsp is 16 bytes aligned in Windows x64
7669
7670 // Stack base
7671 if (stack_size > 0) {
7672 // do the same stack_size adjust in epilog
7673 if (f.avx_epilog_) {
7674 // general purpose registers are saved already, num_of_preserved_gp_reg*8 bytes
7675 // number of general purpose registers:
7676 // even -> rsp 16 byte aligned
7677 // odd -> rsp 8 byte aligned
7678 f.mov(f.rbx, f.rsp);
7679 // Now rbx becomes the pointer for saving spilled XMM6-15 (x64-compulsory) and
7680 // temporary storage for the local variables (reg, xmm, ymm)
7681 // Because we use vmovaps (aligned store/load) for ymm, 32 byte alignment needed for base
7682 // like and rbx, -32; ffffffffffffffe0H (r64 with imm32: sign extended)
7683 f.and_(f.rbx, -32); // align 32 bytes
7684
7685 // padding for keep alignment (16 bytes for rsp)
7686 if (num_of_preserved_gp_reg & 1)
7687 stack_size += 16+8; // 8 or 24. Worst case.
7688 else
7689 stack_size += 16; // 0 or 16 Worst case.
7690 } else if (num_of_preserved_gp_reg & 1) {
7691 // Copy with alignment
7692 f.lea(f.rbx, f.ptr[f.rsp - 8]);
7693 stack_size += 8; // padding for keep alignment
7694 } else {
7695 f.mov(f.rbx, f.rsp);
7696 }
7697 }
7698 #else
7699 if (stack_size > 0) {
7700 // Align stack pointer
7701 if (f.avx_epilog_)
7702 f.and_(f.esp, 0xFFFFFFE0); // 32 byte alignment for aligned local ymm spill register storage
7703 else
7704 f.and_(f.esp, 0xFFFFFFF0); // 16 byte alignment
7705 // in x86 we don't adjust stack_size here, esp is restored by ebp
7706 // Stack base
7707 f.mov(f.ebx, f.esp);
7708 }
7709 #endif
7710
7711 // Move stack pointer
7712 if (stack_size > 0) {
7713 f.sub(f.zsp, static_cast<uint32>(stack_size));
7714 }
7715
7716 #ifdef JITASM64
7717 // Save xmm registers
7718 uint32 xmm_reg_mask = preserved_reg[2];
7719 for (size_t i = 0; xmm_reg_mask != 0; ++i) {
7720 uint32 reg_id = detail::bit_scan_forward(xmm_reg_mask);
7721 if (f.avx_epilog_) // PF AVS+ anti AVX->SSE2 penalty
7722 f.vmovaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id)));
7723 else
7724 f.movaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id)));
7725 xmm_reg_mask &= ~(1 << reg_id);
7726 }
7727 #endif
7728 }
7729
7730 /// Generate epilog instructions
7731 inline void GenerateEpilog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)
7732 {
7733 avoid_unused_warn(preserved_reg_stack);
7734
7735 size_t stack_size = f.stack_manager_.GetSize();
7736 const size_t num_of_preserved_gp_reg = detail::Count1Bits(preserved_reg[0]);
7737
7738 #ifdef JITASM64
7739 // Restore xmm registers
7740 // Push the register id and index by saved order
7741 FixedArray<uint32, 16> regs;
7742 for (uint32 reg_mask = preserved_reg[2]; reg_mask != 0; ) {
7743 uint32 reg_id = detail::bit_scan_forward(reg_mask);
7744 regs.push_back(reg_id);
7745 reg_mask &= ~(1 << reg_id);
7746 }
7747
7748 // Insert restore instruction by inverse order
7749 while (!regs.empty()) {
7750 // PF AVS+: generate vmovaps to avoid AVX->SSE2 penalty
7751 if (f.avx_epilog_)
7752 f.vmovaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]);
7753 else
7754 f.movaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]);
7755 regs.pop_back();
7756 }
7757
7758 // Move stack pointer
7759 if (stack_size > 0) {
7760 // same calculation like in prolog
7761 if (f.avx_epilog_) {
7762 if (num_of_preserved_gp_reg & 1)
7763 stack_size += 16 + 8; // 8 or 24. Worst case.
7764 else
7765 stack_size += 16; // 0 or 16 Worst case.
7766 } else if (num_of_preserved_gp_reg & 1) {
7767 stack_size += 8; // padding for keep alignment
7768 }
7769 f.add(f.zsp, static_cast<uint32>(stack_size));
7770 }
7771 #else
7772 // Move stack pointer
7773 if (stack_size > 0) {
7774 f.lea(f.zsp, f.ptr[f.zbp - num_of_preserved_gp_reg * 4]);
7775 }
7776 #endif
7777
7778 // Restore general-purpose registers
7779 for (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ) {
7780 uint32 reg_id = detail::bit_scan_reverse(reg_mask);
7781 f.pop(Reg(static_cast<PhysicalRegID>(reg_id)));
7782 reg_mask &= ~(1 << reg_id);
7783 }
7784
7785 // Restore frame pointer
7786 f.pop(f.zbp);
7787 // PF AVS+: avoid AVX->SSE2 penalty
7788 if(f.avx_epilog_)
7789 f.vzeroupper();
7790 f.ret();
7791 }
7792
7793 struct OrderedLabel {
7794 size_t id;
7795 size_t instr_idx;
7796 OrderedLabel(size_t id_, size_t instr_idx_) : id(id_), instr_idx(instr_idx_) {}
7797 bool operator<(const OrderedLabel& rhs) const {return instr_idx < rhs.instr_idx;}
7798 };
7799
7800 /// Rewrite instructions
7801 /**
7802 * - Replace symbolic register to physical register
7803 * - Generate instructions for register move and spill
7804 * - Generate function prolog and epilog
7805 */
7806 inline void RewriteInstructions(Frontend& f, const ControlFlowGraph& cfg, const VariableManager& var_manager, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)
7807 {
7808 // Prepare instruction number ordered labels for adjusting label position
7809 std::vector<OrderedLabel> orderd_labels; // instruction number order
7810 orderd_labels.reserve(f.labels_.size());
7811 for (size_t i = 0; i < f.labels_.size(); ++i) {
7812 orderd_labels.push_back(OrderedLabel(i, f.labels_[i].instr_number));
7813 }
7814 std::sort(orderd_labels.begin(), orderd_labels.end());
7815 std::vector<OrderedLabel>::iterator cur_label = orderd_labels.begin();
7816
7817 // Move original instruction list
7818 // Now the instruction list in Frontend is empty!
7819 Frontend::InstrList org_instrs;
7820 org_instrs.swap(f.instrs_);
7821 f.instrs_.reserve(org_instrs.size());
7822
7823 for (ControlFlowGraph::BlockList::const_iterator it = cfg.begin(); it != cfg.end(); ++it) {
7824 const BasicBlock *block = *it;
7825 JITASM_TRACE("\n==== Block%d ====\n", block->depth);
7826 if (block->depth == (size_t)-1) {
7827 // Eliminate unreachable code block
7828 JITASM_TRACE("Unreachable block!\n");
7829
7830 // Invalidate labels in this block
7831 while (cur_label != orderd_labels.end() && cur_label->instr_idx < block->instr_end) {
7832 f.labels_[cur_label->id].instr_number = (size_t)-1;
7833 ++cur_label;
7834 }
7835
7836 continue;
7837 }
7838
7839 // Initialize interval_range
7840 detail::ConstRange< std::vector<Lifetime::Interval> > interval_range[3];
7841 for (size_t reg_family = 0; reg_family < 3; ++reg_family) {
7842 interval_range[reg_family].first = block->lifetime[reg_family].intervals.begin();
7843 interval_range[reg_family].second = block->lifetime[reg_family].intervals.end();
7844 }
7845
7846 const size_t instr_size = block->instr_end - block->instr_begin;
7847 for (size_t instr_offset = 0; instr_offset < instr_size; ++instr_offset) {
7848 const size_t org_instr_index = block->instr_begin + instr_offset;
7849
7850 // Step each intervals and insert inter-interval instructions
7851 if (interval_range[0].size() > 1 && detail::next(interval_range[0].first)->instr_idx_offset == instr_offset) {
7852 JITASM_TRACE("---- General purpose register ----\n");
7853 const Lifetime::Interval& first_interval = *interval_range[0].first;
7854 GenerateInterIntervalInstr(first_interval, *++interval_range[0].first, var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager));
7855 }
7856 if (interval_range[1].size() > 1 && detail::next(interval_range[1].first)->instr_idx_offset == instr_offset) {
7857 JITASM_TRACE("---- MMX register ----\n");
7858 const Lifetime::Interval& first_interval = *interval_range[1].first;
7859 GenerateInterIntervalInstr(first_interval, *++interval_range[1].first, var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager));
7860 }
7861 if (interval_range[2].size() > 1 && detail::next(interval_range[2].first)->instr_idx_offset == instr_offset) {
7862 JITASM_TRACE("---- XMM/YMM register ----\n");
7863 const Lifetime::Interval& first_interval = *interval_range[2].first;
7864 GenerateInterIntervalInstr(first_interval, *++interval_range[2].first, var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager));
7865 }
7866
7867 const size_t cur_instr_index = f.instrs_.size();
7868 const InstrID instr_id = org_instrs[org_instr_index].GetID();
7869 if (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG) {
7870 // No actual machine code
7871 } else if (instr_id == I_COMPILER_PROLOG) {
7872 // Generate function prolog
7873 GenerateProlog(f, preserved_reg, preserved_reg_stack);
7874 } else if (instr_id == I_COMPILER_EPILOG) {
7875 // Generate function epilog
7876 GenerateEpilog(f, preserved_reg, preserved_reg_stack);
7877 } else {
7878 // Copy instruction
7879 f.instrs_.push_back(org_instrs[org_instr_index]);
7880 Instr &instr = f.instrs_.back();
7881
7882 // Replace symbolic register to physical register
7883 for (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) {
7884 detail::Opd& opd = instr.GetOpd(i);
7885 if (opd.IsReg()) {
7886 if (opd.reg_.IsSymbolic()) {
7887 opd.reg_.type = static_cast<RegType>(opd.reg_.type - R_TYPE_SYMBOLIC_GP);
7888 opd.reg_.id = interval_range[GetRegFamily(opd.reg_.GetType())].first->assignment_table[opd.reg_.id];
7889 }
7890 } else if (opd.IsMem()) {
7891 if (opd.base_.IsSymbolic()) {
7892 opd.base_.type = R_TYPE_GP;
7893 opd.base_.id = interval_range[0].first->assignment_table[opd.base_.id];
7894 }
7895 if (opd.index_.IsSymbolic()) {
7896 if (opd.index_.type == R_TYPE_SYMBOLIC_GP) opd.index_.type = R_TYPE_GP;
7897 else if (opd.index_.type == R_TYPE_SYMBOLIC_XMM) opd.index_.type = R_TYPE_XMM;
7898 else { JITASM_ASSERT(opd.index_.type == R_TYPE_SYMBOLIC_YMM); opd.index_.type = R_TYPE_YMM; }
7899 opd.index_.id = interval_range[GetRegFamily(opd.index_.GetType())].first->assignment_table[opd.index_.id];
7900 }
7901 }
7902 }
7903 }
7904
7905 // Adjust label position
7906 while (cur_label != orderd_labels.end() && cur_label->instr_idx == org_instr_index) {
7907 f.labels_[cur_label->id].instr_number += cur_instr_index - org_instr_index;
7908 ++cur_label;
7909 }
7910 }
7911
7912 // Generate inter-block instructions
7913 JITASM_ASSERT(!(!block->successor[0] && block->successor[1]));
7914 if (block->successor[0] && !block->successor[1]) {
7915 // 1 successor
7916
7917 // Remove last instruction if it is jump
7918 Instr jump_instr(I_NOP, 0, 0);
7919 if (Frontend::IsJump(f.instrs_.back().GetID())) {
7920 jump_instr = f.instrs_.back();
7921 f.instrs_.pop_back();
7922 }
7923
7924 JITASM_TRACE("==== Edge to Block%d\n", block->successor[0]->depth);
7925 GenerateInterBlockInstr(block, block->successor[0], f, var_manager);
7926
7927 // Add last instruction if it is jump
7928 if (Frontend::IsJump(jump_instr.GetID())) {
7929 f.instrs_.push_back(jump_instr);
7930 }
7931 } else if (block->successor[0] && block->successor[1]) {
7932 // 2 successors
7933 JITASM_ASSERT(Frontend::IsJump(f.instrs_.back().GetID()) && f.instrs_.back().GetOpd(0).IsImm()); // the last instruction must be jump
7934 const size_t jump_instr_idx = f.instrs_.size() - 1;
7935 const size_t label_successor1 = static_cast<size_t>(f.instrs_.back().GetOpd(0).GetImm());
7936
7937 // Generate inter-block instructions between current block and successor 1 separately
7938 Frontend::InstrList temp_instrs;
7939 temp_instrs.swap(f.instrs_);
7940 JITASM_TRACE("==== Edge to Block%d\n", block->successor[1]->depth);
7941 GenerateInterBlockInstr(block, block->successor[1], f, var_manager);
7942 temp_instrs.swap(f.instrs_);
7943
7944 // Insert inter-block instructions between current block and successor 0
7945 JITASM_TRACE("==== Edge to Block%d\n", block->successor[0]->depth);
7946 GenerateInterBlockInstr(block, block->successor[0], f, var_manager);
7947
7948 if (!temp_instrs.empty()) {
7949 // Insert inter-block instructions between current block and successor 1 and change jump flow
7950
7951 // Jump to successor0
7952 const size_t label_successor0 = f.NewLabelID("");
7953 f.AppendJmp(label_successor0);
7954
7955 // Change conditional jump to successor1_edge instead of successor1
7956 const size_t label_successor1_edge = f.NewLabelID("");
7957 f.L(label_successor1_edge);
7958 Frontend::ChangeLabelID(f.instrs_[jump_instr_idx], label_successor1_edge);
7959
7960 // Insert instructions
7961 f.instrs_.insert(f.instrs_.end(), temp_instrs.begin(), temp_instrs.end());
7962 f.AppendJmp(label_successor1);
7963
7964 // Label of successor0 block
7965 f.L(label_successor0);
7966 }
7967 }
7968 }
7969 }
7970
7971 /// Compile
7972 inline void Compile(Frontend& f)
7973 {
7974 #ifdef JITASM64
7975 // Available registers : rax, rcx, rdx, rsi, rdi, r8 ~ r15, mm0 ~ mm7, xmm0/ymm0 ~ xmm15/ymm15
7976 const uint32 available_reg[3] = {0xFFC7, 0xFF, 0xFFFF};
7977
7978 #ifdef JITASM_WIN
7979 // Win64 preserved registers : rbx, rsi, rdi, r12 ~ r15, xmm6 ~ xmm15
7980 uint32 preserved_reg[3] = {(1<<RBX)|(1<<RSI)|(1<<RDI)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0};
7981 #else
7982 // x64 Linux preserved registers : rbx, r12 ~ r15, xmm6 ~ xmm15
7983 uint32 preserved_reg[3] = {(1<<RBX)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0};
7984 #endif
7985 #else
7986 // Available registers : eax, ecx, edx, esi, edi, mm0 ~ mm7, xmm0/ymm0 ~ xmm7/ymm7
7987 const uint32 available_reg[3] = {(1<<EAX)|(1<<ECX)|(1<<EDX)|(1<<ESI)|(1<<EDI), 0xFF, 0xFF};
7988
7989 // Preserved registers : ebx, esi, edi
7990 uint32 preserved_reg[3] = {(1<<EBX)|(1<<ESI)|(1<<EDI), 0, 0};
7991 #endif
7992
7993 uint32 used_physical_reg[3];
7994 bool need_reg_alloc[3];
7995 if (!PrepareCompile(f.instrs_, used_physical_reg, need_reg_alloc)) {
7996 // No compile process
7997 return;
7998 }
7999
8000 VariableManager var_manager;
8001 ControlFlowGraph cfg;
8002
8003 if (need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2]) {
8004 // Register allocation process
8005
8006 // Build CFG including loop detection
8007 cfg.Build(f);
8008
8009 // Live variable analysis
8010 LiveVariableAnalysis(f, cfg, var_manager);
8011
8012 // Linear scan register allocation
8013 for (size_t reg_family = 0; reg_family < 3; ++reg_family) {
8014 if (need_reg_alloc[reg_family]) {
8015 used_physical_reg[reg_family] = LinearScanRegisterAlloc(cfg, reg_family, available_reg[reg_family], var_manager.GetAttributes(reg_family));
8016 }
8017 }
8018 } else {
8019 // No register allocation
8020 // Build dummy CFG
8021 cfg.BuildDummy(f);
8022 }
8023
8024 #ifdef JITASM_DEBUG_DUMP
8025 cfg.DumpDot();
8026 #endif
8027
8028 // Identify saving registers
8029 preserved_reg[0] &= used_physical_reg[0];
8030 preserved_reg[1] &= used_physical_reg[1];
8031 preserved_reg[2] &= used_physical_reg[2];
8032
8033 // Reserve stack for saving xmm register
8034 Addr preserved_reg_stack(RegID::Invalid(), 0);
8035 if (preserved_reg[2] != 0) {
8036 // For saving xmm registers
8037 preserved_reg_stack = f.stack_manager_.Alloc(detail::Count1Bits(preserved_reg[2]) * 16, 16);
8038 }
8039
8040 // Allocate stack for spill variable
8041 var_manager.AllocSpillSlots(f.stack_manager_);
8042
8043 // ebx(rbx) does not include in used_physical_reg
8044 // because ebx(rbx) is going to be modified in prolog.
8045 if (f.stack_manager_.GetSize() > 0) {
8046 preserved_reg[0] |= (1 << EBX);
8047 }
8048
8049 RewriteInstructions(f, cfg, var_manager, preserved_reg, preserved_reg_stack);
8050 }
8051
8052 } // namespace compiler
8053
8054 namespace detail
8055 {
8056 struct CondExpr {
8057 virtual void operator()(Frontend& f, size_t beg, size_t end) const = 0;
8058 virtual ~CondExpr() {}
8059 };
8060
8061 // &&
8062 struct CondExpr_ExprAnd : CondExpr {
8063 const CondExpr& lhs_;
8064 const CondExpr& rhs_;
8065 CondExpr_ExprAnd(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {}
8066 void operator()(Frontend& f, size_t beg, size_t end) const {
8067 size_t label = f.NewLabelID("");
8068 lhs_(f, label, end);
8069 f.L(label);
8070 rhs_(f, beg, end);
8071 }
8072 CondExpr_ExprAnd& operator=(const CondExpr_ExprAnd&);
8073 };
8074
8075 // ||
8076 struct CondExpr_ExprOr : CondExpr {
8077 const CondExpr& lhs_;
8078 const CondExpr& rhs_;
8079 CondExpr_ExprOr(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {}
8080 void operator()(Frontend& f, size_t beg, size_t end) const {
8081 size_t label = f.NewLabelID("");
8082 lhs_(f, beg, label);
8083 f.L(label);
8084 rhs_(f, beg, end);
8085 }
8086 CondExpr_ExprOr& operator=(const CondExpr_ExprOr&);
8087 };
8088
8089 // cmp
8090 template<class L, class R, JumpCondition Jcc>
8091 struct CondExpr_Cmp : CondExpr {
8092 L lhs_;
8093 R rhs_;
8094 CondExpr_Cmp(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {}
8095 void operator()(Frontend& f, size_t beg, size_t end) const {
8096 f.cmp(lhs_, rhs_);
8097 f.AppendJcc(Jcc, beg);
8098 f.AppendJmp(end);
8099 }
8100 };
8101
8102 // or
8103 template<class L, class R, JumpCondition Jcc>
8104 struct CondExpr_Or : CondExpr {
8105 L lhs_;
8106 R rhs_;
8107 CondExpr_Or(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {}
8108 void operator()(Frontend& f, size_t beg, size_t end) const {
8109 f.or_(lhs_, rhs_);
8110 f.AppendJcc(Jcc, beg);
8111 f.AppendJmp(end);
8112 }
8113 };
8114 }
8115
8116 // &&
8117 inline detail::CondExpr_ExprAnd operator&&(const detail::CondExpr& lhs, const detail::CondExpr& rhs) {return detail::CondExpr_ExprAnd(lhs, rhs);}
8118 // ||
8119 inline detail::CondExpr_ExprOr operator||(const detail::CondExpr& lhs, const detail::CondExpr& rhs) {return detail::CondExpr_ExprOr(lhs, rhs);}
8120
8121 // !
8122 inline detail::CondExpr_Or<Reg8, Reg8, JCC_E> operator!(const Reg8& lhs) {return detail::CondExpr_Or<Reg8, Reg8, JCC_E>(lhs, lhs);}
8123 inline detail::CondExpr_Or<Reg16, Reg16, JCC_E> operator!(const Reg16& lhs) {return detail::CondExpr_Or<Reg16, Reg16, JCC_E>(lhs, lhs);}
8124 inline detail::CondExpr_Or<Reg32, Reg32, JCC_E> operator!(const Reg32& lhs) {return detail::CondExpr_Or<Reg32, Reg32, JCC_E>(lhs, lhs);}
8125 #ifdef JITASM64
8126 inline detail::CondExpr_Or<Reg64, Reg64, JCC_E> operator!(const Reg64& lhs) {return detail::CondExpr_Or<Reg64, Reg64, JCC_E>(lhs, lhs);}
8127 #endif
8128 inline detail::CondExpr_Cmp<Mem8, Imm8, JCC_E> operator!(const Mem8& lhs) {return detail::CondExpr_Cmp<Mem8, Imm8, JCC_E>(lhs, 0);}
8129 inline detail::CondExpr_Cmp<Mem16, Imm16, JCC_E> operator!(const Mem16& lhs) {return detail::CondExpr_Cmp<Mem16, Imm16, JCC_E>(lhs, 0);}
8130 inline detail::CondExpr_Cmp<Mem32, Imm32, JCC_E> operator!(const Mem32& lhs) {return detail::CondExpr_Cmp<Mem32, Imm32, JCC_E>(lhs, 0);}
8131 #ifdef JITASM64
8132 inline detail::CondExpr_Cmp<Mem64, Imm32, JCC_E> operator!(const Mem64& lhs) {return detail::CondExpr_Cmp<Mem64, Imm32, JCC_E>(lhs, 0);}
8133 #endif
8134
8135 // <
8136 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_B> operator<(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_B>(lhs, rhs);}
8137 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_B> operator<(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_B>(lhs, rhs);}
8138 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_B> operator<(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_B>(lhs, rhs);}
8139 #ifdef JITASM64
8140 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_B> operator<(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_B>(lhs, rhs);}
8141 #endif
8142 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_B> operator<(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_B>(lhs, rhs);}
8143 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_B> operator<(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_B>(lhs, rhs);}
8144 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_B> operator<(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_B>(lhs, rhs);}
8145 #ifdef JITASM64
8146 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_B> operator<(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_B>(lhs, rhs);}
8147 #endif
8148
8149 // >
8150 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_A> operator>(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_A>(lhs, rhs);}
8151 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_A> operator>(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_A>(lhs, rhs);}
8152 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_A> operator>(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_A>(lhs, rhs);}
8153 #ifdef JITASM64
8154 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_A> operator>(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_A>(lhs, rhs);}
8155 #endif
8156 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_A> operator>(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_A>(lhs, rhs);}
8157 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_A> operator>(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_A>(lhs, rhs);}
8158 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_A> operator>(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_A>(lhs, rhs);}
8159 #ifdef JITASM64
8160 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_A> operator>(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_A>(lhs, rhs);}
8161 #endif
8162
8163 // <=
8164 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_BE> operator<=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_BE>(lhs, rhs);}
8165 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_BE> operator<=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_BE>(lhs, rhs);}
8166 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_BE> operator<=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_BE>(lhs, rhs);}
8167 #ifdef JITASM64
8168 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_BE> operator<=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_BE>(lhs, rhs);}
8169 #endif
8170 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_BE> operator<=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_BE>(lhs, rhs);}
8171 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_BE> operator<=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_BE>(lhs, rhs);}
8172 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_BE> operator<=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_BE>(lhs, rhs);}
8173 #ifdef JITASM64
8174 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_BE> operator<=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_BE>(lhs, rhs);}
8175 #endif
8176
8177 // >=
8178 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_AE> operator>=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_AE>(lhs, rhs);}
8179 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_AE> operator>=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_AE>(lhs, rhs);}
8180 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_AE> operator>=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_AE>(lhs, rhs);}
8181 #ifdef JITASM64
8182 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_AE> operator>=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_AE>(lhs, rhs);}
8183 #endif
8184 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_AE> operator>=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_AE>(lhs, rhs);}
8185 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_AE> operator>=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_AE>(lhs, rhs);}
8186 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_AE> operator>=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_AE>(lhs, rhs);}
8187 #ifdef JITASM64
8188 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_AE> operator>=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_AE>(lhs, rhs);}
8189 #endif
8190
8191 // ==
8192 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_E> operator==(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_E>(lhs, rhs);}
8193 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_E> operator==(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_E>(lhs, rhs);}
8194 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_E> operator==(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_E>(lhs, rhs);}
8195 #ifdef JITASM64
8196 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_E> operator==(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_E>(lhs, rhs);}
8197 #endif
8198 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_E> operator==(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_E>(lhs, rhs);}
8199 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_E> operator==(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_E>(lhs, rhs);}
8200 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_E> operator==(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_E>(lhs, rhs);}
8201 #ifdef JITASM64
8202 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_E> operator==(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_E>(lhs, rhs);}
8203 #endif
8204
8205 // !=
8206 template<class R> detail::CondExpr_Cmp<Reg8, R, JCC_NE> operator!=(const Reg8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg8, R, JCC_NE>(lhs, rhs);}
8207 template<class R> detail::CondExpr_Cmp<Reg16, R, JCC_NE> operator!=(const Reg16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg16, R, JCC_NE>(lhs, rhs);}
8208 template<class R> detail::CondExpr_Cmp<Reg32, R, JCC_NE> operator!=(const Reg32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg32, R, JCC_NE>(lhs, rhs);}
8209 #ifdef JITASM64
8210 template<class R> detail::CondExpr_Cmp<Reg64, R, JCC_NE> operator!=(const Reg64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Reg64, R, JCC_NE>(lhs, rhs);}
8211 #endif
8212 template<class R> detail::CondExpr_Cmp<Mem8, R, JCC_NE> operator!=(const Mem8& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem8, R, JCC_NE>(lhs, rhs);}
8213 template<class R> detail::CondExpr_Cmp<Mem16, R, JCC_NE> operator!=(const Mem16& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem16, R, JCC_NE>(lhs, rhs);}
8214 template<class R> detail::CondExpr_Cmp<Mem32, R, JCC_NE> operator!=(const Mem32& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem32, R, JCC_NE>(lhs, rhs);}
8215 #ifdef JITASM64
8216 template<class R> detail::CondExpr_Cmp<Mem64, R, JCC_NE> operator!=(const Mem64& lhs, const R& rhs) {return detail::CondExpr_Cmp<Mem64, R, JCC_NE>(lhs, rhs);}
8217 #endif
8218
8219 namespace detail {
8220 // Flags for ArgumentTraits
8221 enum {
8222 ARG_IN_REG = (1<<0), ///< Argument is stored in general purpose register.
8223 ARG_IN_STACK = (1<<1), ///< Argument is stored on stack.
8224 ARG_IN_MMX = (1<<2), ///< Argument is stored in mmx register.
8225 ARG_IN_XMM_SP = (1<<3), ///< Argument is stored in xmm register as single precision.
8226 ARG_IN_XMM_DP = (1<<4), ///< Argument is stored in xmm register as double precision.
8227 ARG_IN_XMM_INT = (1<<5), ///< Argument is stored in xmm register as integer.
8228 ARG_TYPE_VALUE = (1<<6), ///< Argument is value which is passed.
8229 ARG_TYPE_PTR = (1<<7) ///< Argument is pointer which is passed to.
8230 };
8231
8232 /// cdecl argument type traits
8233 template<int N, class T, int Size = sizeof(T)>
8234 struct ArgTraits_cdecl {
8235 enum {
8236 stack_size = (Size + 4 - 1) / 4 * 4,
8237 flag = ARG_IN_STACK | ARG_TYPE_VALUE,
8238 reg_id = INVALID
8239 };
8240 };
8241
8242 #if JITASM_MMINTRIN
8243 // specialization for __m64
8244 template<int N> struct ArgTraits_cdecl<N, __m64, 8> {enum {stack_size = 0, flag = ARG_IN_MMX | ARG_TYPE_VALUE, reg_id = MM0};};
8245 #endif
8246
8247 #if JITASM_XMMINTRIN
8248 // specialization for __m128
8249 template<int N> struct ArgTraits_cdecl<N, __m128, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_SP | ARG_TYPE_VALUE, reg_id = XMM0};};
8250 #endif
8251
8252 #if JITASM_EMMINTRIN
8253 // specialization for __m128d
8254 template<int N> struct ArgTraits_cdecl<N, __m128d, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_DP | ARG_TYPE_VALUE, reg_id = XMM0};};
8255
8256 // specialization for __m128i
8257 template<int N> struct ArgTraits_cdecl<N, __m128i, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_INT | ARG_TYPE_VALUE, reg_id = XMM0};};
8258 #endif
8259
8260
8261 /// Microsoft x64 fastcall argument type traits
8262 template<int N, class T, int Size = sizeof(T)>
8263 struct ArgTraits_win64 {
8264 enum {
8265 stack_size = 8,
8266 flag = ARG_IN_STACK | (Size == 1 || Size == 2 || Size == 4 || Size == 8 ? ARG_TYPE_VALUE : ARG_TYPE_PTR),
8267 reg_id = INVALID
8268 };
8269 };
8270
8271 /**
8272 * Base class for argument which is stored in general purpose register.
8273 */
8274 template<int RegID, int Flag> struct ArgTraits_win64_reg {
8275 enum {
8276 stack_size = 8,
8277 flag = Flag,
8278 reg_id = RegID
8279 };
8280 };
8281
8282 // specialization for argument pointer stored in register
8283 template<class T, int Size> struct ArgTraits_win64<0, T, Size> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_PTR> {};
8284 template<class T, int Size> struct ArgTraits_win64<1, T, Size> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_PTR> {};
8285 template<class T, int Size> struct ArgTraits_win64<2, T, Size> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_PTR> {};
8286 template<class T, int Size> struct ArgTraits_win64<3, T, Size> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_PTR> {};
8287
8288 // specialization for 1 byte type
8289 template<class T> struct ArgTraits_win64<0, T, 1> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8290 template<class T> struct ArgTraits_win64<1, T, 1> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8291 template<class T> struct ArgTraits_win64<2, T, 1> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};
8292 template<class T> struct ArgTraits_win64<3, T, 1> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};
8293
8294 // specialization for 2 bytes type
8295 template<class T> struct ArgTraits_win64<0, T, 2> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8296 template<class T> struct ArgTraits_win64<1, T, 2> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8297 template<class T> struct ArgTraits_win64<2, T, 2> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};
8298 template<class T> struct ArgTraits_win64<3, T, 2> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};
8299
8300 // specialization for 4 bytes type
8301 template<class T> struct ArgTraits_win64<0, T, 4> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8302 template<class T> struct ArgTraits_win64<1, T, 4> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8303 template<class T> struct ArgTraits_win64<2, T, 4> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};
8304 template<class T> struct ArgTraits_win64<3, T, 4> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};
8305
8306 // specialization for 8 bytes type
8307 template<class T> struct ArgTraits_win64<0, T, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8308 template<class T> struct ArgTraits_win64<1, T, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8309 template<class T> struct ArgTraits_win64<2, T, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};
8310 template<class T> struct ArgTraits_win64<3, T, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};
8311
8312 #if JITASM_MMINTRIN
8313 // specialization for __m64
8314 template<> struct ArgTraits_win64<0, __m64, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8315 template<> struct ArgTraits_win64<1, __m64, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};
8316 template<> struct ArgTraits_win64<2, __m64, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};
8317 template<> struct ArgTraits_win64<3, __m64, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};
8318 #endif
8319
8320 // specialization for float
8321 template<> struct ArgTraits_win64<0, float, 4> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8322 template<> struct ArgTraits_win64<1, float, 4> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8323 template<> struct ArgTraits_win64<2, float, 4> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8324 template<> struct ArgTraits_win64<3, float, 4> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8325
8326 // specialization for double
8327 template<> struct ArgTraits_win64<0, double, 8> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8328 template<> struct ArgTraits_win64<1, double, 8> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8329 template<> struct ArgTraits_win64<2, double, 8> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8330 template<> struct ArgTraits_win64<3, double, 8> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8331
8332
8333 /// System V ABI AMD64 argument type traits
8334 template<int N, class T, int Size = sizeof(T)>
8335 struct ArgTraits_linux64 {
8336 enum {
8337 stack_size = (Size + 8 - 1) / 8 * 8,
8338 flag = ARG_IN_STACK | ARG_TYPE_VALUE,
8339 reg_id = INVALID
8340 };
8341 };
8342
8343 // INTEGER class
8344 struct ArgTraits_linux64_integer {
8345 enum {
8346 stack_size = 0,
8347 flag = ARG_IN_REG | ARG_TYPE_VALUE,
8348 reg_id = RDI
8349 };
8350 };
8351
8352 template<int N> struct ArgTraits_linux64<N, bool, sizeof(bool) > : ArgTraits_linux64_integer {};
8353 template<int N> struct ArgTraits_linux64<N, char, sizeof(char) > : ArgTraits_linux64_integer {};
8354 template<int N> struct ArgTraits_linux64<N, unsigned char, sizeof(unsigned char) > : ArgTraits_linux64_integer {};
8355 template<int N> struct ArgTraits_linux64<N, short, sizeof(short) > : ArgTraits_linux64_integer {};
8356 template<int N> struct ArgTraits_linux64<N, unsigned short, sizeof(unsigned short) > : ArgTraits_linux64_integer {};
8357 template<int N> struct ArgTraits_linux64<N, int, sizeof(int) > : ArgTraits_linux64_integer {};
8358 template<int N> struct ArgTraits_linux64<N, unsigned int, sizeof(unsigned int) > : ArgTraits_linux64_integer {};
8359 template<int N> struct ArgTraits_linux64<N, long, sizeof(long) > : ArgTraits_linux64_integer {};
8360 template<int N> struct ArgTraits_linux64<N, unsigned long, sizeof(unsigned long) > : ArgTraits_linux64_integer {};
8361 template<int N> struct ArgTraits_linux64<N, long long, sizeof(long long) > : ArgTraits_linux64_integer {};
8362 template<int N> struct ArgTraits_linux64<N, unsigned long long, sizeof(unsigned long long)> : ArgTraits_linux64_integer {};
8363 template<int N, class T> struct ArgTraits_linux64<N, T *, 8 > : ArgTraits_linux64_integer {};
8364
8365 // SSE class
8366 template<int Flag> struct ArgTraits_linux64_sse {
8367 enum {
8368 stack_size = 0,
8369 flag = Flag,
8370 reg_id = XMM0
8371 };
8372 };
8373
8374 template<int N> struct ArgTraits_linux64<N, float, sizeof(float)> : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8375 template<int N> struct ArgTraits_linux64<N, double, sizeof(double)> : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8376 #if JITASM_MMINTRIN
8377 template<int N> struct ArgTraits_linux64<N, __m64, sizeof(__m64)> : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {};
8378 #endif
8379 #if JITASM_XMMINTRIN
8380 template<int N> struct ArgTraits_linux64<N, __m128, sizeof(__m128)> : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};
8381 #endif
8382 #if JITASM_EMMINTRIN
8383 template<int N> struct ArgTraits_linux64<N, __m128d, sizeof(__m128d)> : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};
8384 template<int N> struct ArgTraits_linux64<N, __m128i, sizeof(__m128i)> : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {};
8385 #endif
8386
8387
8388 /// Special argument type
8389 struct ArgNone {};
8390
8391 /// Argument information
8392 struct ArgInfo
8393 {
8394 Addr addr;
8395 PhysicalRegID reg_id;
8396 uint32 flag;
8397 uint32 index_gp;
8398 uint32 index_mmx;
8399 uint32 index_xmm;
8400
8401 ArgInfo(const Addr& addr_, PhysicalRegID reg_id_, uint32 flg, uint32 idx_gp = 0, uint32 idx_mmx = 0, uint32 idx_xmm_ = 0) : addr(addr_), reg_id(reg_id_), flag(flg), index_gp(idx_gp), index_mmx(idx_mmx), index_xmm(idx_xmm_) {}
8402
8403 template<class CurArgTraits, class NextArgTraits> ArgInfo Next() const {
8404 ArgInfo next_arg_info(addr + CurArgTraits::stack_size, static_cast<PhysicalRegID>(NextArgTraits::reg_id), NextArgTraits::flag, index_gp, index_mmx, index_xmm);
8405 if (CurArgTraits::flag & ARG_IN_REG) next_arg_info.index_gp++;
8406 if (CurArgTraits::flag & ARG_IN_MMX) next_arg_info.index_mmx++;
8407 if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) next_arg_info.index_xmm++;
8408
8409 #ifdef JITASM64
8410 #ifdef JITASM_WIN
8411 // for Win64
8412 #else
8413 // for x64 Linux
8414 if (NextArgTraits::flag & ARG_IN_REG) {
8415 const PhysicalRegID gp_regs[] = {RDI, RSI, RDX, RCX, R8, R9};
8416 next_arg_info.reg_id = next_arg_info.index_gp < 6 ? gp_regs[next_arg_info.index_gp] : INVALID;
8417 }
8418 if (CurArgTraits::flag & ARG_IN_REG) {
8419 if (reg_id == INVALID) {
8420 // This register argument is passed on stack
8421 next_arg_info.addr = next_arg_info.addr + 8;
8422 }
8423 }
8424
8425 // __m128/__m128d/__m128i
8426 if (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {
8427 if (next_arg_info.index_xmm < 8) {
8428 next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm);
8429 } else {
8430 next_arg_info.reg_id = INVALID;
8431 }
8432 }
8433 if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {
8434 if (reg_id == INVALID) {
8435 // This __m128/__m128d/__m128i argument is passed on stack
8436 next_arg_info.addr = next_arg_info.addr + 16;
8437 }
8438 }
8439 #endif
8440 #else
8441 // for x86 Win/Linux
8442
8443 // __m64
8444 if (NextArgTraits::flag & ARG_IN_MMX) {
8445 if (next_arg_info.index_mmx < 3) {
8446 next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_mmx);
8447 } else {
8448 next_arg_info.reg_id = INVALID;
8449 }
8450 }
8451 if (CurArgTraits::flag & ARG_IN_MMX) {
8452 if (reg_id == INVALID) {
8453 // This __m64 argument is passed on stack
8454 next_arg_info.addr = next_arg_info.addr + 8;
8455 }
8456 }
8457
8458 // __m128/__m128d/__m128i
8459 if (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {
8460 if (next_arg_info.index_xmm < 3) {
8461 next_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm);
8462 } else {
8463 next_arg_info.reg_id = INVALID;
8464 }
8465 }
8466 if (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {
8467 if (reg_id == INVALID) {
8468 // This __m128/__m128d/__m128i argument is passed on stack
8469 next_arg_info.addr = next_arg_info.addr + 16;
8470 }
8471 }
8472 #endif
8473
8474 return next_arg_info;
8475 }
8476 };
8477
8478 /// Result type traits
8479 template<class T>
8480 struct ResultTraits {
8481 enum { size = sizeof(T) };
8482 typedef OpdT<sizeof(T) * 8> OpdR;
8483 typedef AddressingPtr<OpdR> ResultPtr;
8484 };
8485
8486 // specialization for void
8487 template<>
8488 struct ResultTraits<void> {
8489 enum { size = 0 };
8490 struct OpdR {};
8491 struct ResultPtr {};
8492 };
8493
8494 /// Result store destination
8495 struct ResultDest {
8496 Reg ptr;
8497 ResultDest(Frontend& f, const ArgInfo& dest)
8498 {
8499 if (dest.reg_id != INVALID) {
8500 // result pointer on register
8501 f.DeclareRegArg(ptr, Reg(dest.reg_id), !dest.addr.reg_.IsInvalid() ? f.ptr[dest.addr] : Opd());
8502 } else if (!dest.addr.reg_.IsInvalid()) {
8503 // result pointer on stack
8504 f.DeclareStackArg(ptr, f.ptr[dest.addr]);
8505 }
8506 }
8507 };
8508
8509 /// Function result
8510 template<class T, int Size = ResultTraits<T>::size>
8511 struct ResultT {
8512 enum { ArgR = 1 /* First (hidden) argument is pointer for copying result. */};
8513 typedef typename ResultTraits<T>::OpdR OpdR;
8514 OpdR val_;
8515 ResultT() {}
8516 ResultT(const MemT<OpdR>& val) : val_(val) {}
8517 void StoreResult(Frontend& f, const ResultDest& dst)
8518 {
8519 if (val_.IsMem()) {
8520 f.lea(f.zsi, static_cast<MemT<OpdR>&>(val_));
8521 f.mov(f.zcx, Size);
8522 f.rep_movsb(dst.ptr, f.zsi, f.zcx);
8523 f.DeclareResultReg(dst.ptr);
8524 }
8525 }
8526 };
8527
8528 // specialization for void
8529 template<>
8530 struct ResultT<void, 0> {
8531 enum { ArgR = 0 };
8532 ResultT();
8533 };
8534
8535 // specialization for 1byte type
8536 template<class T>
8537 struct ResultT<T, 1> {
8538 enum { ArgR = 0 };
8539 Opd8 val_;
8540 ResultT() {}
8541 ResultT(const Opd8& val) : val_(val) {}
8542 ResultT(uint8 imm) : val_(Imm8(imm)) {}
8543 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8544 {
8545 if (val_.IsGpReg()) {
8546 if (val_.GetReg().IsSymbolic()) {
8547 f.DeclareResultReg(val_);
8548 } else if (val_.GetReg().id != AL) {
8549 f.mov(f.al, static_cast<Reg8&>(val_));
8550 }
8551 } else if (val_.IsMem()) {
8552 f.mov(f.al, static_cast<Mem8&>(val_));
8553 } else if (val_.IsImm()) {
8554 f.mov(f.al, static_cast<Imm8&>(val_));
8555 }
8556 }
8557 };
8558
8559 // specialization for 2bytes type
8560 template<class T>
8561 struct ResultT<T, 2> {
8562 enum { ArgR = 0 };
8563 Opd16 val_;
8564 ResultT() {}
8565 ResultT(const Opd16& val) : val_(val) {}
8566 ResultT(uint16 imm) : val_(Imm16(imm)) {}
8567 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8568 {
8569 if (val_.IsGpReg()) {
8570 if (val_.GetReg().IsSymbolic()) {
8571 f.DeclareResultReg(val_);
8572 } else if (val_.GetReg().id != AX) {
8573 f.mov(f.ax, static_cast<Reg16&>(val_));
8574 }
8575 } else if (val_.IsMem()) {
8576 f.mov(f.ax, static_cast<Mem16&>(val_));
8577 } else if (val_.IsImm()) {
8578 f.mov(f.ax, static_cast<Imm16&>(val_));
8579 }
8580 }
8581 };
8582
8583 // specialization for 4bytes type
8584 template<class T>
8585 struct ResultT<T, 4> {
8586 enum { ArgR = 0 };
8587 Opd32 val_;
8588 ResultT() {}
8589 ResultT(const Opd32& val) : val_(val) {}
8590 ResultT(uint32 imm) : val_(Imm32(imm)) {}
8591 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8592 {
8593 if (val_.IsGpReg()) {
8594 if (val_.GetReg().IsSymbolic()) {
8595 f.DeclareResultReg(val_);
8596 } else if (val_.GetReg().id != EAX) {
8597 f.mov(f.eax, static_cast<Reg32&>(val_));
8598 }
8599 } else if (val_.IsMem()) {
8600 f.mov(f.eax, static_cast<Mem32&>(val_));
8601 } else if (val_.IsImm()) {
8602 f.mov(f.eax, static_cast<Imm32&>(val_));
8603 }
8604 }
8605 };
8606
8607 // specialization for 8bytes type
8608 template<class T>
8609 struct ResultT<T, 8> {
8610 enum { ArgR = 0 };
8611 Opd64 val_;
8612 ResultT() {}
8613 ResultT(const Opd64& val) : val_(val) {}
8614 ResultT(uint64 imm) : val_(Imm64(imm)) {}
8615 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8616 {
8617 #ifdef JITASM64
8618 if (val_.IsGpReg()) {
8619 if (val_.GetReg().IsSymbolic()) {
8620 f.DeclareResultReg(val_);
8621 } else if (val_.GetReg().id != RAX) {
8622 f.mov(f.rax, static_cast<Reg64&>(val_));
8623 }
8624 } else if (val_.IsMem()) {
8625 f.mov(f.rax, static_cast<Mem64&>(val_));
8626 } else if (val_.IsImm()) {
8627 f.mov(f.rax, static_cast<Imm64&>(val_));
8628 } else if (val_.IsMmxReg()) {
8629 f.movq(f.rax, static_cast<MmxReg&>(val_));
8630 }
8631 #else
8632 if (val_.IsMem()) {
8633 // from memory
8634 Mem32 lo(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp());
8635 Mem32 hi(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp() + 4);
8636 f.mov(f.eax, lo);
8637 f.mov(f.edx, hi);
8638 } else if (val_.IsImm()) {
8639 // from immediate
8640 f.mov(f.eax, static_cast<sint32>(val_.GetImm()));
8641 f.mov(f.edx, static_cast<sint32>(val_.GetImm() >> 32));
8642 }
8643 #endif
8644 }
8645 };
8646
8647 // specialization for float
8648 template<>
8649 struct ResultT<float, 4> {
8650 enum { ArgR = 0 };
8651 detail::Opd val_;
8652 ResultT() {}
8653 ResultT(const FpuReg& fpu) : val_(fpu) {}
8654 ResultT(const Mem32& mem) : val_(mem) {}
8655 ResultT(const XmmReg& xmm) : val_(xmm) {}
8656 ResultT(const float imm) : val_(Imm32(*(uint32*)&imm)) {}
8657 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8658 {
8659 #ifdef JITASM64
8660 if (val_.IsFpuReg()) {
8661 // from FPU register
8662 f.fstp(f.real4_ptr[f.rsp - 4]);
8663 f.movss(f.xmm0, f.dword_ptr[f.rsp - 4]);
8664 } else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) {
8665 // from memory
8666 f.movss(f.xmm0, static_cast<Mem32&>(val_));
8667 } else if (val_.IsXmmReg()) {
8668 // from XMM register
8669 if (val_.GetReg().IsSymbolic()) {
8670 f.DeclareResultReg(val_);
8671 } else if (val_.GetReg().id != XMM0) {
8672 f.movss(f.xmm0, static_cast<XmmReg&>(val_));
8673 }
8674 } else if (val_.IsImm()) {
8675 // from float immediate
8676 f.mov(f.dword_ptr[f.rsp - 4], static_cast<Imm32&>(val_));
8677 f.movss(f.xmm0, f.dword_ptr[f.rsp - 4]);
8678 }
8679 #else
8680 if (val_.IsFpuReg()) {
8681 // from FPU register
8682 if (val_.GetReg().id != ST0) {
8683 f.fld(static_cast<FpuReg&>(val_));
8684 }
8685 } else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) {
8686 // from memory
8687 f.fld(static_cast<Mem32&>(val_));
8688 } else if (val_.IsXmmReg()) {
8689 // from XMM register
8690 f.movss(f.dword_ptr[f.esp - 4], static_cast<XmmReg&>(val_));
8691 f.fld(f.real4_ptr[f.esp - 4]);
8692 } else if (val_.IsImm()) {
8693 // from float immediate
8694 f.mov(f.dword_ptr[f.esp - 4], static_cast<Imm32&>(val_));
8695 f.fld(f.real4_ptr[f.esp - 4]);
8696 }
8697 #endif
8698 }
8699 };
8700
8701 // specialization for double
8702 template<>
8703 struct ResultT<double, 8> {
8704 enum { ArgR = 0 };
8705 detail::Opd val_;
8706 double imm_;
8707 ResultT() {}
8708 ResultT(const FpuReg& fpu) : val_(fpu) {}
8709 ResultT(const Mem64& mem) : val_(mem) {}
8710 ResultT(const XmmReg& xmm) : val_(xmm) {}
8711 ResultT(const double imm) : val_(Imm32(0)), imm_(imm) {}
8712 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8713 {
8714 #ifdef JITASM64
8715 if (val_.IsFpuReg()) {
8716 // from FPU register
8717 f.fstp(f.real8_ptr[f.rsp - 8]);
8718 f.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]);
8719 } else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) {
8720 // from memory
8721 f.movsd(f.xmm0, static_cast<Mem64&>(val_));
8722 } else if (val_.IsXmmReg()) {
8723 // from XMM register
8724 if (val_.GetReg().IsSymbolic()) {
8725 f.DeclareResultReg(val_);
8726 } else if (val_.GetReg().id != XMM0) {
8727 f.movsd(f.xmm0, static_cast<XmmReg&>(val_));
8728 }
8729 } else if (val_.IsImm()) {
8730 // from float immediate
8731 f.mov(f.dword_ptr[f.rsp - 8], *reinterpret_cast<uint32*>(&imm_));
8732 f.mov(f.dword_ptr[f.rsp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1));
8733 f.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]);
8734 }
8735 #else
8736 if (val_.IsFpuReg()) {
8737 // from FPU register
8738 if (val_.GetReg().id != ST0) {
8739 f.fld(static_cast<FpuReg&>(val_));
8740 }
8741 } else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) {
8742 // from memory
8743 f.fld(static_cast<Mem64&>(val_));
8744 } else if (val_.IsXmmReg()) {
8745 // from XMM register
8746 f.movsd(f.qword_ptr[f.esp - 8], static_cast<XmmReg&>(val_));
8747 f.fld(f.real8_ptr[f.esp - 8]);
8748 } else if (val_.IsImm()) { // val_ is immediate 0
8749 // from double immediate
8750 f.mov(f.dword_ptr[f.esp - 8], *reinterpret_cast<uint32*>(&imm_));
8751 f.mov(f.dword_ptr[f.esp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1));
8752 f.fld(f.real8_ptr[f.esp - 8]);
8753 }
8754 #endif
8755 }
8756 };
8757
8758
8759 #if JITASM_MMINTRIN
8760 // specialization for __m64
8761 template<>
8762 struct ResultT<__m64, 8> {
8763 enum { ArgR = 0 };
8764 Opd64 val_;
8765 ResultT() {}
8766 ResultT(const MmxReg& mm) : val_(mm) {}
8767 ResultT(const Mem64& mem) : val_(mem) {}
8768 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8769 {
8770 #if defined(JITASM64) && !defined(JITASM_WIN)
8771 if (val_.IsMmxReg()) {
8772 f.movq2dq(f.xmm0, static_cast<const MmxReg&>(val_));
8773 } else if (val_.IsMem()) {
8774 f.movq(f.xmm0, static_cast<const Mem64&>(val_));
8775 }
8776 #else
8777 if (val_.IsMmxReg()) {
8778 if (val_.GetReg().IsSymbolic()) {
8779 f.DeclareResultReg(val_);
8780 } else if (val_.GetReg().id != MM0) {
8781 f.movq(f.mm0, static_cast<const MmxReg&>(val_));
8782 }
8783 } else if (val_.IsMem()) {
8784 f.movq(f.mm0, static_cast<const Mem64&>(val_));
8785 }
8786 #endif
8787 }
8788 };
8789 #endif // JITASM_MMINTRIN
8790
8791 #if JITASM_XMMINTRIN
8792 // specialization for __m128
8793 template<>
8794 struct ResultT<__m128, 16> {
8795 enum { ArgR = 0 };
8796 Opd128 val_;
8797 ResultT() {}
8798 ResultT(const XmmReg& xmm) : val_(xmm) {}
8799 ResultT(const Mem128& mem) : val_(mem) {}
8800 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8801 {
8802 if (val_.IsXmmReg()) {
8803 if (val_.GetReg().IsSymbolic()) {
8804 f.DeclareResultReg(val_);
8805 } else if (val_.GetReg().id != XMM0) {
8806 f.movaps(f.xmm0, static_cast<const XmmReg&>(val_));
8807 }
8808 } else if (val_.IsMem()) {
8809 f.movaps(f.xmm0, static_cast<const Mem128&>(val_));
8810 }
8811 }
8812 };
8813 #endif // JITASM_XMMINTRIN
8814
8815 #if JITASM_EMMINTRIN
8816 // specialization for __m128d
8817 template<>
8818 struct ResultT<__m128d, 16> {
8819 enum { ArgR = 0 };
8820 Opd128 val_;
8821 ResultT() {}
8822 ResultT(const XmmReg& xmm) : val_(xmm) {}
8823 ResultT(const Mem128& mem) : val_(mem) {}
8824 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8825 {
8826 if (val_.IsXmmReg()) {
8827 if (val_.GetReg().IsSymbolic()) {
8828 f.DeclareResultReg(val_);
8829 } else if (val_.GetReg().id != XMM0) {
8830 f.movapd(f.xmm0, static_cast<const XmmReg&>(val_));
8831 }
8832 } else if (val_.IsMem()) {
8833 f.movapd(f.xmm0, static_cast<const Mem128&>(val_));
8834 }
8835 }
8836 };
8837
8838 // specialization for __m128i
8839 template<>
8840 struct ResultT<__m128i, 16> {
8841 enum { ArgR = 0 };
8842 Opd128 val_;
8843 ResultT() {}
8844 ResultT(const XmmReg& xmm) : val_(xmm) {}
8845 ResultT(const Mem128& mem) : val_(mem) {}
8846 void StoreResult(Frontend& f, const ResultDest& /*dst*/)
8847 {
8848 if (val_.IsXmmReg()) {
8849 if (val_.GetReg().IsSymbolic()) {
8850 f.DeclareResultReg(val_);
8851 } else if (val_.GetReg().id != XMM0) {
8852 f.movdqa(f.xmm0, static_cast<const XmmReg&>(val_));
8853 }
8854 } else if (val_.IsMem()) {
8855 f.movdqa(f.xmm0, static_cast<const Mem128&>(val_));
8856 }
8857 }
8858 };
8859 #endif // JITASM_EMMINTRIN
8860
8861
8862 namespace calling_convention_cdecl
8863 {
8864 #ifdef JITASM64
8865 #ifdef JITASM_WIN
8866 template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_win64<N, T, Size> {};
8867 #else
8868 template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_linux64<N, T, Size> {};
8869 #endif
8870 #else
8871 template<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_cdecl<N, T, Size> {};
8872 #endif
8873
8874 template<class R>
8875 ArgInfo ResultInfo()
8876 {
8877 if (ResultT<R>::ArgR) {
8878 #ifdef JITASM64
8879 return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, RBP), SIZE_OF_GP_REG * 2), RCX, ARG_IN_REG | ARG_TYPE_PTR);
8880 #else
8881 return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * 2), INVALID, ARG_IN_STACK | ARG_TYPE_PTR);
8882 #endif
8883 } else {
8884 return ArgInfo(Addr(RegID::Invalid(), 0), INVALID, 0);
8885 }
8886 }
8887
8888 template<class R, class A1>
8889 ArgInfo ArgInfo1() { return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * (2 + ResultT<R>::ArgR)), static_cast<PhysicalRegID>(ArgTraits<ResultT<R>::ArgR + 0, A1>::reg_id), ArgTraits<ResultT<R>::ArgR + 0, A1>::flag); }
8890 template<class R, class A1, class A2>
8891 ArgInfo ArgInfo2() { return ArgInfo(ArgInfo1<R, A1>()).Next< ArgTraits<ResultT<R>::ArgR + 0, A1>, ArgTraits<ResultT<R>::ArgR + 1, A2> >(); }
8892 template<class R, class A1, class A2, class A3>
8893 ArgInfo ArgInfo3() { return ArgInfo(ArgInfo2<R, A1, A2>()).Next< ArgTraits<ResultT<R>::ArgR + 1, A2>, ArgTraits<ResultT<R>::ArgR + 2, A3> >(); }
8894 template<class R, class A1, class A2, class A3, class A4>
8895 ArgInfo ArgInfo4() { return ArgInfo(ArgInfo3<R, A1, A2, A3>()).Next< ArgTraits<ResultT<R>::ArgR + 2, A3>, ArgTraits<ResultT<R>::ArgR + 3, A4> >(); }
8896 template<class R, class A1, class A2, class A3, class A4, class A5>
8897 ArgInfo ArgInfo5() { return ArgInfo(ArgInfo4<R, A1, A2, A3, A4>()).Next< ArgTraits<ResultT<R>::ArgR + 3, A4>, ArgTraits<ResultT<R>::ArgR + 4, A5> >(); }
8898 template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
8899 ArgInfo ArgInfo6() { return ArgInfo(ArgInfo5<R, A1, A2, A3, A4, A5>()).Next< ArgTraits<ResultT<R>::ArgR + 4, A5>, ArgTraits<ResultT<R>::ArgR + 5, A6> >(); }
8900 template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
8901 ArgInfo ArgInfo7() { return ArgInfo(ArgInfo6<R, A1, A2, A3, A4, A5, A6>()).Next< ArgTraits<ResultT<R>::ArgR + 5, A6>, ArgTraits<ResultT<R>::ArgR + 6, A7> >(); }
8902 template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
8903 ArgInfo ArgInfo8() { return ArgInfo(ArgInfo7<R, A1, A2, A3, A4, A5, A6, A7>()).Next< ArgTraits<ResultT<R>::ArgR + 6, A7>, ArgTraits<ResultT<R>::ArgR + 7, A8> >(); }
8904 template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
8905 ArgInfo ArgInfo9() { return ArgInfo(ArgInfo8<R, A1, A2, A3, A4, A5, A6, A7, A8>()).Next< ArgTraits<ResultT<R>::ArgR + 7, A8>, ArgTraits<ResultT<R>::ArgR + 8, A9> >(); }
8906 template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
8907 ArgInfo ArgInfo10() { return ArgInfo(ArgInfo9<R, A1, A2, A3, A4, A5, A6, A7, A8, A9>()).Next< ArgTraits<ResultT<R>::ArgR + 8, A9>, ArgTraits<ResultT<R>::ArgR + 9, A10> >(); }
8908
8909 /// Function argument
8910 template<class T, size_t Size = sizeof(T)>
8911 struct Arg
8912 {
8913 Addr addr_;
8914 #ifdef JITASM64
8915 Arg(Frontend& f, const ArgInfo& arg_info) : addr_(Reg()) {
8916 if (arg_info.reg_id != INVALID) {
8917 f.DeclareRegArg(Reg(addr_.reg_), Reg(arg_info.reg_id), f.ptr[arg_info.addr]);
8918 } else {
8919 f.DeclareStackArg(Reg(addr_.reg_), f.ptr[arg_info.addr]);
8920 }
8921 }
8922 #else
8923 Arg(Frontend& f, const ArgInfo& arg_info) : addr_(arg_info.addr) {}
8924 #endif
8925 operator Addr () {return addr_;}
8926 };
8927
8928 // specialization for 1byte type
8929 template<class T>
8930 struct Arg<T, 1>
8931 {
8932 Frontend *f_;
8933 ArgInfo arg_info_;
8934
8935 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
8936 operator Addr () {
8937 #ifdef JITASM64
8938 // Dump to shadow space when x64 argument on register
8939 if (arg_info_.reg_id != INVALID) {
8940 f_->movzx(Reg64(arg_info_.reg_id), Reg8(arg_info_.reg_id));
8941 f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));
8942 }
8943 #endif
8944 return arg_info_.addr;
8945 }
8946 operator Reg8 () {
8947 Reg8 reg;
8948 if (arg_info_.reg_id == INVALID) {
8949 f_->DeclareStackArg(reg, f_->byte_ptr[arg_info_.addr]); // argument on stack
8950 } else {
8951 f_->DeclareRegArg(reg, Reg8(arg_info_.reg_id), f_->byte_ptr[arg_info_.addr]); // argument on register
8952 }
8953 return reg;
8954 }
8955 };
8956
8957 // specialization for 2byte type
8958 template<class T>
8959 struct Arg<T, 2>
8960 {
8961 Frontend *f_;
8962 ArgInfo arg_info_;
8963
8964 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
8965 operator Addr () {
8966 #ifdef JITASM64
8967 // Dump to shadow space when x64 argument on register
8968 if (arg_info_.reg_id != INVALID) {
8969 f_->movzx(Reg64(arg_info_.reg_id), Reg16(arg_info_.reg_id));
8970 f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));
8971 }
8972 #endif
8973 return arg_info_.addr;
8974 }
8975 operator Reg16 () {
8976 Reg16 reg;
8977 if (arg_info_.reg_id == INVALID) {
8978 f_->DeclareStackArg(reg, f_->word_ptr[arg_info_.addr]); // argument on stack
8979 } else {
8980 f_->DeclareRegArg(reg, Reg16(arg_info_.reg_id), f_->word_ptr[arg_info_.addr]); // argument on register
8981 }
8982 return reg;
8983 }
8984 };
8985
8986 // specialization for 4byte type
8987 template<class T>
8988 struct Arg<T, 4>
8989 {
8990 Frontend *f_;
8991 ArgInfo arg_info_;
8992
8993 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
8994 operator Addr () {
8995 #ifdef JITASM64
8996 // Dump to shadow space when x64 argument on register
8997 if (arg_info_.reg_id != INVALID) {
8998 f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));
8999 }
9000 #endif
9001 return arg_info_.addr;
9002 }
9003 operator Reg32 () {
9004 Reg32 reg;
9005 if (arg_info_.reg_id == INVALID) {
9006 f_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]); // argument on stack
9007 } else {
9008 f_->DeclareRegArg(reg, Reg32(arg_info_.reg_id), f_->dword_ptr[arg_info_.addr]); // argument on register
9009 }
9010 return reg;
9011 }
9012 };
9013
9014 #ifdef JITASM64
9015 // specialization for 8byte type
9016 template<class T>
9017 struct Arg<T, 8>
9018 {
9019 Frontend *f_;
9020 ArgInfo arg_info_;
9021
9022 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
9023 operator Addr () {
9024 // Dump to shadow space when x64 argument on register
9025 if (arg_info_.reg_id != INVALID) {
9026 f_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));
9027 }
9028 return arg_info_.addr;
9029 }
9030 operator Reg64 () {
9031 Reg64 reg;
9032 if (arg_info_.reg_id == INVALID) {
9033 f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]); // argument on stack
9034 } else {
9035 f_->DeclareRegArg(reg, Reg64(arg_info_.reg_id), f_->qword_ptr[arg_info_.addr]); // argument on register
9036 }
9037 return reg;
9038 }
9039 };
9040 #endif
9041
9042 // specialization for float
9043 template<>
9044 struct Arg<float, 4>
9045 {
9046 Frontend *f_;
9047 ArgInfo arg_info_;
9048
9049 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
9050 operator Addr () {
9051 #ifdef JITASM64
9052 // Dump to shadow space when x64 argument on register
9053 if (arg_info_.reg_id != INVALID) {
9054 f_->movss(f_->dword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id));
9055 }
9056 #endif
9057 return arg_info_.addr;
9058 }
9059 operator XmmReg () {
9060 XmmReg reg;
9061 if (arg_info_.reg_id == INVALID) {
9062 f_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]); // argument on stack
9063 } else {
9064 f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id)); // argument on register
9065 }
9066 return reg;
9067 }
9068 };
9069
9070 // specialization for double
9071 template<>
9072 struct Arg<double, 8>
9073 {
9074 Frontend *f_;
9075 ArgInfo arg_info_;
9076
9077 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
9078 operator Addr () {
9079 #ifdef JITASM64
9080 // Dump to shadow space when x64 argument on register
9081 if (arg_info_.reg_id != INVALID) {
9082 f_->movsd(f_->qword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id));
9083 }
9084 #endif
9085 return arg_info_.addr;
9086 }
9087 operator XmmReg () {
9088 XmmReg reg;
9089 if (arg_info_.reg_id == INVALID) {
9090 f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]); // argument on stack
9091 } else {
9092 f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id)); // argument on register
9093 }
9094 return reg;
9095 }
9096 };
9097
9098 #if JITASM_MMINTRIN
9099 // specialization for __m64
9100 template<>
9101 struct Arg<__m64, 8>
9102 {
9103 Frontend *f_;
9104 ArgInfo arg_info_;
9105
9106 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
9107 operator Addr () {
9108 if (arg_info_.reg_id != INVALID) {
9109 // Passed by mmx register
9110 if (arg_info_.flag & ARG_IN_REG) {
9111 // Win64
9112 #ifdef JITASM64
9113 // Dump to shadow space when Win64 argument on register
9114 Reg64 arg;
9115 f_->DeclareRegArg(arg, Reg64(arg_info_.reg_id));
9116 f_->mov(f_->qword_ptr[arg_info_.addr], arg);
9117 #endif
9118 return arg_info_.addr;
9119 } else if (arg_info_.flag & ARG_IN_XMM_INT) {
9120 // x64 Linux
9121 XmmReg arg;
9122 f_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id));
9123 Addr addr = f_->stack_manager_.Alloc(8, 8);
9124 f_->movq(f_->qword_ptr[addr], arg);
9125 return addr;
9126 } else {
9127 MmxReg arg;
9128 f_->DeclareRegArg(arg, MmxReg(arg_info_.reg_id));
9129 Addr addr = f_->stack_manager_.Alloc(8, 8);
9130 f_->movq(f_->qword_ptr[addr], arg);
9131 return addr;
9132 }
9133 } else {
9134 // Passed by stack
9135 return arg_info_.addr;
9136 }
9137 }
9138 operator MmxReg () {
9139 MmxReg reg;
9140 if (arg_info_.reg_id != INVALID) {
9141 // Passed by register
9142 if (arg_info_.flag & ARG_IN_REG) {
9143 // Win64
9144 #ifdef JITASM64
9145 Reg64 arg;
9146 f_->DeclareRegArg(arg, Reg64(arg_info_.reg_id));
9147 f_->movq(reg, arg);
9148 #endif
9149 } else if(arg_info_.flag & ARG_IN_XMM_INT) {
9150 // x64 Linux
9151 XmmReg arg;
9152 f_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id));
9153 f_->movdq2q(reg, arg);
9154 } else {
9155 f_->DeclareRegArg(reg, MmxReg(arg_info_.reg_id));
9156 }
9157 } else {
9158 // Passed by stack
9159 f_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]);
9160 }
9161 return reg;
9162 }
9163 };
9164 #endif // JITASM_MMINTRIN
9165
9166 #if JITASM_XMMINTRIN
9167 // specialization for __m128
9168 template<>
9169 struct Arg<__m128, 16>
9170 {
9171 Frontend *f_;
9172 ArgInfo arg_info_;
9173
9174 Arg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}
9175 operator Addr () {
9176 if (arg_info_.flag & ARG_TYPE_PTR) {
9177 Reg ptr;
9178 if (arg_info_.reg_id != INVALID) {
9179 f_->DeclareRegArg(ptr, Reg(arg_info_.reg_id)); // argument on register
9180 } else {
9181 f_->mov(ptr, f_->ptr[arg_info_.addr]);
9182 }
9183 return ptr;
9184 } else if (arg_info_.reg_id != INVALID) {
9185 Addr addr = f_->stack_manager_.Alloc(16, 16);
9186 f_->movdqa(f_->xmmword_ptr[addr], XmmReg(arg_info_.reg_id));
9187 return addr;
9188 } else {
9189 return arg_info_.addr;
9190 }
9191 }
9192 operator XmmReg () {
9193 XmmReg reg;
9194 if (arg_info_.flag & ARG_TYPE_PTR) {
9195 // Passed by pointer
9196 if (arg_info_.reg_id != INVALID) {
9197 // argument pointer on register
9198 f_->movdqa(reg, f_->xmmword_ptr[Reg(arg_info_.reg_id)]);
9199 } else {
9200 // argument pointer on stack
9201 Reg ptr;
9202 f_->mov(ptr, f_->ptr[arg_info_.addr]);
9203 f_->movdqa(reg, f_->xmmword_ptr[ptr]);
9204 }
9205 } else if (arg_info_.reg_id != INVALID) {
9206 // Passed by xmm register
9207 f_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id));
9208 } else {
9209 // Passed by stack
9210 f_->DeclareStackArg(reg, f_->xmmword_ptr[arg_info_.addr]);
9211 }
9212 return reg;
9213 }
9214 };
9215 #endif // JITASM_XMMINTRIN
9216
9217 #if JITASM_EMMINTRIN
9218 // specialization for __m128d, __m128i
9219 template<> struct Arg<__m128d, 16> : Arg<__m128, 16> {
9220 Arg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {}
9221 };
9222
9223 template<> struct Arg<__m128i, 16> : Arg<__m128, 16> {
9224 Arg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {}
9225 };
9226 #endif // JITASM_EMMINTRIN
9227 } // namespace calling_convention_cdecl
9228
9229 } // namespace detail
9230
9231 /// cdecl function
9232 template<
9233 class R,
9234 class Derived,
9235 class A1 = detail::ArgNone,
9236 class A2 = detail::ArgNone,
9237 class A3 = detail::ArgNone,
9238 class A4 = detail::ArgNone,
9239 class A5 = detail::ArgNone,
9240 class A6 = detail::ArgNone,
9241 class A7 = detail::ArgNone,
9242 class A8 = detail::ArgNone,
9243 class A9 = detail::ArgNone,
9244 class A10 = detail::ArgNone>
9245 struct function_cdecl : Frontend
9246 {
9247 typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
9248 typedef detail::ResultT<R> Result; ///< main function result type
9249 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9250
9251 operator FuncPtr() { return (FuncPtr)GetCode(); }
9252 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9253 void naked_main() {
9254 using namespace detail::calling_convention_cdecl;
9255 Prolog();
9256 detail::ResultDest result_dst(*this, ResultInfo<R>());
9257 static_cast<Derived *>(this)->main(
9258 Arg<A1>(*this, ArgInfo1<R,A1>()),
9259 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9260 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9261 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9262 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),
9263 Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),
9264 Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),
9265 Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()),
9266 Arg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>()),
9267 Arg<A10>(*this, ArgInfo10<R,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>())
9268 ).StoreResult(*this, result_dst);
9269 Epilog();
9270 }
9271 };
9272
9273 // specialization for 10 arguments and no result
9274 template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
9275 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> : Frontend
9276 {
9277 typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
9278 operator FuncPtr() { return (FuncPtr)GetCode(); }
9279 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9280 void naked_main() {
9281 using namespace detail::calling_convention_cdecl;
9282 Prolog();
9283 static_cast<Derived *>(this)->main(
9284 Arg<A1>(*this, ArgInfo1<void,A1>()),
9285 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9286 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9287 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9288 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),
9289 Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),
9290 Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),
9291 Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()),
9292 Arg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>()),
9293 Arg<A10>(*this, ArgInfo10<void,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>()));
9294 Epilog();
9295 }
9296 };
9297
9298 // specialization for 9 arguments
9299 template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
9300 struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend
9301 {
9302 typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
9303 typedef detail::ResultT<R> Result; ///< main function result type
9304 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9305 operator FuncPtr() { return (FuncPtr)GetCode(); }
9306 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9307 void naked_main() {
9308 using namespace detail::calling_convention_cdecl;
9309 Prolog();
9310 detail::ResultDest result_dst(*this, ResultInfo<R>());
9311 static_cast<Derived *>(this)->main(
9312 Arg<A1>(*this, ArgInfo1<R,A1>()),
9313 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9314 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9315 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9316 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),
9317 Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),
9318 Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),
9319 Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()),
9320 Arg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>())
9321 ).StoreResult(*this, result_dst);
9322 Epilog();
9323 }
9324 };
9325
9326 // specialization for 9 arguments and no result
9327 template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
9328 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend
9329 {
9330 typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
9331 operator FuncPtr() { return (FuncPtr)GetCode(); }
9332 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9333 void naked_main() {
9334 using namespace detail::calling_convention_cdecl;
9335 Prolog();
9336 static_cast<Derived *>(this)->main(
9337 Arg<A1>(*this, ArgInfo1<void,A1>()),
9338 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9339 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9340 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9341 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),
9342 Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),
9343 Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),
9344 Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()),
9345 Arg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>()));
9346 Epilog();
9347 }
9348 };
9349
9350 // specialization for 8 arguments
9351 template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
9352 struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend
9353 {
9354 typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8);
9355 typedef detail::ResultT<R> Result; ///< main function result type
9356 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9357 operator FuncPtr() { return (FuncPtr)GetCode(); }
9358 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9359 void naked_main() {
9360 using namespace detail::calling_convention_cdecl;
9361 Prolog();
9362 detail::ResultDest result_dst(*this, ResultInfo<R>());
9363 static_cast<Derived *>(this)->main(
9364 Arg<A1>(*this, ArgInfo1<R,A1>()),
9365 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9366 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9367 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9368 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),
9369 Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),
9370 Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),
9371 Arg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>())
9372 ).StoreResult(*this, result_dst);
9373 Epilog();
9374 }
9375 };
9376
9377 // specialization for 8 arguments and no result
9378 template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
9379 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend
9380 {
9381 typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8);
9382 operator FuncPtr() { return (FuncPtr)GetCode(); }
9383 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9384 void naked_main() {
9385 using namespace detail::calling_convention_cdecl;
9386 Prolog();
9387 static_cast<Derived *>(this)->main(
9388 Arg<A1>(*this, ArgInfo1<void,A1>()),
9389 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9390 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9391 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9392 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),
9393 Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),
9394 Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),
9395 Arg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()));
9396 Epilog();
9397 }
9398 };
9399
9400 // specialization for 7 arguments
9401 template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9402 struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9403 {
9404 typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7);
9405 typedef detail::ResultT<R> Result; ///< main function result type
9406 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9407 operator FuncPtr() { return (FuncPtr)GetCode(); }
9408 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9409 void naked_main() {
9410 using namespace detail::calling_convention_cdecl;
9411 Prolog();
9412 detail::ResultDest result_dst(*this, ResultInfo<R>());
9413 static_cast<Derived *>(this)->main(
9414 Arg<A1>(*this, ArgInfo1<R,A1>()),
9415 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9416 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9417 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9418 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),
9419 Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),
9420 Arg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>())
9421 ).StoreResult(*this, result_dst);
9422 Epilog();
9423 }
9424 };
9425
9426 // specialization for 7 arguments and no result
9427 template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
9428 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9429 {
9430 typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7);
9431 operator FuncPtr() { return (FuncPtr)GetCode(); }
9432 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9433 void naked_main() {
9434 using namespace detail::calling_convention_cdecl;
9435 Prolog();
9436 static_cast<Derived *>(this)->main(
9437 Arg<A1>(*this, ArgInfo1<void,A1>()),
9438 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9439 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9440 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9441 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),
9442 Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),
9443 Arg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()));
9444 Epilog();
9445 }
9446 };
9447
9448 // specialization for 6 arguments
9449 template<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6>
9450 struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9451 {
9452 typedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6);
9453 typedef detail::ResultT<R> Result; ///< main function result type
9454 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9455 operator FuncPtr() { return (FuncPtr)GetCode(); }
9456 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9457 void naked_main() {
9458 using namespace detail::calling_convention_cdecl;
9459 Prolog();
9460 detail::ResultDest result_dst(*this, ResultInfo<R>());
9461 static_cast<Derived *>(this)->main(
9462 Arg<A1>(*this, ArgInfo1<R,A1>()),
9463 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9464 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9465 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9466 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),
9467 Arg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>())
9468 ).StoreResult(*this, result_dst);
9469 Epilog();
9470 }
9471 };
9472
9473 // specialization for 6 arguments and no result
9474 template<class Derived, class A1, class A2, class A3, class A4, class A5, class A6>
9475 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9476 {
9477 typedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6);
9478 operator FuncPtr() { return (FuncPtr)GetCode(); }
9479 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9480 void naked_main() {
9481 using namespace detail::calling_convention_cdecl;
9482 Prolog();
9483 static_cast<Derived *>(this)->main(
9484 Arg<A1>(*this, ArgInfo1<void,A1>()),
9485 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9486 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9487 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9488 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),
9489 Arg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()));
9490 Epilog();
9491 }
9492 };
9493
9494 // specialization for 5 arguments
9495 template<class R, class Derived, class A1, class A2, class A3, class A4, class A5>
9496 struct function_cdecl<R, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9497 {
9498 typedef R (*FuncPtr)(A1, A2, A3, A4, A5);
9499 typedef detail::ResultT<R> Result; ///< main function result type
9500 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9501 operator FuncPtr() { return (FuncPtr)GetCode(); }
9502 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9503 void naked_main() {
9504 using namespace detail::calling_convention_cdecl;
9505 Prolog();
9506 detail::ResultDest result_dst(*this, ResultInfo<R>());
9507 static_cast<Derived *>(this)->main(
9508 Arg<A1>(*this, ArgInfo1<R,A1>()),
9509 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9510 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9511 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),
9512 Arg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>())
9513 ).StoreResult(*this, result_dst);
9514 Epilog();
9515 }
9516 };
9517
9518 // specialization for 5 arguments and no result
9519 template<class Derived, class A1, class A2, class A3, class A4, class A5>
9520 struct function_cdecl<void, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9521 {
9522 typedef void (*FuncPtr)(A1, A2, A3, A4, A5);
9523 operator FuncPtr() { return (FuncPtr)GetCode(); }
9524 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9525 void naked_main() {
9526 using namespace detail::calling_convention_cdecl;
9527 Prolog();
9528 static_cast<Derived *>(this)->main(
9529 Arg<A1>(*this, ArgInfo1<void,A1>()),
9530 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9531 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9532 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),
9533 Arg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()));
9534 Epilog();
9535 }
9536 };
9537
9538 // specialization for 4 arguments
9539 template<class R, class Derived, class A1, class A2, class A3, class A4>
9540 struct function_cdecl<R, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9541 {
9542 typedef R (*FuncPtr)(A1, A2, A3, A4);
9543 typedef detail::ResultT<R> Result; ///< main function result type
9544 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9545 operator FuncPtr() { return (FuncPtr)GetCode(); }
9546 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9547 void naked_main() {
9548 using namespace detail::calling_convention_cdecl;
9549 Prolog();
9550 detail::ResultDest result_dst(*this, ResultInfo<R>());
9551 static_cast<Derived *>(this)->main(
9552 Arg<A1>(*this, ArgInfo1<R,A1>()),
9553 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9554 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),
9555 Arg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>())
9556 ).StoreResult(*this, result_dst);
9557 Epilog();
9558 }
9559 };
9560
9561 // specialization for 4 arguments and no result
9562 template<class Derived, class A1, class A2, class A3, class A4>
9563 struct function_cdecl<void, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9564 {
9565 typedef void (*FuncPtr)(A1, A2, A3, A4);
9566 operator FuncPtr() { return (FuncPtr)GetCode(); }
9567 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9568 void naked_main() {
9569 using namespace detail::calling_convention_cdecl;
9570 Prolog();
9571 static_cast<Derived *>(this)->main(
9572 Arg<A1>(*this, ArgInfo1<void,A1>()),
9573 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9574 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),
9575 Arg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()));
9576 Epilog();
9577 }
9578 };
9579
9580 // specialization for 3 arguments
9581 template<class R, class Derived, class A1, class A2, class A3>
9582 struct function_cdecl<R, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9583 {
9584 typedef R (*FuncPtr)(A1, A2, A3);
9585 typedef detail::ResultT<R> Result; ///< main function result type
9586 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9587 operator FuncPtr() { return (FuncPtr)GetCode(); }
9588 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9589 void naked_main() {
9590 using namespace detail::calling_convention_cdecl;
9591 Prolog();
9592 detail::ResultDest result_dst(*this, ResultInfo<R>());
9593 static_cast<Derived *>(this)->main(
9594 Arg<A1>(*this, ArgInfo1<R,A1>()),
9595 Arg<A2>(*this, ArgInfo2<R,A1,A2>()),
9596 Arg<A3>(*this, ArgInfo3<R,A1,A2,A3>())
9597 ).StoreResult(*this, result_dst);
9598 Epilog();
9599 }
9600 };
9601
9602 // specialization for 3 arguments and no result
9603 template<class Derived, class A1, class A2, class A3>
9604 struct function_cdecl<void, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9605 {
9606 typedef void (*FuncPtr)(A1, A2, A3);
9607 operator FuncPtr() { return (FuncPtr)GetCode(); }
9608 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9609 void naked_main() {
9610 using namespace detail::calling_convention_cdecl;
9611 Prolog();
9612 static_cast<Derived *>(this)->main(
9613 Arg<A1>(*this, ArgInfo1<void,A1>()),
9614 Arg<A2>(*this, ArgInfo2<void,A1,A2>()),
9615 Arg<A3>(*this, ArgInfo3<void,A1,A2,A3>()));
9616 Epilog();
9617 }
9618 };
9619
9620 // specialization for 2 arguments
9621 template<class R, class Derived, class A1, class A2>
9622 struct function_cdecl<R, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9623 {
9624 typedef R (*FuncPtr)(A1, A2);
9625 typedef detail::ResultT<R> Result; ///< main function result type
9626 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9627 operator FuncPtr() { return (FuncPtr)GetCode(); }
9628 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9629 void naked_main() {
9630 using namespace detail::calling_convention_cdecl;
9631 Prolog();
9632 detail::ResultDest result_dst(*this, ResultInfo<R>());
9633 static_cast<Derived *>(this)->main(
9634 Arg<A1>(*this, ArgInfo1<R,A1>()),
9635 Arg<A2>(*this, ArgInfo2<R,A1,A2>())
9636 ).StoreResult(*this, result_dst);
9637 Epilog();
9638 }
9639 };
9640
9641 // specialization for 2 arguments and no result
9642 template<class Derived, class A1, class A2>
9643 struct function_cdecl<void, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9644 {
9645 typedef void (*FuncPtr)(A1, A2);
9646 operator FuncPtr() { return (FuncPtr)GetCode(); }
9647 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9648 void naked_main() {
9649 using namespace detail::calling_convention_cdecl;
9650 Prolog();
9651 static_cast<Derived *>(this)->main(
9652 Arg<A1>(*this, ArgInfo1<void,A1>()),
9653 Arg<A2>(*this, ArgInfo2<void,A1,A2>()));
9654 Epilog();
9655 }
9656 };
9657
9658 // specialization for 1 argument
9659 template<class R, class Derived, class A1>
9660 struct function_cdecl<R, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9661 {
9662 typedef R (*FuncPtr)(A1);
9663 typedef detail::ResultT<R> Result; ///< main function result type
9664 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9665 operator FuncPtr() { return (FuncPtr)GetCode(); }
9666 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9667 void naked_main() {
9668 using namespace detail::calling_convention_cdecl;
9669 Prolog();
9670 detail::ResultDest result_dst(*this, ResultInfo<R>());
9671 static_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<R,A1>())).StoreResult(*this, result_dst);
9672 Epilog();
9673 }
9674 };
9675
9676 // specialization for 1 argument and no result
9677 template<class Derived, class A1>
9678 struct function_cdecl<void, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9679 {
9680 typedef void (*FuncPtr)(A1);
9681 operator FuncPtr() { return (FuncPtr)GetCode(); }
9682 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9683 void naked_main() {
9684 using namespace detail::calling_convention_cdecl;
9685 Prolog();
9686 static_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<void,A1>()));
9687 Epilog();
9688 }
9689 };
9690
9691 // specialization for no arguments
9692 template<class R, class Derived>
9693 struct function_cdecl<R, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9694 {
9695 typedef R (*FuncPtr)();
9696 typedef detail::ResultT<R> Result; ///< main function result type
9697 typename detail::ResultTraits<R>::ResultPtr result_ptr;
9698 operator FuncPtr() { return (FuncPtr)GetCode(); }
9699 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9700 void naked_main() {
9701 Prolog();
9702 detail::ResultDest result_dst(*this, detail::calling_convention_cdecl::ResultInfo<R>());
9703 static_cast<Derived *>(this)->main().StoreResult(*this, result_dst);
9704 Epilog();
9705 }
9706 };
9707
9708 // specialization for no arguments and no result
9709 template<class Derived>
9710 struct function_cdecl<void, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend
9711 {
9712 typedef void (*FuncPtr)();
9713 operator FuncPtr() { return (FuncPtr)GetCode(); }
9714 void InternalMain() {static_cast<Derived *>(this)->naked_main();}
9715 void naked_main() {
9716 Prolog();
9717 static_cast<Derived *>(this)->main();
9718 Epilog();
9719 }
9720 };
9721
9722
9723 /// function
9724 template<
9725 class R,
9726 class Derived,
9727 class A1 = detail::ArgNone,
9728 class A2 = detail::ArgNone,
9729 class A3 = detail::ArgNone,
9730 class A4 = detail::ArgNone,
9731 class A5 = detail::ArgNone,
9732 class A6 = detail::ArgNone,
9733 class A7 = detail::ArgNone,
9734 class A8 = detail::ArgNone,
9735 class A9 = detail::ArgNone,
9736 class A10 = detail::ArgNone>
9737 struct function : function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> {};
9738
9739 } // namespace jitasm
9740
9741 #if defined(_MSC_VER)
9742 #pragma warning( pop )
9743 #endif
9744
9745 #endif // #ifndef JITASM_H
9746