From e9d13a33649270fc4d5991e7e12f41ca70c45c76 Mon Sep 17 00:00:00 2001 From: _or_75 Date: Wed, 20 May 2026 01:20:35 +0300 Subject: [PATCH] add x86 asmjit --- .gitignore | 1 - .../3rd_party/AsmJit/x86/x86assembler.h | 6680 +++++++++++++++++ .../3rd_party/AsmJit/x86/x86compiler.h | 5626 ++++++++++++++ .../3rd_party/AsmJit/x86/x86context_p.h | 523 ++ .../Include/3rd_party/AsmJit/x86/x86cpuinfo.h | 263 + .../Include/3rd_party/AsmJit/x86/x86inst.h | 2410 ++++++ .../Include/3rd_party/AsmJit/x86/x86operand.h | 1974 +++++ .../3rd_party/AsmJit/x86/x86scheduler_p.h | 63 + 8 files changed, 17539 insertions(+), 1 deletion(-) create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86assembler.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86compiler.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86context_p.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86cpuinfo.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86inst.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86operand.h create mode 100644 Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86scheduler_p.h diff --git a/.gitignore b/.gitignore index 9491a2f..48cb432 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ mono_crash.* [Rr]elease/ [Rr]eleases/ x64/ -x86/ [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86assembler.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86assembler.h new file mode 100644 index 0000000..715eb73 --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86assembler.h @@ -0,0 +1,6680 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86ASSEMBLER_H +#define _ASMJIT_X86_X86ASSEMBLER_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../x86/x86inst.h" +#include "../x86/x86operand.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::X86Assembler] +// ============================================================================ + +// \internal +#define ASMJIT_X86_EMIT_OPTIONS(_Class_) \ + /*! Force short form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& short_() { \ + _instOptions |= kInstOptionShortForm; \ + return *this; \ + } \ + \ + /*! Force long form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& long_() { \ + _instOptions |= kInstOptionLongForm; \ + return *this; \ + } \ + \ + /*! Condition is likely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& taken() { \ + _instOptions |= kInstOptionTaken; \ + return *this; \ + } \ + \ + /*! Condition is unlikely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& notTaken() { \ + _instOptions |= kInstOptionNotTaken; \ + return *this; \ + } \ + \ + /*! Use LOCK prefix. */ \ + ASMJIT_INLINE _Class_& lock() { \ + _instOptions |= kX86InstOptionLock; \ + return *this; \ + } \ + \ + /*! Force REX prefix (X64). */ \ + ASMJIT_INLINE _Class_& rex() { \ + _instOptions |= kX86InstOptionRex; \ + return *this; \ + } \ + \ + /*! Force 3-byte VEX prefix (AVX+). */ \ + ASMJIT_INLINE _Class_& vex3() { \ + _instOptions |= kX86InstOptionVex3; \ + return *this; \ + } \ + \ + /*! Force 4-byte EVEX prefix (AVX512+). */ \ + ASMJIT_INLINE _Class_& evex() { \ + _instOptions |= kX86InstOptionEvex; \ + return *this; \ + } \ + \ + /*! Use zeroing instead of merging (AVX512+). */ \ + ASMJIT_INLINE _Class_& z() { \ + _instOptions |= kX86InstOptionEvexZero; \ + return *this; \ + } \ + \ + /*! Broadcast one element to all other elements (AVX512+). */ \ + ASMJIT_INLINE _Class_& _1ToN() { \ + _instOptions |= kX86InstOptionEvexOneN; \ + return *this; \ + } \ + \ + /*! Suppress all exceptions (AVX512+). */ \ + ASMJIT_INLINE _Class_& sae() { \ + _instOptions |= kX86InstOptionEvexSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-to-nearest` (even) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rn_sae() { \ + _instOptions |= kX86InstOptionEvexRnSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-down` (toward -inf) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rd_sae() { \ + _instOptions |= kX86InstOptionEvexRdSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-up` (toward +inf) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& ru_sae() { \ + _instOptions |= kX86InstOptionEvexRuSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-toward-zero` (truncate) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rz_sae() { \ + _instOptions |= kX86InstOptionEvexRzSae; \ + return *this; \ + } + +//! X86/X64 assembler. +//! +//! Assembler is the main class in AsmJit that can encode instructions and their +//! operands to a binary stream runnable by CPU. It creates internal buffer +//! where the encodes instructions are stored and it contains intrinsics that +//! can be used to emit the code in a convenent way. Code generation is in +//! general safe, because the intrinsics uses method overloading so even the +//! code is emitted it can be checked by a C++ compiler. It's nearly impossible +//! to create invalid instruction, for example `mov [eax], [eax]`, because such +//! overload doesn't exist. +//! +//! Each call to an assembler intrinsic function emits instruction directly +//! to the binary stream. There are also runtime checks that prevent invalid +//! code to be emitted. It will assert in debug mode and put the `Assembler` +//! instance to an error state in production mode. +//! +//! Code Generation +//! --------------- +//! +//! To generate code is only needed to create instance of `Assembler` +//! and to use intrinsics. See example how to do that: +//! +//! ~~~ +//! // Use asmjit namespace. +//! using namespace asmjit; +//! using namespace asmjit::x86; +//! +//! // Create X86Assembler instance. +//! X86Assembler a; +//! +//! // Prolog. +//! a.push(ebp); +//! a.mov(ebp, esp); +//! +//! // Mov 1024 to EAX, EAX is also return value. +//! a.mov(eax, 1024); +//! +//! // Epilog. +//! a.mov(esp, ebp); +//! a.pop(ebp); +//! +//! // Return. +//! a.ret(); +//! ~~~ +//! +//! You can see that syntax is very close to Intel one. Only difference is that +//! you are calling functions that emit binary code for you. All registers are +//! in `asmjit::x86` namespace, so it's very comfortable to use it (look at the +//! `use namespace` section). Without importing `asmjit::x86` registers would +//! have to be written as `x86::eax`, `x86::esp`, and so on. +//! +//! There is also possibility to use memory addresses and immediates. Use +//! `ptr()`, `byte_ptr()`, `word_ptr()`, `dword_ptr()` and similar functions to +//! build a memory address operand. In most cases `ptr()` is enough, because an +//! information related to the operand size is needed only in rare cases, that +//! is an instruction without having any register operands, such as `inc [mem]`. +//! +//! for example, `a` is an `X86Assembler` instance: +//! +//! ~~~ +//! a.mov(ptr(eax), 0); // mov ptr [eax], 0 +//! a.mov(ptr(eax), edx); // mov ptr [eax], edx +//! ~~~ +//! +//! But it's also possible to create complex addresses offered by x86 architecture: +//! +//! ~~~ +//! // eax + ecx*x addresses +//! a.mov(ptr(eax, ecx, 0), 0); // mov ptr [eax + ecx], 0 +//! a.mov(ptr(eax, ecx, 1), 0); // mov ptr [eax + ecx * 2], 0 +//! a.mov(ptr(eax, ecx, 2), 0); // mov ptr [eax + ecx * 4], 0 +//! a.mov(ptr(eax, ecx, 3), 0); // mov ptr [eax + ecx * 8], 0 +//! // eax + ecx*x + disp addresses +//! a.mov(ptr(eax, ecx, 0, 4), 0); // mov ptr [eax + ecx + 4], 0 +//! a.mov(ptr(eax, ecx, 1, 8), 0); // mov ptr [eax + ecx * 2 + 8], 0 +//! a.mov(ptr(eax, ecx, 2, 12), 0); // mov ptr [eax + ecx * 4 + 12], 0 +//! a.mov(ptr(eax, ecx, 3, 16), 0); // mov ptr [eax + ecx * 8 + 16], 0 +//! ~~~ +//! +//! All addresses shown are using `x86::ptr()` to make memory operand. Some +//! assembler instructions using a single operand need to know the size of +//! the operand to avoid ambiguity. For example `a.inc(ptr(eax))` is ambiguous +//! and would cause a runtime error. This problem can be fixed by using memory +//! operand with size specified - `byte_ptr`, `word_ptr`, `dword_ptr`, see the +//! code below: +//! +//! ~~~ +//! // [byte] address. +//! a.inc(byte_ptr(eax)); // Inc byte ptr [eax]. +//! a.dec(byte_ptr(eax)); // Dec byte ptr [eax]. +//! // [word] address. +//! a.inc(word_ptr(eax)); // Inc word ptr [eax]. +//! a.dec(word_ptr(eax)); // Dec word ptr [eax]. +//! // [dword] address. +//! a.inc(dword_ptr(eax)); // Inc dword ptr [eax]. +//! a.dec(dword_ptr(eax)); // Dec dword ptr [eax]. +//! // [dword] address. +//! a.inc(dword_ptr(rax)); // Inc qword ptr [rax]. +//! a.dec(dword_ptr(rax)); // Dec qword ptr [rax]. +//! ~~~ +//! +//! Calling JIT Code +//! ---------------- +//! +//! After you are finished with emitting instructions, you can make your function +//! callable by using `Assembler::make()` method. This method will use memory +//! manager to allocate virtual memory and relocates generated code to it. The +//! memory is allocated through `Runtime` instance provided to `X86Assembler` +//! constructor. +//! +//! The size of the code generated can be retrieved by `getCodeSize()` and +//! `getOffset()` methods. The `getOffset()` method returns the current offset +//! (that is mostly equal to the final code size, if called after the code +//! generation) and `getCodeSize()` returns the final code size with possible +//! trampolines. The `takeCode()` method can be used to take the internal buffer +//! and reset the code generator, but the buffer returned has to be freed manually +//! in such case. +//! +//! Machine code can be executed only in memory that is marked executable. This +//! mark is usually not set for memory returned by a C/C++ `malloc()` function. +//! The `VMemUtil::alloc()` function can be used allocate a memory where the code +//! can be executed. Please note that `VMemUtil` is a low-level class that works +//! at memory page level. High level interface that is similar to malloc/free is +//! provided by `VMemMgr` class. +//! +//! The next example shows how to allocate memory where the code can be executed: +//! +//! ~~~ +//! using namespace asmjit; +//! +//! JitRuntime runtime; +//! X86Assembler a(&runtime); +//! +//! ... Code generation ... +//! +//! // The function prototype. +//! typedef void (*MyFunc)(); +//! +//! // Make the function. +//! MyFunc func = asmjit_cast(a.make()); +//! +//! // Call the function. +//! func(); +//! +//! // Release the function if not needed anymore. +//! runtime.release(func); +//! ~~~ +//! +//! This was a very primitive example showing how the generated code can be. +//! executed by using the foundation of classes AsmJit offers. In production +//! nobody is likely to generate a function that is only called once and freed +//! immediately after it's been called, however, the concept of releasing code +//! that is not needed anymore should be clear. +//! +//! Labels +//! ------ +//! +//! While generating assembler code, you will usually need to create complex +//! code with labels. Labels are fully supported and you can call `jmp` or +//! `je` (and similar) instructions to initialized or yet uninitialized label. +//! Each label expects to be bound into offset. To bind label to specific +//! offset, use `CodeGen::bind()` method. +//! +//! See next example that contains complete code that creates simple memory +//! copy function (in DWord entities). +//! +//! ~~~ +//! // Example: Usage of Label (32-bit code). +//! // +//! // Create simple DWord memory copy function: +//! // ASMJIT_STDCALL void copy32(uint32_t* dst, const uint32_t* src, size_t count); +//! using namespace asmjit; +//! +//! // Assembler instance. +//! JitRuntime runtime; +//! Assembler a(&runtime); +//! +//! // Constants. +//! const int arg_offset = 8; // Arguments offset (STDCALL EBP). +//! const int arg_size = 12; // Arguments size. +//! +//! // Labels. +//! Label L_Loop(a); +//! +//! // Prolog. +//! a.push(ebp); +//! a.mov(ebp, esp); +//! a.push(esi); +//! a.push(edi); +//! +//! // Fetch arguments +//! a.mov(esi, dword_ptr(ebp, arg_offset + 0)); // Get dst. +//! a.mov(edi, dword_ptr(ebp, arg_offset + 4)); // Get src. +//! a.mov(ecx, dword_ptr(ebp, arg_offset + 8)); // Get count. +//! +//! // Bind L_Loop label to here. +//! a.bind(L_Loop); +//! +//! Copy 4 bytes. +//! a.mov(eax, dword_ptr(esi)); +//! a.mov(dword_ptr(edi), eax); +//! +//! // Increment pointers. +//! a.add(esi, 4); +//! a.add(edi, 4); +//! +//! // Repeat loop until (--ecx != 0). +//! a.dec(ecx); +//! a.jz(L_Loop); +//! +//! // Epilog. +//! a.pop(edi); +//! a.pop(esi); +//! a.mov(esp, ebp); +//! a.pop(ebp); +//! +//! // Return: Pop the stack by `arg_size` as defined by `STDCALL` convention. +//! a.ret(arg_size); +//! ~~~ +//! +//! If you need more abstraction for generating assembler code and you want +//! to hide calling conventions between 32-bit and 64-bit operating systems, +//! look at `Compiler` class that is designed for higher level code +//! generation. +//! +//! Advanced Code Generation +//! ------------------------ +//! +//! This section describes some advanced generation features of `Assembler` +//! class which can be simply overlooked. The first thing that is very likely +//! needed is generic register support. In previous example the named registers +//! were used. AsmJit contains functions which can convert register index into +//! operand and back. +//! +//! Let's define function which can be used to generate some abstract code: +//! +//! ~~~ +//! // Simple function that generates dword copy. +//! void genCopyDWord(Assembler& a, const X86GpReg& dst, const X86GpReg& src, const X86GpReg& tmp) { +//! a.mov(tmp, dword_ptr(src)); +//! a.mov(dword_ptr(dst), tmp); +//! } +//! ~~~ +//! +//! This function can be called like `genCopyDWord(a, edi, esi, ebx)` or by +//! using existing `X86GpReg` instances. This abstraction allows to join more +//! code sections together without rewriting each to use specific registers. +//! You need to take care only about implicit registers which may be used by +//! several instructions (like mul, imul, div, idiv, shifting, etc...). +//! +//! Next, more advanced, but often needed technique is that you can build your +//! own registers allocator. X86 architecture contains 8 general purpose +//! registers, 8 Mm registers and 8 Xmm/Ymm/Zmm registers. X64 architecture +//! extends the count of Gp registers and Xmm/Ymm/Zmm registers to 16. AVX-512 +//! architecture extends Xmm/Ymm/Zmm SIMD registers to 32. +//! +//! To create a general purpose register operand from register index use +//! `gpb_lo()`, `gpb_hi()`, `gpw()`, `gpd()`, `gpq()`. To create registers of +//! other types there `fp()`, `mm()`, `k()`, `xmm()`, `ymm()` and `zmm()` +//! functions available that return a new register operand. +//! +//! \sa X86Compiler. +struct ASMJIT_VCLASS X86Assembler : public Assembler { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_API X86Assembler(Runtime* runtime, uint32_t arch +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + = kArchHost +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + ); + ASMJIT_API virtual ~X86Assembler(); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + //! Get count of registers of the current architecture and mode. + ASMJIT_INLINE const X86RegCount& getRegCount() const { + return _regCount; + } + + //! Get Gpd or Gpq register depending on the current architecture. + ASMJIT_INLINE X86GpReg gpz(uint32_t index) const { + return X86GpReg(zax, index); + } + + //! Create an architecture dependent intptr_t memory operand. + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const { + return x86::ptr(label, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + ASMJIT_API Error setArch(uint32_t arch); + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void db(uint8_t x) { embed(&x, 1); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void dw(uint16_t x) { embed(&x, 2); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void dd(uint32_t x) { embed(&x, 4); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void dq(uint64_t x) { embed(&x, 8); } + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void dint8(int8_t x) { embed(&x, sizeof(int8_t)); } + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void duint8(uint8_t x) { embed(&x, sizeof(uint8_t)); } + + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void dint16(int16_t x) { embed(&x, sizeof(int16_t)); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void duint16(uint16_t x) { embed(&x, sizeof(uint16_t)); } + + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void dint32(int32_t x) { embed(&x, sizeof(int32_t)); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void duint32(uint32_t x) { embed(&x, sizeof(uint32_t)); } + + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void dint64(int64_t x) { embed(&x, sizeof(int64_t)); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void duint64(uint64_t x) { embed(&x, sizeof(uint64_t)); } + + //! Add float data to the instruction stream. + ASMJIT_INLINE void dfloat(float x) { embed(&x, sizeof(float)); } + //! Add double data to the instruction stream. + ASMJIT_INLINE void ddouble(double x) { embed(&x, sizeof(double)); } + + //! Add Mm data to the instruction stream. + ASMJIT_INLINE void dmm(const Vec64& x) { embed(&x, sizeof(Vec64)); } + //! Add Xmm data to the instruction stream. + ASMJIT_INLINE void dxmm(const Vec128& x) { embed(&x, sizeof(Vec128)); } + //! Add Ymm data to the instruction stream. + ASMJIT_INLINE void dymm(const Vec256& x) { embed(&x, sizeof(Vec256)); } + + //! Add data in a given structure instance to the instruction stream. + template + ASMJIT_INLINE void dstruct(const T& x) { embed(&x, static_cast(sizeof(T))); } + + //! Embed absolute label pointer (4 or 8 bytes). + ASMJIT_API Error embedLabel(const Label& op); + + // -------------------------------------------------------------------------- + // [Align] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error align(uint32_t mode, uint32_t offset); + + // -------------------------------------------------------------------------- + // [Reloc] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual size_t _relocCode(void* dst, Ptr baseAddress) const; + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + + // ------------------------------------------------------------------------- + // [Options] + // ------------------------------------------------------------------------- + + ASMJIT_X86_EMIT_OPTIONS(X86Assembler) + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of registers depending on the current architecture. + X86RegCount _regCount; + + //! EAX or RAX register depending on the current architecture. + X86GpReg zax; + //! ECX or RCX register depending on the current architecture. + X86GpReg zcx; + //! EDX or RDX register depending on the current architecture. + X86GpReg zdx; + //! EBX or RBX register depending on the current architecture. + X86GpReg zbx; + //! ESP or RSP register depending on the current architecture. + X86GpReg zsp; + //! EBP or RBP register depending on the current architecture. + X86GpReg zbp; + //! ESI or RSI register depending on the current architecture. + X86GpReg zsi; + //! EDI or RDI register depending on the current architecture. + X86GpReg zdi; + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + +#define INST_0x(_Inst_, _Code_) \ + ASMJIT_INLINE Error _Inst_() { \ + return emit(_Code_); \ + } + +#define INST_1x(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0); \ + } + +#define INST_1i(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(int o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(unsigned int o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(int64_t o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(uint64_t o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0) { \ + return emit(_Translate_(cc), o0); \ + } \ + \ + ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \ + ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \ + ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \ + ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \ + ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \ + ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \ + ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \ + ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \ + ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \ + ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \ + ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \ + ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \ + ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \ + ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \ + ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \ + ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \ + ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \ + ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \ + ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \ + ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \ + ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \ + ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \ + ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \ + ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \ + ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \ + ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \ + ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \ + ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \ + ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \ + ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); } + +#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Translate_(cc), o0, o1); \ + } \ + \ + ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); } + +#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1, int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1, unsigned int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1, int64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1, uint64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } + +#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2, int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2, unsigned int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2, int64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2, uint64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } + + // -------------------------------------------------------------------------- + // [X86/X64] + // -------------------------------------------------------------------------- + + //! Add with Carry. + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86GpReg) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86Mem) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86GpReg, Imm) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpReg) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) + + //! Add. + INST_2x(add, kX86InstIdAdd, X86GpReg, X86GpReg) + //! \overload + INST_2x(add, kX86InstIdAdd, X86GpReg, X86Mem) + //! \overload + INST_2i(add, kX86InstIdAdd, X86GpReg, Imm) + //! \overload + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpReg) + //! \overload + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) + + //! And. + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86GpReg) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86Mem) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86GpReg, Imm) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpReg) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) + + //! Bit scan forward. + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86GpReg, !o0.isGpb()) + //! \overload + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86Mem, !o0.isGpb()) + + //! Bit scan reverse. + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86GpReg, !o0.isGpb()) + //! \overload + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86Mem, !o0.isGpb()) + + //! Byte swap (32-bit or 64-bit registers only) (i486). + INST_1x_(bswap, kX86InstIdBswap, X86GpReg, o0.getSize() >= 4) + + //! Bit test. + INST_2x(bt, kX86InstIdBt, X86GpReg, X86GpReg) + //! \overload + INST_2i(bt, kX86InstIdBt, X86GpReg, Imm) + //! \overload + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpReg) + //! \overload + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) + + //! Bit test and complement. + INST_2x(btc, kX86InstIdBtc, X86GpReg, X86GpReg) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86GpReg, Imm) + //! \overload + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpReg) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) + + //! Bit test and reset. + INST_2x(btr, kX86InstIdBtr, X86GpReg, X86GpReg) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86GpReg, Imm) + //! \overload + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpReg) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) + + //! Bit test and set. + INST_2x(bts, kX86InstIdBts, X86GpReg, X86GpReg) + //! \overload + INST_2i(bts, kX86InstIdBts, X86GpReg, Imm) + //! \overload + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpReg) + //! \overload + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) + + //! Call. + INST_1x(call, kX86InstIdCall, X86GpReg) + //! \overload + INST_1x(call, kX86InstIdCall, X86Mem) + //! \overload + INST_1x(call, kX86InstIdCall, Label) + //! \overload + INST_1x(call, kX86InstIdCall, Imm) + //! \overload + ASMJIT_INLINE Error call(Ptr o0) { return call(Imm(o0)); } + + //! Clear carry flag. + INST_0x(clc, kX86InstIdClc) + //! Clear direction flag. + INST_0x(cld, kX86InstIdCld) + //! Complement carry flag. + INST_0x(cmc, kX86InstIdCmc) + + //! Convert BYTE to WORD (AX <- Sign Extend AL). + INST_0x(cbw, kX86InstIdCbw) + //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). + INST_0x(cdq, kX86InstIdCdq) + //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only). + INST_0x(cdqe, kX86InstIdCdqe) + //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only). + INST_0x(cqo, kX86InstIdCqo) + //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). + INST_0x(cwd, kX86InstIdCwd) + //! Convert WORD to DWORD (EAX <- Sign Extend AX). + INST_0x(cwde, kX86InstIdCwde) + + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86GpReg) + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86Mem) + + //! Compare two operands. + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86GpReg) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86Mem) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86GpReg, Imm) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpReg) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm) + + //! Compare BYTE in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsb, kX86InstIdCmpsB) + //! Compare DWORD in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsd, kX86InstIdCmpsD) + //! Compare QWORD in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(cmpsq, kX86InstIdCmpsQ) + //! Compare WORD in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsw, kX86InstIdCmpsW) + + //! Compare and exchange (i486). + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86GpReg, X86GpReg) + //! \overload + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86Mem, X86GpReg) + + //! Compare and exchange 128-bit value in RDX:RAX with the memory operand (X64 Only). + INST_1x(cmpxchg16b, kX86InstIdCmpxchg16b, X86Mem) + //! Compare and exchange 64-bit value in EDX:EAX with the memory operand (Pentium). + INST_1x(cmpxchg8b, kX86InstIdCmpxchg8b, X86Mem) + + //! CPU identification (i486). + INST_0x(cpuid, kX86InstIdCpuid) + + //! Decimal adjust AL after addition (X86 Only). + INST_0x(daa, kX86InstIdDaa) + //! Decimal adjust AL after subtraction (X86 Only). + INST_0x(das, kX86InstIdDas) + + //! Decrement by 1. + INST_1x(dec, kX86InstIdDec, X86GpReg) + //! \overload + INST_1x(dec, kX86InstIdDec, X86Mem) + + //! Unsigned divide (xDX:xAX <- xDX:xAX / o0). + INST_1x(div, kX86InstIdDiv, X86GpReg) + //! \overload + INST_1x(div, kX86InstIdDiv, X86Mem) + + //! Make stack frame for procedure parameters. + INST_2x(enter, kX86InstIdEnter, Imm, Imm) + + //! Signed divide (xDX:xAX <- xDX:xAX / op). + INST_1x(idiv, kX86InstIdIdiv, X86GpReg) + //! \overload + INST_1x(idiv, kX86InstIdIdiv, X86Mem) + + //! Signed multiply (xDX:xAX <- xAX * o0). + INST_1x(imul, kX86InstIdImul, X86GpReg) + //! \overload + INST_1x(imul, kX86InstIdImul, X86Mem) + + //! Signed multiply. + INST_2x(imul, kX86InstIdImul, X86GpReg, X86GpReg) + //! \overload + INST_2x(imul, kX86InstIdImul, X86GpReg, X86Mem) + //! \overload + INST_2i(imul, kX86InstIdImul, X86GpReg, Imm) + + //! Signed multiply. + INST_3i(imul, kX86InstIdImul, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(imul, kX86InstIdImul, X86GpReg, X86Mem, Imm) + + //! Increment by 1. + INST_1x(inc, kX86InstIdInc, X86GpReg) + //! \overload + INST_1x(inc, kX86InstIdInc, X86Mem) + + //! Interrupt. + INST_1i(int_, kX86InstIdInt, Imm) + //! Interrupt 3 - trap to debugger. + ASMJIT_INLINE Error int3() { return int_(3); } + + //! Jump to `label` if condition `cc` is met. + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) + + //! Short jump if CX/ECX/RCX is zero. + INST_2x_(jecxz, kX86InstIdJecxz, X86GpReg, Label, o0.getRegIndex() == kX86RegIndexCx) + + //! Jump. + INST_1x(jmp, kX86InstIdJmp, X86GpReg) + //! \overload + INST_1x(jmp, kX86InstIdJmp, X86Mem) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Label) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Imm) + //! \overload + ASMJIT_INLINE Error jmp(Ptr dst) { return jmp(Imm(dst)); } + + //! Load AH from flags. + INST_0x(lahf, kX86InstIdLahf) + + //! Load effective address + INST_2x(lea, kX86InstIdLea, X86GpReg, X86Mem) + + //! High level procedure exit. + INST_0x(leave, kX86InstIdLeave) + + //! Load BYTE from DS:[ESI/RSI] to AL. + INST_0x(lodsb, kX86InstIdLodsB) + //! Load DWORD from DS:[ESI/RSI] to EAX. + INST_0x(lodsd, kX86InstIdLodsD) + //! Load QWORD from DS:[RDI] to RAX (X64 Only). + INST_0x(lodsq, kX86InstIdLodsQ) + //! Load WORD from DS:[ESI/RSI] to AX. + INST_0x(lodsw, kX86InstIdLodsW) + + //! Move. + INST_2x(mov, kX86InstIdMov, X86GpReg, X86GpReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86GpReg, X86Mem) + //! \overload + INST_2i(mov, kX86InstIdMov, X86GpReg, Imm) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpReg) + //! \overload + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) + + //! Move from segment register. + INST_2x(mov, kX86InstIdMov, X86GpReg, X86SegReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) + //! Move to segment register. + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) + + //! Move (AL|AX|EAX|RAX <- absolute address in immediate). + INST_2x_(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm, o0.getRegIndex() == 0); + //! \overload + ASMJIT_INLINE Error mov_ptr(const X86GpReg& o0, Ptr o1) { + ASMJIT_ASSERT(o0.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, o0, Imm(o1)); + } + + //! Move (absolute address in immediate <- AL|AX|EAX|RAX). + INST_2x_(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg, o1.getRegIndex() == 0); + //! \overload + ASMJIT_INLINE Error mov_ptr(Ptr o0, const X86GpReg& o1) { + ASMJIT_ASSERT(o1.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, Imm(o0), o1); + } + + //! Move data after dwapping bytes (SSE3 - Atom). + INST_2x_(movbe, kX86InstIdMovbe, X86GpReg, X86Mem, !o0.isGpb()); + //! \overload + INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpReg, !o1.isGpb()); + + //! Move BYTE from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsb, kX86InstIdMovsB) + //! Move DWORD from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsd, kX86InstIdMovsD) + //! Move QWORD from DS:[RSI] to ES:[RDI] (X64 Only). + INST_0x(movsq, kX86InstIdMovsQ) + //! Move WORD from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsw, kX86InstIdMovsW) + + //! Move with sign-extension. + INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86GpReg) + //! \overload + INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86Mem) + + //! Move DWORD to QWORD with sign-extension (X64 Only). + INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86GpReg) + //! \overload + INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86Mem) + + //! Move with zero-extension. + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86GpReg) + //! \overload + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86Mem) + + //! Unsigned multiply (xDX:xAX <- xAX * o0). + INST_1x(mul, kX86InstIdMul, X86GpReg) + //! \overload + INST_1x(mul, kX86InstIdMul, X86Mem) + + //! Two's complement negation. + INST_1x(neg, kX86InstIdNeg, X86GpReg) + //! \overload + INST_1x(neg, kX86InstIdNeg, X86Mem) + + //! No operation. + INST_0x(nop, kX86InstIdNop) + + //! One's complement negation. + INST_1x(not_, kX86InstIdNot, X86GpReg) + //! \overload + INST_1x(not_, kX86InstIdNot, X86Mem) + + //! Or. + INST_2x(or_, kX86InstIdOr, X86GpReg, X86GpReg) + //! \overload + INST_2x(or_, kX86InstIdOr, X86GpReg, X86Mem) + //! \overload + INST_2i(or_, kX86InstIdOr, X86GpReg, Imm) + //! \overload + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpReg) + //! \overload + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) + + //! Pop a value from the stack. + INST_1x_(pop, kX86InstIdPop, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + //! \overload + INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + + //! Pop a segment register from the stack. + //! + //! \note There is no instruction to pop a cs segment register. + INST_1x_(pop, kX86InstIdPop, X86SegReg, o0.getRegIndex() != kX86SegCs); + + //! Pop all Gp registers - EDI|ESI|EBP|Ign|EBX|EDX|ECX|EAX (X86 Only). + INST_0x(popa, kX86InstIdPopa) + + //! Pop stack into EFLAGS register (32-bit or 64-bit). + INST_0x(popf, kX86InstIdPopf) + + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push segment register on the stack. + INST_1x(push, kX86InstIdPush, X86SegReg) + //! Push WORD or DWORD/QWORD on the stack. + INST_1i(push, kX86InstIdPush, Imm) + + //! Push all Gp registers - EAX|ECX|EDX|EBX|ESP|EBP|ESI|EDI (X86 Only). + INST_0x(pusha, kX86InstIdPusha) + + //! Push EFLAGS register (32-bit or 64-bit) on the stack. + INST_0x(pushf, kX86InstIdPushf) + + //! Rotate bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rcl, kX86InstIdRcl, X86GpReg, X86GpReg) + //! \overload + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpReg) + //! Rotate bits left. + INST_2i(rcl, kX86InstIdRcl, X86GpReg, Imm) + //! \overload + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) + + //! Rotate bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rcr, kX86InstIdRcr, X86GpReg, X86GpReg) + //! \overload + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpReg) + //! Rotate bits right. + INST_2i(rcr, kX86InstIdRcr, X86GpReg, Imm) + //! \overload + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) + + //! Read time-stamp counter (Pentium). + INST_0x(rdtsc, kX86InstIdRdtsc) + //! Read time-stamp counter and processor id (Pentium). + INST_0x(rdtscp, kX86InstIdRdtscp) + + //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL. + INST_0x(rep_lodsb, kX86InstIdRepLodsB) + //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to EAX. + INST_0x(rep_lodsd, kX86InstIdRepLodsD) + //! Repeated load ECX/RCX QWORDs from DS:[RDI] to RAX (X64 Only). + INST_0x(rep_lodsq, kX86InstIdRepLodsQ) + //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX. + INST_0x(rep_lodsw, kX86InstIdRepLodsW) + + //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsb, kX86InstIdRepMovsB) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsd, kX86InstIdRepMovsD) + //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only). + INST_0x(rep_movsq, kX86InstIdRepMovsQ) + //! Repeated move ECX/RCX WORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsw, kX86InstIdRepMovsW) + + //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL. + INST_0x(rep_stosb, kX86InstIdRepStosB) + //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX. + INST_0x(rep_stosd, kX86InstIdRepStosD) + //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only). + INST_0x(rep_stosq, kX86InstIdRepStosQ) + //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX. + INST_0x(rep_stosw, kX86InstIdRepStosW) + + //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsb, kX86InstIdRepeCmpsB) + //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsd, kX86InstIdRepeCmpsD) + //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(repe_cmpsq, kX86InstIdRepeCmpsQ) + //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsw, kX86InstIdRepeCmpsW) + + //! Repeated find non-AL BYTE starting at ES:[EDI/RDI]. + INST_0x(repe_scasb, kX86InstIdRepeScasB) + //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_0x(repe_scasd, kX86InstIdRepeScasD) + //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only). + INST_0x(repe_scasq, kX86InstIdRepeScasQ) + //! Repeated find non-AX WORD starting at ES:[EDI/RDI]. + INST_0x(repe_scasw, kX86InstIdRepeScasW) + + //! Repeated find AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsb, kX86InstIdRepneCmpsB) + //! Repeated find EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsd, kX86InstIdRepneCmpsD) + //! Repeated find RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(repne_cmpsq, kX86InstIdRepneCmpsQ) + //! Repeated find AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsw, kX86InstIdRepneCmpsW) + + //! Repeated find AL BYTEs starting at ES:[EDI/RDI]. + INST_0x(repne_scasb, kX86InstIdRepneScasB) + //! Repeated find EAX DWORDs starting at ES:[EDI/RDI]. + INST_0x(repne_scasd, kX86InstIdRepneScasD) + //! Repeated find RAX QWORDs starting at ES:[RDI] (X64 Only). + INST_0x(repne_scasq, kX86InstIdRepneScasQ) + //! Repeated find AX WORDs starting at ES:[EDI/RDI]. + INST_0x(repne_scasw, kX86InstIdRepneScasW) + + //! Return. + INST_0x(ret, kX86InstIdRet) + //! \overload + INST_1i(ret, kX86InstIdRet, Imm) + + //! Rotate bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rol, kX86InstIdRol, X86GpReg, X86GpReg) + //! \overload + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpReg) + //! Rotate bits left. + INST_2i(rol, kX86InstIdRol, X86GpReg, Imm) + //! \overload + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) + + //! Rotate bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(ror, kX86InstIdRor, X86GpReg, X86GpReg) + //! \overload + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpReg) + //! Rotate bits right. + INST_2i(ror, kX86InstIdRor, X86GpReg, Imm) + //! \overload + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) + + //! Store AH into flags. + INST_0x(sahf, kX86InstIdSahf) + + //! Integer subtraction with borrow. + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86GpReg) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86Mem) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86GpReg, Imm) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpReg) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) + + //! Shift bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(sal, kX86InstIdSal, X86GpReg, X86GpReg) + //! \overload + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpReg) + //! Shift bits left. + INST_2i(sal, kX86InstIdSal, X86GpReg, Imm) + //! \overload + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) + + //! Shift bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(sar, kX86InstIdSar, X86GpReg, X86GpReg) + //! \overload + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpReg) + //! Shift bits right. + INST_2i(sar, kX86InstIdSar, X86GpReg, Imm) + //! \overload + INST_2i(sar, kX86InstIdSar, X86Mem, Imm) + + //! Find non-AL BYTE starting at ES:[EDI/RDI]. + INST_0x(scasb, kX86InstIdScasB) + //! Find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_0x(scasd, kX86InstIdScasD) + //! Find non-rax QWORD starting at ES:[RDI] (X64 Only). + INST_0x(scasq, kX86InstIdScasQ) + //! Find non-AX WORD starting at ES:[EDI/RDI]. + INST_0x(scasw, kX86InstIdScasW) + + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpReg) + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) + + //! Shift bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(shl, kX86InstIdShl, X86GpReg, X86GpReg) + //! \overload + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpReg) + //! Shift bits left. + INST_2i(shl, kX86InstIdShl, X86GpReg, Imm) + //! \overload + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) + + //! Shift bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(shr, kX86InstIdShr, X86GpReg, X86GpReg) + //! \overload + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpReg) + //! Shift bits right. + INST_2i(shr, kX86InstIdShr, X86GpReg, Imm) + //! \overload + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) + + //! Double precision shift left. + //! + //! \note `o2` register can be only `cl` register. + INST_3x(shld, kX86InstIdShld, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpReg, X86GpReg) + //! Double precision shift left. + INST_3i(shld, kX86InstIdShld, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpReg, Imm) + + //! Double precision shift right. + //! + //! \note `o2` register can be only `cl` register. + INST_3x(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpReg, X86GpReg) + //! Double precision shift right. + INST_3i(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpReg, Imm) + + //! Set carry flag to 1. + INST_0x(stc, kX86InstIdStc) + //! Set direction flag to 1. + INST_0x(std, kX86InstIdStd) + + //! Fill BYTE at ES:[EDI/RDI] with AL. + INST_0x(stosb, kX86InstIdStosB) + //! Fill DWORD at ES:[EDI/RDI] with EAX. + INST_0x(stosd, kX86InstIdStosD) + //! Fill QWORD at ES:[RDI] with RAX (X64 Only). + INST_0x(stosq, kX86InstIdStosQ) + //! Fill WORD at ES:[EDI/RDI] with AX. + INST_0x(stosw, kX86InstIdStosW) + + //! Subtract. + INST_2x(sub, kX86InstIdSub, X86GpReg, X86GpReg) + //! \overload + INST_2x(sub, kX86InstIdSub, X86GpReg, X86Mem) + //! \overload + INST_2i(sub, kX86InstIdSub, X86GpReg, Imm) + //! \overload + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpReg) + //! \overload + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) + + //! Logical compare. + INST_2x(test, kX86InstIdTest, X86GpReg, X86GpReg) + //! \overload + INST_2i(test, kX86InstIdTest, X86GpReg, Imm) + //! \overload + INST_2x(test, kX86InstIdTest, X86Mem, X86GpReg) + //! \overload + INST_2i(test, kX86InstIdTest, X86Mem, Imm) + + //! Undefined instruction - Raise #UD exception. + INST_0x(ud2, kX86InstIdUd2) + + //! Exchange and Add. + INST_2x(xadd, kX86InstIdXadd, X86GpReg, X86GpReg) + //! \overload + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpReg) + + //! Exchange register/memory with register. + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86GpReg) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpReg) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86Mem) + + //! Xor. + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86GpReg) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86Mem) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86GpReg, Imm) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpReg) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [FPU] + // -------------------------------------------------------------------------- + + //! Compute `2^x - 1` - `fp0 = POW(2, fp0) - 1` (FPU). + INST_0x(f2xm1, kX86InstIdF2xm1) + //! Abs `fp0 = ABS(fp0)` (FPU). + INST_0x(fabs, kX86InstIdFabs) + + //! Add `o0 = o0 + o1` (one operand has to be `fp0`) (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add `fp0 = fp0 + float_or_double[o0]` (FPU). + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add `o0 = o0 + fp0` and POP (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) + //! Add `fp1 = fp1 + fp0` and POP (FPU). + INST_0x(faddp, kX86InstIdFaddp) + + //! Load BCD from `[o0]` and PUSH (FPU). + INST_1x(fbld, kX86InstIdFbld, X86Mem) + //! Store BCD-Integer to `[o0]` and POP (FPU). + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) + + //! Complement Sign `fp0 = -fp0` (FPU). + INST_0x(fchs, kX86InstIdFchs) + + //! Clear exceptions (FPU). + INST_0x(fclex, kX86InstIdFclex) + + //! Conditional move `if (CF=1) fp0 = o0` (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move `if (CF|ZF=1) fp0 = o0` (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move `if (ZF=1) fp0 = o0` (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move `if (CF=0) fp0 = o0` (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move `if (CF|ZF=0) fp0 = o0` (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move `if (ZF=0) fp0 = o0` (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move `if (PF=0) fp0 = o0` (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move `if (PF=1) fp0 = o0` (FPU). + INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) + + //! Compare `fp0` with `o0` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86FpReg) + //! Compare `fp0` with `fp1` (FPU). + INST_0x(fcom, kX86InstIdFcom) + //! Compare `fp0` with `float_or_double[o0]` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare `fp0` with `o0` and POP (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare `fp0` with `fp1` and POP (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare `fp0` with `float_or_double[o0]` and POP (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare `fp0` with `fp1` and POP twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) + //! Compare `fp0` with `o0` and set EFLAGS (FPU). + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare `fp0` with `o0` and set EFLAGS and POP (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) + + //! Cos `fp0 = cos(fp0)` (FPU). + INST_0x(fcos, kX86InstIdFcos) + + //! Decrement FPU stack pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) + + //! Divide `o0 = o0 / o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide `fp0 = fp0 / float_or_double[o0]` (FPU). + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) + //! Divide `o0 = o0 / fp0` and POP (FPU). + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) + //! Divide `fp1 = fp1 / fp0` and POP (FPU). + INST_0x(fdivp, kX86InstIdFdivp) + + //! Reverse divide `o0 = o1 / o0` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide `fp0 = float_or_double[o0] / fp0` (FPU). + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) + //! Reverse divide `o0 = fp0 / o0` and POP (FPU). + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) + //! Reverse divide `fp1 = fp0 / fp1` and POP (FPU). + INST_0x(fdivrp, kX86InstIdFdivrp) + + //! Free FP register (FPU). + INST_1x(ffree, kX86InstIdFfree, X86FpReg) + + //! Add `fp0 = fp0 + short_or_int[o0]` (FPU). + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare `fp0` with `short_or_int[o0]` (FPU). + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare `fp0` with `short_or_int[o0]` and POP (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Divide `fp0 = fp0 / short_or_int[o0]` (FPU). + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse divide `fp0 = short_or_int[o0] / fp0` (FPU). + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Load `short_or_int_or_long[o0]` and PUSH (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Multiply `fp0 *= short_or_int[o0]` (FPU). + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Increment FPU stack pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) + //! Initialize FPU (FPU). + INST_0x(finit, kX86InstIdFinit) + + //! Subtract `fp0 = fp0 - short_or_int[o0]` (FPU). + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse subtract `fp0 = short_or_int[o0] - fp0` (FPU). + INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Initialize FPU without checking for pending unmasked exceptions (FPU). + INST_0x(fninit, kX86InstIdFninit) + + //! Store `fp0` as `short_or_int[o0]` (FPU). + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store `fp0` as `short_or_int_or_long[o0]` and POP (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + + //! Load `float_or_double_or_extended[o0]` and PUSH (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! PUSH `o0` (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) + + //! PUSH `1.0` (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! PUSH `log2(10)` (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! PUSH `log2(e)` (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! PUSH `pi` (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! PUSH `log10(2)` (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! PUSH `ln(2)` (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! PUSH `+0.0` (FPU). + INST_0x(fldz, kX86InstIdFldz) + + //! Load x87 FPU control word from `word_ptr[o0]` (FPU). + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) + //! Load x87 FPU environment (14 or 28 bytes) from `[o0]` (FPU). + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) + + //! Multiply `o0 = o0 * o1` (one has to be `fp0`) (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply `fp0 = fp0 * float_or_double[o0]` (FPU). + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply `o0 = o0 * fp0` and POP (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) + //! Multiply `fp1 = fp1 * fp0` and POP (FPU). + INST_0x(fmulp, kX86InstIdFmulp) + + //! Clear exceptions (FPU). + INST_0x(fnclex, kX86InstIdFnclex) + //! No operation (FPU). + INST_0x(fnop, kX86InstIdFnop) + //! Save FPU state to `[o0]` (FPU). + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) + //! Store x87 FPU environment to `[o0]` (FPU). + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) + //! Store x87 FPU control word to `[o0]` (FPU). + INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) + + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) + + //! Partial Arctan `fp1 = atan2(fp1, fp0)` and POP (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Partial Remainder[Trunc] `fp1 = fp0 % fp1` and POP (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Partial Remainder[Round] `fp1 = fp0 % fp1` and POP (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Partial Tan `fp0 = tan(fp0)` and PUSH `1.0` (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0 = round(fp0)` (FPU). + INST_0x(frndint, kX86InstIdFrndint) + + //! Restore FPU state from `[o0]` (94 or 108 bytes) (FPU). + INST_1x(frstor, kX86InstIdFrstor, X86Mem) + //! Save FPU state to `[o0]` (94 or 108 bytes) (FPU). + INST_1x(fsave, kX86InstIdFsave, X86Mem) + + //! Scale `fp0 = fp0 * pow(2, RoundTowardsZero(fp1))` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sin `fp0 = sin(fp0)` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sincos `fp0 = sin(fp0)` and PUSH `cos(fp0)` (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root `fp0 = sqrt(fp0)` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + + //! Store floating point value to `float_or_double[o0]` (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Copy `o0 = fp0` (FPU). + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to `float_or_double_or_extended[o0]` and POP (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Copy `o0 = fp0` and POP (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) + + //! Store x87 FPU control word to `word_ptr[o0]` (FPU). + INST_1x(fstcw, kX86InstIdFstcw, X86Mem) + //! Store x87 FPU environment to `[o0]` (14 or 28 bytes) (FPU). + INST_1x(fstenv, kX86InstIdFstenv, X86Mem) + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x_(fstsw, kX86InstIdFstsw, X86GpReg, o0.getRegIndex() == kX86RegIndexAx) + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) + + //! Subtract `o0 = o0 - o1` (one has to be `fp0`) (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract `fp0 = fp0 - float_or_double[o0]` (FPU). + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract `o0 = o0 - fp0` and POP (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) + //! Subtract `fp1 = fp1 - fp0` and POP (FPU). + INST_0x(fsubp, kX86InstIdFsubp) + + //! Reverse subtract `o0 = o1 - o0` (one has to be `fp0`) (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract `fp0 = fp0 - float_or_double[o0]` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `o0 = o0 - fp0` and POP (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) + //! Reverse subtract `fp1 = fp1 - fp0` and POP (FPU). + INST_0x(fsubrp, kX86InstIdFsubrp) + + //! Compare `fp0` with `0.0` (FPU). + INST_0x(ftst, kX86InstIdFtst) + + //! Unordered compare `fp0` with `o0` (FPU). + INST_1x(fucom, kX86InstIdFucom, X86FpReg) + //! Unordered compare `fp0` with `fp1` (FPU). + INST_0x(fucom, kX86InstIdFucom) + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS and POP (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and POP (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and POP (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and POP twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) + + INST_0x(fwait, kX86InstIdFwait) + + //! Examine fp0 (FPU). + INST_0x(fxam, kX86InstIdFxam) + //! Exchange `fp0` with `o0` (FPU). + INST_1x(fxch, kX86InstIdFxch, X86FpReg) + + //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) + //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxsave, kX86InstIdFxsave, X86Mem) + //! Extract `fp0 = exponent(fp0)` and PUSH `significant(fp0)` (FPU). + INST_0x(fxtract, kX86InstIdFxtract) + + //! Compute `fp1 = fp1 * log2(fp0)` and POP (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 = fp1 * log2(fp0 + 1)` and POP (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) + + // -------------------------------------------------------------------------- + // [MMX] + // -------------------------------------------------------------------------- + + //! Move DWORD (MMX). + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86MmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86GpReg) + + //! Move QWORD (MMX). + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpReg, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86GpReg) + + //! Pack DWORDs to WORDs with signed saturation (MMX). + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86MmReg) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (MMX). + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86MmReg) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (MMX). + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86MmReg) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86Mem) + + //! Packed BYTE add (MMX). + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86Mem) + + //! Packed DWORD add (MMX). + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86Mem) + + //! Packed BYTE add with saturation (MMX). + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86Mem) + + //! Packed WORD add with saturation (MMX). + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (MMX). + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (MMX). + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86Mem) + + //! Packed WORD add (MMX). + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86Mem) + + //! Packed bitwise and (MMX). + INST_2x(pand, kX86InstIdPand, X86MmReg, X86MmReg) + //! \overload + INST_2x(pand, kX86InstIdPand, X86MmReg, X86Mem) + + //! Packed bitwise and-not (MMX). + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86MmReg) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86Mem) + + //! Packed BYTEs compare for equality (MMX). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86Mem) + + //! Packed DWORDs compare for equality (MMX). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86Mem) + + //! Packed WORDs compare for equality (MMX). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86Mem) + + //! Packed BYTEs compare if greater than (MMX). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86Mem) + + //! Packed DWORDs compare if greater than (MMX). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86Mem) + + //! Packed WORDs compare if greater than (MMX). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86Mem) + + //! Packed WORDs multiply high (MMX). + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86Mem) + + //! Packed WORDs multiply low (MMX). + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86Mem) + + //! Pakced bitwise or (MMX). + INST_2x(por, kX86InstIdPor, X86MmReg, X86MmReg) + //! \overload + INST_2x(por, kX86InstIdPor, X86MmReg, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (MMX). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86Mem) + + //! Packed DWORD shift left logical (MMX). + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86MmReg) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86MmReg, Imm) + + //! Packed QWORD shift left logical (MMX). + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86MmReg, Imm) + + //! Packed WORD shift left logical (MMX). + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86MmReg, Imm) + + //! Packed DWORD shift right arithmetic (MMX). + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86MmReg, Imm) + + //! Packed WORD shift right arithmetic (MMX). + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86MmReg, Imm) + + //! Packed DWORD shift right logical (MMX). + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86MmReg, Imm) + + //! Packed QWORD shift right logical (MMX). + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86MmReg, Imm) + + //! Packed WORD shift right logical (MMX). + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86MmReg, Imm) + + //! Packed BYTE subtract (MMX). + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86Mem) + + //! Packed DWORD subtract (MMX). + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86Mem) + + //! Packed BYTE subtract with saturation (MMX). + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86Mem) + + //! Packed WORD subtract with saturation (MMX). + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (MMX). + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (MMX). + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86Mem) + + //! Packed WORD subtract (MMX). + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (MMX). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (MMX). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (MMX). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (MMX). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (MMX). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (MMX). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86Mem) + + //! Packed bitwise xor (MMX). + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86MmReg) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86Mem) + + //! Empty MMX state. + INST_0x(emms, kX86InstIdEmms) + + // ------------------------------------------------------------------------- + // [3dNow] + // ------------------------------------------------------------------------- + + //! Packed SP-FP to DWORD convert (3dNow!). + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86MmReg) + //! \overload + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86Mem) + + //! Packed SP-FP to WORD convert (3dNow!). + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86Mem) + + //! Packed SP-FP accumulate (3dNow!). + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86Mem) + + //! Packed SP-FP addition (3dNow!). + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst == src (3dNow!). + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst >= src (3dNow!). + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst > src (3dNow!). + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86Mem) + + //! Packed SP-FP maximum (3dNow!). + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86Mem) + + //! Packed SP-FP minimum (3dNow!). + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86Mem) + + //! Packed SP-FP multiply (3dNow!). + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86Mem) + + //! Packed SP-FP negative accumulate (3dNow!). + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86Mem) + + //! Packed SP-FP mixed accumulate (3dNow!). + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal Approximation (3dNow!). + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal, first iteration step (3dNow!). + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal, second iteration step (3dNow!). + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal square root approximation (3dNow!). + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86Mem) + + //! Packed SP-FP subtract (3dNow!). + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86Mem) + + //! Packed SP-FP reverse subtract (3dNow!). + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86Mem) + + //! Packed DWORDs to SP-FP (3dNow!). + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86Mem) + + //! Packed WORDs to SP-FP (3dNow!). + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86Mem) + + //! Packed swap DWORDs (3dNow!) + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86Mem) + + //! Prefetch (3dNow!). + INST_1x(prefetch3dnow, kX86InstIdPrefetch3dNow, X86Mem) + + //! Prefetch and set cache to modified (3dNow!). + INST_1x(prefetchw3dnow, kX86InstIdPrefetchw3dNow, X86Mem) + + //! Faster EMMS (3dNow!). + INST_0x(femms, kX86InstIdFemms) + + // -------------------------------------------------------------------------- + // [SSE] + // -------------------------------------------------------------------------- + + //! Packed SP-FP add (SSE). + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86Mem) + + //! Scalar SP-FP add (SSE). + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise and-not (SSE). + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise and (SSE). + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86Mem) + + //! Packed SP-FP compare (SSE). + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86Mem, Imm) + + //! Compare scalar SP-FP (SSE). + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86Mem, Imm) + + //! Scalar ordered SP-FP compare and set EFLAGS (SSE). + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86Mem) + + //! Packed signed INT32 to packed SP-FP conversion (SSE). + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86MmReg) + //! \overload + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86Mem) + + //! Packed SP-FP to packed INT32 conversion (SSE). + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86Mem) + + //! Convert scalar INT32 to SP-FP (SSE). + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86GpReg) + //! \overload + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to INT32 (SSE). + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed INT32 (SSE). + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (SSE). + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86Mem) + + //! Packed SP-FP divide (SSE). + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86Mem) + + //! Scalar SP-FP divide (SSE). + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86Mem) + + //! Load streaming SIMD extension control/status (SSE). + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) + + //! Byte mask write to DS:EDI/RDI (SSE). + INST_2x(maskmovq, kX86InstIdMaskmovq, X86MmReg, X86MmReg) + + //! Packed SP-FP maximum (SSE). + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86Mem) + + //! Scalar SP-FP maximum (SSE). + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86Mem) + + //! Packed SP-FP minimum (SSE). + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86Mem) + + //! Scalar SP-FP minimum (SSE). + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86Mem) + + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86Mem) + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmReg) + + //! Move DWORD. + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86GpReg) + + //! Move QWORD (SSE). + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpReg, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86GpReg) + + //! Move QWORD using NT hint (SSE). + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmReg) + + //! Move high to low packed SP-FP (SSE). + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmReg, X86XmmReg) + + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86XmmReg, X86Mem) + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmReg) + + //! Move low to high packed SP-FP (SSE). + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmReg, X86XmmReg) + + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86XmmReg, X86Mem) + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmReg) + + //! Move aligned packed SP-FP using NT hint (SSE). + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmReg) + + //! Move scalar SP-FP (SSE). + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86Mem) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmReg) + + //! Move unaligned packed SP-FP (SSE). + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86Mem) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmReg) + + //! Packed SP-FP multiply (SSE). + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86Mem) + + //! Scalar SP-FP multiply (SSE). + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise or (SSE). + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86Mem) + + //! Packed BYTE average (SSE). + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86Mem) + + //! Packed WORD average (SSE). + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86Mem) + + //! Extract WORD based on selector (SSE). + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86MmReg, Imm) + + //! Insert WORD based on selector (SSE). + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86Mem, Imm) + + //! Packed WORD maximum (SSE). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86Mem) + + //! Packed BYTE unsigned maximum (SSE). + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86Mem) + + //! Packed WORD minimum (SSE). + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86Mem) + + //! Packed BYTE unsigned minimum (SSE). + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86Mem) + + //! Move Byte mask to integer (SSE). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86MmReg) + + //! Packed WORD unsigned multiply high (SSE). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86Mem) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86Mem) + + //! Packed WORD shuffle (SSE). + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86MmReg, Imm) + //! \overload + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86Mem, Imm) + + //! Packed SP-FP reciprocal (SSE). + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86Mem) + + //! Scalar SP-FP reciprocal (SSE). + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86Mem) + + //! Prefetch (SSE). + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86Mem) + + //! Packed SP-FP square root reciprocal (SSE). + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root reciprocal (SSE). + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86Mem) + + //! Store fence (SSE). + INST_0x(sfence, kX86InstIdSfence) + + //! Shuffle SP-FP (SSE). + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP square root (SSE). + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root (SSE). + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86Mem) + + //! Store streaming SIMD extension control/status (SSE). + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) + + //! Packed SP-FP subtract (SSE). + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86Mem) + + //! Scalar SP-FP subtract (SSE). + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (SSE). + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86Mem) + + //! Unpack high packed SP-FP data (SSE). + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86Mem) + + //! Unpack low packed SP-FP data (SSE). + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise xor (SSE). + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE2] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (SSE2). + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP add (SSE2). + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise and-not (SSE2). + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise and (SSE2). + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86Mem) + + //! Flush cache line (SSE2). + INST_1x(clflush, kX86InstIdClflush, X86Mem) + + //! Packed DP-FP compare (SSE2). + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP compare (SSE2). + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86Mem, Imm) + + //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed DP-FP (SSE2). + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed SP-FP (SSE2). + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (SSE2). + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86Mem) + + //! Convert packed DWORDs integers to packed DP-FP (SSE2). + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86MmReg) + //! \overload + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed DWORDs (SSE2). + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (SSE2). + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86Mem) + + //! Convert scalar DP-FP to DWORD integer (SSE2). + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (SSE2). + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86Mem) + + //! Convert DWORD integer to scalar DP-FP (SSE2). + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86GpReg) + //! \overload + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to DP-FP (SSE2). + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed DWORDs (SSE2). + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86Mem) + + //! Convert with truncation scalar DP-FP to signed DWORDs (SSE2). + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86Mem) + + //! Packed DP-FP divide (SSE2). + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP divide (SSE2). + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86Mem) + + //! Load fence (SSE2). + INST_0x(lfence, kX86InstIdLfence) + + //! Store selected bytes of OWORD to DS:EDI/RDI (SSE2). + INST_2x(maskmovdqu, kX86InstIdMaskmovdqu, X86XmmReg, X86XmmReg) + + //! Packed DP-FP maximum (SSE2). + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP maximum (SSE2). + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86Mem) + + //! Memory fence (SSE2). + INST_0x(mfence, kX86InstIdMfence) + + //! Packed DP-FP minimum (SSE2). + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP minimum (SSE2). + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86Mem) + + //! Move aligned OWORD (SSE2). + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86Mem) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmReg) + + //! Move unaligned OWORD (SSE2). + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86Mem) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmReg) + + //! Extract packed SP-FP sign mask (SSE2). + INST_2x(movmskps, kX86InstIdMovmskps, X86GpReg, X86XmmReg) + + //! Extract packed DP-FP sign mask (SSE2). + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpReg, X86XmmReg) + + //! Move scalar DP-FP (SSE2). + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmReg) + + //! Move aligned packed DP-FP (SSE2). + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmReg) + + //! Move QWORD from Xmm to Mm register (SSE2). + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmReg, X86XmmReg) + + //! Move QWORD from Mm to Xmm register (SSE2). + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmReg, X86MmReg) + + //! Move high packed DP-FP (SSE2). + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmReg) + + //! Move low packed DP-FP (SSE2). + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmReg) + + //! Store OWORD using NT hint (SSE2). + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmReg) + + //! Store DWORD using NT hint (SSE2). + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpReg) + + //! Store packed DP-FP using NT hint (SSE2). + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmReg) + + //! Move unaligned packed DP-FP (SSE2). + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmReg) + + //! Packed DP-FP multiply (SSE2). + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP multiply (SSE2). + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise or (SSE2). + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (SSE2). + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (SSE2). + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (SSE2). + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86Mem) + + //! Packed BYTE Add (SSE2). + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86Mem) + + //! Packed WORD add (SSE2). + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86Mem) + + //! Packed DWORD add (SSE2). + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86Mem) + + //! Packed BYTE add with saturation (SSE2). + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86Mem) + + //! Packed WORD add with saturation (SSE2). + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (SSE2). + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (SSE2). + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86Mem) + + //! Packed bitwise and (SSE2). + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86Mem) + + //! Packed bitwise and-not (SSE2). + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86Mem) + + //! Spin loop hint (SSE2). + INST_0x(pause, kX86InstIdPause) + + //! Packed BYTE average (SSE2). + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86Mem) + + //! Packed WORD average (SSE2). + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86Mem) + + //! Packed BYTE compare for equality (SSE2). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86Mem) + + //! Packed WORD compare for equality (SSE2). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86Mem) + + //! Packed DWORD compare for equality (SSE2). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86Mem) + + //! Packed BYTE compare if greater than (SSE2). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86Mem) + + //! Packed WORD compare if greater than (SSE2). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86Mem) + + //! Packed DWORD compare if greater than (SSE2). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86Mem) + + //! Extract WORD based on selector (SSE2). + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86XmmReg, Imm) + + //! Insert WORD based on selector (SSE2). + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD maximum (SSE2). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned maximum (SSE2). + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86Mem) + + //! Packed WORD minimum (SSE2). + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned minimum (SSE2). + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86Mem) + + //! Move byte mask (SSE2). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86XmmReg) + + //! Packed WORD multiply high (SSE2). + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86Mem) + + //! Packed WORD unsigned multiply high (SSE2). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86Mem) + + //! Packed WORD multiply low (SSE2). + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86Mem) + + //! Packed bitwise or (SSE2). + INST_2x(por, kX86InstIdPor, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(por, kX86InstIdPor, X86XmmReg, X86Mem) + + //! Packed DWORD shift left logical (SSE2). + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86XmmReg, Imm) + + //! Packed QWORD shift left logical (SSE2). + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86XmmReg, Imm) + + //! Packed WORD shift left logical (SSE2). + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86XmmReg, Imm) + + //! Packed OWORD shift left logical (SSE2). + INST_2i(pslldq, kX86InstIdPslldq, X86XmmReg, Imm) + + //! Packed DWORD shift right arithmetic (SSE2). + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86XmmReg, Imm) + + //! Packed WORD shift right arithmetic (SSE2). + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86XmmReg, Imm) + + //! Packed BYTE subtract (SSE2). + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86Mem) + + //! Packed DWORD subtract (SSE2). + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86Mem) + + //! Packed WORD subtract (SSE2). + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD multiply and add (SSE2). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86Mem) + + //! Packed DWORD shuffle (SSE2). + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle high (SSE2). + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle low (SSE2). + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86Mem, Imm) + + //! Packed DWORD shift right logical (SSE2). + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86XmmReg, Imm) + + //! Packed QWORD shift right logical (SSE2). + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmReg, Imm) + + //! Scalar OWORD shift right logical (SSE2). + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmReg, Imm) + + //! Packed WORD shift right logical (SSE2). + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmReg, Imm) + + //! Packed BYTE subtract with saturation (SSE2). + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86Mem) + + //! Packed WORD subtract with saturation (SSE2). + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (SSE2). + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (SSE2). + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (SSE2). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (SSE2). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86Mem) + + //! Unpack high packed QWORDs to OWORD (SSE2). + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (SSE2). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (SSE2). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (SSE2). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86Mem) + + //! Unpack low packed QWORDs to OWORD (SSE2). + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (SSE2). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86Mem) + + //! Packed bitwise xor (SSE2). + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86Mem) + + //! Shuffle DP-FP (SSE2). + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP square root (SSE2). + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP square root (SSE2). + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86Mem) + + //! Packed DP-FP subtract (SSE2). + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP subtract (SSE2). + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86Mem) + + //! Unpack and interleave high packed DP-FP (SSE2). + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86Mem) + + //! Unpack and interleave low packed DP-FP (SSE2). + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise xor (SSE2). + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE3] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add/subtract (SSE3). + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86Mem) + + //! Packed SP-FP add/subtract (SSE3). + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86Mem) + + //! Store truncated `fp0` to `short_or_int_or_long[o0]` and POP (FPU & SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) + + //! Packed DP-FP horizontal add (SSE3). + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86Mem) + + //! Packed SP-FP horizontal add (SSE3). + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86Mem) + + //! Packed DP-FP horizontal subtract (SSE3). + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86Mem) + + //! Packed SP-FP horizontal subtract (SSE3). + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86Mem) + + //! Load 128-bits unaligned (SSE3). + INST_2x(lddqu, kX86InstIdLddqu, X86XmmReg, X86Mem) + + //! Setup monitor address (SSE3). + INST_0x(monitor, kX86InstIdMonitor) + + //! Move one DP-FP and duplicate (SSE3). + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86Mem) + + //! Move packed SP-FP high and duplicate (SSE3). + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86Mem) + + //! Move packed SP-FP low and duplicate (SSE3). + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86Mem) + + //! Monitor wait (SSE3). + INST_0x(mwait, kX86InstIdMwait) + + // -------------------------------------------------------------------------- + // [SSSE3] + // -------------------------------------------------------------------------- + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86Mem) + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86Mem) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86MmReg, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86Mem, Imm) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.1] + // -------------------------------------------------------------------------- + + //! Packed DP-FP blend (SSE4.1). + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP blend (SSE4.1). + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP variable blend (SSE4.1). + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86Mem) + + //! Packed SP-FP variable blend (SSE4.1). + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86Mem) + + //! Packed DP-FP dot product (SSE4.1). + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP dot product (SSE4.1). + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86Mem, Imm) + + //! Extract SP-FP based on selector (SSE4.1). + INST_3i(extractps, kX86InstIdExtractps, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmReg, Imm) + + //! Insert SP-FP based on selector (SSE4.1). + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86Mem, Imm) + + //! Load OWORD aligned using NT hint (SSE4.1). + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmReg, X86Mem) + + //! Packed WORD sums of absolute difference (SSE4.1). + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86Mem, Imm) + + //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86Mem) + + //! Packed BYTE variable blend (SSE4.1). + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86Mem) + + //! Packed WORD blend (SSE4.1). + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86Mem, Imm) + + //! Packed QWORD compare for equality (SSE4.1). + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86Mem) + + //! Extract BYTE based on selector (SSE4.1). + INST_3i(pextrb, kX86InstIdPextrb, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmReg, Imm) + + //! Extract DWORD based on selector (SSE4.1). + INST_3i(pextrd, kX86InstIdPextrd, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmReg, Imm) + + //! Extract QWORD based on selector (SSE4.1). + INST_3i(pextrq, kX86InstIdPextrq, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmReg, Imm) + + //! Extract WORD based on selector (SSE4.1). + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmReg, Imm) + + //! Packed WORD horizontal minimum (SSE4.1). + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86Mem) + + //! Insert BYTE based on selector (SSE4.1). + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86Mem, Imm) + + //! Insert DWORD based on selector (SSE4.1). + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86Mem, Imm) + + //! Insert QWORD based on selector (SSE4.1). + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86Mem, Imm) + + //! Packed BYTE maximum (SSE4.1). + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86Mem) + + //! Packed DWORD maximum (SSE4.1). + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned maximum (SSE4.1). + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmReg, X86Mem) + + //! Packed WORD unsigned maximum (SSE4.1). + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86Mem) + + //! Packed BYTE minimum (SSE4.1). + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86Mem) + + //! Packed DWORD minimum (SSE4.1). + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86Mem) + + //! Packed WORD unsigned minimum (SSE4.1). + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned minimum (SSE4.1). + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86Mem) + + //! BYTE to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86Mem) + + //! Packed BYTE to WORD with sign extend (SSE4.1). + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86Mem) + + //! BYTE to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86Mem) + + //! BYTE to WORD with zero extend (SSE4.1). + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD multiply (SSE4.1). + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86Mem) + + //! Packed DWORD multiply low (SSE4.1). + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86Mem) + + //! Logical compare (SSE4.1). + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86Mem) + + //! Packed DP-FP round (SSE4.1). + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP round (SSE4.1). + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86Mem, Imm) + + //! Scalar DP-FP round (SSE4.1). + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP round (SSE4.1). + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.2] + // -------------------------------------------------------------------------- + + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! Packed compare explicit length strings, return index (SSE4.2). + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (SSE4.2). + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (SSE4.2). + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (SSE4.2). + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86Mem, Imm) + + //! Packed QWORD compare if greater than (SSE4.2). + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE4a] + // -------------------------------------------------------------------------- + + //! Extract Field (SSE4a). + INST_2x(extrq, kX86InstIdExtrq, X86XmmReg, X86XmmReg) + //! Extract Field (SSE4a). + INST_3ii(extrq, kX86InstIdExtrq, X86XmmReg, Imm, Imm) + + //! Insert Field (SSE4a). + INST_2x(insertq, kX86InstIdInsertq, X86XmmReg, X86XmmReg) + //! Insert Field (SSE4a). + INST_4ii(insertq, kX86InstIdInsertq, X86XmmReg, X86XmmReg, Imm, Imm) + + //! Move Non-Temporal Scalar DP-FP (SSE4a). + INST_2x(movntsd, kX86InstIdMovntsd, X86Mem, X86XmmReg) + //! Move Non-Temporal Scalar SP-FP (SSE4a). + INST_2x(movntss, kX86InstIdMovntss, X86Mem, X86XmmReg) + + // -------------------------------------------------------------------------- + // [POPCNT] + // -------------------------------------------------------------------------- + + //! Return the count of number of bits set to 1 (POPCNT). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb()) + + // -------------------------------------------------------------------------- + // [LZCNT] + // -------------------------------------------------------------------------- + + //! Count the number of leading zero bits (LZCNT). + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg) + //! \overload + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem) + + // -------------------------------------------------------------------------- + // [AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow (AESNI). + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86Mem) + + //! Perform the last round of the AES decryption flow (AESNI). + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86Mem) + + //! Perform a single round of the AES encryption flow (AESNI). + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86Mem) + + //! Perform the last round of the AES encryption flow (AESNI). + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86Mem) + + //! Perform the InvMixColumns transformation (AESNI). + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86Mem) + + //! Assist in expanding the AES cipher key (AESNI). + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [XSAVE] + // -------------------------------------------------------------------------- + + //! Restore Processor Extended States specified by `EDX:EAX` (XSAVE). + INST_1x(xrstor, kX86InstIdXrstor, X86Mem) + //! Restore Processor Extended States specified by `EDX:EAX` (XSAVE&X64). + INST_1x(xrstor64, kX86InstIdXrstor64, X86Mem) + + //! Save Processor Extended States specified by `EDX:EAX` (XSAVE). + INST_1x(xsave, kX86InstIdXsave, X86Mem) + //! Save Processor Extended States specified by `EDX:EAX` (XSAVE&X64). + INST_1x(xsave64, kX86InstIdXsave64, X86Mem) + + //! Save Processor Extended States specified by `EDX:EAX` (Optimized) (XSAVEOPT). + INST_1x(xsaveopt, kX86InstIdXsave, X86Mem) + //! Save Processor Extended States specified by `EDX:EAX` (Optimized) (XSAVEOPT&X64). + INST_1x(xsaveopt64, kX86InstIdXsave64, X86Mem) + + //! Get XCR - `EDX:EAX <- XCR[ECX]` (XSAVE). + INST_0x(xgetbv, kX86InstIdXgetbv) + //! Set XCR - `XCR[ECX] <- EDX:EAX` (XSAVE). + INST_0x(xsetbv, kX86InstIdXsetbv) + + // -------------------------------------------------------------------------- + // [AVX] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (AVX). + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP add (AVX). + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP add (AVX) + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP add (AVX) + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP add/subtract (AVX). + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP add/subtract (AVX). + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise and (AVX). + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise and (AVX). + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise and-not (AVX). + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise and-not (AVX). + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP blend (AVX). + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP blend (AVX). + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DP-FP variable blend (AVX). + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed SP-FP variable blend (AVX). + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Broadcast 128-bits of FP data in `o1` to low and high 128-bits in `o0` (AVX). + INST_2x(vbroadcastf128, kX86InstIdVbroadcastf128, X86YmmReg, X86Mem) + //! Broadcast DP-FP element in `o1` to four locations in `o0` (AVX). + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86Mem) + //! Broadcast SP-FP element in `o1` to four locations in `o0` (AVX). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86Mem) + //! Broadcast SP-FP element in `o1` to eight locations in `o0` (AVX). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86Mem) + + //! Packed DP-FP compare (AVX). + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP compare (AVX). + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Scalar DP-FP compare (AVX). + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP compare (AVX). + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar DP-FP ordered compare and set EFLAGS (AVX). + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86Mem) + + //! Scalar SP-FP ordered compare and set EFLAGS (AVX). + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed DP-FP (AVX). + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86Mem) + + //! Convert packed QWORDs to packed SP-FP (AVX). + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (AVX). + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (AVX). + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed DWORDs (AVX). + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (AVX). + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86Mem) + + //! Convert scalar DP-FP to DWORD (AVX). + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (AVX). + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert DWORD integer to scalar DP-FP (AVX). + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86GpReg) + //! \overload + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar INT32 to SP-FP (AVX). + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86GpReg) + //! \overload + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to DP-FP (AVX). + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to INT32 (AVX). + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (AVX). + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed DWORDs (AVX). + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86Mem) + + //! Convert with truncation scalar DP-FP to INT32 (AVX). + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (AVX). + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86Mem) + + //! Packed DP-FP divide (AVX). + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP divide (AVX). + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP divide (AVX). + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP divide (AVX). + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP dot product (AVX). + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP dot product (AVX). + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Extract 128 bits of packed FP data from `o1` and store results in `o0` (AVX). + INST_3i(vextractf128, kX86InstIdVextractf128, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vextractf128, kX86InstIdVextractf128, X86Mem, X86YmmReg, Imm) + + //! Extract SP-FP based on selector (AVX). + INST_3i(vextractps, kX86InstIdVextractps, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vextractps, kX86InstIdVextractps, X86Mem, X86XmmReg, Imm) + + //! Packed DP-FP horizontal add (AVX). + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP horizontal add (AVX). + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP horizontal subtract (AVX). + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP horizontal subtract (AVX). + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Insert 128-bit of packed FP data based on selector (AVX). + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Insert SP-FP based on selector (AVX). + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Load 128-bits unaligned (AVX). + INST_2x(vlddqu, kX86InstIdVlddqu, X86XmmReg, X86Mem) + //! Load 256-bits unaligned (AVX). + INST_2x(vlddqu, kX86InstIdVlddqu, X86YmmReg, X86Mem) + + //! Load streaming SIMD extension control/status (AVX). + INST_1x(vldmxcsr, kX86InstIdVldmxcsr, X86Mem) + + //! Store selected bytes of OWORD to DS:EDI/RDI (AVX). + INST_2x(vmaskmovdqu, kX86InstIdVmaskmovdqu, X86XmmReg, X86XmmReg) + + //! Conditionally load packed DP-FP from `o2` using mask in `o1 and store in `o0` (AVX). + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86YmmReg, X86YmmReg) + + //! Conditionally load packed SP-FP from `o2` using mask in `o1 and store in `o0` (AVX). + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86YmmReg, X86YmmReg) + + //! Packed DP-FP maximum (AVX). + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP maximum (AVX). + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP maximum (AVX). + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP maximum (AVX). + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP minimum (AVX). + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP minimum (AVX). + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP minimum (AVX). + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP minimum (AVX). + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86Mem) + + //! Move 128-bits of aligned packed DP-FP (AVX). + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86XmmReg) + //! Move 256-bits of aligned packed DP-FP (AVX). + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86YmmReg) + + //! Move 128-bits of aligned packed SP-FP (AVX). + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86XmmReg) + //! Move 256-bits of aligned packed SP-FP (AVX). + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86YmmReg) + + //! Move DWORD (AVX). + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86GpReg) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86Mem, X86XmmReg) + + //! Move QWORD (AVX). + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86Mem, X86XmmReg) + + //! Move QWORD (AVX and X64 Only). + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86GpReg) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86GpReg, X86XmmReg) + + //! Move one DP-FP and duplicate (AVX). + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86Mem) + + //! Move 128-bits aligned (AVX). + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86XmmReg) + //! Move 256-bits aligned (AVX). + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86YmmReg) + + //! Move 128-bits unaligned (AVX). + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86XmmReg) + //! Move 256-bits unaligned (AVX). + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86YmmReg) + + //! High to low packed SP-FP (AVX). + INST_3x(vmovhlps, kX86InstIdVmovhlps, X86XmmReg, X86XmmReg, X86XmmReg) + + //! Move high packed DP-FP (AVX). + INST_3x(vmovhpd, kX86InstIdVmovhpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovhpd, kX86InstIdVmovhpd, X86Mem, X86XmmReg) + + //! Move high packed SP-FP (AVX). + INST_3x(vmovhps, kX86InstIdVmovhps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovhps, kX86InstIdVmovhps, X86Mem, X86XmmReg) + + //! Move low to high packed SP-FP (AVX). + INST_3x(vmovlhps, kX86InstIdVmovlhps, X86XmmReg, X86XmmReg, X86XmmReg) + + //! Move low packed DP-FP (AVX). + INST_3x(vmovlpd, kX86InstIdVmovlpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovlpd, kX86InstIdVmovlpd, X86Mem, X86XmmReg) + + //! Move low packed SP-FP (AVX). + INST_3x(vmovlps, kX86InstIdVmovlps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovlps, kX86InstIdVmovlps, X86Mem, X86XmmReg) + + //! Extract packed DP-FP sign mask (AVX). + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86YmmReg) + + //! Extract packed SP-FP sign mask (AVX). + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86YmmReg) + + //! Store 128-bits using NT hint (AVX). + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86XmmReg) + //! Store 256-bits using NT hint (AVX). + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86YmmReg) + + //! Store 128-bits aligned using NT hint (AVX). + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86XmmReg, X86Mem) + + //! Store packed DP-FP (128-bits) using NT hint (AVX). + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86XmmReg) + //! Store packed DP-FP (256-bits) using NT hint (AVX). + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86YmmReg) + + //! Store packed SP-FP (128-bits) using NT hint (AVX). + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86XmmReg) + //! Store packed SP-FP (256-bits) using NT hint (AVX). + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86YmmReg) + + //! Move scalar DP-FP (AVX). + INST_3x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovsd, kX86InstIdVmovsd, X86Mem, X86XmmReg) + + //! Move packed SP-FP high and duplicate (AVX). + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86Mem) + + //! Move packed SP-FP low and duplicate (AVX). + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86Mem) + + //! Move scalar SP-FP (AVX). + INST_3x(vmovss, kX86InstIdVmovss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovss, kX86InstIdVmovss, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovss, kX86InstIdVmovss, X86Mem, X86XmmReg) + + //! Move 128-bits of unaligned packed DP-FP (AVX). + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86XmmReg) + //! Move 256-bits of unaligned packed DP-FP (AVX). + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86YmmReg) + + //! Move 128-bits of unaligned packed SP-FP (AVX). + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86XmmReg) + //! Move 256-bits of unaligned packed SP-FP (AVX). + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86YmmReg) + + //! Packed WORD sums of absolute difference (AVX). + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP multiply (AVX). + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP multiply (AVX). + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP multiply (AVX). + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP multiply (AVX). + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise or (AVX). + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise or (AVX). + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE absolute value (AVX). + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86Mem) + + //! Packed DWORD absolute value (AVX). + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86Mem) + + //! Packed WORD absolute value (AVX). + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (AVX). + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (AVX). + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with unsigned saturation (AVX). + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (AVX). + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add (AVX). + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD add (AVX). + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORD add (AVX). + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add (AVX). + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add with saturation (AVX). + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add with saturation (AVX). + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (AVX). + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (AVX). + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed align right (AVX). + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed bitwise and (AVX). + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise and-not (AVX). + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE average (AVX). + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD average (AVX). + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE variable blend (AVX). + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + //! Packed WORD blend (AVX). + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed BYTEs compare for equality (AVX). + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORDs compare for equality (AVX). + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORDs compare for equality (AVX). + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs compare for equality (AVX). + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTEs compare if greater than (AVX). + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORDs compare if greater than (AVX). + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORDs compare if greater than (AVX). + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs compare if greater than (AVX). + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed compare explicit length strings, return index (AVX). + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (AVX). + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (AVX). + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (AVX). + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP permute (AVX). + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP permute (AVX). + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86Mem, Imm) + + //! Packed 128-bit FP permute (AVX). + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Extract BYTE (AVX). + INST_3i(vpextrb, kX86InstIdVpextrb, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrb, kX86InstIdVpextrb, X86Mem, X86XmmReg, Imm) + + //! Extract DWORD (AVX). + INST_3i(vpextrd, kX86InstIdVpextrd, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrd, kX86InstIdVpextrd, X86Mem, X86XmmReg, Imm) + + //! Extract QWORD (AVX and X64 Only). + INST_3i(vpextrq, kX86InstIdVpextrq, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrq, kX86InstIdVpextrq, X86Mem, X86XmmReg, Imm) + + //! Extract WORD (AVX). + INST_3i(vpextrw, kX86InstIdVpextrw, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrw, kX86InstIdVpextrw, X86Mem, X86XmmReg, Imm) + + //! Packed DWORD horizontal add (AVX). + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (AVX). + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add (AVX). + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal minimum (AVX). + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal subtract (AVX). + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (AVX). + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract (AVX). + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86Mem) + + //! Insert BYTE based on selector (AVX). + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert DWORD based on selector (AVX). + INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert QWORD based on selector (AVX and X64 Only). + INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert WORD based on selector (AVX). + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed multiply and add signed and unsigned bytes (AVX). + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (AVX). + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE maximum (AVX). + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD maximum (AVX). + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD maximum (AVX). + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned maximum (AVX). + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned maximum (AVX). + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned maximum (AVX). + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE minimum (AVX). + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD minimum (AVX). + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD minimum (AVX). + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned minimum (AVX). + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned minimum (AVX). + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned minimum (AVX). + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Move Byte mask to integer (AVX). + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86XmmReg) + + //! BYTE to DWORD with sign extend (AVX). + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with sign extend (AVX). + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86Mem) + + //! Packed BYTE to WORD with sign extend (AVX). + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with sign extend (AVX). + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with sign extend (AVX). + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with sign extend (AVX). + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86Mem) + + //! BYTE to DWORD with zero extend (AVX). + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with zero extend (AVX). + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86Mem) + + //! BYTE to WORD with zero extend (AVX). + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with zero extend (AVX). + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with zero extend (AVX). + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with zero extend (AVX). + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD multiply (AVX). + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (AVX). + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned multiply high (AVX). + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply high (AVX). + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD multiply low (AVX). + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs multiply low (AVX). + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (AVX). + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise or (AVX). + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD sum of absolute differences (AVX). + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE shuffle (AVX). + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD shuffle (AVX). + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle high (AVX). + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle low (AVX). + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86Mem, Imm) + + //! Packed BYTE sign (AVX). + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD sign (AVX). + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD sign (AVX). + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD shift left logical (AVX). + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, Imm) + + //! Packed OWORD shift left logical (AVX). + INST_3i(vpslldq, kX86InstIdVpslldq, X86XmmReg, X86XmmReg, Imm) + + //! Packed QWORD shift left logical (AVX). + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift left logical (AVX). + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, Imm) + + //! Packed DWORD shift right arithmetic (AVX). + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift right arithmetic (AVX). + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, Imm) + + //! Packed DWORD shift right logical (AVX). + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, Imm) + + //! Scalar OWORD shift right logical (AVX). + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86XmmReg, X86XmmReg, Imm) + + //! Packed QWORD shift right logical (AVX). + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift right logical (AVX). + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, Imm) + + //! Packed BYTE subtract (AVX). + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD subtract (AVX). + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORD subtract (AVX). + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract (AVX). + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with saturation (AVX). + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract with saturation (AVX). + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (AVX). + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (AVX). + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86Mem) + + //! Logical compare (AVX). + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86Mem) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (AVX). + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (AVX). + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed QWORDs to OWORD (AVX). + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (AVX). + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (AVX). + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (AVX). + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed QWORDs to OWORD (AVX). + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (AVX). + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise xor (AVX). + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed SP-FP reciprocal (AVX). + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86Mem) + + //! Scalar SP-FP reciprocal (AVX). + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed SP-FP square root reciprocal (AVX). + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86Mem) + + //! Scalar SP-FP square root reciprocal (AVX). + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP round (AVX). + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP round (AVX). + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86Mem, Imm) + + //! Scalar DP-FP round (AVX). + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP round (AVX). + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Shuffle DP-FP (AVX). + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Shuffle SP-FP (AVX). + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DP-FP square root (AVX). + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86Mem) + + //! Packed SP-FP square root (AVX). + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86Mem) + + //! Scalar DP-FP square root (AVX). + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root (AVX). + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86Mem) + + //! Store streaming SIMD extension control/status (AVX). + INST_1x(vstmxcsr, kX86InstIdVstmxcsr, X86Mem) + + //! Packed DP-FP subtract (AVX). + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP subtract (AVX). + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP subtract (AVX). + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP subtract (AVX). + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86Mem) + + //! Logical compare DP-FP (AVX). + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86Mem) + + //! Logical compare SP-FP (AVX). + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (AVX). + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (AVX). + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86Mem) + + //! Unpack and interleave high packed DP-FP (AVX). + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack high packed SP-FP data (AVX). + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack and interleave low packed DP-FP (AVX). + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack low packed SP-FP data (AVX). + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise xor (AVX). + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise xor (AVX). + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86Mem) + + //! Zero all Ymm registers. + INST_0x(vzeroall, kX86InstIdVzeroall) + //! Zero upper 128-bits of all Ymm registers. + INST_0x(vzeroupper, kX86InstIdVzeroupper) + + // -------------------------------------------------------------------------- + // [AVX+AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow (AVX+AESNI). + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the last round of the AES decryption flow (AVX+AESNI). + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform a single round of the AES encryption flow (AVX+AESNI). + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the last round of the AES encryption flow (AVX+AESNI). + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the InvMixColumns transformation (AVX+AESNI). + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86Mem) + + //! Assist in expanding the AES cipher key (AVX+AESNI). + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [AVX+PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Carry-less multiplication QWORD (AVX+PCLMULQDQ). + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [AVX2] + // -------------------------------------------------------------------------- + + //! Broadcast low 128-bit element in `o1` to `o0` (AVX2). + INST_2x(vbroadcasti128, kX86InstIdVbroadcasti128, X86YmmReg, X86Mem) + //! Broadcast low DP-FP element in `o1` to `o0` (AVX2). + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86XmmReg) + //! Broadcast low SP-FP element in `o1` to `o0` (AVX2). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86XmmReg) + + //! Extract 128-bit element from `o1` to `o0` based on selector (AVX2). + INST_3i(vextracti128, kX86InstIdVextracti128, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vextracti128, kX86InstIdVextracti128, X86Mem, X86YmmReg, Imm) + + //! Gather DP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather SP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather DP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather SP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherqps, kX86InstIdVgatherqps, X86XmmReg, X86Mem, X86XmmReg) + + //! Insert 128-bit of packed data based on selector (AVX2). + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Load 256-bits aligned using NT hint (AVX2). + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86YmmReg, X86Mem) + + //! Packed WORD sums of absolute difference (AVX2). + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed BYTE absolute value (AVX2). + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86Mem) + + //! Packed DWORD absolute value (AVX2). + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86Mem) + + //! Packed WORD absolute value (AVX2). + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (AVX2). + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (AVX2). + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack DWORDs to WORDs with unsigned saturation (AVX2). + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (AVX2). + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add (AVX2). + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORD add (AVX2). + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QDWORD add (AVX2). + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add (AVX2). + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add with saturation (AVX2). + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add with saturation (AVX2). + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (AVX2). + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (AVX2). + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed align right (AVX2). + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed bitwise and (AVX2). + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed bitwise and-not (AVX2). + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE average (AVX2). + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD average (AVX2). + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORD blend (AVX2). + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DWORD variable blend (AVX2). + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed WORD blend (AVX2). + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Broadcast BYTE from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86Mem) + //! Broadcast BYTE from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86Mem) + + //! Broadcast DWORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86Mem) + //! Broadcast DWORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86Mem) + + //! Broadcast QWORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86Mem) + //! Broadcast QWORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86Mem) + + //! Broadcast WORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86Mem) + //! Broadcast WORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86Mem) + + //! Packed BYTEs compare for equality (AVX2). + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORDs compare for equality (AVX2). + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORDs compare for equality (AVX2). + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORDs compare for equality (AVX2). + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTEs compare if greater than (AVX2). + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORDs compare if greater than (AVX2). + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORDs compare if greater than (AVX2). + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORDs compare if greater than (AVX2). + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed OWORD permute (AVX2). + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DWORD permute (AVX2). + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP permute (AVX2). + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP permute (AVX2). + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORD permute (AVX2). + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86Mem, Imm) + + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86YmmReg, X86Mem, X86YmmReg) + + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86YmmReg, X86Mem, X86YmmReg) + + INST_3x(vpgatherqd, kX86InstIdVpgatherqd, X86XmmReg, X86Mem, X86XmmReg) + + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed DWORD horizontal add (AVX2). + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal add with saturation (AVX2). + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal add (AVX2). + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD horizontal subtract (AVX2). + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal subtract with saturation (AVX2). + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal subtract (AVX2). + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Move Byte mask to integer (AVX2). + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86YmmReg) + + //! BYTE to DWORD with sign extend (AVX). + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86XmmReg) + + //! Packed BYTE to QWORD with sign extend (AVX2). + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86XmmReg) + + //! Packed BYTE to WORD with sign extend (AVX2). + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86XmmReg) + + //! Packed DWORD to QWORD with sign extend (AVX2). + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86XmmReg) + + //! Packed WORD to DWORD with sign extend (AVX2). + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86XmmReg) + + //! Packed WORD to QWORD with sign extend (AVX2). + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86XmmReg) + + //! BYTE to DWORD with zero extend (AVX2). + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86XmmReg) + + //! Packed BYTE to QWORD with zero extend (AVX2). + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86XmmReg) + + //! BYTE to WORD with zero extend (AVX2). + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86XmmReg) + + //! Packed DWORD to QWORD with zero extend (AVX2). + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86XmmReg) + + //! Packed WORD to DWORD with zero extend (AVX2). + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86XmmReg) + + //! Packed WORD to QWORD with zero extend (AVX2). + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86XmmReg) + + //! Packed multiply and add signed and unsigned bytes (AVX2). + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply and add to packed DWORD (AVX2). + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86XmmReg, X86XmmReg) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86YmmReg, X86YmmReg) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86YmmReg, X86YmmReg, X86Mem) + + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86XmmReg, X86XmmReg) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86YmmReg, X86YmmReg) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE maximum (AVX2). + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD maximum (AVX2). + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD maximum (AVX2). + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE unsigned maximum (AVX2). + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD unsigned maximum (AVX2). + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned maximum (AVX2). + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE minimum (AVX2). + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD minimum (AVX2). + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD minimum (AVX2). + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE unsigned minimum (AVX2). + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD unsigned minimum (AVX2). + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned minimum (AVX2). + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD to QWORD multiply (AVX2). + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply high, round and scale (AVX2). + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned multiply high (AVX2). + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply high (AVX2). + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD multiply low (AVX2). + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORDs multiply low (AVX2). + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD multiply to QWORD (AVX2). + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed bitwise or (AVX2). + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD sum of absolute differences (AVX2). + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE shuffle (AVX2). + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD shuffle (AVX2). + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86YmmReg, Imm) + + //! Packed WORD shuffle high (AVX2). + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86YmmReg, Imm) + + //! Packed WORD shuffle low (AVX2). + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86YmmReg, Imm) + + //! Packed BYTE sign (AVX2). + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD sign (AVX2). + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD sign (AVX2). + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD shift left logical (AVX2). + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, Imm) + + //! Packed OWORD shift left logical (AVX2). + INST_3i(vpslldq, kX86InstIdVpslldq, X86YmmReg, X86YmmReg, Imm) + + //! Packed QWORD shift left logical (AVX2). + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift left logical (AVX2). + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86XmmReg) + //! Packed WORD shift left logical (AVX2). + INST_3i(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, Imm) + + //! Packed DWORD shift right arithmetic (AVX2). + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift right arithmetic (AVX2). + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, Imm) + + //! Packed DWORD shift right logical (AVX2). + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, Imm) + + //! Scalar OWORD shift right logical (AVX2). + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86YmmReg, X86YmmReg, Imm) + + //! Packed QWORD shift right logical (AVX2). + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift right logical (AVX2). + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, Imm) + + //! Packed BYTE subtract (AVX2). + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD subtract (AVX2). + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed QWORD subtract (AVX2). + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE subtract with saturation (AVX2). + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract with saturation (AVX2). + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE subtract with unsigned saturation (AVX2). + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract with unsigned saturation (AVX2). + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract (AVX2). + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed BYTEs to WORDs (AVX2). + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed DWORDs to QWORDs (AVX2). + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed QWORDs to OWORD (AVX2). + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed WORDs to DWORDs (AVX2). + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed BYTEs to WORDs (AVX2). + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed DWORDs to QWORDs (AVX2). + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed QWORDs to OWORD (AVX2). + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed WORDs to DWORDs (AVX2). + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed bitwise xor (AVX2). + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86YmmReg) + + // -------------------------------------------------------------------------- + // [FMA3] + // -------------------------------------------------------------------------- + + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + // -------------------------------------------------------------------------- + // [FMA4] + // -------------------------------------------------------------------------- + + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [XOP] + // -------------------------------------------------------------------------- + + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86XmmReg) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86Mem) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86YmmReg) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86Mem) + + INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86XmmReg) + INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86Mem) + INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86YmmReg) + INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86Mem) + + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86XmmReg) + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86Mem) + + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86XmmReg) + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86Mem) + + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86XmmReg) + INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86Mem) + INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86XmmReg) + INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86Mem) + INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86XmmReg) + INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86Mem) + INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86XmmReg) + INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86Mem) + INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86XmmReg) + INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86Mem) + INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86XmmReg) + INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86Mem) + + INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86XmmReg) + INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86Mem) + INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86XmmReg) + INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86Mem) + INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86XmmReg) + INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86Mem) + INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86XmmReg) + INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86Mem) + INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86XmmReg) + INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86Mem) + INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86XmmReg) + INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86Mem) + + INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86XmmReg) + INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86Mem) + INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86XmmReg) + INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86Mem) + INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86XmmReg) + INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86Mem) + + INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, Imm) + + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [BMI] + // -------------------------------------------------------------------------- + + //! Bitwise and-not (BMI). + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86Mem) + + //! Bit field extract (BMI). + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86Mem, X86GpReg) + + //! Extract lower set isolated bit (BMI). + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86Mem) + + //! Get mask up to lowest set bit (BMI). + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86Mem) + + //! Reset lowest set bit (BMI). + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86Mem) + + //! Count the number of trailing zero bits (BMI). + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86GpReg) + //! \overload + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86Mem) + + // -------------------------------------------------------------------------- + // [BMI2] + // -------------------------------------------------------------------------- + + //! Zero high bits starting with specified bit position (BMI2). + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86Mem, X86GpReg) + + //! Unsigned multiply without affecting flags (BMI2). + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86Mem) + + //! Parallel bits deposit (BMI2). + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86Mem) + + //! Parallel bits extract (BMI2). + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86Mem) + + //! Rotate right without affecting flags (BMI2). + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86Mem, Imm) + + //! Shift arithmetic right without affecting flags (BMI2). + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86Mem, X86GpReg) + + //! Shift logical left without affecting flags (BMI2). + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86Mem, X86GpReg) + + //! Shift logical right without affecting flags (BMI2). + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86Mem, X86GpReg) + + // -------------------------------------------------------------------------- + // [RDRAND] + // -------------------------------------------------------------------------- + + //! Store a random number in destination register (RDRAND). + //! + //! Please do not use this instruction in cryptographic software. The result + //! doesn't necessarily have to be random, which may cause a major security + //! hole in the software. + INST_1x(rdrand, kX86InstIdRdrand, X86GpReg) + + // -------------------------------------------------------------------------- + // [F16C] + // -------------------------------------------------------------------------- + + //! Convert packed HP-FP to SP-FP. + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86Mem) + + //! Convert packed SP-FP to HP-FP. + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86XmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86YmmReg, Imm) + + // -------------------------------------------------------------------------- + // [FSGSBASE] + // -------------------------------------------------------------------------- + + INST_1x(rdfsbase, kX86InstIdRdfsbase, X86GpReg) + INST_1x(rdgsbase, kX86InstIdRdgsbase, X86GpReg) + INST_1x(wrfsbase, kX86InstIdWrfsbase, X86GpReg) + INST_1x(wrgsbase, kX86InstIdWrgsbase, X86GpReg) + +#undef INST_0x + +#undef INST_1x +#undef INST_1x_ +#undef INST_1i +#undef INST_1cc + +#undef INST_2x +#undef INST_2x_ +#undef INST_2i +#undef INST_2cc + +#undef INST_3x +#undef INST_3x_ +#undef INST_3i +#undef INST_3ii + +#undef INST_4x +#undef INST_4x_ +#undef INST_4i +#undef INST_4ii +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86ASSEMBLER_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86compiler.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86compiler.h new file mode 100644 index 0000000..56dda3a --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86compiler.h @@ -0,0 +1,5626 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86COMPILER_H +#define _ASMJIT_X86_X86COMPILER_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/compiler.h" +#include "../base/vectypes.h" +#include "../x86/x86assembler.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86CallNode; +struct X86FuncNode; +struct X86VarState; + +//! \addtogroup asmjit_x86_compiler +//! \{ + +// ============================================================================ +// [asmjit::k86VarType] +// ============================================================================ + +//! X86/X64 variable type. +ASMJIT_ENUM(kX86VarType) { + //! Variable is SP-FP (x87). + kX86VarTypeFp32 = kVarTypeFp32, + //! Variable is DP-FP (x87). + kX86VarTypeFp64 = kVarTypeFp64, + + //! Variable is Mm (MMX). + kX86VarTypeMm = 12, + + //! Variable is K (AVX512+) + kX86VarTypeK, + + //! Variable is Xmm (SSE+). + kX86VarTypeXmm, + //! Variable is a scalar Xmm SP-FP number. + kX86VarTypeXmmSs, + //! Variable is a packed Xmm SP-FP number (4 floats). + kX86VarTypeXmmPs, + //! Variable is a scalar Xmm DP-FP number. + kX86VarTypeXmmSd, + //! Variable is a packed Xmm DP-FP number (2 doubles). + kX86VarTypeXmmPd, + + //! Variable is Ymm (AVX+). + kX86VarTypeYmm, + //! Variable is a packed Ymm SP-FP number (8 floats). + kX86VarTypeYmmPs, + //! Variable is a packed Ymm DP-FP number (4 doubles). + kX86VarTypeYmmPd, + + //! Variable is Zmm (AVX512+). + kX86VarTypeZmm, + //! Variable is a packed Zmm SP-FP number (16 floats). + kX86VarTypeZmmPs, + //! Variable is a packed Zmm DP-FP number (8 doubles). + kX86VarTypeZmmPd, + + //! Count of variable types. + kX86VarTypeCount, + + //! \internal + //! \{ + _kX86VarTypeMmStart = kX86VarTypeMm, + _kX86VarTypeMmEnd = kX86VarTypeMm, + + _kX86VarTypeXmmStart = kX86VarTypeXmm, + _kX86VarTypeXmmEnd = kX86VarTypeXmmPd, + + _kX86VarTypeYmmStart = kX86VarTypeYmm, + _kX86VarTypeYmmEnd = kX86VarTypeYmmPd, + + _kX86VarTypeZmmStart = kX86VarTypeZmm, + _kX86VarTypeZmmEnd = kX86VarTypeZmmPd + //! \} +}; + +// ============================================================================ +// [asmjit::kX86VarAttr] +// ============================================================================ + +//! X86/X64 VarAttr flags. +ASMJIT_ENUM(kX86VarAttr) { + kX86VarAttrGpbLo = 0x10000000, + kX86VarAttrGpbHi = 0x20000000 +}; + +// ============================================================================ +// [asmjit::kX86FuncConv] +// ============================================================================ + +//! X86 function calling conventions. +//! +//! Calling convention is scheme how function arguments are passed into +//! function and how functions returns values. In assembler programming +//! it's needed to always comply with function calling conventions, because +//! even small inconsistency can cause undefined behavior or crash. +//! +//! List of calling conventions for 32-bit x86 mode: +//! - `kX86FuncConvCDecl` - Calling convention for C runtime. +//! - `kX86FuncConvStdCall` - Calling convention for WinAPI functions. +//! - `kX86FuncConvMsThisCall` - Calling convention for C++ members under +//! Windows (produced by MSVC and all MSVC compatible compilers). +//! - `kX86FuncConvMsFastCall` - Fastest calling convention that can be used +//! by MSVC compiler. +//! - `kX86FuncConvBorlandFastCall` - Borland fastcall convention. +//! - `kX86FuncConvGccFastCall` - GCC fastcall convention (2 register arguments). +//! - `kX86FuncConvGccRegParm1` - GCC regparm(1) convention. +//! - `kX86FuncConvGccRegParm2` - GCC regparm(2) convention. +//! - `kX86FuncConvGccRegParm3` - GCC regparm(3) convention. +//! +//! List of calling conventions for 64-bit x86 mode (x64): +//! - `kX86FuncConvW64` - Windows 64-bit calling convention (WIN64 ABI). +//! - `kX86FuncConvU64` - Unix 64-bit calling convention (AMD64 ABI). +//! +//! There is also `kFuncConvHost` that is defined to fit the host calling +//! convention. +//! +//! These types are used together with `Compiler::addFunc()` method. +ASMJIT_ENUM(kX86FuncConv) { + // -------------------------------------------------------------------------- + // [X64] + // -------------------------------------------------------------------------- + + //! X64 calling convention for Windows platform (WIN64 ABI). + //! + //! For first four arguments are used these registers: + //! - 1. 32/64-bit integer or floating point argument - rcx/xmm0 + //! - 2. 32/64-bit integer or floating point argument - rdx/xmm1 + //! - 3. 32/64-bit integer or floating point argument - r8/xmm2 + //! - 4. 32/64-bit integer or floating point argument - r9/xmm3 + //! + //! Note first four arguments here means arguments at positions from 1 to 4 + //! (included). For example if second argument is not passed in register then + //! rdx/xmm1 register is unused. + //! + //! All other arguments are pushed on the stack in right-to-left direction. + //! Stack is aligned by 16 bytes. There is 32-byte shadow space on the stack + //! that can be used to save up to four 64-bit registers (probably designed to + //! be used to save first four arguments passed in registers). + //! + //! Arguments direction: + //! - Right to Left (except for first 4 parameters that's in registers) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - Rax register. + //! - Floating points - Xmm0 register. + //! + //! Stack is always aligned by 16 bytes. + //! + //! More information about this calling convention can be found on MSDN: + //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx . + kX86FuncConvW64 = 1, + + //! X64 calling convention for Unix platforms (AMD64 ABI). + //! + //! First six 32 or 64-bit integer arguments are passed in rdi, rsi, rdx, + //! rcx, r8, r9 registers. First eight floating point or Xmm arguments + //! are passed in xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 registers. + //! This means that in registers can be transferred up to 14 arguments total. + //! + //! There is also RED ZONE below the stack pointer that can be used for + //! temporary storage. The red zone is the space from [rsp-128] to [rsp-8]. + //! + //! Arguments direction: + //! - Right to Left (Except for arguments passed in registers). + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - Rax register. + //! - Floating points - Xmm0 register. + //! + //! Stack is always aligned by 16 bytes. + kX86FuncConvU64 = 2, + + // -------------------------------------------------------------------------- + // [X86] + // -------------------------------------------------------------------------- + + //! Cdecl calling convention (used by C runtime). + //! + //! Compatible across MSVC and GCC. + //! + //! Arguments direction: + //! - Right to Left + //! + //! Stack is cleaned by: + //! - Caller. + kX86FuncConvCDecl = 3, + + //! Stdcall calling convention (used by WinAPI). + //! + //! Compatible across MSVC and GCC. + //! + //! Arguments direction: + //! - Right to Left + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvStdCall = 4, + + //! MSVC specific calling convention used by MSVC/Intel compilers + //! for struct/class methods. + //! + //! This is MSVC (and Intel) only calling convention used in Windows + //! world for C++ class methods. Implicit 'this' pointer is stored in + //! ECX register instead of storing it on the stack. + //! + //! Arguments direction: + //! - Right to Left (except this pointer in ECX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! C++ class methods that have variable count of arguments uses different + //! calling convention called cdecl. + //! + //! \note This calling convention is always used by MSVC for class methods, + //! it's implicit and there is no way how to override it. + kX86FuncConvMsThisCall = 5, + + //! MSVC specific fastcall. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note This calling convention differs to GCC one in stack cleaning + //! mechanism. + kX86FuncConvMsFastCall = 6, + + //! Borland specific fastcall with 2 parameters in registers. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in left-to-right order. + //! + //! Arguments direction: + //! - Left to Right (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note Arguments on the stack are in left-to-right order that differs + //! to other fastcall conventions used in different compilers. + kX86FuncConvBorlandFastCall = 7, + + //! GCC specific fastcall convention. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note This calling convention should be compatible with `kX86FuncConvMsFastCall`. + kX86FuncConvGccFastCall = 8, + + //! GCC specific regparm(1) convention. + //! + //! The first parameter (evaluated from left-to-right) is in EAX register, + //! all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first one integer argument in EAX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm1 = 9, + + //! GCC specific regparm(2) convention. + //! + //! Two first parameters (evaluated from left-to-right) are in EAX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in EAX:EDX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm2 = 10, + + //! GCC specific fastcall with 3 parameters in registers. + //! + //! Three first parameters (evaluated from left-to-right) are in + //! EAX:EDX:ECX registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm3 = 11, + + //! \internal + //! + //! Count of function calling conventions. + _kX86FuncConvCount = 12 +}; + +#if !defined(ASMJIT_DOCGEN) +// X86/X64 Host Support - documented in base/compiler.h. +#if defined(ASMJIT_HOST_X86) +enum { + // X86. + kFuncConvHost = kX86FuncConvCDecl, + kFuncConvHostCDecl = kX86FuncConvCDecl, + kFuncConvHostStdCall = kX86FuncConvStdCall, +#if defined(_MSC_VER) + kFuncConvHostFastCall = kX86FuncConvMsFastCall +#elif defined(__GNUC__) + kFuncConvHostFastCall = kX86FuncConvGccFastCall +#elif defined(__BORLANDC__) + kFuncConvHostFastCall = kX86FuncConvBorlandFastCall +#else +#error "kFuncConvHostFastCall not determined." +#endif +}; +#endif // ASMJIT_HOST_X86 + +#if defined(ASMJIT_HOST_X64) +enum { +#if defined(ASMJIT_OS_WINDOWS) + kFuncConvHost = kX86FuncConvW64, +#else + kFuncConvHost = kX86FuncConvU64, +#endif + kFuncConvHostCDecl = kFuncConvHost, + kFuncConvHostStdCall = kFuncConvHost, + kFuncConvHostFastCall = kFuncConvHost +}; +#endif // ASMJIT_HOST_X64 +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::kX86FuncHint] +// ============================================================================ + +//! X86 function hints. +ASMJIT_ENUM(kX86FuncHint) { + //! Use push/pop sequences instead of mov sequences in function prolog + //! and epilog. + kX86FuncHintPushPop = 16, + //! Add emms instruction to the function epilog. + kX86FuncHintEmms = 17, + //! Add sfence instruction to the function epilog. + kX86FuncHintSFence = 18, + //! Add lfence instruction to the function epilog. + kX86FuncHintLFence = 19 +}; + +// ============================================================================ +// [asmjit::kX86FuncFlags] +// ============================================================================ + +//! X86 function flags. +ASMJIT_ENUM(kX86FuncFlags) { + //! Whether to emit register load/save sequence using push/pop pairs. + kX86FuncFlagPushPop = 0x00010000, + + //! Whether to emit `enter` instead of three instructions in case + //! that the function is not naked or misaligned. + kX86FuncFlagEnter = 0x00020000, + + //! Whether to emit `leave` instead of two instructions in case + //! that the function is not naked or misaligned. + kX86FuncFlagLeave = 0x00040000, + + //! Whether it's required to move arguments to a new stack location, + //! because of manual aligning. + kX86FuncFlagMoveArgs = 0x00080000, + + //! Whether to emit `emms` instruction in epilog (auto-detected). + kX86FuncFlagEmms = 0x01000000, + + //! Whether to emit `sfence` instruction in epilog (auto-detected). + //! + //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`. + kX86FuncFlagSFence = 0x02000000, + + //! Whether to emit `lfence` instruction in epilog (auto-detected). + //! + //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`. + kX86FuncFlagLFence = 0x04000000 +}; + +// ============================================================================ +// [asmjit::X86VarInfo] +// ============================================================================ + +//! \internal +//! +//! X86 variable information. +struct X86VarInfo { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get register type, see `kX86RegType`. + ASMJIT_INLINE uint32_t getReg() const { return _reg; } + //! Get register size in bytes. + ASMJIT_INLINE uint32_t getSize() const { return _size; } + //! Get variable class, see `kRegClass`. + ASMJIT_INLINE uint32_t getClass() const { return _class; } + //! Get variable description, see `kVarFlag`. + ASMJIT_INLINE uint32_t getDesc() const { return _desc; } + //! Get variable type name. + ASMJIT_INLINE const char* getName() const { return _name; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Register type, see `kX86RegType`. + uint8_t _reg; + //! Register size in bytes. + uint8_t _size; + //! Register class, see `kRegClass`. + uint8_t _class; + //! Variable flags, see `kVarFlag`. + uint8_t _desc; + //! Variable type name. + char _name[4]; +}; + +//! \internal +ASMJIT_VAR const X86VarInfo _x86VarInfo[]; + +#if defined(ASMJIT_BUILD_X86) +//! \internal +//! +//! Mapping of x86 variables into their real IDs. +//! +//! This mapping translates the following: +//! - `kVarTypeInt64` to `kInvalidVar`. +//! - `kVarTypeUInt64` to `kInvalidVar`. +//! - `kVarTypeIntPtr` to `kVarTypeInt32`. +//! - `kVarTypeUIntPtr` to `kVarTypeUInt32`. +ASMJIT_VAR const uint8_t _x86VarMapping[kX86VarTypeCount]; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) +//! \internal +//! +//! Mapping of x64 variables into their real IDs. +//! +//! This mapping translates the following: +//! - `kVarTypeIntPtr` to `kVarTypeInt64`. +//! - `kVarTypeUIntPtr` to `kVarTypeUInt64`. +ASMJIT_VAR const uint8_t _x64VarMapping[kX86VarTypeCount]; +#endif // ASMJIT_BUILD_X64 + +// ============================================================================ +// [asmjit::X86Var] +// ============================================================================ + +//! Base class for all X86 variables. +struct X86Var : public Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Var() : Var(NoInit) { + reset(); + } + + ASMJIT_INLINE X86Var(const X86Var& other) : Var(other) {} + + explicit ASMJIT_INLINE X86Var(const _NoInit&) : Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Var Specific] + // -------------------------------------------------------------------------- + + //! Clone X86Var operand. + ASMJIT_INLINE X86Var clone() const { + return X86Var(*this); + } + + // -------------------------------------------------------------------------- + // [Type] + // -------------------------------------------------------------------------- + + //! Get register type. + ASMJIT_INLINE uint32_t getRegType() const { return _vreg.type; } + //! Get variable type. + ASMJIT_INLINE uint32_t getVarType() const { return _vreg.vType; } + + //! Get whether the variable is Gp register. + ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; } + //! Get whether the variable is Gpb (8-bit) register. + ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; } + //! Get whether the variable is Gpb-lo (8-bit) register. + ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; } + //! Get whether the variable is Gpb-hi (8-bit) register. + ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; } + //! Get whether the variable is Gpw (16-bit) register. + ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; } + //! Get whether the variable is Gpd (32-bit) register. + ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; } + //! Get whether the variable is Gpq (64-bit) register. + ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; } + + //! Get whether the variable is Mm (64-bit) register. + ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + //! Get whether the variable is K (64-bit) register. + ASMJIT_INLINE bool isK() const { return _vreg.type == kX86RegTypeK; } + + //! Get whether the variable is Xmm (128-bit) register. + ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } + //! Get whether the variable is Ymm (256-bit) register. + ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; } + //! Get whether the variable is Zmm (512-bit) register. + ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; } + + // -------------------------------------------------------------------------- + // [Memory Cast] + // -------------------------------------------------------------------------- + + //! Cast this variable to a memory operand. + //! + //! \note Size of operand depends on native variable type, you can use other + //! variants if you want specific one. + ASMJIT_INLINE X86Mem m(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, getSize()); + } + + //! \overload + ASMJIT_INLINE X86Mem m(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, getSize()); + } + + //! Cast this variable to 8-bit memory operand. + ASMJIT_INLINE X86Mem m8(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 1); + } + + //! \overload + ASMJIT_INLINE X86Mem m8(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 1); + } + + //! Cast this variable to 16-bit memory operand. + ASMJIT_INLINE X86Mem m16(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 2); + } + + //! \overload + ASMJIT_INLINE X86Mem m16(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 2); + } + + //! Cast this variable to 32-bit memory operand. + ASMJIT_INLINE X86Mem m32(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 4); + } + + //! \overload + ASMJIT_INLINE X86Mem m32(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 4); + } + + //! Cast this variable to 64-bit memory operand. + ASMJIT_INLINE X86Mem m64(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 8); + } + + //! \overload + ASMJIT_INLINE X86Mem m64(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 8); + } + + //! Cast this variable to 80-bit memory operand (long double). + ASMJIT_INLINE X86Mem m80(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 10); + } + + //! \overload + ASMJIT_INLINE X86Mem m80(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 10); + } + + //! Cast this variable to 128-bit memory operand. + ASMJIT_INLINE X86Mem m128(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 16); + } + + //! \overload + ASMJIT_INLINE X86Mem m128(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 16); + } + + //! Cast this variable to 256-bit memory operand. + ASMJIT_INLINE X86Mem m256(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 32); + } + + //! \overload + ASMJIT_INLINE X86Mem m256(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 32); + } + + //! Cast this variable to 256-bit memory operand. + ASMJIT_INLINE X86Mem m512(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 64); + } + + //! \overload + ASMJIT_INLINE X86Mem m512(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 64); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Var& operator=(const X86Var& other) { + _copy(other); + return *this; + } + + ASMJIT_INLINE bool operator==(const X86Var& other) const { + return _packed[0] == other._packed[0]; + } + + ASMJIT_INLINE bool operator!=(const X86Var& other) const { + return _packed[0] != other._packed[0]; + } + + // -------------------------------------------------------------------------- + // [Private] + // -------------------------------------------------------------------------- + +protected: + ASMJIT_INLINE X86Var(const X86Var& other, uint32_t reg, uint32_t size) : Var(NoInit) { + _init_packed_op_sz_w0_id(kOperandTypeVar, size, (reg << 8) + other._vreg.index, other._base.id); + _vreg.vType = other._vreg.vType; + } +}; + +// ============================================================================ +// [asmjit::X86GpVar] +// ============================================================================ + +//! Gp variable. +struct X86GpVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86GpVar` instance. + ASMJIT_INLINE X86GpVar() : X86Var() {} + + //! Create a new initialized `X86GpVar` instance. + ASMJIT_INLINE X86GpVar(Compiler& c, uint32_t type = kVarTypeIntPtr, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86GpVar(const X86GpVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86GpVar` instance (internal). + explicit ASMJIT_INLINE X86GpVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86GpVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86GpVar operand. + ASMJIT_INLINE X86GpVar clone() const { + return X86GpVar(*this); + } + + //! Reset X86GpVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [X86GpVar Cast] + // -------------------------------------------------------------------------- + + //! Cast this variable to 8-bit (LO) part of variable + ASMJIT_INLINE X86GpVar r8() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } + //! Cast this variable to 8-bit (LO) part of variable + ASMJIT_INLINE X86GpVar r8Lo() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } + //! Cast this variable to 8-bit (HI) part of variable + ASMJIT_INLINE X86GpVar r8Hi() const { return X86GpVar(*this, kX86RegTypeGpbHi, 1); } + + //! Cast this variable to 16-bit part of variable + ASMJIT_INLINE X86GpVar r16() const { return X86GpVar(*this, kX86RegTypeGpw, 2); } + //! Cast this variable to 32-bit part of variable + ASMJIT_INLINE X86GpVar r32() const { return X86GpVar(*this, kX86RegTypeGpd, 4); } + //! Cast this variable to 64-bit part of variable + ASMJIT_INLINE X86GpVar r64() const { return X86GpVar(*this, kX86RegTypeGpq, 8); } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86GpVar& operator=(const X86GpVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86GpVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86GpVar& other) const { return X86Var::operator!=(other); } + + // -------------------------------------------------------------------------- + // [Private] + // -------------------------------------------------------------------------- + +protected: + ASMJIT_INLINE X86GpVar(const X86GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {} +}; + +// ============================================================================ +// [asmjit::X86MmVar] +// ============================================================================ + +//! Mm variable. +struct X86MmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86MmVar` instance. + ASMJIT_INLINE X86MmVar() : X86Var() {} + //! Create a new initialized `X86MmVar` instance. + ASMJIT_INLINE X86MmVar(Compiler& c, uint32_t type = kX86VarTypeMm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86MmVar(const X86MmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86MmVar` instance (internal). + explicit ASMJIT_INLINE X86MmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86MmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86MmVar operand. + ASMJIT_INLINE X86MmVar clone() const { + return X86MmVar(*this); + } + + //! Reset X86MmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86MmVar& operator=(const X86MmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86MmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86MmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86XmmVar] +// ============================================================================ + +//! Xmm variable. +struct X86XmmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86XmmVar` instance. + ASMJIT_INLINE X86XmmVar() : X86Var() {} + //! Create a new initialized `X86XmmVar` instance. + ASMJIT_INLINE X86XmmVar(Compiler& c, uint32_t type = kX86VarTypeXmm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86XmmVar(const X86XmmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86XmmVar` instance (internal). + explicit ASMJIT_INLINE X86XmmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86XmmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86XmmVar operand. + ASMJIT_INLINE X86XmmVar clone() const { + return X86XmmVar(*this); + } + + //! Reset X86XmmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86XmmVar& operator=(const X86XmmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86XmmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86XmmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86YmmVar] +// ============================================================================ + +//! Ymm variable. +struct X86YmmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86YmmVar` instance. + ASMJIT_INLINE X86YmmVar() : X86Var() {} + //! Create a new initialized `X86YmmVar` instance. + ASMJIT_INLINE X86YmmVar(Compiler& c, uint32_t type = kX86VarTypeYmm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86YmmVar(const X86YmmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86YmmVar` instance (internal). + explicit ASMJIT_INLINE X86YmmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86YmmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86YmmVar operand. + ASMJIT_INLINE X86YmmVar clone() const { + return X86YmmVar(*this); + } + + //! Reset X86YmmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86YmmVar& operator=(const X86YmmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86YmmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86YmmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86VarMap] +// ============================================================================ + +struct X86VarMap : public VarMap { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get variable-attributes list as VarAttr data. + ASMJIT_INLINE VarAttr* getVaList() const { + return const_cast(_list); + } + + //! Get variable-attributes list as VarAttr data (by class). + ASMJIT_INLINE VarAttr* getVaListByClass(uint32_t c) const { + return const_cast(_list) + _start.get(c); + } + + //! Get position of variables (by class). + ASMJIT_INLINE uint32_t getVaStart(uint32_t c) const { + return _start.get(c); + } + + //! Get count of variables (by class). + ASMJIT_INLINE uint32_t getVaCountByClass(uint32_t c) const { + return _count.get(c); + } + + //! Get VarAttr at `index`. + ASMJIT_INLINE VarAttr* getVa(uint32_t index) const { + ASMJIT_ASSERT(index < _vaCount); + return getVaList() + index; + } + + //! Get VarAttr of `c` class at `index`. + ASMJIT_INLINE VarAttr* getVaByClass(uint32_t c, uint32_t index) const { + ASMJIT_ASSERT(index < _count._regs[c]); + return getVaListByClass(c) + index; + } + + // -------------------------------------------------------------------------- + // [Utils] + // -------------------------------------------------------------------------- + + //! Find VarAttr. + ASMJIT_INLINE VarAttr* findVa(VarData* vd) const { + VarAttr* list = getVaList(); + uint32_t count = getVaCount(); + + for (uint32_t i = 0; i < count; i++) + if (list[i].getVd() == vd) + return &list[i]; + + return NULL; + } + + //! Find VarAttr (by class). + ASMJIT_INLINE VarAttr* findVaByClass(uint32_t c, VarData* vd) const { + VarAttr* list = getVaListByClass(c); + uint32_t count = getVaCountByClass(c); + + for (uint32_t i = 0; i < count; i++) + if (list[i].getVd() == vd) + return &list[i]; + + return NULL; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Special registers on input. + //! + //! Special register(s) restricted to one or more physical register. If there + //! is more than one special register it means that we have to duplicate the + //! variable content to all of them (it means that the same varible was used + //! by two or more operands). We forget about duplicates after the register + //! allocation finishes and marks all duplicates as non-assigned. + X86RegMask _inRegs; + + //! Special registers on output. + //! + //! Special register(s) used on output. Each variable can have only one + //! special register on the output, 'X86VarMap' contains all registers from + //! all 'VarAttr's. + X86RegMask _outRegs; + + //! Clobbered registers (by a function call). + X86RegMask _clobberedRegs; + + //! Start indexes of variables per register class. + X86RegCount _start; + //! Count of variables per register class. + X86RegCount _count; + + //! VarAttr list. + VarAttr _list[1]; +}; + +// ============================================================================ +// [asmjit::X86StateCell] +// ============================================================================ + +//! X86/X64 state-cell. +union X86StateCell { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t getState() const { + return _state; + } + + ASMJIT_INLINE void setState(uint32_t state) { + _state = static_cast(state); + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { _packed = 0; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint8_t _packed; + + struct { + uint8_t _state : 2; + uint8_t _unused : 6; + }; +}; + +// ============================================================================ +// [asmjit::X86VarState] +// ============================================================================ + +//! X86/X64 state. +struct X86VarState : VarState { + enum { + //! Base index of Gp registers. + kGpIndex = 0, + //! Count of Gp registers. + kGpCount = 16, + + //! Base index of Mm registers. + kMmIndex = kGpIndex + kGpCount, + //! Count of Mm registers. + kMmCount = 8, + + //! Base index of Xmm registers. + kXmmIndex = kMmIndex + kMmCount, + //! Count of Xmm registers. + kXmmCount = 16, + + //! Count of all registers in `X86VarState`. + kAllCount = kXmmIndex + kXmmCount + }; + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE VarData** getList() { + return _list; + } + + ASMJIT_INLINE VarData** getListByClass(uint32_t c) { + switch (c) { + case kX86RegClassGp : return _listGp; + case kX86RegClassMm : return _listMm; + case kX86RegClassXyz: return _listXmm; + + default: + return NULL; + } + } + + // -------------------------------------------------------------------------- + // [Clear] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset(size_t numCells) { + ::memset(this, 0, kAllCount * sizeof(VarData*) + + 2 * sizeof(X86RegMask) + + numCells * sizeof(X86StateCell)); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + //! List of all allocated variables in one array. + VarData* _list[kAllCount]; + + struct { + //! Allocated Gp registers. + VarData* _listGp[kGpCount]; + //! Allocated Mm registers. + VarData* _listMm[kMmCount]; + //! Allocated Xmm registers. + VarData* _listXmm[kXmmCount]; + }; + }; + + //! Occupied registers (mask). + X86RegMask _occupied; + //! Modified registers (mask). + X86RegMask _modified; + + //! Variables data, the length is stored in `X86Context`. + X86StateCell _cells[1]; +}; + +// ============================================================================ +// [asmjit::X86FuncDecl] +// ============================================================================ + +//! X86 function, including calling convention, arguments and their +//! register indices or stack positions. +struct X86FuncDecl : public FuncDecl { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncDecl` instance. + ASMJIT_INLINE X86FuncDecl() { + reset(); + } + + // -------------------------------------------------------------------------- + // [Accessors - X86] + // -------------------------------------------------------------------------- + + //! Get used registers (mask). + //! + //! \note The result depends on the function calling convention AND the + //! function prototype. Returned mask contains only registers actually used + //! to pass function arguments. + ASMJIT_INLINE uint32_t getUsed(uint32_t c) const { + return _used.get(c); + } + + //! Get passed registers (mask). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE uint32_t getPassed(uint32_t c) const { + return _passed.get(c); + } + + //! Get preserved registers (mask). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE uint32_t getPreserved(uint32_t c) const { + return _preserved.get(c); + } + + //! Get ther order of passed registers (Gp). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE const uint8_t* getPassedOrderGp() const { + return _passedOrderGp; + } + + //! Get ther order of passed registers (Xmm). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE const uint8_t* getPassedOrderXmm() const { + return _passedOrderXmm; + } + + // -------------------------------------------------------------------------- + // [SetPrototype] + // -------------------------------------------------------------------------- + + //! Set function prototype. + //! + //! This will set function calling convention and setup arguments variables. + //! + //! \note This function will allocate variables, it can be called only once. + ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_API void reset(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Used registers. + X86RegMask _used; + + //! Passed registers (defined by the calling convention). + X86RegMask _passed; + //! Preserved registers (defined by the calling convention). + X86RegMask _preserved; + + //! Order of registers defined to pass function arguments (Gp). + uint8_t _passedOrderGp[8]; + //! Order of registers defined to pass function arguments (Xmm). + uint8_t _passedOrderXmm[8]; +}; + +// ============================================================================ +// [asmjit::X86FuncNode] +// ============================================================================ + +//! X86/X64 function node. +struct X86FuncNode : public FuncNode { + ASMJIT_NO_COPY(X86FuncNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncNode` instance. + ASMJIT_INLINE X86FuncNode(Compiler* compiler) : FuncNode(compiler) { + _decl = &_x86Decl; + _saveRestoreRegs.reset(); + + _alignStackSize = 0; + _alignedMemStackSize = 0; + _pushPopStackSize = 0; + _moveStackSize = 0; + _extraStackSize = 0; + + _stackFrameRegIndex = kInvalidReg; + _isStackFrameRegPreserved = false; + _stackFrameCopyGpIndex[0] = kInvalidReg; + _stackFrameCopyGpIndex[1] = kInvalidReg; + _stackFrameCopyGpIndex[2] = kInvalidReg; + _stackFrameCopyGpIndex[3] = kInvalidReg; + _stackFrameCopyGpIndex[4] = kInvalidReg; + _stackFrameCopyGpIndex[5] = kInvalidReg; + } + + //! Destroy the `X86FuncNode` instance. + ASMJIT_INLINE ~X86FuncNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function declaration as `X86FuncDecl`. + ASMJIT_INLINE X86FuncDecl* getDecl() const { + return const_cast(&_x86Decl); + } + + //! Get argument. + ASMJIT_INLINE VarData* getArg(uint32_t i) const { + ASMJIT_ASSERT(i < _x86Decl.getArgCount()); + return static_cast(_argList[i]); + } + + //! Get registers which have to be saved in prolog/epilog. + ASMJIT_INLINE uint32_t getSaveRestoreRegs(uint32_t c) { return _saveRestoreRegs.get(c); } + + //! Get stack size needed to align stack back to the nature alignment. + ASMJIT_INLINE uint32_t getAlignStackSize() const { return _alignStackSize; } + //! Set stack size needed to align stack back to the nature alignment. + ASMJIT_INLINE void setAlignStackSize(uint32_t s) { _alignStackSize = s; } + + //! Get aligned stack size used by variables and memory allocated on the stack. + ASMJIT_INLINE uint32_t getAlignedMemStackSize() const { return _alignedMemStackSize; } + + //! Get stack size used by push/pop sequences in prolog/epilog. + ASMJIT_INLINE uint32_t getPushPopStackSize() const { return _pushPopStackSize; } + //! Set stack size used by push/pop sequences in prolog/epilog. + ASMJIT_INLINE void setPushPopStackSize(uint32_t s) { _pushPopStackSize = s; } + + //! Get stack size used by mov sequences in prolog/epilog. + ASMJIT_INLINE uint32_t getMoveStackSize() const { return _moveStackSize; } + //! Set stack size used by mov sequences in prolog/epilog. + ASMJIT_INLINE void setMoveStackSize(uint32_t s) { _moveStackSize = s; } + + //! Get extra stack size. + ASMJIT_INLINE uint32_t getExtraStackSize() const { return _extraStackSize; } + //! Set extra stack size. + ASMJIT_INLINE void setExtraStackSize(uint32_t s) { _extraStackSize = s; } + + //! Get whether the function has stack frame register. + //! + //! \note Stack frame register can be used for both - aligning purposes or + //! generating standard prolog/epilog sequence. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE bool hasStackFrameReg() const { return _stackFrameRegIndex != kInvalidReg; } + //! Get stack frame register index. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE uint32_t getStackFrameRegIndex() const { return _stackFrameRegIndex; } + //! Get whether the stack frame register is preserved. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE bool isStackFrameRegPreserved() const { return static_cast(_isStackFrameRegPreserved); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! X86 function decl. + X86FuncDecl _x86Decl; + //! Registers which must be saved/restored in prolog/epilog. + X86RegMask _saveRestoreRegs; + + //! Stack size needed to align function back to the nature alignment. + uint32_t _alignStackSize; + //! Like `_memStackSize`, but aligned. + uint32_t _alignedMemStackSize; + + //! Stack required for push/pop in prolog/epilog (X86/X64 specific). + uint32_t _pushPopStackSize; + //! Stack required for movs in prolog/epilog (X86/X64 specific). + uint32_t _moveStackSize; + + //! Stack required to put extra data (for example function arguments + //! when manually aligning to requested alignment). + uint32_t _extraStackSize; + + //! Stack frame register. + uint8_t _stackFrameRegIndex; + //! Whether the stack frame register is preserved. + uint8_t _isStackFrameRegPreserved; + //! Gp registers indexes that can be used to copy function arguments + //! to a new location in case we are doing manual stack alignment. + uint8_t _stackFrameCopyGpIndex[6]; +}; + +// ============================================================================ +// [asmjit::X86CallNode] +// ============================================================================ + +//! X86/X64 function-call node. +struct X86CallNode : public CallNode { + ASMJIT_NO_COPY(X86CallNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86CallNode` instance. + ASMJIT_INLINE X86CallNode(Compiler* compiler, const Operand& target) : CallNode(compiler, target) { + _decl = &_x86Decl; + _usedArgs.reset(); + } + + //! Destroy the `X86CallNode` instance. + ASMJIT_INLINE ~X86CallNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function prototype. + ASMJIT_INLINE X86FuncDecl* getDecl() const { + return const_cast(&_x86Decl); + } + + // -------------------------------------------------------------------------- + // [Prototype] + // -------------------------------------------------------------------------- + + //! Set function prototype. + ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Arg / Ret] + // -------------------------------------------------------------------------- + + //! Set argument at `i` to `op`. + ASMJIT_API bool _setArg(uint32_t i, const Operand& op); + //! Set return at `i` to `op`. + ASMJIT_API bool _setRet(uint32_t i, const Operand& op); + + //! Set argument at `i` to `var`. + ASMJIT_INLINE bool setArg(uint32_t i, const Var& var) { return _setArg(i, var); } + //! Set argument at `i` to `reg` (FP registers only). + ASMJIT_INLINE bool setArg(uint32_t i, const X86FpReg& reg) { return _setArg(i, reg); } + //! Set argument at `i` to `imm`. + ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) { return _setArg(i, imm); } + + //! Set return at `i` to `var`. + ASMJIT_INLINE bool setRet(uint32_t i, const Var& var) { return _setRet(i, var); } + //! Set return at `i` to `reg` (FP registers only). + ASMJIT_INLINE bool setRet(uint32_t i, const X86FpReg& reg) { return _setRet(i, reg); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! X86 declaration. + X86FuncDecl _x86Decl; + //! Mask of all registers actually used to pass function arguments. + //! + //! \note This bit-mask is not the same as `X86Func::_passed`. It contains + //! only registers actually used to do the call while `X86Func::_passed` + //! mask contains all registers for all function prototype combinations. + X86RegMask _usedArgs; +}; + +// ============================================================================ +// [asmjit::X86TypeId / VarMapping] +// ============================================================================ + +#if !defined(ASMJIT_DOCGEN) +ASMJIT_TYPE_ID(X86MmReg, kX86VarTypeMm); +ASMJIT_TYPE_ID(X86MmVar, kX86VarTypeMm); +ASMJIT_TYPE_ID(X86XmmReg, kX86VarTypeXmm); +ASMJIT_TYPE_ID(X86XmmVar, kX86VarTypeXmm); +ASMJIT_TYPE_ID(X86YmmReg, kX86VarTypeYmm); +ASMJIT_TYPE_ID(X86YmmVar, kX86VarTypeYmm); +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::X86Compiler] +// ============================================================================ + +//! X86/X64 compiler. +//! +//! This class is used to store instruction stream and allows to modify it on +//! the fly. It uses different concept than `Assembler` class and in fact +//! `Assembler` is only used as a backend. Compiler never emits machine code +//! and each instruction you use is stored to instruction array instead. This +//! allows to modify instruction stream later and for example to reorder +//! instructions to make better performance. +//! +//! `X86Compiler` moves code generation to a higher level. Higher level +//! constructs allows to write more abstract and extensible code that is not +//! possible with pure `X86Assembler`. +//! +//! The Story +//! --------- +//! +//! Before telling you how Compiler works I'd like to write a story. I'd like +//! to cover reasons why this class was created and why I'm recommending to use +//! it. When I released the first version of AsmJit (0.1) it was a toy. The +//! first function I wrote was function which is still available as testjit and +//! which simply returns 1024. The reason why function works for both 32-bit/ +//! 64-bit mode and for Windows/Unix specific calling conventions is luck, no +//! arguments usage and no registers usage except returning value in EAX/RAX. +//! +//! Then I started a project called BlitJit which was targetted to generating +//! JIT code for computer graphics. After writing some lines I decided that I +//! can't join pieces of code together without abstraction, should be +//! pixels source pointer in ESI/RSI or EDI/RDI or it's completelly +//! irrellevant? What about destination pointer and SSE2 register for reading +//! input pixels? The simple answer might be "just pick some one and use it". +//! +//! Another reason for abstraction is function calling-conventions. It's really +//! not easy to write assembler code for 32-bit and 64-bit platform supporting +//! three calling conventions (32-bit is similar between Windows and Unix, but +//! 64-bit calling conventions are different). +//! +//! At this time I realized that I can't write code which uses named registers, +//! I need to abstract it. In most cases you don't need specific register, you +//! need to emit instruction that does something with 'virtual' register(s), +//! memory, immediate or label. +//! +//! The first version of AsmJit with Compiler was 0.5 (or 0.6?, can't remember). +//! There was support for 32-bit and 64-bit mode, function calling conventions, +//! but when emitting instructions the developer needed to decide which +//! registers are changed, which are only read or completely overwritten. This +//! model helped a lot when generating code, especially when joining more +//! code-sections together, but there was also small possibility for mistakes. +//! Simply the first version of Compiler was great improvement over low-level +//! Assembler class, but the API design wasn't perfect. +//! +//! The second version of Compiler, completelly rewritten and based on +//! different goals, is part of AsmJit starting at version 1.0. This version +//! was designed after the first one and it contains serious improvements over +//! the old one. The first improvement is that you just use instructions with +//! virtual registers - called variables. When using compiler there is no way +//! to use native registers, there are variables instead. AsmJit is smarter +//! than before and it knows which register is needed only for read (r), +//! read/write (w) or overwrite (x). Supported are also instructions which +//! are using some registers in implicit way (these registers are not part of +//! instruction definition in string form). For example to use CPUID instruction +//! you must give it four variables which will be automatically allocated in +//! input/output registers (EAX, EBX, ECX, EDX). +//! +//! Another improvement is algorithm used by a register allocator. In first +//! version the registers were allocated when creating instruction stream. In +//! new version registers are allocated after calling `Compiler::make()`, +//! thus register allocator has information about scope of all variables and +//! statistics of their usage. The algorithm to allocate registers is very +//! simple and it's always called as a 'linear scan register allocator'. When +//! you get out of registers the all possible variables are scored and the worst +//! is spilled. Of course algorithm ignores the variables used for current +//! instruction. +//! +//! In addition, because registers are allocated after the code stream is +//! generated, the state switches between jumps are handled by Compiler too. +//! You don't need to worry about jumps, compiler always do this dirty work +//! for you. +//! +//! The nearly last thing I'd like to present is calling other functions from +//! the generated code. AsmJit uses a `FuncPrototype` class to hold function +//! parameters, their position in stack (or register index) and return value. +//! This class is used internally, but it can be used to create your own +//! function calling-convention. All standard function calling conventions are +//! implemented. +//! +//! Please enjoy the new version of Compiler, it was created for writing a +//! low-level code using high-level API, leaving developer to concentrate on +//! real problems and not to solving a register puzzle. +//! +//! Code Generation +//! --------------- +//! +//! First that is needed to know about compiler is that compiler never emits +//! machine code. It's used as a middleware between @c asmjit::Assembler and +//! your code. There is also convenience method @c make() that allows to +//! generate machine code directly without creating @c asmjit::Assembler +//! instance. +//! +//! Comparison of generating machine code through @c Assembler and directly +//! by @c Compiler: +//! +//! ~~~ +//! // Assembler instance is low level code generation class that emits +//! // machine code. +//! Assembler a; +//! +//! // Compiler instance is high level code generation class that stores all +//! // instructions in internal representation. +//! Compiler c; +//! +//! // ... put your code here ... +//! +//! // Final step - generate code. asmjit::Compiler::serialize() will send all +//! // instructions into Assembler and this ensures generating real machine code. +//! c.serialize(&a); +//! +//! // Your function +//! void* fn = a.make(); +//! ~~~ +//! +//! Example how to generate machine code using only @c Compiler (preferred): +//! +//! ~~~ +//! // Compiler instance is enough. +//! Compiler c; +//! +//! // ... put your code here ... +//! +//! // Your function +//! void* fn = c.make(); +//! ~~~ +//! +//! You can see that there is @c asmjit::Compiler::serialize() function that +//! emits instructions into @c asmjit::Assembler(). This layered architecture +//! means that each class is used for something different and there is no code +//! duplication. For convenience there is also @c asmjit::Compiler::make() +//! method that can create your function using @c asmjit::Assembler, but +//! internally (this is preferred bahavior when using @c asmjit::Compiler). +//! +//! The @c make() method allocates memory using `Runtime` instance passed +//! into the @c Compiler constructor. If code generator is used to create JIT +//! function then virtual memory allocated by `VMemMgr` is used. +//! +//! ~~~ +//! JitRuntime runtime; +//! Compiler c(&runtime); +//! +//! // ... put your code using Compiler instance ... +//! +//! // Your function +//! void* fn = c.make(); +//! +//! runtime.release(fn); +//! ~~~ +//! +//! Functions +//! --------- +//! +//! To build functions with @c Compiler, see @c asmjit::Compiler::addFunc() +//! method. +//! +//! Variables +//! --------- +//! +//! Compiler is able to manage variables and function arguments. Function +//! arguments are moved to variables by using @c setArg() method, where the +//! first parameter is argument index and second parameter is the variable +//! instance. To declare variable use @c newGpVar(), @c newMmVar() and @c +//! newXmmVar() methods. The @c newXXX() methods accept also parameter +//! describing the variable type. For example the @c newGpVar() method always +//! creates variable which size matches the target architecture size (for +//! 32-bit target the 32-bit variable is created, for 64-bit target the +//! variable size is 64-bit). To override this behavior the variable type +//! must be specified. +//! +//! ~~~ +//! // Compiler and function declaration - void f(int*); +//! Compiler c; +//! X86GpVar a0(c, kVarTypeIntPtr); +//! +//! c.addFunc(kFuncConvHost, FuncBuilder1()); +//! c.setArg(0, a0); +//! +//! // Create your variables. +//! X86GpVar x0(c, kVarTypeInt32); +//! X86GpVar x1(c, kVarTypeInt32); +//! +//! // Init your variables. +//! c.mov(x0, 1); +//! c.mov(x1, 2); +//! +//! // ... your code ... +//! c.add(x0, x1); +//! // ... your code ... +//! +//! // Store result to a given pointer in first argument +//! c.mov(dword_ptr(a0), x0); +//! +//! // End of function body. +//! c.endFunc(); +//! +//! // Make the function. +//! typedef void (*MyFunc)(int*); +//! MyFunc func = asmjit_cast(c.make()); +//! ~~~ +//! +//! This code snipped needs to be explained. You can see that there are more +//! variable types that can be used by `Compiler`. Most useful variables can +//! be allocated using general purpose registers (`X86GpVar`), MMX registers +//! (`X86MmVar`) or SSE/SSE2 registers (`X86XmmVar`). +//! +//! X86/X64 variable types: +//! +//! - `kVarTypeInt8` - Signed 8-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt8` - Unsigned 8-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt16` - Signed 16-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt16` - Unsigned 16-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt32` - Signed 32-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt32` - Unsigned 32-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt64` - Signed 64-bit integer, mapped to Gpq register (rax, rbx, ...). +//! - `kVarTypeUInt64` - Unsigned 64-bit integer, mapped to Gpq register (rax, rbx, ...). +//! +//! - `kVarTypeIntPtr` - intptr_t, mapped to Gpd/Gpq register; depends on target, not host! +//! - `kVarTypeUIntPtr` - uintptr_t, mapped to Gpd/Gpq register; depends on target, not host! +//! +//! - `kVarTypeFp32` - 32-bit floating point register (fp0, fp1, ...). +//! - `kVarTypeFp64` - 64-bit floating point register (fp0, fp1, ...). +//! +//! - `kX86VarTypeMm` - 64-bit Mm register (mm0, mm1, ...). +//! +//! - `kX86VarTypeXmm` - 128-bit SSE register. +//! - `kX86VarTypeXmmSs` - 128-bit SSE register that contains a scalar 32-bit SP-FP value. +//! - `kX86VarTypeXmmSd` - 128-bit SSE register that contains a scalar 64-bit DP-FP value. +//! - `kX86VarTypeXmmPs` - 128-bit SSE register that contains 4 packed 32-bit SP-FP values. +//! - `kX86VarTypeXmmPd` - 128-bit SSE register that contains 2 packed 64-bit DP-FP values. +//! +//! - `kX86VarTypeYmm` - 256-bit AVX register. +//! - `kX86VarTypeYmmPs` - 256-bit AVX register that contains 4 packed 32-bit SP-FP values. +//! - `kX86VarTypeYmmPd` - 256-bit AVX register that contains 2 packed 64-bit DP-FP values. +//! +//! Variable states: +//! +//! - `kVarStateUnused - State that is assigned to newly created variables or +//! to not used variables (dereferenced to zero). +//! - `kVarStateReg - State that means that variable is currently allocated in +//! register. +//! - `kVarStateMem - State that means that variable is currently only in +//! memory location. +//! +//! When you create new variable, initial state is always `kVarStateUnused`, +//! allocating it to register or spilling to memory changes this state to +//! `kVarStateReg` or `kVarStateMem`, respectively. During variable lifetime +//! it's usual that its state is changed multiple times. To generate better +//! code, you can control allocating and spilling by using up to four types +//! of methods that allows it (see next list). +//! +//! Explicit variable allocating / spilling methods: +//! +//! - `Compiler::alloc()` - Explicit method to alloc variable into register. +//! It can be used to force allocation a variable before a loop for example. +//! +//! - `Compiler::spill()` - Explicit method to spill variable. If variable +//! is in register and you call this method, it's moved to its home memory +//! location. If variable is not in register no operation is performed. +//! +//! - `Compiler::unuse()` - Unuse variable (you can use this to end the +//! variable scope or sub-scope). +//! +//! Please see AsmJit tutorials (testcompiler.cpp and testvariables.cpp) for +//! more complete examples. +//! +//! Memory Management +//! ----------------- +//! +//! Compiler Memory management follows these rules: +//! +//! - Everything created by `Compiler` is always freed by `Compiler`. +//! - To get decent performance, compiler always uses larger memory buffer +//! for objects to allocate and when compiler instance is destroyed, this +//! buffer is freed. Destructors of active objects are called when +//! destroying compiler instance. Destructors of abadonded compiler +//! objects are called immediately after abadonding them. +//! - This type of memory management is called 'zone memory management'. +//! +//! This means that you can't use any `Compiler` object after destructing it, +//! it also means that each object like `Label`, `Var` and others are created +//! and managed by @c Compiler itself. These objects contain ID which is +//! used internally by Compiler to store additional information about these +//! objects. +//! +//! Control-Flow and State Management +//! --------------------------------- +//! +//! The `Compiler` automatically manages state of the variables when using +//! control flow instructions like jumps, conditional jumps and calls. There +//! is minimal heuristics for choosing the method how state is saved or restored. +//! +//! Generally the state can be changed only when using jump or conditional jump +//! instruction. When using non-conditional jump then state change is embedded +//! into the instruction stream before the jump. When using conditional jump +//! the `Compiler` decides whether to restore state before the jump or whether +//! to use another block where state is restored. The last case is that no-code +//! have to be emitted and there is no state change (this is of course ideal). +//! +//! Choosing whether to embed 'restore-state' section before conditional jump +//! is quite simple. If jump is likely to be 'taken' then code is embedded, if +//! jump is unlikely to be taken then the small code section for state-switch +//! will be generated instead. +//! +//! Next example is the situation where the extended code block is used to +//! do state-change: +//! +//! ~~~ +//! Compiler c; +//! +//! c.addFunc(kFuncConvHost, FuncBuilder0()); +//! +//! // Labels. +//! Label L0(c); +//! +//! // Variables. +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! // Cleanup. After these two lines, the var0 and var1 will be always stored +//! // in registers. Our example is very small, but in larger code the var0 can +//! // be spilled by xor(var1, var1). +//! c.xor_(var0, var0); +//! c.xor_(var1, var1); +//! c.cmp(var0, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We manually spill these variables. +//! c.spill(var0); +//! c.spill(var1); +//! // State: +//! // var0 - memory. +//! // var1 - memory. +//! +//! // Conditional jump to L0. It will be always taken, but compiler thinks that +//! // it is unlikely taken so it will embed state change code somewhere. +//! c.je(L0); +//! +//! // Do something. The variables var0 and var1 will be allocated again. +//! c.add(var0, 1); +//! c.add(var1, 2); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // Bind label here, the state is not changed. +//! c.bind(L0); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We need to use var0 and var1, because if compiler detects that variables +//! // are out of scope then it optimizes the state-change. +//! c.sub(var0, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! c.endFunc(); +//! ~~~ +//! +//! The output: +//! +//! ~~~ +//! xor eax, eax ; xor var_0, var_0 +//! xor ecx, ecx ; xor var_1, var_1 +//! cmp eax, ecx ; cmp var_0, var_1 +//! mov [esp - 24], eax ; spill var_0 +//! mov [esp - 28], ecx ; spill var_1 +//! je L0_Switch +//! mov eax, [esp - 24] ; alloc var_0 +//! add eax, 1 ; add var_0, 1 +//! mov ecx, [esp - 28] ; alloc var_1 +//! add ecx, 2 ; add var_1, 2 +//! L0: +//! sub eax, ecx ; sub var_0, var_1 +//! ret +//! +//! ; state-switch begin +//! L0_Switch0: +//! mov eax, [esp - 24] ; alloc var_0 +//! mov ecx, [esp - 28] ; alloc var_1 +//! jmp short L0 +//! ; state-switch end +//! ~~~ +//! +//! You can see that the state-switch section was generated (see L0_Switch0). +//! The compiler is unable to restore state immediately when emitting the +//! forward jump (the code is generated from first to last instruction and +//! the target state is simply not known at this time). +//! +//! To tell `Compiler` that you want to embed state-switch code before jump +//! it's needed to create backward jump (where also processor expects that it +//! will be taken). To demonstrate the possibility to embed state-switch before +//! jump we use slightly modified code: +//! +//! ~~~ +//! Compiler c; +//! +//! c.addFunc(kFuncConvHost, FuncBuilder0()); +//! +//! // Labels. +//! Label L0(c); +//! +//! // Variables. +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! // Cleanup. After these two lines, the var0 and var1 will be always stored +//! // in registers. Our example is very small, but in larger code the var0 can +//! // be spilled by xor(var1, var1). +//! c.xor_(var0, var0); +//! c.xor_(var1, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We manually spill these variables. +//! c.spill(var0); +//! c.spill(var1); +//! // State: +//! // var0 - memory. +//! // var1 - memory. +//! +//! // Bind our label here. +//! c.bind(L0); +//! +//! // Do something, the variables will be allocated again. +//! c.add(var0, 1); +//! c.add(var1, 2); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // Backward conditional jump to L0. The default behavior is that it is taken +//! // so state-change code will be embedded here. +//! c.je(L0); +//! +//! c.endFunc(); +//! ~~~ +//! +//! The output: +//! +//! ~~~ +//! xor ecx, ecx ; xor var_0, var_0 +//! xor edx, edx ; xor var_1, var_1 +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! L2: +//! mov ecx, [esp - 24] ; alloc var_0 +//! add ecx, 1 ; add var_0, 1 +//! mov edx, [esp - 28] ; alloc var_1 +//! add edx, 2 ; add var_1, 2 +//! +//! ; state-switch begin +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! ; state-switch end +//! +//! je short L2 +//! ret +//! ~~~ +//! +//! Please notice where the state-switch section is located. The `Compiler` +//! decided that jump is likely to be taken so the state change is embedded +//! before the conditional jump. To change this behavior into the previous +//! case it's needed to add an option (kInstOptionTaken/kInstOptionNotTaken). +//! +//! Replacing the c.je(L0) by c.taken(); c.je(L0) +//! will generate code like this: +//! +//! ~~~ +//! xor ecx, ecx ; xor var_0, var_0 +//! xor edx, edx ; xor var_1, var_1 +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! L0: +//! mov ecx, [esp - 24] ; alloc var_0 +//! add ecx, 1 ; add var_0, a +//! mov edx, [esp - 28] ; alloc var_1 +//! add edx, 2 ; add var_1, 2 +//! je L0_Switch, 2 +//! ret +//! +//! ; state-switch begin +//! L0_Switch: +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! jmp short L0 +//! ; state-switch end +//! ~~~ +//! +//! This section provided information about how state-change works. The +//! behavior is deterministic and it can be overridden. +//! +//! Advanced Code Generation +//! ------------------------ +//! +//! This section describes advanced method of code generation available to +//! `Compiler` (but also to `Assembler`). When emitting code to instruction +//! stream the methods like `mov()`, `add()`, `sub()` can be called directly +//! (advantage is static-type control performed also by C++ compiler) or +//! indirectly using `emit()` method. The `emit()` method needs only instruction +//! code and operands. +//! +//! Example of code generating by standard type-safe API: +//! +//! ~~~ +//! Compiler c; +//! +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! ... +//! +//! c.mov(var0, 0); +//! c.add(var0, var1); +//! c.sub(var0, var1); +//! ~~~ +//! +//! The code above can be rewritten as: +//! +//! ~~~ +//! Compiler c; +//! +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! ... +//! +//! c.emit(kX86InstIdMov, var0, 0); +//! c.emit(kX86InstIdAdd, var0, var1); +//! c.emit(kX86InstIdSub, var0, var1); +//! ~~~ +//! +//! The advantage of first snippet is very friendly API and type-safe control +//! that is controlled by the C++ compiler. The advantage of second snippet is +//! availability to replace or generate instruction code in different places. +//! See the next example how the `emit()` method can be used to generate abstract +//! code. +//! +//! Use case: +//! +//! ~~~ +//! bool emitArithmetic(Compiler& c, X86XmmVar& var0, X86XmmVar& var1, const char* op) { +//! uint32_t code = kInstIdNone; +//! +//! if (strcmp(op, "ADD") == 0) +//! code = kX86InstIdAddss; +//! else if (::strcmp(op, "SUBTRACT") == 0) +//! code = kX86InstIdSubss; +//! else if (::strcmp(op, "MULTIPLY") == 0) +//! code = kX86InstIdMulss; +//! else if (::strcmp(op, "DIVIDE") == 0) +//! code = kX86InstIdDivss; +//! else +//! // Invalid parameter? +//! return false; +//! +//! c.emit(code, var0, var1); +//! } +//! ~~~ +//! +//! Other use cases are waiting for you! Be sure that instruction you are +//! emitting is correct and encodable, because if not, Assembler will set +//! status code to `kErrorUnknownInst`. +struct ASMJIT_VCLASS X86Compiler : public Compiler { + ASMJIT_NO_COPY(X86Compiler) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `X86Compiler` instance. + ASMJIT_API X86Compiler(Runtime* runtime, uint32_t arch +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + = kArchHost +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + ); + + //! Destroy the `X86Compiler` instance. + ASMJIT_API ~X86Compiler(); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! Set the architecture to `arch`. + ASMJIT_API Error setArch(uint32_t arch); + + //! Get count of registers of the current architecture and mode. + ASMJIT_INLINE const X86RegCount& getRegCount() const { + return _regCount; + } + + //! Get Gpd or Gpq register depending on the current architecture. + ASMJIT_INLINE X86GpReg gpz(uint32_t index) const { + return X86GpReg(zax, index); + } + + //! Create an architecture dependent intptr_t memory operand. + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const { + return x86::ptr(label, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, int32_t disp = 0) { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + // -------------------------------------------------------------------------- + // [Inst / Emit] + // -------------------------------------------------------------------------- + + //! Create a new `InstNode`. + ASMJIT_API InstNode* newInst(uint32_t code); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4); + + //! Add a new `InstNode`. + ASMJIT_API InstNode* emit(uint32_t code); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4); + + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, int o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, uint64_t o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, int o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, uint64_t o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3); + + // -------------------------------------------------------------------------- + // [Func] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncNode`. + ASMJIT_API X86FuncNode* newFunc(uint32_t conv, const FuncPrototype& p); + + //! Add a new function. + //! + //! \param conv Calling convention to use (see \ref kFuncConv enum) + //! \param params Function arguments prototype. + //! + //! This method is usually used as a first step when generating functions + //! by `Compiler`. First parameter `cconv` specifies function calling + //! convention to use. Second parameter `params` specifies function + //! arguments. To create function arguments are used templates + //! `FuncBuilder0<...>`, `FuncBuilder1<...>`, `FuncBuilder2<...>`, etc... + //! + //! Templates with FuncBuilder prefix are used to generate argument IDs + //! based on real C++ types. See next example how to generate function with + //! two 32-bit integer arguments. + //! + //! ~~~ + //! // Building function using asmjit::Compiler example. + //! + //! // Compiler instance + //! Compiler c; + //! + //! // Begin of function, also emits function prolog. + //! c.addFunc( + //! // Default calling convention (32-bit cdecl or 64-bit for host OS) + //! kFuncConvHost, + //! // Using function builder to generate arguments list + //! FuncBuilder2()); + //! + //! // End of function, also emits function epilog. + //! c.endFunc(); + //! ~~~ + //! + //! You can see that building functions is really easy. Previous code snipped + //! will generate code for function with two 32-bit integer arguments. You + //! can access arguments by `asmjit::Function::getArg()` method. Arguments + //! are indexed from 0 (like everything in C). + //! + //! ~~~ + //! // Accessing function arguments through asmjit::Function example. + //! + //! // Compiler instance + //! Compiler c; + //! X86GpVar a0(c, kVarTypeInt32); + //! X86GpVar a1(c, kVarTypeInt32); + //! + //! // Begin of function (also emits function prolog) + //! c.addFunc( + //! // Default calling convention (32-bit cdecl or 64-bit for host OS) + //! kFuncConvHost, + //! // Using function builder to generate arguments list + //! FuncBuilder2()); + //! + //! c.setArg(0, a0); + //! c.setArg(1, a1); + //! + //! // Use them. + //! c.add(a0, a1); + //! + //! // End of function - emits function epilog and return instruction. + //! c.endFunc(); + //! ~~~ + //! + //! Arguments are like variables. How to manipulate with variables is + //! documented in `Compiler`, variables section. + //! + //! \note To get current function use `getFunc()` method or save pointer to + //! `FuncNode` returned by `Compiler::addFunc<>` method. The recommended way + //! is saving the pointer and using it to specify function arguments and + //! return value. + //! + //! \sa FuncBuilder0, FuncBuilder1, FuncBuilder2, ... + ASMJIT_API X86FuncNode* addFunc(uint32_t conv, const FuncPrototype& p); + + //! End of current function. + ASMJIT_API EndNode* endFunc(); + + //! Get current function as `X86FuncNode`. + //! + //! This method can be called within `addFunc()` and `endFunc()` block to get + //! current function you are working with. It's recommended to store `FuncNode` + //! pointer returned by `addFunc<>` method, because this allows you in future + //! implement function sections outside of function itself. + ASMJIT_INLINE X86FuncNode* getFunc() const { + return static_cast(_func); + } + + // -------------------------------------------------------------------------- + // [Ret] + // -------------------------------------------------------------------------- + + //! Create a new `RetNode`. + ASMJIT_API RetNode* newRet(const Operand& o0, const Operand& o1); + //! Add a new `RetNode`. + ASMJIT_API RetNode* addRet(const Operand& o0, const Operand& o1); + + // -------------------------------------------------------------------------- + // [Call] + // -------------------------------------------------------------------------- + + //! Create a new `X86CallNode`. + ASMJIT_API X86CallNode* newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); + //! Add a new `X86CallNode`. + ASMJIT_API X86CallNode* addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Vars] + // -------------------------------------------------------------------------- + + //! Set function argument to `var`. + ASMJIT_API Error setArg(uint32_t argIndex, Var& var); + + ASMJIT_API virtual Error _newVar(Var* var, uint32_t type, const char* name); + + //! Create a new Gp variable. + ASMJIT_INLINE X86GpVar newGpVar(uint32_t vType = kVarTypeIntPtr, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeIntStart, _kVarTypeIntEnd)); + + X86GpVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Mm variable. + ASMJIT_INLINE X86MmVar newMmVar(uint32_t vType = kX86VarTypeMm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeMmStart, _kX86VarTypeMmEnd)); + + X86MmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Xmm variable. + ASMJIT_INLINE X86XmmVar newXmmVar(uint32_t vType = kX86VarTypeXmm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd)); + + X86XmmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Ymm variable. + ASMJIT_INLINE X86YmmVar newYmmVar(uint32_t vType = kX86VarTypeYmm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd)); + + X86YmmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + // -------------------------------------------------------------------------- + // [Stack] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name); + + //! Create a new memory chunk allocated on the current function's stack. + ASMJIT_INLINE X86Mem newStack(uint32_t size, uint32_t alignment, const char* name = NULL) { + X86Mem m(NoInit); + _newStack(&m, size, alignment, name); + return m; + } + + // -------------------------------------------------------------------------- + // [Const] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size); + + //! Put data to a constant-pool and get a memory reference to it. + ASMJIT_INLINE X86Mem newConst(uint32_t scope, const void* data, size_t size) { + X86Mem m(NoInit); + _newConst(&m, scope, data, size); + return m; + } + + //! Put a BYTE `val` to a constant-pool. + ASMJIT_INLINE X86Mem newByteConst(uint32_t scope, uint8_t val) { return newConst(scope, &val, 1); } + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newWordConst(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newDWordConst(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newQWordConst(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } + + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt16Const(uint32_t scope, int16_t val) { return newConst(scope, &val, 2); } + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt16Const(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt32Const(uint32_t scope, int32_t val) { return newConst(scope, &val, 4); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt32Const(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt64Const(uint32_t scope, int64_t val) { return newConst(scope, &val, 8); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt64Const(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } + + //! Put a SP-FP `val` to a constant-pool. + ASMJIT_INLINE X86Mem newFloatConst(uint32_t scope, float val) { return newConst(scope, &val, 4); } + //! Put a DP-FP `val` to a constant-pool. + ASMJIT_INLINE X86Mem newDoubleConst(uint32_t scope, double val) { return newConst(scope, &val, 8); } + + //! Put a MMX `val` to a constant-pool. + ASMJIT_INLINE X86Mem newMmConst(uint32_t scope, const Vec64& val) { return newConst(scope, &val, 8); } + //! Put a XMM `val` to a constant-pool. + ASMJIT_INLINE X86Mem newXmmConst(uint32_t scope, const Vec128& val) { return newConst(scope, &val, 16); } + //! Put a YMM `val` to a constant-pool. + ASMJIT_INLINE X86Mem newYmmConst(uint32_t scope, const Vec256& val) { return newConst(scope, &val, 32); } + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* db(uint8_t x) { return embed(&x, 1); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dw(uint16_t x) { return embed(&x, 2); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dd(uint32_t x) { return embed(&x, 4); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dq(uint64_t x) { return embed(&x, 8); } + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint8(int8_t x) { return embed(&x, static_cast(sizeof(int8_t))); } + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint8(uint8_t x) { return embed(&x, static_cast(sizeof(uint8_t))); } + + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint16(int16_t x) { return embed(&x, static_cast(sizeof(int16_t))); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint16(uint16_t x) { return embed(&x, static_cast(sizeof(uint16_t))); } + + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint32(int32_t x) { return embed(&x, static_cast(sizeof(int32_t))); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint32(uint32_t x) { return embed(&x, static_cast(sizeof(uint32_t))); } + + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint64(int64_t x) { return embed(&x, static_cast(sizeof(int64_t))); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint64(uint64_t x) { return embed(&x, static_cast(sizeof(uint64_t))); } + + //! Add float data to the instruction stream. + ASMJIT_INLINE EmbedNode* dfloat(float x) { return embed(&x, static_cast(sizeof(float))); } + //! Add double data to the instruction stream. + ASMJIT_INLINE EmbedNode* ddouble(double x) { return embed(&x, static_cast(sizeof(double))); } + + //! Add Mm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dmm(const Vec64& x) { return embed(&x, static_cast(sizeof(Vec64))); } + //! Add Xmm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dxmm(const Vec128& x) { return embed(&x, static_cast(sizeof(Vec128))); } + //! Add Ymm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dymm(const Vec256& x) { return embed(&x, static_cast(sizeof(Vec256))); } + + //! Add data in a given structure instance to the instruction stream. + template + ASMJIT_INLINE EmbedNode* dstruct(const T& x) { return embed(&x, static_cast(sizeof(T))); } + + // -------------------------------------------------------------------------- + // [Make] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void* make(); + + // ------------------------------------------------------------------------- + // [Assembler] + // ------------------------------------------------------------------------- + + ASMJIT_API virtual Assembler* _newAssembler(); + + // ------------------------------------------------------------------------- + // [Serialize] + // ------------------------------------------------------------------------- + + ASMJIT_API virtual Error serialize(Assembler* assembler); + + // ------------------------------------------------------------------------- + // [Options] + // ------------------------------------------------------------------------- + + ASMJIT_X86_EMIT_OPTIONS(X86Compiler) + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of registers depending on the current architecture. + X86RegCount _regCount; + + //! EAX or RAX register depending on the current architecture. + X86GpReg zax; + //! ECX or RCX register depending on the current architecture. + X86GpReg zcx; + //! EDX or RDX register depending on the current architecture. + X86GpReg zdx; + //! EBX or RBX register depending on the current architecture. + X86GpReg zbx; + //! ESP or RSP register depending on the current architecture. + X86GpReg zsp; + //! EBP or RBP register depending on the current architecture. + X86GpReg zbp; + //! ESI or RSI register depending on the current architecture. + X86GpReg zsi; + //! EDI or RDI register depending on the current architecture. + X86GpReg zdi; + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + +#define INST_0x(_Inst_, _Code_) \ + ASMJIT_INLINE InstNode* _Inst_() { \ + return emit(_Code_); \ + } + +#define INST_1x(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0); \ + } + +#define INST_1i(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(int o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(unsigned int o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(int64_t o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(uint64_t o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0) { \ + return emit(_Translate_(cc), o0); \ + } \ + \ + ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); } + +#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, unsigned int o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int64_t o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, uint64_t o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Translate_(cc), o0, o1); \ + } \ + \ + ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); } + +#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int o1, int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, unsigned int o1, unsigned int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int64_t o1, int64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, uint64_t o1, uint64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } + +#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int o2, int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2, unsigned int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2, int64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2, uint64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } + + // -------------------------------------------------------------------------- + // [X86/X64] + // -------------------------------------------------------------------------- + + //! Add with carry. + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86GpVar) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86Mem) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86GpVar, Imm) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpVar) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) + + //! Add. + INST_2x(add, kX86InstIdAdd, X86GpVar, X86GpVar) + //! \overload + INST_2x(add, kX86InstIdAdd, X86GpVar, X86Mem) + //! \overload + INST_2i(add, kX86InstIdAdd, X86GpVar, Imm) + //! \overload + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpVar) + //! \overload + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) + + //! And. + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86GpVar) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86Mem) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86GpVar, Imm) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpVar) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) + + //! Bit scan forward. + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86GpVar, !o0.isGpb()) + //! \overload + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86Mem, !o0.isGpb()) + + //! Bit scan reverse. + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86GpVar, !o0.isGpb()) + //! \overload + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86Mem, !o0.isGpb()) + + //! Byte swap (32-bit or 64-bit registers only) (i486). + INST_1x_(bswap, kX86InstIdBswap, X86GpVar, o0.getSize() >= 4) + + //! Bit test. + INST_2x(bt, kX86InstIdBt, X86GpVar, X86GpVar) + //! \overload + INST_2i(bt, kX86InstIdBt, X86GpVar, Imm) + //! \overload + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpVar) + //! \overload + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) + + //! Bit test and complement. + INST_2x(btc, kX86InstIdBtc, X86GpVar, X86GpVar) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86GpVar, Imm) + //! \overload + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpVar) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) + + //! Bit test and reset. + INST_2x(btr, kX86InstIdBtr, X86GpVar, X86GpVar) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86GpVar, Imm) + //! \overload + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpVar) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) + + //! Bit test and set. + INST_2x(bts, kX86InstIdBts, X86GpVar, X86GpVar) + //! \overload + INST_2i(bts, kX86InstIdBts, X86GpVar, Imm) + //! \overload + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpVar) + //! \overload + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) + + //! Call a function. + ASMJIT_INLINE X86CallNode* call(const X86GpVar& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const X86Mem& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const Label& label, uint32_t conv, const FuncPrototype& p) { + return addCall(label, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const Imm& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(Ptr dst, uint32_t conv, const FuncPrototype& p) { + return addCall(Imm(dst), conv, p); + } + + //! Clear carry flag + INST_0x(clc, kX86InstIdClc) + //! Clear direction flag + INST_0x(cld, kX86InstIdCld) + //! Complement carry Flag. + INST_0x(cmc, kX86InstIdCmc) + + //! Convert BYTE to WORD (AX <- Sign Extend AL). + INST_1x(cbw, kX86InstIdCbw, X86GpVar /* al */) + //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). + INST_2x(cdq, kX86InstIdCdq, X86GpVar /* edx */, X86GpVar /* eax */) + //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only). + INST_1x(cdqe, kX86InstIdCdqe, X86GpVar /* eax */) + //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only). + INST_2x(cqo, kX86InstIdCdq, X86GpVar /* rdx */, X86GpVar /* rax */) + //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). + INST_2x(cwd, kX86InstIdCwd, X86GpVar /* dx */, X86GpVar /* ax */) + //! Convert WORD to DWORD (EAX <- Sign Extend AX). + INST_1x(cwde, kX86InstIdCwde, X86GpVar /* eax */) + + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86GpVar) + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86Mem) + + //! Compare two operands. + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86GpVar) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86Mem) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86GpVar, Imm) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpVar) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm) + + //! Compare BYTE in ES:`o0` and DS:`o1`. + INST_2x(cmpsb, kX86InstIdCmpsB, X86GpVar, X86GpVar) + //! Compare DWORD in ES:`o0` and DS:`o1`. + INST_2x(cmpsd, kX86InstIdCmpsD, X86GpVar, X86GpVar) + //! Compare QWORD in ES:`o0` and DS:`o1` (X64 Only). + INST_2x(cmpsq, kX86InstIdCmpsQ, X86GpVar, X86GpVar) + //! Compare WORD in ES:`o0` and DS:`o1`. + INST_2x(cmpsw, kX86InstIdCmpsW, X86GpVar, X86GpVar) + + //! Compare and exchange (i486). + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86GpVar, X86GpVar) + //! \overload + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86Mem, X86GpVar) + + //! Compare and exchange 128-bit value in RDX:RAX with `x_mem` (X64 Only). + ASMJIT_INLINE InstNode* cmpxchg16b( + const X86GpVar& r_edx, const X86GpVar& r_eax, + const X86GpVar& r_ecx, const X86GpVar& r_ebx, + const X86Mem& x_mem) { + + return emit(kX86InstIdCmpxchg16b, r_edx, r_eax, r_ecx, r_ebx, x_mem); + } + + //! Compare and exchange 64-bit value in EDX:EAX with `x_mem` (Pentium). + ASMJIT_INLINE InstNode* cmpxchg8b( + const X86GpVar& r_edx, const X86GpVar& r_eax, + const X86GpVar& r_ecx, const X86GpVar& r_ebx, + const X86Mem& x_mem) { + + return emit(kX86InstIdCmpxchg8b, r_edx, r_eax, r_ecx, r_ebx, x_mem); + } + + //! CPU identification (i486). + ASMJIT_INLINE InstNode* cpuid( + const X86GpVar& x_eax, + const X86GpVar& w_ebx, + const X86GpVar& x_ecx, + const X86GpVar& w_edx) { + + // Destination variables must be different. + ASMJIT_ASSERT(x_eax.getId() != w_ebx.getId() && + w_ebx.getId() != x_ecx.getId() && + x_ecx.getId() != w_edx.getId()); + + return emit(kX86InstIdCpuid, x_eax, w_ebx, x_ecx, w_edx); + } + + //! Decimal adjust AL after addition (X86 Only). + INST_1x(daa, kX86InstIdDaa, X86GpVar) + //! Decimal adjust AL after subtraction (X86 Only). + INST_1x(das, kX86InstIdDas, X86GpVar) + + //! Decrement by 1. + INST_1x(dec, kX86InstIdDec, X86GpVar) + //! \overload + INST_1x(dec, kX86InstIdDec, X86Mem) + + //! Unsigned divide (o0:o1 <- o0:o1 / o2). + //! + //! Remainder is stored in `o0`, quotient is stored in `o1`. + INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed divide (o0:o1 <- o0:o1 / o2). + //! + //! Remainder is stored in `o0`, quotient is stored in `o1`. + INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed multiply (o0:o1 <- o1 * o2). + //! + //! Hi value is stored in `o0`, lo value is stored in `o1`. + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed multiply. + INST_2x(imul, kX86InstIdImul, X86GpVar, X86GpVar) + //! \overload + INST_2x(imul, kX86InstIdImul, X86GpVar, X86Mem) + //! \overload + INST_2i(imul, kX86InstIdImul, X86GpVar, Imm) + + //! Signed multiply. + INST_3i(imul, kX86InstIdImul, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(imul, kX86InstIdImul, X86GpVar, X86Mem, Imm) + + //! Increment by 1. + INST_1x(inc, kX86InstIdInc, X86GpVar) + //! \overload + INST_1x(inc, kX86InstIdInc, X86Mem) + + //! Interrupt. + INST_1i(int_, kX86InstIdInt, Imm) + //! Interrupt 3 - trap to debugger. + ASMJIT_INLINE InstNode* int3() { return int_(3); } + + //! Jump to label `label` if condition `cc` is met. + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) + + //! Short jump if CX/ECX/RCX is zero. + INST_2x(jecxz, kX86InstIdJecxz, X86GpVar, Label) + + //! Jump. + INST_1x(jmp, kX86InstIdJmp, X86GpVar) + //! \overload + INST_1x(jmp, kX86InstIdJmp, X86Mem) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Label) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Imm) + //! \overload + ASMJIT_INLINE InstNode* jmp(Ptr dst) { return jmp(Imm(dst)); } + + //! Load AH from flags. + INST_1x(lahf, kX86InstIdLahf, X86GpVar) + + //! Load effective address + INST_2x(lea, kX86InstIdLea, X86GpVar, X86Mem) + + //! Load BYTE from DS:`o1` to `o0`. + INST_2x(lodsb, kX86InstIdLodsB, X86GpVar, X86GpVar) + //! Load DWORD from DS:`o1` to `o0`. + INST_2x(lodsd, kX86InstIdLodsD, X86GpVar, X86GpVar) + //! Load QWORD from DS:`o1` to `o0` (X64 Only). + INST_2x(lodsq, kX86InstIdLodsQ, X86GpVar, X86GpVar) + //! Load WORD from DS:`o1` to `o0`. + INST_2x(lodsw, kX86InstIdLodsW, X86GpVar, X86GpVar) + + //! Move. + INST_2x(mov, kX86InstIdMov, X86GpVar, X86GpVar) + //! \overload + INST_2x(mov, kX86InstIdMov, X86GpVar, X86Mem) + //! \overload + INST_2i(mov, kX86InstIdMov, X86GpVar, Imm) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpVar) + //! \overload + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) + + //! Move from segment register. + INST_2x(mov, kX86InstIdMov, X86GpVar, X86SegReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) + //! Move to segment register. + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpVar) + //! \overload + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) + + //! Move (AL|AX|EAX|RAX <- absolute address in immediate). + INST_2x(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm); + //! \overload + ASMJIT_INLINE InstNode* mov_ptr(const X86GpReg& o0, Ptr o1) { + ASMJIT_ASSERT(o0.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, o0, Imm(o1)); + } + + //! Move (absolute address in immediate <- AL|AX|EAX|RAX). + INST_2x(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg); + //! \overload + ASMJIT_INLINE InstNode* mov_ptr(Ptr o0, const X86GpReg& o1) { + ASMJIT_ASSERT(o1.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, Imm(o0), o1); + } + + //! Move data after swapping bytes (SSE3 - Atom). + INST_2x_(movbe, kX86InstIdMovbe, X86GpVar, X86Mem, !o0.isGpb()); + //! \overload + INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpVar, !o1.isGpb()); + + //! Load BYTE from DS:`o1` to ES:`o0`. + INST_2x(movsb, kX86InstIdMovsB, X86GpVar, X86GpVar) + //! Load DWORD from DS:`o1` to ES:`o0`. + INST_2x(movsd, kX86InstIdMovsD, X86GpVar, X86GpVar) + //! Load QWORD from DS:`o1` to ES:`o0` (X64 Only). + INST_2x(movsq, kX86InstIdMovsQ, X86GpVar, X86GpVar) + //! Load WORD from DS:`o1` to ES:`o0`. + INST_2x(movsw, kX86InstIdMovsW, X86GpVar, X86GpVar) + + //! Move with sign-extension. + INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86GpVar) + //! \overload + INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86Mem) + + //! Move DWORD to QWORD with sign-extension (X64 Only). + INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86GpVar) + //! \overload + INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86Mem) + + //! Move with zero-extension. + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86GpVar) + //! \overload + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86Mem) + + //! Unsigned multiply (o0:o1 <- o1 * o2). + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Two's complement negation. + INST_1x(neg, kX86InstIdNeg, X86GpVar) + //! \overload + INST_1x(neg, kX86InstIdNeg, X86Mem) + + //! No operation. + INST_0x(nop, kX86InstIdNop) + + //! One's complement negation. + INST_1x(not_, kX86InstIdNot, X86GpVar) + //! \overload + INST_1x(not_, kX86InstIdNot, X86Mem) + + //! Or. + INST_2x(or_, kX86InstIdOr, X86GpVar, X86GpVar) + //! \overload + INST_2x(or_, kX86InstIdOr, X86GpVar, X86Mem) + //! \overload + INST_2i(or_, kX86InstIdOr, X86GpVar, Imm) + //! \overload + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpVar) + //! \overload + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) + + //! Pop a value from the stack. + INST_1x_(pop, kX86InstIdPop, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + //! \overload + INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + + //! Pop stack into EFLAGS Register (32-bit or 64-bit). + INST_0x(popf, kX86InstIdPopf) + + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86Mem,o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push segment register on the stack. + INST_1x(push, kX86InstIdPush, X86SegReg) + //! Push WORD or DWORD/QWORD on the stack. + INST_1i(push, kX86InstIdPush, Imm) + + //! Push EFLAGS register (32-bit or 64-bit) on the stack. + INST_0x(pushf, kX86InstIdPushf) + + //! Rotate bits left. + INST_2x(rcl, kX86InstIdRcl, X86GpVar, X86GpVar) + //! \overload + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpVar) + //! Rotate bits left. + INST_2i(rcl, kX86InstIdRcl, X86GpVar, Imm) + //! \overload + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) + + //! Rotate bits right. + INST_2x(rcr, kX86InstIdRcr, X86GpVar, X86GpVar) + //! \overload + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpVar) + //! Rotate bits right. + INST_2i(rcr, kX86InstIdRcr, X86GpVar, Imm) + //! \overload + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) + + //! Read time-stamp counter (Pentium). + INST_2x_(rdtsc, kX86InstIdRdtsc, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! Read time-stamp counter and processor id (Pentium). + INST_3x_(rdtscp, kX86InstIdRdtscp, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL. + INST_3x_(rep_lodsb, kX86InstIdRepLodsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to AL. + INST_3x_(rep_lodsd, kX86InstIdRepLodsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX QWORDs from DS:[RSI] to RAX (X64 Only). + INST_3x_(rep_lodsq, kX86InstIdRepLodsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX. + INST_3x_(rep_lodsw, kX86InstIdRepLodsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsb, kX86InstIdRepMovsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsd, kX86InstIdRepMovsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only). + INST_3x_(rep_movsq, kX86InstIdRepMovsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsw, kX86InstIdRepMovsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL. + INST_3x_(rep_stosb, kX86InstIdRepStosB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX. + INST_3x_(rep_stosd, kX86InstIdRepStosD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only). + INST_3x_(rep_stosq, kX86InstIdRepStosQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX. + INST_3x_(rep_stosw, kX86InstIdRepStosW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsb, kX86InstIdRepeCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsd, kX86InstIdRepeCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_3x_(repe_cmpsq, kX86InstIdRepeCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsw, kX86InstIdRepeCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find non-AL BYTE starting at ES:[EDI/RDI]. + INST_3x_(repe_scasb, kX86InstIdRepeScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_3x_(repe_scasd, kX86InstIdRepeScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only). + INST_3x_(repe_scasq, kX86InstIdRepeScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-AX WORD starting at ES:[EDI/RDI]. + INST_3x_(repe_scasw, kX86InstIdRepeScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find AL BYTEs in [RDI] and [RSI]. + INST_3x_(repne_cmpsb, kX86InstIdRepneCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find EAX DWORDs in [RDI] and [RSI]. + INST_3x_(repne_cmpsd, kX86InstIdRepneCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find RAX QWORDs in [RDI] and [RSI] (X64 Only). + INST_3x_(repne_cmpsq, kX86InstIdRepneCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find AX WORDs in [RDI] and [RSI]. + INST_3x_(repne_cmpsw, kX86InstIdRepneCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated Find AL BYTEs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasb, kX86InstIdRepneScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find EAX DWORDs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasd, kX86InstIdRepneScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find RAX QWORDs, starting at ES:[RDI] (X64 Only). + INST_3x_(repne_scasq, kX86InstIdRepneScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find AX WORDs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasw, kX86InstIdRepneScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Return. + ASMJIT_INLINE RetNode* ret() { return addRet(noOperand, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0) { return addRet(o0, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0, const X86GpVar& o1) { return addRet(o0, o1); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0) { return addRet(o0, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0, const X86XmmVar& o1) { return addRet(o0, o1); } + + //! Rotate bits left. + INST_2x(rol, kX86InstIdRol, X86GpVar, X86GpVar) + //! \overload + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpVar) + //! Rotate bits left. + INST_2i(rol, kX86InstIdRol, X86GpVar, Imm) + //! \overload + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) + + //! Rotate bits right. + INST_2x(ror, kX86InstIdRor, X86GpVar, X86GpVar) + //! \overload + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpVar) + //! Rotate bits right. + INST_2i(ror, kX86InstIdRor, X86GpVar, Imm) + //! \overload + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) + + //! Store `a` (allocated in AH/AX/EAX/RAX) into Flags. + INST_1x(sahf, kX86InstIdSahf, X86GpVar) + + //! Integer subtraction with borrow. + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86GpVar) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86Mem) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86GpVar, Imm) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpVar) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) + + //! Shift bits left. + INST_2x(sal, kX86InstIdSal, X86GpVar, X86GpVar) + //! \overload + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpVar) + //! Shift bits left. + INST_2i(sal, kX86InstIdSal, X86GpVar, Imm) + //! \overload + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) + + //! Shift bits right. + INST_2x(sar, kX86InstIdSar, X86GpVar, X86GpVar) + //! \overload + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpVar) + //! Shift bits right. + INST_2i(sar, kX86InstIdSar, X86GpVar, Imm) + //! \overload + INST_2i(sar, kX86InstIdSar, X86Mem, Imm) + + //! Find non `o1` BYTE starting at ES:`o0`. + INST_2x(scasb, kX86InstIdScasB, X86GpVar, X86GpVar) + //! Find non `o1` DWORD starting at ES:`o0`. + INST_2x(scasd, kX86InstIdScasD, X86GpVar, X86GpVar) + //! Find non `o1` QWORD starting at ES:`o0` (X64 Only). + INST_2x(scasq, kX86InstIdScasQ, X86GpVar, X86GpVar) + //! Find non `o1` WORD starting at ES:`o0`. + INST_2x(scasw, kX86InstIdScasW, X86GpVar, X86GpVar) + + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpVar) + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) + + //! Shift bits left. + INST_2x(shl, kX86InstIdShl, X86GpVar, X86GpVar) + //! \overload + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpVar) + //! Shift bits left. + INST_2i(shl, kX86InstIdShl, X86GpVar, Imm) + //! \overload + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) + + //! Shift bits right. + INST_2x(shr, kX86InstIdShr, X86GpVar, X86GpVar) + //! \overload + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpVar) + //! Shift bits right. + INST_2i(shr, kX86InstIdShr, X86GpVar, Imm) + //! \overload + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) + + //! Double precision shift left. + INST_3x(shld, kX86InstIdShld, X86GpVar, X86GpVar, X86GpVar) + //! \overload + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpVar, X86GpVar) + //! Double precision shift left. + INST_3i(shld, kX86InstIdShld, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpVar, Imm) + + //! Double precision shift right. + INST_3x(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, X86GpVar) + //! \overload + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpVar, X86GpVar) + //! Double precision shift right. + INST_3i(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpVar, Imm) + + //! Set carry flag to 1. + INST_0x(stc, kX86InstIdStc) + //! Set direction flag to 1. + INST_0x(std, kX86InstIdStd) + + //! Fill BYTE at ES:`o0` with `o1`. + INST_2x(stosb, kX86InstIdStosB, X86GpVar, X86GpVar) + //! Fill DWORD at ES:`o0` with `o1`. + INST_2x(stosd, kX86InstIdStosD, X86GpVar, X86GpVar) + //! Fill QWORD at ES:`o0` with `o1` (X64 Only). + INST_2x(stosq, kX86InstIdStosQ, X86GpVar, X86GpVar) + //! Fill WORD at ES:`o0` with `o1`. + INST_2x(stosw, kX86InstIdStosW, X86GpVar, X86GpVar) + + //! Subtract. + INST_2x(sub, kX86InstIdSub, X86GpVar, X86GpVar) + //! \overload + INST_2x(sub, kX86InstIdSub, X86GpVar, X86Mem) + //! \overload + INST_2i(sub, kX86InstIdSub, X86GpVar, Imm) + //! \overload + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpVar) + //! \overload + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) + + //! Logical compare. + INST_2x(test, kX86InstIdTest, X86GpVar, X86GpVar) + //! \overload + INST_2i(test, kX86InstIdTest, X86GpVar, Imm) + //! \overload + INST_2x(test, kX86InstIdTest, X86Mem, X86GpVar) + //! \overload + INST_2i(test, kX86InstIdTest, X86Mem, Imm) + + //! Undefined instruction - Raise #UD exception. + INST_0x(ud2, kX86InstIdUd2) + + //! Exchange and add. + INST_2x(xadd, kX86InstIdXadd, X86GpVar, X86GpVar) + //! \overload + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpVar) + + //! Exchange register/memory with register. + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86GpVar) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpVar) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86Mem) + + //! Xor. + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86GpVar) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86Mem) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86GpVar, Imm) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpVar) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [FPU] + // -------------------------------------------------------------------------- + + //! Compute `2^x - 1` - `fp0 = POW(2, fp0) - 1` (FPU). + INST_0x(f2xm1, kX86InstIdF2xm1) + //! Abs `fp0 = ABS(fp0)` (FPU). + INST_0x(fabs, kX86InstIdFabs) + + //! Add `o0 = o0 + o1` (one operand has to be `fp0`) (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add `fp0 = fp0 + float_or_double[o0]` (FPU). + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add `o0 = o0 + fp0` and POP (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) + //! Add `fp1 = fp1 + fp0` and POP (FPU). + INST_0x(faddp, kX86InstIdFaddp) + + //! Load BCD from `[o0]` and PUSH (FPU). + INST_1x(fbld, kX86InstIdFbld, X86Mem) + //! Store BCD-Integer to `[o0]` and POP (FPU). + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) + + //! Complement Sign `fp0 = -fp0` (FPU). + INST_0x(fchs, kX86InstIdFchs) + + //! Clear exceptions (FPU). + INST_0x(fclex, kX86InstIdFclex) + + //! Conditional move `if (CF=1) fp0 = o0` (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move `if (CF|ZF=1) fp0 = o0` (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move `if (ZF=1) fp0 = o0` (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move `if (CF=0) fp0 = o0` (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move `if (CF|ZF=0) fp0 = o0` (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move `if (ZF=0) fp0 = o0` (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move `if (PF=0) fp0 = o0` (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move `if (PF=1) fp0 = o0` (FPU). + INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) + + //! Compare `fp0` with `o0` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86FpReg) + //! Compare `fp0` with `fp1` (FPU). + INST_0x(fcom, kX86InstIdFcom) + //! Compare `fp0` with `float_or_double[o0]` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare `fp0` with `o0` and POP (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare `fp0` with `fp1` and POP (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare `fp0` with `float_or_double[o0]` and POP (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare `fp0` with `fp1` and POP twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) + //! Compare `fp0` with `o0` and set EFLAGS (FPU). + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare `fp0` with `o0` and set EFLAGS and POP (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) + + //! Cos `fp0 = cos(fp0)` (FPU). + INST_0x(fcos, kX86InstIdFcos) + + //! Decrement FPU stack pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) + + //! Divide `o0 = o0 / o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide `fp0 = fp0 / float_or_double[o0]` (FPU). + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) + //! Divide `o0 = o0 / fp0` and POP (FPU). + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) + //! Divide `fp1 = fp1 / fp0` and POP (FPU). + INST_0x(fdivp, kX86InstIdFdivp) + + //! Reverse divide `o0 = o1 / o0` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide `fp0 = float_or_double[o0] / fp0` (FPU). + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) + //! Reverse divide `o0 = fp0 / o0` and POP (FPU). + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) + //! Reverse divide `fp1 = fp0 / fp1` and POP (FPU). + INST_0x(fdivrp, kX86InstIdFdivrp) + + //! Free FP register (FPU). + INST_1x(ffree, kX86InstIdFfree, X86FpReg) + + //! Add `fp0 = fp0 + short_or_int[o0]` (FPU). + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare `fp0` with `short_or_int[o0]` (FPU). + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare `fp0` with `short_or_int[o0]` and POP (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Divide `fp0 = fp0 / short_or_int[o0]` (FPU). + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse divide `fp0 = short_or_int[o0] / fp0` (FPU). + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Load `short_or_int_or_long[o0]` and PUSH (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Multiply `fp0 *= short_or_int[o0]` (FPU). + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Increment FPU stack pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) + //! Initialize FPU (FPU). + INST_0x(finit, kX86InstIdFinit) + + //! Subtract `fp0 = fp0 - short_or_int[o0]` (FPU). + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse subtract `fp0 = short_or_int[o0] - fp0` (FPU). + INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Initialize FPU without checking for pending unmasked exceptions (FPU). + INST_0x(fninit, kX86InstIdFninit) + + //! Store `fp0` as `short_or_int[o0]` (FPU). + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store `fp0` as `short_or_int_or_long[o0]` and POP (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + + //! Load `float_or_double_or_extended[o0]` and PUSH (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! PUSH `o0` (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) + + //! PUSH `1.0` (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! PUSH `log2(10)` (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! PUSH `log2(e)` (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! PUSH `pi` (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! PUSH `log10(2)` (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! PUSH `ln(2)` (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! PUSH `+0.0` (FPU). + INST_0x(fldz, kX86InstIdFldz) + + //! Load x87 FPU control word from `word_ptr[o0]` (FPU). + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) + //! Load x87 FPU environment (14 or 28 bytes) from `[o0]` (FPU). + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) + + //! Multiply `o0 = o0 * o1` (one has to be `fp0`) (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply `fp0 = fp0 * float_or_double[o0]` (FPU). + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply `o0 = o0 * fp0` and POP (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) + //! Multiply `fp1 = fp1 * fp0` and POP (FPU). + INST_0x(fmulp, kX86InstIdFmulp) + + //! Clear exceptions (FPU). + INST_0x(fnclex, kX86InstIdFnclex) + //! No operation (FPU). + INST_0x(fnop, kX86InstIdFnop) + //! Save FPU state to `[o0]` (FPU). + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) + //! Store x87 FPU environment to `[o0]` (FPU). + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) + //! Store x87 FPU control word to `[o0]` (FPU). + INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) + + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86GpVar) + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) + + //! Partial Arctan `fp1 = atan2(fp1, fp0)` and POP (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Partial Remainder[Trunc] `fp1 = fp0 % fp1` and POP (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Partial Remainder[Round] `fp1 = fp0 % fp1` and POP (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Partial Tan `fp0 = tan(fp0)` and PUSH `1.0` (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0 = round(fp0)` (FPU). + INST_0x(frndint, kX86InstIdFrndint) + + //! Restore FPU state from `[o0]` (94 or 108 bytes) (FPU). + INST_1x(frstor, kX86InstIdFrstor, X86Mem) + //! Save FPU state to `[o0]` (94 or 108 bytes) (FPU). + INST_1x(fsave, kX86InstIdFsave, X86Mem) + + //! Scale `fp0 = fp0 * pow(2, RoundTowardsZero(fp1))` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sin `fp0 = sin(fp0)` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sincos `fp0 = sin(fp0)` and PUSH `cos(fp0)` (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root `fp0 = sqrt(fp0)` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + + //! Store floating point value to `float_or_double[o0]` (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Copy `o0 = fp0` (FPU). + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to `float_or_double_or_extended[o0]` and POP (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Copy `o0 = fp0` and POP (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) + + //! Store x87 FPU control word to `word_ptr[o0]` (FPU). + INST_1x(fstcw, kX86InstIdFstcw, X86Mem) + //! Store x87 FPU environment to `[o0]` (14 or 28 bytes) (FPU). + INST_1x(fstenv, kX86InstIdFstenv, X86Mem) + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86GpVar) + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) + + //! Subtract `o0 = o0 - o1` (one has to be `fp0`) (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract `fp0 = fp0 - float_or_double[o0]` (FPU). + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract `o0 = o0 - fp0` and POP (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) + //! Subtract `fp1 = fp1 - fp0` and POP (FPU). + INST_0x(fsubp, kX86InstIdFsubp) + + //! Reverse subtract `o0 = o1 - o0` (one has to be `fp0`) (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract `fp0 = fp0 - float_or_double[o0]` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `o0 = o0 - fp0` and POP (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) + //! Reverse subtract `fp1 = fp1 - fp0` and POP (FPU). + INST_0x(fsubrp, kX86InstIdFsubrp) + + //! Compare `fp0` with `0.0` (FPU). + INST_0x(ftst, kX86InstIdFtst) + + //! Unordered compare `fp0` with `o0` (FPU). + INST_1x(fucom, kX86InstIdFucom, X86FpReg) + //! Unordered compare `fp0` with `fp1` (FPU). + INST_0x(fucom, kX86InstIdFucom) + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS and POP (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and POP (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and POP (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and POP twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) + + INST_0x(fwait, kX86InstIdFwait) + + //! Examine fp0 (FPU). + INST_0x(fxam, kX86InstIdFxam) + //! Exchange `fp0` with `o0` (FPU). + INST_1x(fxch, kX86InstIdFxch, X86FpReg) + + //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) + //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxsave, kX86InstIdFxsave, X86Mem) + //! Extract `fp0 = exponent(fp0)` and PUSH `significant(fp0)` (FPU). + INST_0x(fxtract, kX86InstIdFxtract) + + //! Compute `fp1 = fp1 * log2(fp0)` and POP (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 = fp1 * log2(fp0 + 1)` and POP (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) + + // -------------------------------------------------------------------------- + // [MMX] + // -------------------------------------------------------------------------- + + //! Move DWORD (MMX). + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86MmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86GpVar) + + //! Move QWORD (MMX). + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpVar, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86GpVar) + + //! Pack DWORDs to WORDs with signed saturation (MMX). + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86MmVar) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (MMX). + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86MmVar) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (MMX). + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86MmVar) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86Mem) + + //! Packed BYTE add (MMX). + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86Mem) + + //! Packed DWORD add (MMX). + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86Mem) + + //! Packed BYTE add with saturation (MMX). + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86Mem) + + //! Packed WORD add with saturation (MMX). + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86Mem) + + //! Packed BYTE add with unsigned saturation (MMX). + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86Mem) + + //! Packed WORD add with unsigned saturation (MMX). + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86Mem) + + //! Packed WORD add (MMX). + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86Mem) + + //! Packed and (MMX). + INST_2x(pand, kX86InstIdPand, X86MmVar, X86MmVar) + //! \overload + INST_2x(pand, kX86InstIdPand, X86MmVar, X86Mem) + + //! Packed and-not (MMX). + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86MmVar) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86Mem) + + //! Packed BYTEs compare for equality (MMX). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86Mem) + + //! Packed DWORDs compare for equality (MMX). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86Mem) + + //! Packed WORDs compare for equality (MMX). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86Mem) + + //! Packed BYTEs compare if greater than (MMX). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86Mem) + + //! Packed DWORDs compare if greater than (MMX). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86Mem) + + //! Packed WORDs compare if greater than (MMX). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86Mem) + + //! Packed WORD multiply high (MMX). + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86Mem) + + //! Packed WORD multiply low (MMX). + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86Mem) + + //! Packed bitwise or (MMX). + INST_2x(por, kX86InstIdPor, X86MmVar, X86MmVar) + //! \overload + INST_2x(por, kX86InstIdPor, X86MmVar, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (MMX). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86Mem) + + //! Packed DWORD shift left logical (MMX). + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86MmVar) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86MmVar, Imm) + + //! Packed QWORD shift left logical (MMX). + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86MmVar, Imm) + + //! Packed WORD shift left logical (MMX). + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86MmVar, Imm) + + //! Packed DWORD shift right arithmetic (MMX). + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86MmVar, Imm) + + //! Packed WORD shift right arithmetic (MMX). + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86MmVar, Imm) + + //! Packed DWORD shift right logical (MMX). + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86MmVar, Imm) + + //! Packed QWORD shift right logical (MMX). + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86MmVar, Imm) + + //! Packed WORD shift right logical (MMX). + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86MmVar, Imm) + + //! Packed BYTE subtract (MMX). + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86Mem) + + //! Packed DWORD subtract (MMX). + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86Mem) + + //! Packed BYTE subtract with saturation (MMX). + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86Mem) + + //! Packed WORD subtract with saturation (MMX). + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (MMX). + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86Mem) + + //! Packed WORD subtract with unsigned saturation (MMX). + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86Mem) + + //! Packed WORD subtract (MMX). + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86Mem) + + //! Unpack high packed BYTEs to WORDs (MMX). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (MMX). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86Mem) + + //! Unpack high packed WORDs to DWORDs (MMX). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86Mem) + + //! Unpack low packed BYTEs to WORDs (MMX). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (MMX). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86Mem) + + //! Unpack low packed WORDs to DWORDs (MMX). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86Mem) + + //! Packed bitwise xor (MMX). + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86MmVar) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86Mem) + + //! Empty MMX state. + INST_0x(emms, kX86InstIdEmms) + + // -------------------------------------------------------------------------- + // [3DNOW] + // -------------------------------------------------------------------------- + + //! Packed SP-FP to DWORD convert (3dNow!). + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86MmVar) + //! \overload + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86Mem) + + //! Packed SP-FP to WORD convert (3dNow!). + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86Mem) + + //! Packed SP-FP accumulate (3dNow!). + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86Mem) + + //! Packed SP-FP addition (3dNow!). + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst == src (3dNow!). + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst >= src (3dNow!). + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst > src (3dNow!). + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86Mem) + + //! Packed SP-FP maximum (3dNow!). + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86Mem) + + //! Packed SP-FP minimum (3dNow!). + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86Mem) + + //! Packed SP-FP multiply (3dNow!). + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86Mem) + + //! Packed SP-FP negative accumulate (3dNow!). + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86Mem) + + //! Packed SP-FP mixed accumulate (3dNow!). + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal approximation (3dNow!). + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal, first iteration step (3dNow!). + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal, second iteration step (3dNow!). + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal square root approximation (3dNow!). + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86Mem) + + //! Packed SP-FP subtract (3dNow!). + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86Mem) + + //! Packed SP-FP reverse subtract (3dNow!). + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86Mem) + + //! Packed DWORDs to SP-FP (3dNow!). + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86Mem) + + //! Packed WORDs to SP-FP (3dNow!). + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86Mem) + + //! Packed swap DWORDs (3dNow!) + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86Mem) + + //! Prefetch (3dNow!). + INST_1x(prefetch_3dnow, kX86InstIdPrefetch3dNow, X86Mem) + + //! Prefetch and set cache to modified (3dNow!). + INST_1x(prefetchw_3dnow, kX86InstIdPrefetchw3dNow, X86Mem) + + //! Faster EMMS (3dNow!). + INST_0x(femms, kX86InstIdFemms) + + // -------------------------------------------------------------------------- + // [SSE] + // -------------------------------------------------------------------------- + + //! Packed SP-FP add (SSE). + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86Mem) + + //! Scalar SP-FP add (SSE). + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise and-not (SSE). + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise and (SSE). + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86Mem) + + //! Packed SP-FP compare (SSE). + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86Mem, Imm) + + //! Compare scalar SP-FP Values (SSE). + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86Mem, Imm) + + //! Scalar ordered SP-FP compare and set EFLAGS (SSE). + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86Mem) + + //! Packed signed INT32 to packed SP-FP conversion (SSE). + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86MmVar) + //! \overload + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86Mem) + + //! Packed SP-FP to packed INT32 conversion (SSE). + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86Mem) + + //! Convert scalar INT32 to SP-FP (SSE). + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86GpVar) + //! \overload + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86Mem) + + //! Convert scalar SP-FP to INT32 (SSE). + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86Mem) + + //! Convert with truncation packed SP-FP to packed INT32 (SSE). + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (SSE). + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86Mem) + + //! Packed SP-FP divide (SSE). + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86Mem) + + //! Scalar SP-FP divide (SSE). + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86Mem) + + //! Load streaming SIMD extension control/status (SSE). + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) + + //! Byte mask write (SSE). + INST_3x(maskmovq, kX86InstIdMaskmovq, X86GpVar /* zdi */, X86MmVar, X86MmVar) + + //! Packed SP-FP maximum (SSE). + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86Mem) + + //! Scalar SP-FP maximum (SSE). + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86Mem) + + //! Packed SP-FP minimum (SSE). + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86Mem) + + //! Scalar SP-FP minimum (SSE). + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86Mem) + + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86Mem) + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmVar) + + //! Move DWORD. + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86XmmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86GpVar) + + //! Move QWORD (SSE). + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpVar, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86GpVar) + + //! Move QWORD using NT hint (SSE). + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmVar) + + //! Move high to low packed SP-FP (SSE). + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmVar, X86XmmVar) + + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86XmmVar, X86Mem) + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmVar) + + //! Move low to high packed SP-FP (SSE). + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmVar, X86XmmVar) + + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86XmmVar, X86Mem) + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmVar) + + //! Move aligned packed SP-FP using NT hint (SSE). + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmVar) + + //! Move scalar SP-FP (SSE). + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86Mem) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmVar) + + //! Move unaligned packed SP-FP (SSE). + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86Mem) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmVar) + + //! Packed SP-FP multiply (SSE). + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86Mem) + + //! Scalar SP-FP multiply (SSE). + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise or (SSE). + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86Mem) + + //! Packed BYTE average (SSE). + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86Mem) + + //! Packed WORD average (SSE). + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86Mem) + + //! Extract WORD based on selector (SSE). + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86MmVar, Imm) + + //! Insert WORD based on selector (SSE). + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86Mem, Imm) + + //! Packed WORD maximum (SSE). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86Mem) + + //! Packed BYTE unsigned maximum (SSE). + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86Mem) + + //! Packed WORD minimum (SSE). + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86Mem) + + //! Packed BYTE unsigned minimum (SSE). + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86Mem) + + //! Move byte mask to integer (SSE). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86MmVar) + + //! Packed WORD unsigned multiply high (SSE). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86Mem) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86Mem) + + //! Packed WORD shuffle (SSE). + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86MmVar, Imm) + //! \overload + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86Mem, Imm) + + //! Packed SP-FP reciprocal (SSE). + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86Mem) + + //! Scalar SP-FP reciprocal (SSE). + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86Mem) + + //! Prefetch (SSE). + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86Mem) + + //! Packed SP-FP Square root reciprocal (SSE). + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86Mem) + + //! Scalar SP-FP Square root reciprocal (SSE). + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86Mem) + + //! Store fence (SSE). + INST_0x(sfence, kX86InstIdSfence) + + //! Shuffle SP-FP (SSE). + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP square root (SSE). + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86Mem) + + //! Scalar SP-FP square root (SSE). + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86Mem) + + //! Store streaming SIMD extension control/status (SSE). + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) + + //! Packed SP-FP subtract (SSE). + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86Mem) + + //! Scalar SP-FP subtract (SSE). + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (SSE). + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86Mem) + + //! Unpack high packed SP-FP data (SSE). + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86Mem) + + //! Unpack low packed SP-FP data (SSE). + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise xor (SSE). + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE2] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (SSE2). + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP add (SSE2). + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise and-not (SSE2). + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise and (SSE2). + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86Mem) + + //! Flush cache line (SSE2). + INST_1x(clflush, kX86InstIdClflush, X86Mem) + + //! Packed DP-FP compare (SSE2). + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86Mem, Imm) + + //! Scalar SP-FP compare (SSE2). + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86Mem, Imm) + + //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86Mem) + + //! Convert packed DWORD integers to packed DP-FP (SSE2). + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86Mem) + + //! Convert packed DWORD integers to packed SP-FP (SSE2). + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (SSE2). + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86Mem) + + //! Convert packed DWORDs to packed DP-FP (SSE2). + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86MmVar) + //! \overload + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86Mem) + + //! Convert packed SP-FP to packed DWORDs (SSE2). + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (SSE2). + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86Mem) + + //! Convert scalar DP-FP to DWORD (SSE2). + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (SSE2). + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86Mem) + + //! Convert DWORD to scalar DP-FP (SSE2). + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86GpVar) + //! \overload + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86Mem) + + //! Convert scalar SP-FP to DP-FP (SSE2). + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86Mem) + + //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86Mem) + + //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86Mem) + + //! Convert with truncation scalar DP-FP to DWORD (SSE2). + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86Mem) + + //! Packed DP-FP divide (SSE2). + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP divide (SSE2). + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86Mem) + + //! Load fence (SSE2). + INST_0x(lfence, kX86InstIdLfence) + + //! Store selected bytes of OWORD (SSE2). + INST_3x(maskmovdqu, kX86InstIdMaskmovdqu, X86GpVar /* zdi */, X86XmmVar, X86XmmVar) + + //! Packed DP-FP maximum (SSE2). + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP maximum (SSE2). + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86Mem) + + //! Memory fence (SSE2). + INST_0x(mfence, kX86InstIdMfence) + + //! Packed DP-FP minimum (SSE2). + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP minimum (SSE2). + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86Mem) + + //! Move aligned OWORD (SSE2). + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86Mem) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmVar) + + //! Move unaligned OWORD (SSE2). + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86Mem) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmVar) + + //! Extract packed SP-FP sign mask (SSE2). + INST_2x(movmskps, kX86InstIdMovmskps, X86GpVar, X86XmmVar) + + //! Extract packed DP-FP sign mask (SSE2). + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpVar, X86XmmVar) + + //! Move scalar DP-FP (SSE2). + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmVar) + + //! Move aligned packed DP-FP (SSE2). + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmVar) + + //! Move QWORD from Xmm to Mm register (SSE2). + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmVar, X86XmmVar) + + //! Move QWORD from Mm to Xmm register (SSE2). + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmVar, X86MmVar) + + //! Move high packed DP-FP (SSE2). + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmVar) + + //! Move low packed DP-FP (SSE2). + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmVar) + + //! Store OWORD using NT hint (SSE2). + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmVar) + + //! Store DWORD using NT hint (SSE2). + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpVar) + + //! Store packed DP-FP using NT hint (SSE2). + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmVar) + + //! Move unaligned packed DP-FP (SSE2). + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmVar) + + //! Packed DP-FP multiply (SSE2). + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP multiply (SSE2). + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise or (SSE2). + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (SSE2). + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (SSE2). + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (SSE2). + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86Mem) + + //! Packed BYTE add (SSE2). + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86Mem) + + //! Packed WORD add (SSE2). + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86Mem) + + //! Packed DWORD add (SSE2). + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86Mem) + + //! Packed BYTE add with saturation (SSE2). + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86Mem) + + //! Packed WORD add with saturation (SSE2). + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86Mem) + + //! Packed BYTE add with unsigned saturation (SSE2). + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86Mem) + + //! Packed WORD add with unsigned saturation (SSE2). + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86Mem) + + //! Packed bitwise and (SSE2). + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86Mem) + + //! Packed bitwise and-not (SSE2). + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86Mem) + + //! Spin loop hint (SSE2). + INST_0x(pause, kX86InstIdPause) + + //! Packed BYTE average (SSE2). + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86Mem) + + //! Packed WORD average (SSE2). + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86Mem) + + //! Packed BYTE compare for equality (SSE2). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86Mem) + + //! Packed WROD compare for equality (SSE2). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86Mem) + + //! Packed DWORD compare for equality (SSE2). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86Mem) + + //! Packed BYTE compare if greater than (SSE2). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86Mem) + + //! Packed WORD compare if greater than (SSE2). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86Mem) + + //! Packed DWORD compare if greater than (SSE2). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86Mem) + + //! Extract WORD based on selector (SSE2). + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86XmmVar, Imm) + + //! Insert WORD based on selector (SSE2). + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86Mem, Imm) + + //! Packed WORD maximum (SSE2). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86Mem) + + //! Packed BYTE unsigned maximum (SSE2). + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86Mem) + + //! Packed WORD minimum (SSE2). + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86Mem) + + //! Packed BYTE unsigned minimum (SSE2). + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86Mem) + + //! Move BYTE mask (SSE2). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86XmmVar) + + //! Packed WORD multiply high (SSE2). + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86Mem) + + //! Packed WORD unsigned multiply high (SSE2). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86Mem) + + //! Packed WORD multiply low (SSE2). + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86Mem) + + //! Packed bitwise or (SSE2). + INST_2x(por, kX86InstIdPor, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(por, kX86InstIdPor, X86XmmVar, X86Mem) + + //! Packed DWORD shift left logical (SSE2). + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86XmmVar, Imm) + + //! Packed QWORD shift left logical (SSE2). + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86XmmVar, Imm) + + //! Packed WORD shift left logical (SSE2). + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86XmmVar, Imm) + + //! Packed OWORD shift left logical (SSE2). + INST_2i(pslldq, kX86InstIdPslldq, X86XmmVar, Imm) + + //! Packed DWORD shift right arithmetic (SSE2). + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86XmmVar, Imm) + + //! Packed WORD shift right arithmetic (SSE2). + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86XmmVar, Imm) + + //! Packed BYTE subtract (SSE2). + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86Mem) + + //! Packed DWORD subtract (SSE2). + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86Mem) + + //! Packed WORD subtract (SSE2). + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD multiply and add (SSE2). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86Mem) + + //! Packed DWORD shuffle (SSE2). + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86Mem, Imm) + + //! Packed WORD shuffle high (SSE2). + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86Mem, Imm) + + //! Packed WORD shuffle low (SSE2). + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86Mem, Imm) + + //! Packed DWORD shift right logical (SSE2). + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86XmmVar, Imm) + + //! Packed QWORD shift right logical (SSE2). + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmVar, Imm) + + //! Scalar OWORD shift right logical (SSE2). + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmVar, Imm) + + //! Packed WORD shift right logical (SSE2). + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmVar, Imm) + + //! Packed BYTE subtract with saturation (SSE2). + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86Mem) + + //! Packed WORD subtract with saturation (SSE2). + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (SSE2). + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86Mem) + + //! Packed WORD subtract with unsigned saturation (SSE2). + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86Mem) + + //! Unpack high packed BYTEs to WORDs (SSE2). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (SSE2). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86Mem) + + //! Unpack high packed QWORDs to OWORD (SSE2). + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86Mem) + + //! Unpack high packed WORDs to DWORDs (SSE2). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86Mem) + + //! Unpack low packed BYTEs to WORDs (SSE2). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (SSE2). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86Mem) + + //! Unpack low packed QWORDs to OWORD (SSE2). + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86Mem) + + //! Unpack low packed WORDs to DWORDs (SSE2). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86Mem) + + //! Packed bitwise xor (SSE2). + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86Mem) + + //! Shuffle DP-FP (SSE2). + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86Mem, Imm) + + //! Packed DP-FP square root (SSE2). + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP square root (SSE2). + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86Mem) + + //! Packed DP-FP subtract (SSE2). + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP subtract (SSE2). + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86Mem) + + //! Unpack and interleave high packed DP-FP (SSE2). + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86Mem) + + //! Unpack and interleave low packed DP-FP (SSE2). + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise xor (SSE2). + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE3] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add/subtract (SSE3). + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86Mem) + + //! Packed SP-FP add/subtract (SSE3). + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86Mem) + + //! Store truncated `fp0` to `short_or_int_or_long[o0]` and POP (FPU & SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) + + //! Packed DP-FP horizontal add (SSE3). + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86Mem) + + //! Packed SP-FP horizontal add (SSE3). + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86Mem) + + //! Packed DP-FP horizontal subtract (SSE3). + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86Mem) + + //! Packed SP-FP horizontal subtract (SSE3). + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86Mem) + + //! Load 128-bits unaligned (SSE3). + INST_2x(lddqu, kX86InstIdLddqu, X86XmmVar, X86Mem) + + // //! Setup monitor address (SSE3). + // INST_0x(monitor, kX86InstIdMonitor) + + //! Move one DP-FP and duplicate (SSE3). + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86Mem) + + //! Move packed SP-FP high and duplicate (SSE3). + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86Mem) + + //! Move packed SP-FP low and duplicate (SSE3). + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86Mem) + + // //! Monitor wait (SSE3). + // INST_0x(mwait, kX86InstIdMwait) + + // -------------------------------------------------------------------------- + // [SSSE3] + // -------------------------------------------------------------------------- + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86Mem) + + //! PackedBYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86Mem) + + //! Packed WORD horizontal add with with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86Mem) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86MmVar, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86Mem, Imm) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.1] + // -------------------------------------------------------------------------- + + //! Packed DP-FP blend (SSE4.1). + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP blend (SSE4.1). + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86Mem, Imm) + + //! Packed DP-FP variable blend (SSE4.1). + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed SP-FP variable blend (SSE4.1). + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed DP-FP dot product (SSE4.1). + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP dot product (SSE4.1). + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86Mem, Imm) + + //! Extract SP-FP based on selector (SSE4.1). + INST_3i(extractps, kX86InstIdExtractps, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmVar, Imm) + + //! Insert SP-FP based on selector (SSE4.1). + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86Mem, Imm) + + //! Load OWORD aligned using NT hint (SSE4.1). + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmVar, X86Mem) + + //! Packed WORD sums of absolute difference (SSE4.1). + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86Mem, Imm) + + //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86Mem) + + //! Packed BYTE variable blend (SSE4.1). + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed WORD blend (SSE4.1). + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86Mem, Imm) + + //! Packed QWORD compare for equality (SSE4.1). + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86Mem) + + //! Extract BYTE based on selector (SSE4.1). + INST_3i(pextrb, kX86InstIdPextrb, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmVar, Imm) + + //! Extract DWORD based on selector (SSE4.1). + INST_3i(pextrd, kX86InstIdPextrd, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmVar, Imm) + + //! Extract QWORD based on selector (SSE4.1). + INST_3i(pextrq, kX86InstIdPextrq, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmVar, Imm) + + //! Extract WORD based on selector (SSE4.1). + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmVar, Imm) + + //! Packed WORD horizontal minimum (SSE4.1). + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86Mem) + + //! Insert BYTE based on selector (SSE4.1). + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86Mem, Imm) + + //! Insert DWORD based on selector (SSE4.1). + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86Mem, Imm) + + //! Insert QWORD based on selector (SSE4.1). + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86Mem, Imm) + + //! Packed BYTE maximum (SSE4.1). + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86Mem) + + //! Packed DWORD maximum (SSE4.1). + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86Mem) + + //! Packed DWORD unsigned maximum (SSE4.1). + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmVar, X86Mem) + + //! Packed WORD unsigned maximum (SSE4.1). + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86Mem) + + //! Packed BYTE minimum (SSE4.1). + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86Mem) + + //! Packed DWORD minimum (SSE4.1). + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86Mem) + + //! Packed WORD unsigned minimum (SSE4.1). + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86Mem) + + //! Packed DWORD unsigned minimum (SSE4.1). + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86Mem) + + //! Packed BYTE to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86Mem) + + //! Packed BYTE to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86Mem) + + //! Packed BYTE to WORD with sign extend (SSE4.1). + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86Mem) + + //! Packed WORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86Mem) + + //! BYTE to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86Mem) + + //! Packed BYTE to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86Mem) + + //! BYTE to WORD with zero extend (SSE4.1). + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86Mem) + + //! Packed WORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD multiply (SSE4.1). + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86Mem) + + //! Packed DWORD multiply low (SSE4.1). + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86Mem) + + //! Logical compare (SSE4.1). + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86Mem) + + //! Packed DP-FP round (SSE4.1). + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP round (SSE4.1). + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86Mem, Imm) + + //! Scalar DP-FP round (SSE4.1). + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86Mem, Imm) + + //! Scalar SP-FP round (SSE4.1). + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.2] + // -------------------------------------------------------------------------- + + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! Packed compare explicit length strings, return index (SSE4.2). + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (SSE4.2). + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (SSE4.2). + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (SSE4.2). + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86Mem, Imm) + + //! Packed QWORD compare if greater than (SSE4.2). + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE4a] + // -------------------------------------------------------------------------- + + //! Extract Field (SSE4a). + INST_2x(extrq, kX86InstIdExtrq, X86XmmVar, X86XmmVar) + //! Extract Field (SSE4a). + INST_3ii(extrq, kX86InstIdExtrq, X86XmmVar, Imm, Imm) + + //! Insert Field (SSE4a). + INST_2x(insertq, kX86InstIdInsertq, X86XmmVar, X86XmmVar) + //! Insert Field (SSE4a). + INST_4ii(insertq, kX86InstIdInsertq, X86XmmVar, X86XmmVar, Imm, Imm) + + //! Move Non-Temporal Scalar DP-FP (SSE4a). + INST_2x(movntsd, kX86InstIdMovntsd, X86Mem, X86XmmVar) + //! Move Non-Temporal Scalar SP-FP (SSE4a). + INST_2x(movntss, kX86InstIdMovntss, X86Mem, X86XmmVar) + + // -------------------------------------------------------------------------- + // [POPCNT] + // -------------------------------------------------------------------------- + + //! Return the count of number of bits set to 1 (POPCNT). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb()) + + // -------------------------------------------------------------------------- + // [LZCNT] + // -------------------------------------------------------------------------- + + //! Count the number of leading zero bits (LZCNT). + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpVar, X86GpVar) + //! \overload + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpVar, X86Mem) + + // -------------------------------------------------------------------------- + // [AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow. + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86Mem) + + //! Perform the last round of the AES decryption flow. + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86Mem) + + //! Perform a single round of the AES encryption flow. + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86Mem) + + //! Perform the last round of the AES encryption flow. + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86Mem) + + //! Perform the InvMixColumns transformation. + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86Mem) + + //! Assist in expanding the AES cipher key. + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86XmmVar, Imm); + //! \overload + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86Mem, Imm); + + // -------------------------------------------------------------------------- + // [XSAVE] + // -------------------------------------------------------------------------- + + //! Restore Processor Extended States specified by `o1:o2` (XSAVE). + INST_3x(xrstor, kX86InstIdXrstor, X86Mem, X86GpVar, X86GpVar) + //! Restore Processor Extended States specified by `o1:o2` (XSAVE&X64). + INST_3x(xrstor64, kX86InstIdXrstor64, X86Mem, X86GpVar, X86GpVar) + + //! Save Processor Extended States specified by `o1:o2` (XSAVE). + INST_3x(xsave, kX86InstIdXsave, X86Mem, X86GpVar, X86GpVar) + //! Save Processor Extended States specified by `o1:o2` (XSAVE&X64). + INST_3x(xsave64, kX86InstIdXsave64, X86Mem, X86GpVar, X86GpVar) + + //! Save Processor Extended States specified by `o1:o2` (Optimized) (XSAVEOPT). + INST_3x(xsaveopt, kX86InstIdXsave, X86Mem, X86GpVar, X86GpVar) + //! Save Processor Extended States specified by `o1:o2` (Optimized) (XSAVEOPT&X64). + INST_3x(xsaveopt64, kX86InstIdXsave64, X86Mem, X86GpVar, X86GpVar) + + //! Get XCR - `o1:o2 <- XCR[o0]` (`EDX:EAX <- XCR[ECX]`) (XSAVE). + INST_3x(xgetbv, kX86InstIdXgetbv, X86GpVar, X86GpVar, X86GpVar) + //! Set XCR - `XCR[o0] <- o1:o2` (`XCR[ECX] <- EDX:EAX`) (XSAVE). + INST_3x(xsetbv, kX86InstIdXsetbv, X86GpVar, X86GpVar, X86GpVar) + + // -------------------------------------------------------------------------- + // [Cleanup] + // -------------------------------------------------------------------------- + +#undef INST_0x + +#undef INST_1x +#undef INST_1x_ +#undef INST_1i +#undef INST_1cc + +#undef INST_2x +#undef INST_2x_ +#undef INST_2i +#undef INST_2cc + +#undef INST_3x +#undef INST_3x_ +#undef INST_3i +#undef INST_3ii + +#undef INST_4x +#undef INST_4x_ +#undef INST_4i +#undef INST_4ii +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86COMPILER_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86context_p.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86context_p.h new file mode 100644 index 0000000..8c138f6 --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86context_p.h @@ -0,0 +1,523 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86CONTEXT_P_H +#define _ASMJIT_X86_X86CONTEXT_P_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/compiler.h" +#include "../base/context_p.h" +#include "../base/intutil.h" +#include "../x86/x86assembler.h" +#include "../x86/x86compiler.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_x86_compiler +//! \{ + +// ============================================================================ +// [asmjit::X86Context] +// ============================================================================ + +#if defined(ASMJIT_DEBUG) +# define ASMJIT_X86_CHECK_STATE _checkState(); +#else +# define ASMJIT_X86_CHECK_STATE +#endif // ASMJIT_DEBUG + +//! \internal +//! +//! Compiler context is used by `X86Compiler`. +//! +//! Compiler context is used during compilation and normally developer doesn't +//! need access to it. The context is user per function (it's reset after each +//! function is generated). +struct X86Context : public Context { + ASMJIT_NO_COPY(X86Context) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86Context` instance. + X86Context(X86Compiler* compiler); + //! Destroy the `X86Context` instance. + virtual ~X86Context(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + virtual void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isX64() const { + return _zsp.getSize() == 16; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get compiler as `X86Compiler`. + ASMJIT_INLINE X86Compiler* getCompiler() const { + return static_cast(_compiler); + } + + //! Get function as `X86FuncNode`. + ASMJIT_INLINE X86FuncNode* getFunc() const { + return reinterpret_cast(_func); + } + + //! Get clobbered registers (global). + ASMJIT_INLINE uint32_t getClobberedRegs(uint32_t c) { + return _clobberedRegs.get(c); + } + + // -------------------------------------------------------------------------- + // [Helpers] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86VarMap* newVarMap(uint32_t vaCount) { + return static_cast( + _baseZone.alloc(sizeof(X86VarMap) + vaCount * sizeof(VarAttr))); + } + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + + void emitLoad(VarData* vd, uint32_t regIndex, const char* reason); + void emitSave(VarData* vd, uint32_t regIndex, const char* reason); + void emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason); + void emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason); + + void emitPushSequence(uint32_t regs); + void emitPopSequence(uint32_t regs); + + void emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex); + void emitMoveVarOnStack(uint32_t dstType, const X86Mem* dst, uint32_t srcType, uint32_t srcIndex); + void emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src); + + void emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src); + + // -------------------------------------------------------------------------- + // [Register Management] + // -------------------------------------------------------------------------- + + void _checkState(); + + ASMJIT_INLINE uint32_t getRegSize() const { + return _zsp.getSize(); + } + + // -------------------------------------------------------------------------- + // [Attach / Detach] + // -------------------------------------------------------------------------- + + //! Attach. + //! + //! Attach a register to the 'VarData', changing 'VarData' members to show + //! that the variable is currently alive and linking variable with the + //! current 'X86VarState'. + template + ASMJIT_INLINE void attach(VarData* vd, uint32_t regIndex, bool modified) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(regIndex != kInvalidReg); + + // Prevent Esp allocation if C==Gp. + ASMJIT_ASSERT(C != kX86RegClassGp || regIndex != kX86RegIndexSp); + + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setState(kVarStateReg); + vd->setRegIndex(regIndex); + vd->addHomeIndex(regIndex); + vd->setModified(modified); + + _x86State.getListByClass(C)[regIndex] = vd; + _x86State._occupied.or_(C, regMask); + _x86State._modified.or_(C, static_cast(modified) << regIndex); + + ASMJIT_X86_CHECK_STATE + } + + //! Detach. + //! + //! The opposite of 'Attach'. Detach resets the members in 'VarData' + //! (regIndex, state and changed flags) and unlinks the variable with the + //! current 'X86VarState'. + template + ASMJIT_INLINE void detach(VarData* vd, uint32_t regIndex, uint32_t vState) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getRegIndex() == regIndex); + ASMJIT_ASSERT(vState != kVarStateReg); + + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setState(vState); + vd->resetRegIndex(); + vd->setModified(false); + + _x86State.getListByClass(C)[regIndex] = NULL; + _x86State._occupied.andNot(C, regMask); + _x86State._modified.andNot(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Rebase] + // -------------------------------------------------------------------------- + + //! Rebase. + //! + //! Change the register of the 'VarData' changing also the current 'X86VarState'. + //! Rebase is nearly identical to 'Detach' and 'Attach' sequence, but doesn't + // change the 'VarData' modified flag. + template + ASMJIT_INLINE void rebase(VarData* vd, uint32_t newRegIndex, uint32_t oldRegIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + + uint32_t newRegMask = IntUtil::mask(newRegIndex); + uint32_t oldRegMask = IntUtil::mask(oldRegIndex); + uint32_t bothRegMask = newRegMask ^ oldRegMask; + + vd->setRegIndex(newRegIndex); + + _x86State.getListByClass(C)[oldRegIndex] = NULL; + _x86State.getListByClass(C)[newRegIndex] = vd; + + _x86State._occupied.xor_(C, bothRegMask); + _x86State._modified.xor_(C, bothRegMask & -static_cast(vd->isModified())); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Load / Save] + // -------------------------------------------------------------------------- + + //! Load. + //! + //! Load variable from its memory slot to a register, emitting 'Load' + //! instruction and changing the variable state to allocated. + template + ASMJIT_INLINE void load(VarData* vd, uint32_t regIndex) { + // Can be only called if variable is not allocated. + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() != kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() == kInvalidReg); + + emitLoad(vd, regIndex, "Load"); + attach(vd, regIndex, false); + + ASMJIT_X86_CHECK_STATE + } + + //! Save. + //! + //! Save the variable into its home location, but keep it as allocated. + template + ASMJIT_INLINE void save(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() == kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = IntUtil::mask(regIndex); + + emitSave(vd, regIndex, "Save"); + + vd->setModified(false); + _x86State._modified.andNot(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Move / Swap] + // -------------------------------------------------------------------------- + + //! Move a register. + //! + //! Move register from one index to another, emitting 'Move' if needed. This + //! function does nothing if register is already at the given index. + template + ASMJIT_INLINE void move(VarData* vd, uint32_t regIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() == kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + + uint32_t oldIndex = vd->getRegIndex(); + if (regIndex != oldIndex) { + emitMove(vd, regIndex, oldIndex, "Move"); + rebase(vd, regIndex, oldIndex); + } + + ASMJIT_X86_CHECK_STATE + } + + //! Swap two registers + //! + //! It's only possible to swap Gp registers. + ASMJIT_INLINE void swapGp(VarData* aVd, VarData* bVd) { + ASMJIT_ASSERT(aVd != bVd); + + ASMJIT_ASSERT(aVd->getClass() == kX86RegClassGp); + ASMJIT_ASSERT(aVd->getState() == kVarStateReg); + ASMJIT_ASSERT(aVd->getRegIndex() != kInvalidReg); + + ASMJIT_ASSERT(bVd->getClass() == kX86RegClassGp); + ASMJIT_ASSERT(bVd->getState() == kVarStateReg); + ASMJIT_ASSERT(bVd->getRegIndex() != kInvalidReg); + + uint32_t aIndex = aVd->getRegIndex(); + uint32_t bIndex = bVd->getRegIndex(); + + emitSwapGp(aVd, bVd, aIndex, bIndex, "Swap"); + + aVd->setRegIndex(bIndex); + bVd->setRegIndex(aIndex); + + _x86State.getListByClass(kX86RegClassGp)[aIndex] = bVd; + _x86State.getListByClass(kX86RegClassGp)[bIndex] = aVd; + + uint32_t m = aVd->isModified() ^ bVd->isModified(); + _x86State._modified.xor_(kX86RegClassGp, (m << aIndex) | (m << bIndex)); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Alloc / Spill] + // -------------------------------------------------------------------------- + + //! Alloc. + template + ASMJIT_INLINE void alloc(VarData* vd, uint32_t regIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(regIndex != kInvalidReg); + + uint32_t oldRegIndex = vd->getRegIndex(); + uint32_t oldState = vd->getState(); + uint32_t regMask = IntUtil::mask(regIndex); + + ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == NULL || regIndex == oldRegIndex); + + if (oldState != kVarStateReg) { + if (oldState == kVarStateMem) + emitLoad(vd, regIndex, "Alloc"); + vd->setModified(false); + } + else if (oldRegIndex != regIndex) { + emitMove(vd, regIndex, oldRegIndex, "Alloc"); + + _x86State.getListByClass(C)[oldRegIndex] = NULL; + regMask ^= IntUtil::mask(oldRegIndex); + } + else { + ASMJIT_X86_CHECK_STATE + return; + } + + vd->setState(kVarStateReg); + vd->setRegIndex(regIndex); + + _x86State.getListByClass(C)[regIndex] = vd; + _x86State._occupied.xor_(C, regMask); + _x86State._modified.xor_(C, regMask & -static_cast(vd->isModified())); + + ASMJIT_X86_CHECK_STATE + } + + //! Spill. + //! + //! Spill variable/register, saves the content to the memory-home if modified. + template + ASMJIT_INLINE void spill(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + + if (vd->getState() != kVarStateReg) { + ASMJIT_X86_CHECK_STATE + return; + } + + uint32_t regIndex = vd->getRegIndex(); + + ASMJIT_ASSERT(regIndex != kInvalidReg); + ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == vd); + + if (vd->isModified()) + emitSave(vd, regIndex, "Spill"); + detach(vd, regIndex, kVarStateMem); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Modify] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void modify(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setModified(true); + _x86State._modified.or_(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Unuse] + // -------------------------------------------------------------------------- + + //! Unuse. + //! + //! Unuse variable, it will be detached it if it's allocated then its state + //! will be changed to kVarStateUnused. + template + ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vState != kVarStateReg); + + uint32_t regIndex = vd->getRegIndex(); + if (regIndex != kInvalidReg) + detach(vd, regIndex, vState); + else + vd->setState(vState); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [State] + // -------------------------------------------------------------------------- + + //! Get state as `X86VarState`. + ASMJIT_INLINE X86VarState* getState() const { + return const_cast(&_x86State); + } + + virtual void loadState(VarState* src); + virtual VarState* saveState(); + + virtual void switchState(VarState* src); + virtual void intersectStates(VarState* a, VarState* b); + + // -------------------------------------------------------------------------- + // [Memory] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem getVarMem(VarData* vd) { + (void)getVarCell(vd); + + X86Mem mem(_memSlot); + mem.setBase(vd->getId()); + return mem; + } + + // -------------------------------------------------------------------------- + // [Fetch] + // -------------------------------------------------------------------------- + + virtual Error fetch(); + + // -------------------------------------------------------------------------- + // [Annotate] + // -------------------------------------------------------------------------- + + virtual Error annotate(); + + // -------------------------------------------------------------------------- + // [Translate] + // -------------------------------------------------------------------------- + + virtual Error translate(); + + // -------------------------------------------------------------------------- + // [Schedule] + // -------------------------------------------------------------------------- + + virtual Error schedule(); + + // -------------------------------------------------------------------------- + // [Serialize] + // -------------------------------------------------------------------------- + + virtual Error serialize(Assembler* assembler, Node* start, Node* stop); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of X86/X64 registers. + X86RegCount _regCount; + //! X86/X64 stack-pointer (esp or rsp). + X86GpReg _zsp; + //! X86/X64 frame-pointer (ebp or rbp). + X86GpReg _zbp; + //! Temporary memory operand. + X86Mem _memSlot; + + //! X86/X64 specific compiler state, linked to `_state`. + X86VarState _x86State; + //! Clobbered registers (for the whole function). + X86RegMask _clobberedRegs; + + //! Memory cell where is stored address used to restore manually + //! aligned stack. + MemCell* _stackFrameCell; + + //! Global allocable registers mask. + uint32_t _gaRegs[kX86RegClassCount]; + + //! Function arguments base pointer (register). + uint8_t _argBaseReg; + //! Function variables base pointer (register). + uint8_t _varBaseReg; + //! Whether to emit comments. + uint8_t _emitComments; + + //! Function arguments base offset. + int32_t _argBaseOffset; + //! Function variables base offset. + int32_t _varBaseOffset; + + //! Function arguments displacement. + int32_t _argActualDisp; + //! Function variables displacement. + int32_t _varActualDisp; + + //! Temporary string builder used for logging. + StringBuilderT<256> _stringBuilder; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86CONTEXT_P_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86cpuinfo.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86cpuinfo.h new file mode 100644 index 0000000..47c3e41 --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86cpuinfo.h @@ -0,0 +1,263 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86CPUINFO_H +#define _ASMJIT_X86_X86CPUINFO_H + +// [Dependencies - AsmJit] +#include "../base/cpuinfo.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86CpuInfo; + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::kX86CpuFeature] +// ============================================================================ + +//! X86 CPU features. +ASMJIT_ENUM(kX86CpuFeature) { + //! Cpu has Not-Execute-Bit. + kX86CpuFeatureNX = 0, + //! Cpu has multithreading. + kX86CpuFeatureMT, + //! Cpu has RDTSC. + kX86CpuFeatureRDTSC, + //! Cpu has RDTSCP. + kX86CpuFeatureRDTSCP, + //! Cpu has CMOV. + kX86CpuFeatureCMOV, + //! Cpu has CMPXCHG8B. + kX86CpuFeatureCMPXCHG8B, + //! Cpu has CMPXCHG16B (X64). + kX86CpuFeatureCMPXCHG16B, + //! Cpu has CLFUSH. + kX86CpuFeatureCLFLUSH, + //! Cpu has CLFUSH (Optimized). + kX86CpuFeatureCLFLUSHOpt, + //! Cpu has PREFETCH. + kX86CpuFeaturePREFETCH, + //! Cpu has PREFETCHWT1. + kX86CpuFeaturePREFETCHWT1, + //! Cpu has LAHF/SAHF. + kX86CpuFeatureLahfSahf, + //! Cpu has FXSAVE/FXRSTOR. + kX86CpuFeatureFXSR, + //! Cpu has FXSAVE/FXRSTOR (Optimized). + kX86CpuFeatureFXSROpt, + //! Cpu has MMX. + kX86CpuFeatureMMX, + //! Cpu has extended MMX. + kX86CpuFeatureMMX2, + //! Cpu has 3dNow! + kX86CpuFeature3DNOW, + //! Cpu has enchanced 3dNow! + kX86CpuFeature3DNOW2, + //! Cpu has SSE. + kX86CpuFeatureSSE, + //! Cpu has SSE2. + kX86CpuFeatureSSE2, + //! Cpu has SSE3. + kX86CpuFeatureSSE3, + //! Cpu has SSSE3. + kX86CpuFeatureSSSE3, + //! Cpu has SSE4.A. + kX86CpuFeatureSSE4A, + //! Cpu has SSE4.1. + kX86CpuFeatureSSE4_1, + //! Cpu has SSE4.2. + kX86CpuFeatureSSE4_2, + //! Cpu has Misaligned SSE (MSSE). + kX86CpuFeatureMSSE, + //! Cpu has MONITOR and MWAIT. + kX86CpuFeatureMONITOR, + //! Cpu has MOVBE. + kX86CpuFeatureMOVBE, + //! Cpu has POPCNT. + kX86CpuFeaturePOPCNT, + //! Cpu has LZCNT. + kX86CpuFeatureLZCNT, + //! Cpu has AESNI. + kX86CpuFeatureAESNI, + //! Cpu has PCLMULQDQ. + kX86CpuFeaturePCLMULQDQ, + //! Cpu has RDRAND. + kX86CpuFeatureRDRAND, + //! Cpu has RDSEED. + kX86CpuFeatureRDSEED, + //! Cpu has SHA-1 and SHA-256. + kX86CpuFeatureSHA, + //! Cpu has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0. + kX86CpuFeatureXSave, + //! OS has enabled XSAVE, you can call XGETBV to get value of XCR0. + kX86CpuFeatureXSaveOS, + //! Cpu has AVX. + kX86CpuFeatureAVX, + //! Cpu has AVX2. + kX86CpuFeatureAVX2, + //! Cpu has F16C. + kX86CpuFeatureF16C, + //! Cpu has FMA3. + kX86CpuFeatureFMA3, + //! Cpu has FMA4. + kX86CpuFeatureFMA4, + //! Cpu has XOP. + kX86CpuFeatureXOP, + //! Cpu has BMI. + kX86CpuFeatureBMI, + //! Cpu has BMI2. + kX86CpuFeatureBMI2, + //! Cpu has HLE. + kX86CpuFeatureHLE, + //! Cpu has RTM. + kX86CpuFeatureRTM, + //! Cpu has ADX. + kX86CpuFeatureADX, + //! Cpu has MPX (Memory Protection Extensions). + kX86CpuFeatureMPX, + //! Cpu has FSGSBASE. + kX86CpuFeatureFSGSBase, + //! Cpu has optimized REP MOVSB/STOSB. + kX86CpuFeatureMOVSBSTOSBOpt, + + //! Cpu has AVX-512F (Foundation). + kX86CpuFeatureAVX512F, + //! Cpu has AVX-512CD (Conflict Detection). + kX86CpuFeatureAVX512CD, + //! Cpu has AVX-512PF (Prefetch Instructions). + kX86CpuFeatureAVX512PF, + //! Cpu has AVX-512ER (Exponential and Reciprocal Instructions). + kX86CpuFeatureAVX512ER, + //! Cpu has AVX-512DQ (DWord/QWord). + kX86CpuFeatureAVX512DQ, + //! Cpu has AVX-512BW (Byte/Word). + kX86CpuFeatureAVX512BW, + //! Cpu has AVX VL (Vector Length Excensions). + kX86CpuFeatureAVX512VL, + + //! Count of X86/X64 Cpu features. + kX86CpuFeatureCount +}; + +// ============================================================================ +// [asmjit::X86CpuId] +// ============================================================================ + +//! X86/X64 CPUID output. +union X86CpuId { + //! EAX/EBX/ECX/EDX output. + uint32_t i[4]; + + struct { + //! EAX output. + uint32_t eax; + //! EBX output. + uint32_t ebx; + //! ECX output. + uint32_t ecx; + //! EDX output. + uint32_t edx; + }; +}; + +// ============================================================================ +// [asmjit::X86CpuUtil] +// ============================================================================ + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +//! CPU utilities available only if the host processor is X86/X64. +struct X86CpuUtil { + //! Get the result of calling CPUID instruction to `out`. + ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out); + + //! Detect the Host CPU. + ASMJIT_API static void detect(X86CpuInfo* cpuInfo); +}; +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + +// ============================================================================ +// [asmjit::X86CpuInfo] +// ============================================================================ + +struct X86CpuInfo : public CpuInfo { + ASMJIT_NO_COPY(X86CpuInfo) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) : + CpuInfo(size) {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get processor type. + ASMJIT_INLINE uint32_t getProcessorType() const { + return _processorType; + } + + //! Get brand index. + ASMJIT_INLINE uint32_t getBrandIndex() const { + return _brandIndex; + } + + //! Get flush cache line size. + ASMJIT_INLINE uint32_t getFlushCacheLineSize() const { + return _flushCacheLineSize; + } + + //! Get maximum logical processors count. + ASMJIT_INLINE uint32_t getMaxLogicalProcessors() const { + return _maxLogicalProcessors; + } + + // -------------------------------------------------------------------------- + // [Statics] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + //! Get global instance of `X86CpuInfo`. + static ASMJIT_INLINE const X86CpuInfo* getHost() { + return static_cast(CpuInfo::getHost()); + } +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Processor type. + uint32_t _processorType; + //! Brand index. + uint32_t _brandIndex; + //! Flush cache line size in bytes. + uint32_t _flushCacheLineSize; + //! Maximum number of addressable IDs for logical processors. + uint32_t _maxLogicalProcessors; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86CPUINFO_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86inst.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86inst.h new file mode 100644 index 0000000..e36b791 --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86inst.h @@ -0,0 +1,2410 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86INST_H +#define _ASMJIT_X86_X86INST_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/compiler.h" +#include "../base/globals.h" +#include "../base/intutil.h" +#include "../base/operand.h" +#include "../base/vectypes.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86InstInfo; +struct X86InstExtendedInfo; + +//! \addtogroup asmjit_x86_inst +//! \{ + +// ============================================================================ +// [asmjit::X86Inst/X86Cond - Globals] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) +//! \internal +//! +//! X86/X64 instructions' names, accessible through `X86InstInfo`. +ASMJIT_VAR const char _x86InstName[]; +#endif // !ASMJIT_DISABLE_NAMES + +//! \internal +//! +//! X86/X64 instructions' extended information, accessible through `X86InstInfo`. +ASMJIT_VAR const X86InstExtendedInfo _x86InstExtendedInfo[]; + +//! \internal +//! +//! X86/X64 instructions' information. +ASMJIT_VAR const X86InstInfo _x86InstInfo[]; + +//! \internal +//! +//! X86/X64 condition codes to reversed condition codes map. +ASMJIT_VAR const uint32_t _x86ReverseCond[20]; + +//! \internal +//! +//! X86/X64 condition codes to "cmovcc" group map. +ASMJIT_VAR const uint32_t _x86CondToCmovcc[20]; + +//! \internal +//! +//! X86/X64 condition codes to "jcc" group map. +ASMJIT_VAR const uint32_t _x86CondToJcc[20]; + +//! \internal +//! +//! X86/X64 condition codes to "setcc" group map. +ASMJIT_VAR const uint32_t _x86CondToSetcc[20]; + +// ============================================================================ +// [asmjit::kX86InstId] +// ============================================================================ + +//! X86/X64 instruction IDs. +//! +//! Note that these instruction codes are AsmJit specific. Each instruction has +//! a unique ID that is used as an index to AsmJit instruction table. The list +//! is sorted alphabetically except instructions starting with `j`, because the +//! `jcc` instruction is composition of an opcode and condition code. It means +//! that these instructions are sorted as `jcc`, `jecxz` and `jmp`. Please use +//! \ref X86Util::getInstIdByName() if you need instruction name to ID mapping +//! and are not aware on how to handle such case. +ASMJIT_ENUM(kX86InstId) { + kX86InstIdAdc = 1, // X86/X64 + kX86InstIdAdd, // X86/X64 + kX86InstIdAddpd, // SSE2 + kX86InstIdAddps, // SSE + kX86InstIdAddsd, // SSE2 + kX86InstIdAddss, // SSE + kX86InstIdAddsubpd, // SSE3 + kX86InstIdAddsubps, // SSE3 + kX86InstIdAesdec, // AESNI + kX86InstIdAesdeclast, // AESNI + kX86InstIdAesenc, // AESNI + kX86InstIdAesenclast, // AESNI + kX86InstIdAesimc, // AESNI + kX86InstIdAeskeygenassist, // AESNI + kX86InstIdAnd, // X86/X64 + kX86InstIdAndn, // BMI + kX86InstIdAndnpd, // SSE2 + kX86InstIdAndnps, // SSE + kX86InstIdAndpd, // SSE2 + kX86InstIdAndps, // SSE + kX86InstIdBextr, // BMI + kX86InstIdBlendpd, // SSE4.1 + kX86InstIdBlendps, // SSE4.1 + kX86InstIdBlendvpd, // SSE4.1 + kX86InstIdBlendvps, // SSE4.1 + kX86InstIdBlsi, // BMI + kX86InstIdBlsmsk, // BMI + kX86InstIdBlsr, // BMI + kX86InstIdBsf, // X86/X64 + kX86InstIdBsr, // X86/X64 + kX86InstIdBswap, // X86/X64 (i486+) + kX86InstIdBt, // X86/X64 + kX86InstIdBtc, // X86/X64 + kX86InstIdBtr, // X86/X64 + kX86InstIdBts, // X86/X64 + kX86InstIdBzhi, // BMI2 + kX86InstIdCall, // X86/X64 + kX86InstIdCbw, // X86/X64 + kX86InstIdCdq, // X86/X64 + kX86InstIdCdqe, // X64 only + kX86InstIdClc, // X86/X64 + kX86InstIdCld, // X86/X64 + kX86InstIdClflush, // SSE2 + kX86InstIdCmc, // X86/X64 + kX86InstIdCmova, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovae, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovb, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovc, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmove, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovg, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovge, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovl, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovle, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovna, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovne, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovng, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovno, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovns, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovo, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovp, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovs, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovz, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmp, // X86/X64 + kX86InstIdCmppd, // SSE2 + kX86InstIdCmpps, // SSE + kX86InstIdCmpsB, // CMPS - X86/X64 + kX86InstIdCmpsD, // CMPS - X86/X64 + kX86InstIdCmpsQ, // CMPS - X64 + kX86InstIdCmpsW, // CMPS - X86/X64 + kX86InstIdCmpsd, // SSE2 + kX86InstIdCmpss, // SSE + kX86InstIdCmpxchg, // X86/X64 (i486+) + kX86InstIdCmpxchg16b, // X64 only + kX86InstIdCmpxchg8b, // X86/X64 (i586+) + kX86InstIdComisd, // SSE2 + kX86InstIdComiss, // SSE + kX86InstIdCpuid, // X86/X64 (i486/i586+) + kX86InstIdCqo, // X64 only + kX86InstIdCrc32, // SSE4.2 + kX86InstIdCvtdq2pd, // SSE2 + kX86InstIdCvtdq2ps, // SSE2 + kX86InstIdCvtpd2dq, // SSE2 + kX86InstIdCvtpd2pi, // SSE2 + kX86InstIdCvtpd2ps, // SSE2 + kX86InstIdCvtpi2pd, // SSE2 + kX86InstIdCvtpi2ps, // SSE + kX86InstIdCvtps2dq, // SSE2 + kX86InstIdCvtps2pd, // SSE2 + kX86InstIdCvtps2pi, // SSE + kX86InstIdCvtsd2si, // SSE2 + kX86InstIdCvtsd2ss, // SSE2 + kX86InstIdCvtsi2sd, // SSE2 + kX86InstIdCvtsi2ss, // SSE + kX86InstIdCvtss2sd, // SSE2 + kX86InstIdCvtss2si, // SSE + kX86InstIdCvttpd2dq, // SSE2 + kX86InstIdCvttpd2pi, // SSE2 + kX86InstIdCvttps2dq, // SSE2 + kX86InstIdCvttps2pi, // SSE + kX86InstIdCvttsd2si, // SSE2 + kX86InstIdCvttss2si, // SSE + kX86InstIdCwd, // X86/X64 + kX86InstIdCwde, // X86/X64 + kX86InstIdDaa, // X86 only + kX86InstIdDas, // X86 only + kX86InstIdDec, // X86/X64 + kX86InstIdDiv, // X86/X64 + kX86InstIdDivpd, // SSE2 + kX86InstIdDivps, // SSE + kX86InstIdDivsd, // SSE2 + kX86InstIdDivss, // SSE + kX86InstIdDppd, // SSE4.1 + kX86InstIdDpps, // SSE4.1 + kX86InstIdEmms, // MMX + kX86InstIdEnter, // X86/X64 + kX86InstIdExtractps, // SSE4.1 + kX86InstIdExtrq, // SSE4a + kX86InstIdF2xm1, // FPU + kX86InstIdFabs, // FPU + kX86InstIdFadd, // FPU + kX86InstIdFaddp, // FPU + kX86InstIdFbld, // FPU + kX86InstIdFbstp, // FPU + kX86InstIdFchs, // FPU + kX86InstIdFclex, // FPU + kX86InstIdFcmovb, // FPU + kX86InstIdFcmovbe, // FPU + kX86InstIdFcmove, // FPU + kX86InstIdFcmovnb, // FPU + kX86InstIdFcmovnbe, // FPU + kX86InstIdFcmovne, // FPU + kX86InstIdFcmovnu, // FPU + kX86InstIdFcmovu, // FPU + kX86InstIdFcom, // FPU + kX86InstIdFcomi, // FPU + kX86InstIdFcomip, // FPU + kX86InstIdFcomp, // FPU + kX86InstIdFcompp, // FPU + kX86InstIdFcos, // FPU + kX86InstIdFdecstp, // FPU + kX86InstIdFdiv, // FPU + kX86InstIdFdivp, // FPU + kX86InstIdFdivr, // FPU + kX86InstIdFdivrp, // FPU + kX86InstIdFemms, // 3dNow! + kX86InstIdFfree, // FPU + kX86InstIdFiadd, // FPU + kX86InstIdFicom, // FPU + kX86InstIdFicomp, // FPU + kX86InstIdFidiv, // FPU + kX86InstIdFidivr, // FPU + kX86InstIdFild, // FPU + kX86InstIdFimul, // FPU + kX86InstIdFincstp, // FPU + kX86InstIdFinit, // FPU + kX86InstIdFist, // FPU + kX86InstIdFistp, // FPU + kX86InstIdFisttp, // SSE3 + kX86InstIdFisub, // FPU + kX86InstIdFisubr, // FPU + kX86InstIdFld, // FPU + kX86InstIdFld1, // FPU + kX86InstIdFldcw, // FPU + kX86InstIdFldenv, // FPU + kX86InstIdFldl2e, // FPU + kX86InstIdFldl2t, // FPU + kX86InstIdFldlg2, // FPU + kX86InstIdFldln2, // FPU + kX86InstIdFldpi, // FPU + kX86InstIdFldz, // FPU + kX86InstIdFmul, // FPU + kX86InstIdFmulp, // FPU + kX86InstIdFnclex, // FPU + kX86InstIdFninit, // FPU + kX86InstIdFnop, // FPU + kX86InstIdFnsave, // FPU + kX86InstIdFnstcw, // FPU + kX86InstIdFnstenv, // FPU + kX86InstIdFnstsw, // FPU + kX86InstIdFpatan, // FPU + kX86InstIdFprem, // FPU + kX86InstIdFprem1, // FPU + kX86InstIdFptan, // FPU + kX86InstIdFrndint, // FPU + kX86InstIdFrstor, // FPU + kX86InstIdFsave, // FPU + kX86InstIdFscale, // FPU + kX86InstIdFsin, // FPU + kX86InstIdFsincos, // FPU + kX86InstIdFsqrt, // FPU + kX86InstIdFst, // FPU + kX86InstIdFstcw, // FPU + kX86InstIdFstenv, // FPU + kX86InstIdFstp, // FPU + kX86InstIdFstsw, // FPU + kX86InstIdFsub, // FPU + kX86InstIdFsubp, // FPU + kX86InstIdFsubr, // FPU + kX86InstIdFsubrp, // FPU + kX86InstIdFtst, // FPU + kX86InstIdFucom, // FPU + kX86InstIdFucomi, // FPU + kX86InstIdFucomip, // FPU + kX86InstIdFucomp, // FPU + kX86InstIdFucompp, // FPU + kX86InstIdFwait, // FPU + kX86InstIdFxam, // FPU + kX86InstIdFxch, // FPU + kX86InstIdFxrstor, // FPU + kX86InstIdFxsave, // FPU + kX86InstIdFxtract, // FPU + kX86InstIdFyl2x, // FPU + kX86InstIdFyl2xp1, // FPU + kX86InstIdHaddpd, // SSE3 + kX86InstIdHaddps, // SSE3 + kX86InstIdHsubpd, // SSE3 + kX86InstIdHsubps, // SSE3 + kX86InstIdIdiv, // X86/X64 + kX86InstIdImul, // X86/X64 + kX86InstIdInc, // X86/X64 + kX86InstIdInsertps, // SSE4.1 + kX86InstIdInsertq, // SSE4a + kX86InstIdInt, // X86/X64 + kX86InstIdJa, // X86/X64 (jcc) + kX86InstIdJae, // X86/X64 (jcc) + kX86InstIdJb, // X86/X64 (jcc) + kX86InstIdJbe, // X86/X64 (jcc) + kX86InstIdJc, // X86/X64 (jcc) + kX86InstIdJe, // X86/X64 (jcc) + kX86InstIdJg, // X86/X64 (jcc) + kX86InstIdJge, // X86/X64 (jcc) + kX86InstIdJl, // X86/X64 (jcc) + kX86InstIdJle, // X86/X64 (jcc) + kX86InstIdJna, // X86/X64 (jcc) + kX86InstIdJnae, // X86/X64 (jcc) + kX86InstIdJnb, // X86/X64 (jcc) + kX86InstIdJnbe, // X86/X64 (jcc) + kX86InstIdJnc, // X86/X64 (jcc) + kX86InstIdJne, // X86/X64 (jcc) + kX86InstIdJng, // X86/X64 (jcc) + kX86InstIdJnge, // X86/X64 (jcc) + kX86InstIdJnl, // X86/X64 (jcc) + kX86InstIdJnle, // X86/X64 (jcc) + kX86InstIdJno, // X86/X64 (jcc) + kX86InstIdJnp, // X86/X64 (jcc) + kX86InstIdJns, // X86/X64 (jcc) + kX86InstIdJnz, // X86/X64 (jcc) + kX86InstIdJo, // X86/X64 (jcc) + kX86InstIdJp, // X86/X64 (jcc) + kX86InstIdJpe, // X86/X64 (jcc) + kX86InstIdJpo, // X86/X64 (jcc) + kX86InstIdJs, // X86/X64 (jcc) + kX86InstIdJz, // X86/X64 (jcc) + kX86InstIdJecxz, // X86/X64 (jcxz/jecxz/jrcxz) + kX86InstIdJmp, // X86/X64 (jmp) + kX86InstIdLahf, // X86/X64 (CPUID NEEDED) + kX86InstIdLddqu, // SSE3 + kX86InstIdLdmxcsr, // SSE + kX86InstIdLea, // X86/X64 + kX86InstIdLeave, // X86/X64 + kX86InstIdLfence, // SSE2 + kX86InstIdLodsB, // LODS - X86/X64 + kX86InstIdLodsD, // LODS - X86/X64 + kX86InstIdLodsQ, // LODS - X86/X64 + kX86InstIdLodsW, // LODS - X86/X64 + kX86InstIdLzcnt, // LZCNT + kX86InstIdMaskmovdqu, // SSE2 + kX86InstIdMaskmovq, // MMX-Ext + kX86InstIdMaxpd, // SSE2 + kX86InstIdMaxps, // SSE + kX86InstIdMaxsd, // SSE2 + kX86InstIdMaxss, // SSE + kX86InstIdMfence, // SSE2 + kX86InstIdMinpd, // SSE2 + kX86InstIdMinps, // SSE + kX86InstIdMinsd, // SSE2 + kX86InstIdMinss, // SSE + kX86InstIdMonitor, // SSE3 + kX86InstIdMov, // X86/X64 + kX86InstIdMovPtr, // X86/X64 + kX86InstIdMovapd, // SSE2 + kX86InstIdMovaps, // SSE + kX86InstIdMovbe, // SSE3 - Intel-Atom + kX86InstIdMovd, // MMX/SSE2 + kX86InstIdMovddup, // SSE3 + kX86InstIdMovdq2q, // SSE2 + kX86InstIdMovdqa, // SSE2 + kX86InstIdMovdqu, // SSE2 + kX86InstIdMovhlps, // SSE + kX86InstIdMovhpd, // SSE2 + kX86InstIdMovhps, // SSE + kX86InstIdMovlhps, // SSE + kX86InstIdMovlpd, // SSE2 + kX86InstIdMovlps, // SSE + kX86InstIdMovmskpd, // SSE2 + kX86InstIdMovmskps, // SSE2 + kX86InstIdMovntdq, // SSE2 + kX86InstIdMovntdqa, // SSE4.1 + kX86InstIdMovnti, // SSE2 + kX86InstIdMovntpd, // SSE2 + kX86InstIdMovntps, // SSE + kX86InstIdMovntq, // MMX-Ext + kX86InstIdMovntsd, // SSE4a + kX86InstIdMovntss, // SSE4a + kX86InstIdMovq, // MMX/SSE/SSE2 + kX86InstIdMovq2dq, // SSE2 + kX86InstIdMovsB, // MOVS - X86/X64 + kX86InstIdMovsD, // MOVS - X86/X64 + kX86InstIdMovsQ, // MOVS - X64 + kX86InstIdMovsW, // MOVS - X86/X64 + kX86InstIdMovsd, // SSE2 + kX86InstIdMovshdup, // SSE3 + kX86InstIdMovsldup, // SSE3 + kX86InstIdMovss, // SSE + kX86InstIdMovsx, // X86/X64 + kX86InstIdMovsxd, // X86/X64 + kX86InstIdMovupd, // SSE2 + kX86InstIdMovups, // SSE + kX86InstIdMovzx, // X86/X64 + kX86InstIdMpsadbw, // SSE4.1 + kX86InstIdMul, // X86/X64 + kX86InstIdMulpd, // SSE2 + kX86InstIdMulps, // SSE + kX86InstIdMulsd, // SSE2 + kX86InstIdMulss, // SSE + kX86InstIdMulx, // BMI2 + kX86InstIdMwait, // SSE3 + kX86InstIdNeg, // X86/X64 + kX86InstIdNop, // X86/X64 + kX86InstIdNot, // X86/X64 + kX86InstIdOr, // X86/X64 + kX86InstIdOrpd, // SSE2 + kX86InstIdOrps, // SSE + kX86InstIdPabsb, // SSSE3 + kX86InstIdPabsd, // SSSE3 + kX86InstIdPabsw, // SSSE3 + kX86InstIdPackssdw, // MMX/SSE2 + kX86InstIdPacksswb, // MMX/SSE2 + kX86InstIdPackusdw, // SSE4.1 + kX86InstIdPackuswb, // MMX/SSE2 + kX86InstIdPaddb, // MMX/SSE2 + kX86InstIdPaddd, // MMX/SSE2 + kX86InstIdPaddq, // SSE2 + kX86InstIdPaddsb, // MMX/SSE2 + kX86InstIdPaddsw, // MMX/SSE2 + kX86InstIdPaddusb, // MMX/SSE2 + kX86InstIdPaddusw, // MMX/SSE2 + kX86InstIdPaddw, // MMX/SSE2 + kX86InstIdPalignr, // SSSE3 + kX86InstIdPand, // MMX/SSE2 + kX86InstIdPandn, // MMX/SSE2 + kX86InstIdPause, // SSE2. + kX86InstIdPavgb, // MMX-Ext + kX86InstIdPavgw, // MMX-Ext + kX86InstIdPblendvb, // SSE4.1 + kX86InstIdPblendw, // SSE4.1 + kX86InstIdPclmulqdq, // PCLMULQDQ + kX86InstIdPcmpeqb, // MMX/SSE2 + kX86InstIdPcmpeqd, // MMX/SSE2 + kX86InstIdPcmpeqq, // SSE4.1 + kX86InstIdPcmpeqw, // MMX/SSE2 + kX86InstIdPcmpestri, // SSE4.2 + kX86InstIdPcmpestrm, // SSE4.2 + kX86InstIdPcmpgtb, // MMX/SSE2 + kX86InstIdPcmpgtd, // MMX/SSE2 + kX86InstIdPcmpgtq, // SSE4.2 + kX86InstIdPcmpgtw, // MMX/SSE2 + kX86InstIdPcmpistri, // SSE4.2 + kX86InstIdPcmpistrm, // SSE4.2 + kX86InstIdPdep, // BMI2 + kX86InstIdPext, // BMI2 + kX86InstIdPextrb, // SSE4.1 + kX86InstIdPextrd, // SSE4.1 + kX86InstIdPextrq, // SSE4.1 + kX86InstIdPextrw, // MMX-Ext/SSE2 + kX86InstIdPf2id, // 3dNow! + kX86InstIdPf2iw, // Enhanced 3dNow! + kX86InstIdPfacc, // 3dNow! + kX86InstIdPfadd, // 3dNow! + kX86InstIdPfcmpeq, // 3dNow! + kX86InstIdPfcmpge, // 3dNow! + kX86InstIdPfcmpgt, // 3dNow! + kX86InstIdPfmax, // 3dNow! + kX86InstIdPfmin, // 3dNow! + kX86InstIdPfmul, // 3dNow! + kX86InstIdPfnacc, // Enhanced 3dNow! + kX86InstIdPfpnacc, // Enhanced 3dNow! + kX86InstIdPfrcp, // 3dNow! + kX86InstIdPfrcpit1, // 3dNow! + kX86InstIdPfrcpit2, // 3dNow! + kX86InstIdPfrsqit1, // 3dNow! + kX86InstIdPfrsqrt, // 3dNow! + kX86InstIdPfsub, // 3dNow! + kX86InstIdPfsubr, // 3dNow! + kX86InstIdPhaddd, // SSSE3 + kX86InstIdPhaddsw, // SSSE3 + kX86InstIdPhaddw, // SSSE3 + kX86InstIdPhminposuw, // SSE4.1 + kX86InstIdPhsubd, // SSSE3 + kX86InstIdPhsubsw, // SSSE3 + kX86InstIdPhsubw, // SSSE3 + kX86InstIdPi2fd, // 3dNow! + kX86InstIdPi2fw, // Enhanced 3dNow! + kX86InstIdPinsrb, // SSE4.1 + kX86InstIdPinsrd, // SSE4.1 + kX86InstIdPinsrq, // SSE4.1 + kX86InstIdPinsrw, // MMX-Ext + kX86InstIdPmaddubsw, // SSSE3 + kX86InstIdPmaddwd, // MMX/SSE2 + kX86InstIdPmaxsb, // SSE4.1 + kX86InstIdPmaxsd, // SSE4.1 + kX86InstIdPmaxsw, // MMX-Ext + kX86InstIdPmaxub, // MMX-Ext + kX86InstIdPmaxud, // SSE4.1 + kX86InstIdPmaxuw, // SSE4.1 + kX86InstIdPminsb, // SSE4.1 + kX86InstIdPminsd, // SSE4.1 + kX86InstIdPminsw, // MMX-Ext + kX86InstIdPminub, // MMX-Ext + kX86InstIdPminud, // SSE4.1 + kX86InstIdPminuw, // SSE4.1 + kX86InstIdPmovmskb, // MMX-Ext + kX86InstIdPmovsxbd, // SSE4.1 + kX86InstIdPmovsxbq, // SSE4.1 + kX86InstIdPmovsxbw, // SSE4.1 + kX86InstIdPmovsxdq, // SSE4.1 + kX86InstIdPmovsxwd, // SSE4.1 + kX86InstIdPmovsxwq, // SSE4.1 + kX86InstIdPmovzxbd, // SSE4.1 + kX86InstIdPmovzxbq, // SSE4.1 + kX86InstIdPmovzxbw, // SSE4.1 + kX86InstIdPmovzxdq, // SSE4.1 + kX86InstIdPmovzxwd, // SSE4.1 + kX86InstIdPmovzxwq, // SSE4.1 + kX86InstIdPmuldq, // SSE4.1 + kX86InstIdPmulhrsw, // SSSE3 + kX86InstIdPmulhuw, // MMX-Ext + kX86InstIdPmulhw, // MMX/SSE2 + kX86InstIdPmulld, // SSE4.1 + kX86InstIdPmullw, // MMX/SSE2 + kX86InstIdPmuludq, // SSE2 + kX86InstIdPop, // X86/X64 + kX86InstIdPopa, // X86 only + kX86InstIdPopcnt, // SSE4.2 + kX86InstIdPopf, // X86/X64 + kX86InstIdPor, // MMX/SSE2 + kX86InstIdPrefetch, // MMX-Ext/SSE + kX86InstIdPrefetch3dNow, // 3dNow! + kX86InstIdPrefetchw3dNow, // 3dNow! + kX86InstIdPsadbw, // MMX-Ext + kX86InstIdPshufb, // SSSE3 + kX86InstIdPshufd, // SSE2 + kX86InstIdPshufhw, // SSE2 + kX86InstIdPshuflw, // SSE2 + kX86InstIdPshufw, // MMX-Ext + kX86InstIdPsignb, // SSSE3 + kX86InstIdPsignd, // SSSE3 + kX86InstIdPsignw, // SSSE3 + kX86InstIdPslld, // MMX/SSE2 + kX86InstIdPslldq, // SSE2 + kX86InstIdPsllq, // MMX/SSE2 + kX86InstIdPsllw, // MMX/SSE2 + kX86InstIdPsrad, // MMX/SSE2 + kX86InstIdPsraw, // MMX/SSE2 + kX86InstIdPsrld, // MMX/SSE2 + kX86InstIdPsrldq, // SSE2 + kX86InstIdPsrlq, // MMX/SSE2 + kX86InstIdPsrlw, // MMX/SSE2 + kX86InstIdPsubb, // MMX/SSE2 + kX86InstIdPsubd, // MMX/SSE2 + kX86InstIdPsubq, // SSE2 + kX86InstIdPsubsb, // MMX/SSE2 + kX86InstIdPsubsw, // MMX/SSE2 + kX86InstIdPsubusb, // MMX/SSE2 + kX86InstIdPsubusw, // MMX/SSE2 + kX86InstIdPsubw, // MMX/SSE2 + kX86InstIdPswapd, // Enhanced 3dNow! + kX86InstIdPtest, // SSE4.1 + kX86InstIdPunpckhbw, // MMX/SSE2 + kX86InstIdPunpckhdq, // MMX/SSE2 + kX86InstIdPunpckhqdq, // SSE2 + kX86InstIdPunpckhwd, // MMX/SSE2 + kX86InstIdPunpcklbw, // MMX/SSE2 + kX86InstIdPunpckldq, // MMX/SSE2 + kX86InstIdPunpcklqdq, // SSE2 + kX86InstIdPunpcklwd, // MMX/SSE2 + kX86InstIdPush, // X86/X64 + kX86InstIdPusha, // X86 only + kX86InstIdPushf, // X86/X64 + kX86InstIdPxor, // MMX/SSE2 + kX86InstIdRcl, // X86/X64 + kX86InstIdRcpps, // SSE + kX86InstIdRcpss, // SSE + kX86InstIdRcr, // X86/X64 + kX86InstIdRdfsbase, // FSGSBASE (x64) + kX86InstIdRdgsbase, // FSGSBASE (x64) + kX86InstIdRdrand, // RDRAND + kX86InstIdRdtsc, // X86/X64 + kX86InstIdRdtscp, // X86/X64 + kX86InstIdRepLodsB, // X86/X64 (REP) + kX86InstIdRepLodsD, // X86/X64 (REP) + kX86InstIdRepLodsQ, // X64 only (REP) + kX86InstIdRepLodsW, // X86/X64 (REP) + kX86InstIdRepMovsB, // X86/X64 (REP) + kX86InstIdRepMovsD, // X86/X64 (REP) + kX86InstIdRepMovsQ, // X64 only (REP) + kX86InstIdRepMovsW, // X86/X64 (REP) + kX86InstIdRepStosB, // X86/X64 (REP) + kX86InstIdRepStosD, // X86/X64 (REP) + kX86InstIdRepStosQ, // X64 only (REP) + kX86InstIdRepStosW, // X86/X64 (REP) + kX86InstIdRepeCmpsB, // X86/X64 (REP) + kX86InstIdRepeCmpsD, // X86/X64 (REP) + kX86InstIdRepeCmpsQ, // X64 only (REP) + kX86InstIdRepeCmpsW, // X86/X64 (REP) + kX86InstIdRepeScasB, // X86/X64 (REP) + kX86InstIdRepeScasD, // X86/X64 (REP) + kX86InstIdRepeScasQ, // X64 only (REP) + kX86InstIdRepeScasW, // X86/X64 (REP) + kX86InstIdRepneCmpsB, // X86/X64 (REP) + kX86InstIdRepneCmpsD, // X86/X64 (REP) + kX86InstIdRepneCmpsQ, // X64 only (REP) + kX86InstIdRepneCmpsW, // X86/X64 (REP) + kX86InstIdRepneScasB, // X86/X64 (REP) + kX86InstIdRepneScasD, // X86/X64 (REP) + kX86InstIdRepneScasQ, // X64 only (REP) + kX86InstIdRepneScasW, // X86/X64 (REP) + kX86InstIdRet, // X86/X64 + kX86InstIdRol, // X86/X64 + kX86InstIdRor, // X86/X64 + kX86InstIdRorx, // BMI2 + kX86InstIdRoundpd, // SSE4.1 + kX86InstIdRoundps, // SSE4.1 + kX86InstIdRoundsd, // SSE4.1 + kX86InstIdRoundss, // SSE4.1 + kX86InstIdRsqrtps, // SSE + kX86InstIdRsqrtss, // SSE + kX86InstIdSahf, // X86/X64 (CPUID NEEDED) + kX86InstIdSal, // X86/X64 + kX86InstIdSar, // X86/X64 + kX86InstIdSarx, // BMI2 + kX86InstIdSbb, // X86/X64 + kX86InstIdScasB, // SCAS - X86/X64 + kX86InstIdScasD, // SCAS - X86/X64 + kX86InstIdScasQ, // SCAS - X64 + kX86InstIdScasW, // SCAS - X86/X64 + kX86InstIdSeta, // X86/X64 (setcc) + kX86InstIdSetae, // X86/X64 (setcc) + kX86InstIdSetb, // X86/X64 (setcc) + kX86InstIdSetbe, // X86/X64 (setcc) + kX86InstIdSetc, // X86/X64 (setcc) + kX86InstIdSete, // X86/X64 (setcc) + kX86InstIdSetg, // X86/X64 (setcc) + kX86InstIdSetge, // X86/X64 (setcc) + kX86InstIdSetl, // X86/X64 (setcc) + kX86InstIdSetle, // X86/X64 (setcc) + kX86InstIdSetna, // X86/X64 (setcc) + kX86InstIdSetnae, // X86/X64 (setcc) + kX86InstIdSetnb, // X86/X64 (setcc) + kX86InstIdSetnbe, // X86/X64 (setcc) + kX86InstIdSetnc, // X86/X64 (setcc) + kX86InstIdSetne, // X86/X64 (setcc) + kX86InstIdSetng, // X86/X64 (setcc) + kX86InstIdSetnge, // X86/X64 (setcc) + kX86InstIdSetnl, // X86/X64 (setcc) + kX86InstIdSetnle, // X86/X64 (setcc) + kX86InstIdSetno, // X86/X64 (setcc) + kX86InstIdSetnp, // X86/X64 (setcc) + kX86InstIdSetns, // X86/X64 (setcc) + kX86InstIdSetnz, // X86/X64 (setcc) + kX86InstIdSeto, // X86/X64 (setcc) + kX86InstIdSetp, // X86/X64 (setcc) + kX86InstIdSetpe, // X86/X64 (setcc) + kX86InstIdSetpo, // X86/X64 (setcc) + kX86InstIdSets, // X86/X64 (setcc) + kX86InstIdSetz, // X86/X64 (setcc) + kX86InstIdSfence, // MMX-Ext/SSE + kX86InstIdShl, // X86/X64 + kX86InstIdShld, // X86/X64 + kX86InstIdShlx, // BMI2 + kX86InstIdShr, // X86/X64 + kX86InstIdShrd, // X86/X64 + kX86InstIdShrx, // BMI2 + kX86InstIdShufpd, // SSE2 + kX86InstIdShufps, // SSE + kX86InstIdSqrtpd, // SSE2 + kX86InstIdSqrtps, // SSE + kX86InstIdSqrtsd, // SSE2 + kX86InstIdSqrtss, // SSE + kX86InstIdStc, // X86/X64 + kX86InstIdStd, // X86/X64 + kX86InstIdStmxcsr, // SSE + kX86InstIdStosB, // STOS - X86/X64 + kX86InstIdStosD, // STOS - X86/X64 + kX86InstIdStosQ, // STOS - X64 + kX86InstIdStosW, // STOS - X86/X64 + kX86InstIdSub, // X86/X64 + kX86InstIdSubpd, // SSE2 + kX86InstIdSubps, // SSE + kX86InstIdSubsd, // SSE2 + kX86InstIdSubss, // SSE + kX86InstIdTest, // X86/X64 + kX86InstIdTzcnt, // TZCNT + kX86InstIdUcomisd, // SSE2 + kX86InstIdUcomiss, // SSE + kX86InstIdUd2, // X86/X64 + kX86InstIdUnpckhpd, // SSE2 + kX86InstIdUnpckhps, // SSE + kX86InstIdUnpcklpd, // SSE2 + kX86InstIdUnpcklps, // SSE + kX86InstIdVaddpd, // AVX + kX86InstIdVaddps, // AVX + kX86InstIdVaddsd, // AVX + kX86InstIdVaddss, // AVX + kX86InstIdVaddsubpd, // AVX + kX86InstIdVaddsubps, // AVX + kX86InstIdVaesdec, // AVX+AESNI + kX86InstIdVaesdeclast, // AVX+AESNI + kX86InstIdVaesenc, // AVX+AESNI + kX86InstIdVaesenclast, // AVX+AESNI + kX86InstIdVaesimc, // AVX+AESNI + kX86InstIdVaeskeygenassist,// AVX+AESNI + kX86InstIdVandnpd, // AVX + kX86InstIdVandnps, // AVX + kX86InstIdVandpd, // AVX + kX86InstIdVandps, // AVX + kX86InstIdVblendpd, // AVX + kX86InstIdVblendps, // AVX + kX86InstIdVblendvpd, // AVX + kX86InstIdVblendvps, // AVX + kX86InstIdVbroadcastf128, // AVX + kX86InstIdVbroadcasti128, // AVX2 + kX86InstIdVbroadcastsd, // AVX/AVX2 + kX86InstIdVbroadcastss, // AVX/AVX2 + kX86InstIdVcmppd, // AVX + kX86InstIdVcmpps, // AVX + kX86InstIdVcmpsd, // AVX + kX86InstIdVcmpss, // AVX + kX86InstIdVcomisd, // AVX + kX86InstIdVcomiss, // AVX + kX86InstIdVcvtdq2pd, // AVX + kX86InstIdVcvtdq2ps, // AVX + kX86InstIdVcvtpd2dq, // AVX + kX86InstIdVcvtpd2ps, // AVX + kX86InstIdVcvtph2ps, // F16C + kX86InstIdVcvtps2dq, // AVX + kX86InstIdVcvtps2pd, // AVX + kX86InstIdVcvtps2ph, // F16C + kX86InstIdVcvtsd2si, // AVX + kX86InstIdVcvtsd2ss, // AVX + kX86InstIdVcvtsi2sd, // AVX + kX86InstIdVcvtsi2ss, // AVX + kX86InstIdVcvtss2sd, // AVX + kX86InstIdVcvtss2si, // AVX + kX86InstIdVcvttpd2dq, // AVX + kX86InstIdVcvttps2dq, // AVX + kX86InstIdVcvttsd2si, // AVX + kX86InstIdVcvttss2si, // AVX + kX86InstIdVdivpd, // AVX + kX86InstIdVdivps, // AVX + kX86InstIdVdivsd, // AVX + kX86InstIdVdivss, // AVX + kX86InstIdVdppd, // AVX + kX86InstIdVdpps, // AVX + kX86InstIdVextractf128, // AVX + kX86InstIdVextracti128, // AVX2 + kX86InstIdVextractps, // AVX + kX86InstIdVfmadd132pd, // FMA3 + kX86InstIdVfmadd132ps, // FMA3 + kX86InstIdVfmadd132sd, // FMA3 + kX86InstIdVfmadd132ss, // FMA3 + kX86InstIdVfmadd213pd, // FMA3 + kX86InstIdVfmadd213ps, // FMA3 + kX86InstIdVfmadd213sd, // FMA3 + kX86InstIdVfmadd213ss, // FMA3 + kX86InstIdVfmadd231pd, // FMA3 + kX86InstIdVfmadd231ps, // FMA3 + kX86InstIdVfmadd231sd, // FMA3 + kX86InstIdVfmadd231ss, // FMA3 + kX86InstIdVfmaddpd, // FMA4 + kX86InstIdVfmaddps, // FMA4 + kX86InstIdVfmaddsd, // FMA4 + kX86InstIdVfmaddss, // FMA4 + kX86InstIdVfmaddsub132pd, // FMA3 + kX86InstIdVfmaddsub132ps, // FMA3 + kX86InstIdVfmaddsub213pd, // FMA3 + kX86InstIdVfmaddsub213ps, // FMA3 + kX86InstIdVfmaddsub231pd, // FMA3 + kX86InstIdVfmaddsub231ps, // FMA3 + kX86InstIdVfmaddsubpd, // FMA4 + kX86InstIdVfmaddsubps, // FMA4 + kX86InstIdVfmsub132pd, // FMA3 + kX86InstIdVfmsub132ps, // FMA3 + kX86InstIdVfmsub132sd, // FMA3 + kX86InstIdVfmsub132ss, // FMA3 + kX86InstIdVfmsub213pd, // FMA3 + kX86InstIdVfmsub213ps, // FMA3 + kX86InstIdVfmsub213sd, // FMA3 + kX86InstIdVfmsub213ss, // FMA3 + kX86InstIdVfmsub231pd, // FMA3 + kX86InstIdVfmsub231ps, // FMA3 + kX86InstIdVfmsub231sd, // FMA3 + kX86InstIdVfmsub231ss, // FMA3 + kX86InstIdVfmsubadd132pd, // FMA3 + kX86InstIdVfmsubadd132ps, // FMA3 + kX86InstIdVfmsubadd213pd, // FMA3 + kX86InstIdVfmsubadd213ps, // FMA3 + kX86InstIdVfmsubadd231pd, // FMA3 + kX86InstIdVfmsubadd231ps, // FMA3 + kX86InstIdVfmsubaddpd, // FMA4 + kX86InstIdVfmsubaddps, // FMA4 + kX86InstIdVfmsubpd, // FMA4 + kX86InstIdVfmsubps, // FMA4 + kX86InstIdVfmsubsd, // FMA4 + kX86InstIdVfmsubss, // FMA4 + kX86InstIdVfnmadd132pd, // FMA3 + kX86InstIdVfnmadd132ps, // FMA3 + kX86InstIdVfnmadd132sd, // FMA3 + kX86InstIdVfnmadd132ss, // FMA3 + kX86InstIdVfnmadd213pd, // FMA3 + kX86InstIdVfnmadd213ps, // FMA3 + kX86InstIdVfnmadd213sd, // FMA3 + kX86InstIdVfnmadd213ss, // FMA3 + kX86InstIdVfnmadd231pd, // FMA3 + kX86InstIdVfnmadd231ps, // FMA3 + kX86InstIdVfnmadd231sd, // FMA3 + kX86InstIdVfnmadd231ss, // FMA3 + kX86InstIdVfnmaddpd, // FMA4 + kX86InstIdVfnmaddps, // FMA4 + kX86InstIdVfnmaddsd, // FMA4 + kX86InstIdVfnmaddss, // FMA4 + kX86InstIdVfnmsub132pd, // FMA3 + kX86InstIdVfnmsub132ps, // FMA3 + kX86InstIdVfnmsub132sd, // FMA3 + kX86InstIdVfnmsub132ss, // FMA3 + kX86InstIdVfnmsub213pd, // FMA3 + kX86InstIdVfnmsub213ps, // FMA3 + kX86InstIdVfnmsub213sd, // FMA3 + kX86InstIdVfnmsub213ss, // FMA3 + kX86InstIdVfnmsub231pd, // FMA3 + kX86InstIdVfnmsub231ps, // FMA3 + kX86InstIdVfnmsub231sd, // FMA3 + kX86InstIdVfnmsub231ss, // FMA3 + kX86InstIdVfnmsubpd, // FMA4 + kX86InstIdVfnmsubps, // FMA4 + kX86InstIdVfnmsubsd, // FMA4 + kX86InstIdVfnmsubss, // FMA4 + kX86InstIdVfrczpd, // XOP + kX86InstIdVfrczps, // XOP + kX86InstIdVfrczsd, // XOP + kX86InstIdVfrczss, // XOP + kX86InstIdVgatherdpd, // AVX2 + kX86InstIdVgatherdps, // AVX2 + kX86InstIdVgatherqpd, // AVX2 + kX86InstIdVgatherqps, // AVX2 + kX86InstIdVhaddpd, // AVX + kX86InstIdVhaddps, // AVX + kX86InstIdVhsubpd, // AVX + kX86InstIdVhsubps, // AVX + kX86InstIdVinsertf128, // AVX + kX86InstIdVinserti128, // AVX2 + kX86InstIdVinsertps, // AVX + kX86InstIdVlddqu, // AVX + kX86InstIdVldmxcsr, // AVX + kX86InstIdVmaskmovdqu, // AVX + kX86InstIdVmaskmovpd, // AVX + kX86InstIdVmaskmovps, // AVX + kX86InstIdVmaxpd, // AVX + kX86InstIdVmaxps, // AVX + kX86InstIdVmaxsd, // AVX + kX86InstIdVmaxss, // AVX + kX86InstIdVminpd, // AVX + kX86InstIdVminps, // AVX + kX86InstIdVminsd, // AVX + kX86InstIdVminss, // AVX + kX86InstIdVmovapd, // AVX + kX86InstIdVmovaps, // AVX + kX86InstIdVmovd, // AVX + kX86InstIdVmovddup, // AVX + kX86InstIdVmovdqa, // AVX + kX86InstIdVmovdqu, // AVX + kX86InstIdVmovhlps, // AVX + kX86InstIdVmovhpd, // AVX + kX86InstIdVmovhps, // AVX + kX86InstIdVmovlhps, // AVX + kX86InstIdVmovlpd, // AVX + kX86InstIdVmovlps, // AVX + kX86InstIdVmovmskpd, // AVX + kX86InstIdVmovmskps, // AVX + kX86InstIdVmovntdq, // AVX + kX86InstIdVmovntdqa, // AVX/AVX2 + kX86InstIdVmovntpd, // AVX + kX86InstIdVmovntps, // AVX + kX86InstIdVmovq, // AVX + kX86InstIdVmovsd, // AVX + kX86InstIdVmovshdup, // AVX + kX86InstIdVmovsldup, // AVX + kX86InstIdVmovss, // AVX + kX86InstIdVmovupd, // AVX + kX86InstIdVmovups, // AVX + kX86InstIdVmpsadbw, // AVX/AVX2 + kX86InstIdVmulpd, // AVX + kX86InstIdVmulps, // AVX + kX86InstIdVmulsd, // AVX + kX86InstIdVmulss, // AVX + kX86InstIdVorpd, // AVX + kX86InstIdVorps, // AVX + kX86InstIdVpabsb, // AVX2 + kX86InstIdVpabsd, // AVX2 + kX86InstIdVpabsw, // AVX2 + kX86InstIdVpackssdw, // AVX2 + kX86InstIdVpacksswb, // AVX2 + kX86InstIdVpackusdw, // AVX2 + kX86InstIdVpackuswb, // AVX2 + kX86InstIdVpaddb, // AVX2 + kX86InstIdVpaddd, // AVX2 + kX86InstIdVpaddq, // AVX2 + kX86InstIdVpaddsb, // AVX2 + kX86InstIdVpaddsw, // AVX2 + kX86InstIdVpaddusb, // AVX2 + kX86InstIdVpaddusw, // AVX2 + kX86InstIdVpaddw, // AVX2 + kX86InstIdVpalignr, // AVX2 + kX86InstIdVpand, // AVX2 + kX86InstIdVpandn, // AVX2 + kX86InstIdVpavgb, // AVX2 + kX86InstIdVpavgw, // AVX2 + kX86InstIdVpblendd, // AVX2 + kX86InstIdVpblendvb, // AVX2 + kX86InstIdVpblendw, // AVX2 + kX86InstIdVpbroadcastb, // AVX2 + kX86InstIdVpbroadcastd, // AVX2 + kX86InstIdVpbroadcastq, // AVX2 + kX86InstIdVpbroadcastw, // AVX2 + kX86InstIdVpclmulqdq, // AVX+PCLMULQDQ + kX86InstIdVpcmov, // XOP + kX86InstIdVpcmpeqb, // AVX2 + kX86InstIdVpcmpeqd, // AVX2 + kX86InstIdVpcmpeqq, // AVX2 + kX86InstIdVpcmpeqw, // AVX2 + kX86InstIdVpcmpestri, // AVX + kX86InstIdVpcmpestrm, // AVX + kX86InstIdVpcmpgtb, // AVX2 + kX86InstIdVpcmpgtd, // AVX2 + kX86InstIdVpcmpgtq, // AVX2 + kX86InstIdVpcmpgtw, // AVX2 + kX86InstIdVpcmpistri, // AVX + kX86InstIdVpcmpistrm, // AVX + kX86InstIdVpcomb, // XOP + kX86InstIdVpcomd, // XOP + kX86InstIdVpcomq, // XOP + kX86InstIdVpcomub, // XOP + kX86InstIdVpcomud, // XOP + kX86InstIdVpcomuq, // XOP + kX86InstIdVpcomuw, // XOP + kX86InstIdVpcomw, // XOP + kX86InstIdVperm2f128, // AVX + kX86InstIdVperm2i128, // AVX2 + kX86InstIdVpermd, // AVX2 + kX86InstIdVpermil2pd, // XOP + kX86InstIdVpermil2ps, // XOP + kX86InstIdVpermilpd, // AVX + kX86InstIdVpermilps, // AVX + kX86InstIdVpermpd, // AVX2 + kX86InstIdVpermps, // AVX2 + kX86InstIdVpermq, // AVX2 + kX86InstIdVpextrb, // AVX + kX86InstIdVpextrd, // AVX + kX86InstIdVpextrq, // AVX (x64 only) + kX86InstIdVpextrw, // AVX + kX86InstIdVpgatherdd, // AVX2 + kX86InstIdVpgatherdq, // AVX2 + kX86InstIdVpgatherqd, // AVX2 + kX86InstIdVpgatherqq, // AVX2 + kX86InstIdVphaddbd, // XOP + kX86InstIdVphaddbq, // XOP + kX86InstIdVphaddbw, // XOP + kX86InstIdVphaddd, // AVX2 + kX86InstIdVphadddq, // XOP + kX86InstIdVphaddsw, // AVX2 + kX86InstIdVphaddubd, // XOP + kX86InstIdVphaddubq, // XOP + kX86InstIdVphaddubw, // XOP + kX86InstIdVphaddudq, // XOP + kX86InstIdVphadduwd, // XOP + kX86InstIdVphadduwq, // XOP + kX86InstIdVphaddw, // AVX2 + kX86InstIdVphaddwd, // XOP + kX86InstIdVphaddwq, // XOP + kX86InstIdVphminposuw, // AVX + kX86InstIdVphsubbw, // XOP + kX86InstIdVphsubd, // AVX2 + kX86InstIdVphsubdq, // XOP + kX86InstIdVphsubsw, // AVX2 + kX86InstIdVphsubw, // AVX2 + kX86InstIdVphsubwd, // XOP + kX86InstIdVpinsrb, // AVX + kX86InstIdVpinsrd, // AVX + kX86InstIdVpinsrq, // AVX (x64 only) + kX86InstIdVpinsrw, // AVX + kX86InstIdVpmacsdd, // XOP + kX86InstIdVpmacsdqh, // XOP + kX86InstIdVpmacsdql, // XOP + kX86InstIdVpmacssdd, // XOP + kX86InstIdVpmacssdqh, // XOP + kX86InstIdVpmacssdql, // XOP + kX86InstIdVpmacsswd, // XOP + kX86InstIdVpmacssww, // XOP + kX86InstIdVpmacswd, // XOP + kX86InstIdVpmacsww, // XOP + kX86InstIdVpmadcsswd, // XOP + kX86InstIdVpmadcswd, // XOP + kX86InstIdVpmaddubsw, // AVX/AVX2 + kX86InstIdVpmaddwd, // AVX/AVX2 + kX86InstIdVpmaskmovd, // AVX2 + kX86InstIdVpmaskmovq, // AVX2 + kX86InstIdVpmaxsb, // AVX/AVX2 + kX86InstIdVpmaxsd, // AVX/AVX2 + kX86InstIdVpmaxsw, // AVX/AVX2 + kX86InstIdVpmaxub, // AVX/AVX2 + kX86InstIdVpmaxud, // AVX/AVX2 + kX86InstIdVpmaxuw, // AVX/AVX2 + kX86InstIdVpminsb, // AVX/AVX2 + kX86InstIdVpminsd, // AVX/AVX2 + kX86InstIdVpminsw, // AVX/AVX2 + kX86InstIdVpminub, // AVX/AVX2 + kX86InstIdVpminud, // AVX/AVX2 + kX86InstIdVpminuw, // AVX/AVX2 + kX86InstIdVpmovmskb, // AVX/AVX2 + kX86InstIdVpmovsxbd, // AVX/AVX2 + kX86InstIdVpmovsxbq, // AVX/AVX2 + kX86InstIdVpmovsxbw, // AVX/AVX2 + kX86InstIdVpmovsxdq, // AVX/AVX2 + kX86InstIdVpmovsxwd, // AVX/AVX2 + kX86InstIdVpmovsxwq, // AVX/AVX2 + kX86InstIdVpmovzxbd, // AVX/AVX2 + kX86InstIdVpmovzxbq, // AVX/AVX2 + kX86InstIdVpmovzxbw, // AVX/AVX2 + kX86InstIdVpmovzxdq, // AVX/AVX2 + kX86InstIdVpmovzxwd, // AVX/AVX2 + kX86InstIdVpmovzxwq, // AVX/AVX2 + kX86InstIdVpmuldq, // AVX/AVX2 + kX86InstIdVpmulhrsw, // AVX/AVX2 + kX86InstIdVpmulhuw, // AVX/AVX2 + kX86InstIdVpmulhw, // AVX/AVX2 + kX86InstIdVpmulld, // AVX/AVX2 + kX86InstIdVpmullw, // AVX/AVX2 + kX86InstIdVpmuludq, // AVX/AVX2 + kX86InstIdVpor, // AVX/AVX2 + kX86InstIdVpperm, // XOP + kX86InstIdVprotb, // XOP + kX86InstIdVprotd, // XOP + kX86InstIdVprotq, // XOP + kX86InstIdVprotw, // XOP + kX86InstIdVpsadbw, // AVX/AVX2 + kX86InstIdVpshab, // XOP + kX86InstIdVpshad, // XOP + kX86InstIdVpshaq, // XOP + kX86InstIdVpshaw, // XOP + kX86InstIdVpshlb, // XOP + kX86InstIdVpshld, // XOP + kX86InstIdVpshlq, // XOP + kX86InstIdVpshlw, // XOP + kX86InstIdVpshufb, // AVX/AVX2 + kX86InstIdVpshufd, // AVX/AVX2 + kX86InstIdVpshufhw, // AVX/AVX2 + kX86InstIdVpshuflw, // AVX/AVX2 + kX86InstIdVpsignb, // AVX/AVX2 + kX86InstIdVpsignd, // AVX/AVX2 + kX86InstIdVpsignw, // AVX/AVX2 + kX86InstIdVpslld, // AVX/AVX2 + kX86InstIdVpslldq, // AVX/AVX2 + kX86InstIdVpsllq, // AVX/AVX2 + kX86InstIdVpsllvd, // AVX2 + kX86InstIdVpsllvq, // AVX2 + kX86InstIdVpsllw, // AVX/AVX2 + kX86InstIdVpsrad, // AVX/AVX2 + kX86InstIdVpsravd, // AVX2 + kX86InstIdVpsraw, // AVX/AVX2 + kX86InstIdVpsrld, // AVX/AVX2 + kX86InstIdVpsrldq, // AVX/AVX2 + kX86InstIdVpsrlq, // AVX/AVX2 + kX86InstIdVpsrlvd, // AVX2 + kX86InstIdVpsrlvq, // AVX2 + kX86InstIdVpsrlw, // AVX/AVX2 + kX86InstIdVpsubb, // AVX/AVX2 + kX86InstIdVpsubd, // AVX/AVX2 + kX86InstIdVpsubq, // AVX/AVX2 + kX86InstIdVpsubsb, // AVX/AVX2 + kX86InstIdVpsubsw, // AVX/AVX2 + kX86InstIdVpsubusb, // AVX/AVX2 + kX86InstIdVpsubusw, // AVX/AVX2 + kX86InstIdVpsubw, // AVX/AVX2 + kX86InstIdVptest, // AVX + kX86InstIdVpunpckhbw, // AVX/AVX2 + kX86InstIdVpunpckhdq, // AVX/AVX2 + kX86InstIdVpunpckhqdq, // AVX/AVX2 + kX86InstIdVpunpckhwd, // AVX/AVX2 + kX86InstIdVpunpcklbw, // AVX/AVX2 + kX86InstIdVpunpckldq, // AVX/AVX2 + kX86InstIdVpunpcklqdq, // AVX/AVX2 + kX86InstIdVpunpcklwd, // AVX/AVX2 + kX86InstIdVpxor, // AVX/AVX2 + kX86InstIdVrcpps, // AVX + kX86InstIdVrcpss, // AVX + kX86InstIdVroundpd, // AVX + kX86InstIdVroundps, // AVX + kX86InstIdVroundsd, // AVX + kX86InstIdVroundss, // AVX + kX86InstIdVrsqrtps, // AVX + kX86InstIdVrsqrtss, // AVX + kX86InstIdVshufpd, // AVX + kX86InstIdVshufps, // AVX + kX86InstIdVsqrtpd, // AVX + kX86InstIdVsqrtps, // AVX + kX86InstIdVsqrtsd, // AVX + kX86InstIdVsqrtss, // AVX + kX86InstIdVstmxcsr, // AVX + kX86InstIdVsubpd, // AVX + kX86InstIdVsubps, // AVX + kX86InstIdVsubsd, // AVX + kX86InstIdVsubss, // AVX + kX86InstIdVtestpd, // AVX + kX86InstIdVtestps, // AVX + kX86InstIdVucomisd, // AVX + kX86InstIdVucomiss, // AVX + kX86InstIdVunpckhpd, // AVX + kX86InstIdVunpckhps, // AVX + kX86InstIdVunpcklpd, // AVX + kX86InstIdVunpcklps, // AVX + kX86InstIdVxorpd, // AVX + kX86InstIdVxorps, // AVX + kX86InstIdVzeroall, // AVX + kX86InstIdVzeroupper, // AVX + kX86InstIdWrfsbase, // FSGSBASE (x64) + kX86InstIdWrgsbase, // FSGSBASE (x64) + kX86InstIdXadd, // X86/X64 (i486+) + kX86InstIdXchg, // X86/X64 + kX86InstIdXgetbv, // XSAVE + kX86InstIdXor, // X86/X64 + kX86InstIdXorpd, // SSE2 + kX86InstIdXorps, // SSE + kX86InstIdXrstor, // XSAVE + kX86InstIdXrstor64, // XSAVE + kX86InstIdXsave, // XSAVE + kX86InstIdXsave64, // XSAVE + kX86InstIdXsaveopt, // XSAVE + kX86InstIdXsaveopt64, // XSAVE + kX86InstIdXsetbv, // XSAVE + + _kX86InstIdCount, + + _kX86InstIdCmovcc = kX86InstIdCmova, + _kX86InstIdJcc = kX86InstIdJa, + _kX86InstIdSetcc = kX86InstIdSeta, + + _kX86InstIdJbegin = kX86InstIdJa, + _kX86InstIdJend = kX86InstIdJmp +}; + +// ============================================================================ +// [asmjit::kX86InstOptions] +// ============================================================================ + +//! X86/X64 instruction emit options, mainly for internal purposes. +ASMJIT_ENUM(kX86InstOptions) { + //! Emit instruction with LOCK prefix. + //! + //! If this option is used and instruction doesn't support LOCK prefix an + //! invalid instruction error is generated. + kX86InstOptionLock = 0x00000010, + + //! Force REX prefix (X64). + //! + //! This option should be used carefully as there are combinations of + //! instructions and their operands that are not encodable. The REX prefix + //! can't be used together with AH, BH, CH, and DH registers. AsmJit reports + //! \ref kErrorIllegalInstruction in such case. + kX86InstOptionRex = 0x00000040, + + //! \internal + //! + //! Reserved by `X86Assembler`, do not use! + _kX86InstOptionNoRex = 0x00000080, + + //! Force 3-byte VEX prefix even if the instruction is encodable by 2-byte + //! VEX prefix (AVX). + //! + //! Ignored if the instruction is not AVX or `kX86InstOptionEVEX` is used. + kX86InstOptionVex3 = 0x00000100, + + //! Force 4-byte EVEX prefix even if the instruction is encodable by using + //! VEX prefix. Please note that all higher bits from `kX86InstOptionEvex` + //! are reserved for EVEX and forces EVEX encoding to be used implicitly. + kX86InstOptionEvex = 0x00010000, + //! Use zeroing instead of merging (AVX512+). + kX86InstOptionEvexZero = 0x00020000, + //! Broadcast one element to all other elements (AVX512+). + kX86InstOptionEvexOneN = 0x00040000, + //! Suppress all exceptions (AVX512+). + kX86InstOptionEvexSae = 0x00080000, + + //! Static rounding mode `round-to-nearest` (even) and `SAE` (AVX512+). + kX86InstOptionEvexRnSae = 0x00100000, + //! Static rounding mode `round-down` (toward -inf) and `SAE` (AVX512+). + kX86InstOptionEvexRdSae = 0x00200000, + //! Static rounding mode `round-up` (toward +inf) and `SAE` (AVX512+). + kX86InstOptionEvexRuSae = 0x00400000, + //! Static rounding mode `round-toward-zero` (truncate) and `SAE` (AVX512+). + kX86InstOptionEvexRzSae = 0x00800000 +}; + +// ============================================================================ +// [asmjit::kX86InstEncodingId] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction groups. +//! +//! This group is specific to AsmJit and only used by `X86Assembler`. +ASMJIT_ENUM(kX86InstEncodingId) { + //! Never used. + kX86InstEncodingIdNone = 0, + + kX86InstEncodingIdX86Op, + kX86InstEncodingIdX86Op_66H, + kX86InstEncodingIdX86Rm, + kX86InstEncodingIdX86Rm_B, + kX86InstEncodingIdX86RmReg, + kX86InstEncodingIdX86RegRm, + kX86InstEncodingIdX86M, + //! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor. + kX86InstEncodingIdX86Arith, + //! Bswap. + kX86InstEncodingIdX86BSwap, + //! Bt/Btc/Btr/Bts. + kX86InstEncodingIdX86BTest, + //! Call. + kX86InstEncodingIdX86Call, + //! Enter. + kX86InstEncodingIdX86Enter, + //! Imul. + kX86InstEncodingIdX86Imul, + //! Inc/Dec. + kX86InstEncodingIdX86IncDec, + //! Int. + kX86InstEncodingIdX86Int, + //! Jcc. + kX86InstEncodingIdX86Jcc, + //! Jcxz/Jecxz/Jrcxz. + kX86InstEncodingIdX86Jecxz, + //! Jmp. + kX86InstEncodingIdX86Jmp, + //! Lea. + kX86InstEncodingIdX86Lea, + //! Mov. + kX86InstEncodingIdX86Mov, + //! Movsx/Movzx. + kX86InstEncodingIdX86MovSxZx, + //! Movsxd. + kX86InstEncodingIdX86MovSxd, + //! Mov having absolute memory operand (x86/x64). + kX86InstEncodingIdX86MovPtr, + //! Push. + kX86InstEncodingIdX86Push, + //! Pop. + kX86InstEncodingIdX86Pop, + //! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX. + kX86InstEncodingIdX86Rep, + //! Ret. + kX86InstEncodingIdX86Ret, + //! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr. + kX86InstEncodingIdX86Rot, + //! Setcc. + kX86InstEncodingIdX86Set, + //! Shld/Rhrd. + kX86InstEncodingIdX86Shlrd, + //! Test. + kX86InstEncodingIdX86Test, + //! Xadd. + kX86InstEncodingIdX86Xadd, + //! Xchg. + kX86InstEncodingIdX86Xchg, + + //! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1. + kX86InstEncodingIdFpuOp, + //! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr. + kX86InstEncodingIdFpuArith, + //! Fcom/Fcomp. + kX86InstEncodingIdFpuCom, + //! Fld/Fst/Fstp. + kX86InstEncodingIdFpuFldFst, + //! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr. + kX86InstEncodingIdFpuM, + //! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch. + kX86InstEncodingIdFpuR, + //! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp. + kX86InstEncodingIdFpuRDef, + //! Fnstsw/Fstsw. + kX86InstEncodingIdFpuStsw, + + //! Mm/Xmm instruction. + kX86InstEncodingIdExtRm, + //! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register). + kX86InstEncodingIdExtRm_P, + //! Mm/Xmm instruction (propagates REX.W if GPQ is used). + kX86InstEncodingIdExtRm_Q, + //! Mm/Xmm instruction (propagates 66H and REX.W). + kX86InstEncodingIdExtRm_PQ, + //! Mm/Xmm instruction having Rm/Ri encodings. + kX86InstEncodingIdExtRmRi, + //! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register). + kX86InstEncodingIdExtRmRi_P, + //! Mm/Xmm instruction having Rmi encoding. + kX86InstEncodingIdExtRmi, + //! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register). + kX86InstEncodingIdExtRmi_P, + //! Crc32. + kX86InstEncodingIdExtCrc, + //! Pextrb/Pextrw/Pextrd/Pextrq/Extractps. + kX86InstEncodingIdExtExtract, + //! Lfence/Mfence/Sfence. + kX86InstEncodingIdExtFence, + //! Mov Mm/Xmm. + //! + //! 0x66 prefix must be set manually in opcodes. + //! + //! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/X86Mem format, + //! - Secondary opcode is used for instructions in (X)Mm/X86Mem <- (X)Mm format. + kX86InstEncodingIdExtMov, + //! Mov Mm/Xmm. + kX86InstEncodingIdExtMovNoRexW, + //! Movbe. + kX86InstEncodingIdExtMovBe, + //! Movd. + kX86InstEncodingIdExtMovD, + //! Movq. + kX86InstEncodingIdExtMovQ, + //! Prefetch. + kX86InstEncodingIdExtPrefetch, + + //! Extrq (SSE4a). + kX86InstEncodingIdExtExtrq, + //! Insrq (SSE4a). + kX86InstEncodingIdExtInsertq, + + //! 3dNow instruction. + kX86InstEncodingId3dNow, + + //! AVX instruction without operands. + kX86InstEncodingIdAvxOp, + //! AVX instruction encoded as 'M'. + kX86InstEncodingIdAvxM, + //! AVX instruction encoded as 'MR'. + kX86InstEncodingIdAvxMr, + //! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxMr_P, + //! AVX instruction encoded as 'MRI'. + kX86InstEncodingIdAvxMri, + //! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxMri_P, + //! AVX instruction encoded as 'RM'. + kX86InstEncodingIdAvxRm, + //! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRm_P, + //! AVX instruction encoded as 'RMI'. + kX86InstEncodingIdAvxRmi, + //! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRmi_P, + //! AVX instruction encoded as 'RVM'. + kX86InstEncodingIdAvxRvm, + //! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvm_P, + //! AVX instruction encoded as 'RVMR'. + kX86InstEncodingIdAvxRvmr, + //! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvmr_P, + //! AVX instruction encoded as 'RVMI'. + kX86InstEncodingIdAvxRvmi, + //! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvmi_P, + //! AVX instruction encoded as 'RMV'. + kX86InstEncodingIdAvxRmv, + //! AVX instruction encoded as 'RMVI'. + kX86InstEncodingIdAvxRmvi, + //! AVX instruction encoded as 'RM' or 'MR'. + kX86InstEncodingIdAvxRmMr, + //! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRmMr_P, + //! AVX instruction encoded as 'RVM' or 'RMI'. + kX86InstEncodingIdAvxRvmRmi, + //! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvmRmi_P, + //! AVX instruction encoded as 'RVM' or 'MR'. + kX86InstEncodingIdAvxRvmMr, + //! AVX instruction encoded as 'RVM' or 'MVR'. + kX86InstEncodingIdAvxRvmMvr, + //! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvmMvr_P, + //! AVX instruction encoded as 'RVM' or 'VMI'. + kX86InstEncodingIdAvxRvmVmi, + //! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvmVmi_P, + //! AVX instruction encoded as 'VM'. + kX86InstEncodingIdAvxVm, + //! AVX instruction encoded as 'VMI'. + kX86InstEncodingIdAvxVmi, + //! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxVmi_P, + //! AVX instruction encoded as 'RVRM' or 'RVMR'. + kX86InstEncodingIdAvxRvrmRvmr, + //! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdAvxRvrmRvmr_P, + //! Vmovss/Vmovsd. + kX86InstEncodingIdAvxMovSsSd, + //! AVX2 gather family instructions (VSIB). + kX86InstEncodingIdAvxGather, + //! AVX2 gather family instructions (VSIB), differs only in mem operand. + kX86InstEncodingIdAvxGatherEx, + + //! FMA4 instruction in form [R, R, R/M, R/M]. + kX86InstEncodingIdFma4, + //! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used). + kX86InstEncodingIdFma4_P, + + //! XOP instruction encoded as 'RM'. + kX86InstEncodingIdXopRm, + //! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdXopRm_P, + //! XOP instruction encoded as 'RVM' or 'RMV'. + kX86InstEncodingIdXopRvmRmv, + //! XOP instruction encoded as 'RVM' or 'RMI'. + kX86InstEncodingIdXopRvmRmi, + //! XOP instruction encoded as 'RVMR'. + kX86InstEncodingIdXopRvmr, + //! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdXopRvmr_P, + //! XOP instruction encoded as 'RVMI'. + kX86InstEncodingIdXopRvmi, + //! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdXopRvmi_P, + //! XOP instruction encoded as 'RVRM' or 'RVMR'. + kX86InstEncodingIdXopRvrmRvmr, + //! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstEncodingIdXopRvrmRvmr_P, + + //! Count of X86 instruction groups. + _kX86InstEncodingIdCount +}; + +// ============================================================================ +// [asmjit::kX86InstOpCode] +// ============================================================================ + +//! \internal +//! +//! X86/X64 Instruction opcode encoding used by asmjit 'X86InstInfo' table. +//! +//! This schema is AsmJit specific and has been designed to allow encoding of +//! all X86 instructions available. X86, MMX, and SSE+ instructions always use +//! `MMMMM` and `PP` fields, which are encoded to corresponding prefixes needed +//! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields +//! in a VEX prefix. +//! +//! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1 +//! byte is needed by most of the instructions, 2 bytes are only used by legacy +//! X87-FPU instructions. This means that a second byte is free to by used by +//! AVX and AVX-512 instructions. +//! +//! The fields description: +//! +//! - `MMMMM` field is used to encode prefixes needed by the instruction or as +//! a part of VEX/EVEX prefix. +//! +//! - `PP` field is used to encode prefixes needed by the instruction or as a +//! part of VEX/EVEX prefix. +//! +//! - `L` field is used exclusively by AVX+ and AVX512+ instruction sets. It +//! describes vector size, which is 128-bit for Xmm register `L_128`, 256 +//! for Ymm register `L_256` and 512-bit for Zmm register `L_512`. The `L` +//! field is omitted in case that instruction supports multiple vector lengths, +//! however, if the instruction requires specific `L` value it's specified as +//! a part of the opcode. +//! +//! - `W` field is the most complicated. It was added by 64-bit architecture +//! to promote default operation width (instructions that perform 32-bit +//! operation by default require to override the width to 64-bit explicitly). +//! There is nothing wrong on this, however, some instructions introduced +//! implicit `W` override, for example a `cdqe` instruction is basically a +//! `cwde` instructiontion with overridden `W` (set to 1). There are some +//! others in the base X86 instruction set. More recent instruction sets +//! started using `W` field more often: +//! +//! - AVX instructions started using `W` field as an extended opcode for FMA, +//! GATHER, PERM, and other instructions. It also uses `W` field to override +//! the default operation width in instructions like `vmovq`. AVX `W` field +//! is +//! +//! - AVX-512 instructions started using `W` field as an extended opcode for +//! all new instructions. This wouldn't have been an issue if the `W` field +//! of AVX-512 have matched AVX, but this is not the case. +//! +//! - `O` field is an extended opcode field (3) bytes used by ModR/M BYTE. +ASMJIT_ENUM(kX86InstOpCode) { + // `MMMMM` field in AVX/XOP/AVX-512 instruction (5 bits). + // + // `OpCode` leading bytes in legacy encoding. + // + // AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use + // 2 bits and XOP 4 bits. AVX-512 shrinks `MMMMM` field into `MM` so it's + // safe to assume that `MM` field won't grow in the future as EVEX doesn't + // use more than 2 bits. There is always a way how a fifth bit can be stored + // if needed. + kX86InstOpCode_MM_Shift = 16, + kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // AsmJit specific, not part of AVX. + + // `PP` field in AVX/XOP/AVX-512 instruction. + // + // `Mandatory Prefix` in legacy encoding. + // + // AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1 + // more bit that is used to emit 9B prefix for some X87-FPU instructions. + kX86InstOpCode_PP_Shift = 20, + kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // AsmJit specific, not part of AVX. + + // `L` field in AVX/XOP/AVX-512 instruction. + // + // AVX/XOP can only use the first bit `L.128` or `L.256`. AVX-512 makes it + // possible to use also `L.512`. + // + // \note If the instruction set manual describes an instruction by using `LIG` + // it means that the `L` field is ignored. AsmJit emits `0` in such case. + kX86InstOpCode_L_Shift = 23, + kX86InstOpCode_L_Mask = 0x03U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_128 = 0x00U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_256 = 0x01U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_512 = 0x02U << kX86InstOpCode_L_Shift, + + // `O` field (ModR/M). + kX86InstOpCode_O_Shift = 25, + kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift, + + // `W` field used in EVEX instruction encoding. + kX86InstOpCode_EW_Shift = 30, + kX86InstOpCode_EW_Mask = 0x01U << kX86InstOpCode_EW_Shift, + kX86InstOpCode_EW = 0x01U << kX86InstOpCode_EW_Shift, + + // `W` field used in REX/VEX instruction encoding. + // + // \note If the instruction set manual describes an instruction by using `WIG` + // it means that the `W` field is ignored. AsmJit emits `0` in such case. + kX86InstOpCode_W_Shift = 31, + kX86InstOpCode_W_Mask = 0x01U << kX86InstOpCode_W_Shift, + kX86InstOpCode_W = 0x01U << kX86InstOpCode_W_Shift, +}; + +// ============================================================================ +// [asmjit::kX86InstFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction flags. +ASMJIT_ENUM(kX86InstFlags) { + //! No flags. + kX86InstFlagNone = 0x00000000, + + //! Instruction is a control-flow instruction. + //! + //! Control flow instructions are jmp, jcc, call and ret. + kX86InstFlagFlow = 0x00000001, + + //! Instruction is a compare/test like instruction. + kX86InstFlagTest = 0x00000002, + + //! Instruction is a move like instruction. + //! + //! Move instructions typically overwrite the first operand by the second + //! operand. The first operand can be the exact copy of the second operand + //! or it can be any kind of conversion or shuffling. + //! + //! Mov instructions are 'mov', 'movd', 'movq', movdq', 'lea', multimedia + //! instructions like 'cvtdq2pd', shuffle instructions like 'pshufb' and + //! SSE/SSE2 mathematic instructions like 'rcp?', 'round?' and 'rsqrt?'. + //! + //! There are some MOV instructions that do only a partial move (for example + //! 'cvtsi2ss'), register allocator has to know the variable size and use + //! the flag accordingly to it. + kX86InstFlagMove = 0x00000004, + + //! Instruction is an exchange like instruction. + //! + //! Exchange instruction typically overwrite first and second operand. So + //! far only the instructions 'xchg' and 'xadd' are considered. + kX86InstFlagXchg = 0x00000008, + + //! Instruction accesses Fp register(s). + kX86InstFlagFp = 0x00000010, + + //! Instruction can be prefixed by using the LOCK prefix. + kX86InstFlagLock = 0x00000020, + + //! Instruction requires special handling, used by \ref Compiler. + kX86InstFlagSpecial = 0x00000040, + + //! Instruction always performs memory access. + //! + //! This flag is always combined with `kX86InstFlagSpecial` and describes + //! that there is an implicit address which is accessed (usually EDI/RDI or + //! ESI/EDI). + kX86InstFlagSpecialMem = 0x00000080, + + //! Instruction memory operand can refer to 16-bit address (used by FPU). + kX86InstFlagMem2 = 0x00000100, + //! Instruction memory operand can refer to 32-bit address (used by FPU). + kX86InstFlagMem4 = 0x00000200, + //! Instruction memory operand can refer to 64-bit address (used by FPU). + kX86InstFlagMem8 = 0x00000400, + //! Instruction memory operand can refer to 80-bit address (used by FPU). + kX86InstFlagMem10 = 0x00000800, + + //! Zeroes the rest of the register if the source operand is memory. + //! + //! Special behavior related to some SIMD load instructions. + kX86InstFlagZ = 0x00001000, + + //! Instruction is supported by AVX. + kX86InstFlagAvx = 0x00010000, + //! Instruction is supported by XOP. + kX86InstFlagXop = 0x00020000, + + //! Instruction is supported by AVX-512 F (Zmm). + kX86InstFlagAvx512F = 0x00100000, + //! Instruction is supported by AVX-512 CD (Zmm). + kX86InstFlagAvx512CD = 0x00200000, + //! Instruction is supported by AVX-512 PF (Zmm). + kX86InstFlagAvx512PF = 0x00400000, + //! Instruction is supported by AVX-512 ER (Zmm). + kX86InstFlagAvx512ER = 0x00800000, + //! Instruction is supported by AVX-512 DQ (Zmm). + kX86InstFlagAvx512DQ = 0x01000000, + //! Instruction is supported by AVX-512 BW (Zmm). + kX86InstFlagAvx512BW = 0x02000000, + //! Instruction is supported by AVX-512 VL (Xmm/Ymm). + kX86InstFlagAvx512VL = 0x04000000, + + //! Instruction supports masking {k0..k7}. + kX86InstFlagAvx512KMask = 0x08000000, + //! Instruction supports zeroing of elements {k0z..k7z}. + kX86InstFlagAvx512KZero = 0x10000000, + //! Instruction supports broadcast {1toN}. + kX86InstFlagAvx512Broadcast = 0x20000000, + //! Instruction supports suppressing all exceptions {sae}. + kX86InstFlagAvx512Sae = 0x40000000, + //! Instruction supports static rounding control with SAE {rnd-sae}, + kX86InstFlagAvx512Rnd = 0x80000000 +}; + +// ============================================================================ +// [asmjit::kX86InstOp] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction operand flags. +ASMJIT_ENUM(kX86InstOp) { + //! Instruction operand can be 8-bit Gpb register. + kX86InstOpGb = 0x0001, + //! Instruction operand can be 16-bit Gpw register. + kX86InstOpGw = 0x0002, + //! Instruction operand can be 32-bit Gpd register. + kX86InstOpGd = 0x0004, + //! Instruction operand can be 64-bit Gpq register. + kX86InstOpGq = 0x0008, + + //! Instruction operand can be Fp register. + kX86InstOpFp = 0x0010, + //! Instruction operand can be 64-bit Mm register. + kX86InstOpMm = 0x0020, + + //! Instruction operand can be 64-bit K register. + kX86InstOpK = 0x0040, + + //! Instruction operand can be 128-bit Xmm register. + kX86InstOpXmm = 0x0100, + //! Instruction operand can be 256-bit Ymm register. + kX86InstOpYmm = 0x0200, + //! Instruction operand can be 512-bit Zmm register. + kX86InstOpZmm = 0x0400, + + //! Instruction operand can be memory. + kX86InstOpMem = 0x1000, + //! Instruction operand can be immediate. + kX86InstOpImm = 0x2000, + //! Instruction operand can be label. + kX86InstOpLabel = 0x4000, + //! Instruction operand doesn't have to be used. + //! + //! \note If no operand is specified the meaning is clear (the operand at the + //! particular index doesn't exist), however, when one or more operand is + //! specified, it's not clear whether the operand can be omitted or not. When + //! `kX86InstOpNone` is used it means that the operand is not used in some + //! cases. + kX86InstOpNone = 0x8000 +}; + +// ============================================================================ +// [asmjit::kX86Cond] +// ============================================================================ + +//! X86/X64 Condition codes. +ASMJIT_ENUM(kX86Cond) { + kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned) + kX86CondAE = 0x03, // CF==0 (unsigned) + kX86CondB = 0x02, // CF==1 (unsigned) + kX86CondBE = 0x06, // CF==1 | ZF==1 (unsigned) + kX86CondC = 0x02, // CF==1 + kX86CondE = 0x04, // ZF==1 (signed/unsigned) + kX86CondG = 0x0F, // ZF==0 & SF==OF (signed) + kX86CondGE = 0x0D, // SF==OF (signed) + kX86CondL = 0x0C, // SF!=OF (signed) + kX86CondLE = 0x0E, // ZF==1 | SF!=OF (signed) + kX86CondNA = 0x06, // CF==1 | ZF==1 (unsigned) + kX86CondNAE = 0x02, // CF==1 (unsigned) + kX86CondNB = 0x03, // CF==0 (unsigned) + kX86CondNBE = 0x07, // CF==0 & ZF==0 (unsigned) + kX86CondNC = 0x03, // CF==0 + kX86CondNE = 0x05, // ZF==0 (signed/unsigned) + kX86CondNG = 0x0E, // ZF==1 | SF!=OF (signed) + kX86CondNGE = 0x0C, // SF!=OF (signed) + kX86CondNL = 0x0D, // SF==OF (signed) + kX86CondNLE = 0x0F, // ZF==0 & SF==OF (signed) + kX86CondNO = 0x01, // OF==0 + kX86CondNP = 0x0B, // PF==0 + kX86CondNS = 0x09, // SF==0 + kX86CondNZ = 0x05, // ZF==0 + kX86CondO = 0x00, // OF==1 + kX86CondP = 0x0A, // PF==1 + kX86CondPE = 0x0A, // PF==1 + kX86CondPO = 0x0B, // PF==0 + kX86CondS = 0x08, // SF==1 + kX86CondZ = 0x04, // ZF==1 + + // Simplified condition codes. + kX86CondSign = kX86CondS , //!< Sign (S). + kX86CondNotSign = kX86CondNS, //!< Not Sign (NS). + + kX86CondOverflow = kX86CondO , //!< Signed Overflow (O) + kX86CondNotOverflow = kX86CondNO, //!< Not Signed Overflow (NO) + + kX86CondLess = kX86CondL , //!< Signed `a < b` (L or NGE). + kX86CondLessEqual = kX86CondLE, //!< Signed `a <= b` (LE or NG ). + kX86CondGreater = kX86CondG , //!< Signed `a > b` (G or NLE). + kX86CondGreaterEqual = kX86CondGE, //!< Signed `a >= b` (GE or NL ). + kX86CondBelow = kX86CondB , //!< Unsigned `a < b` (B or NAE). + kX86CondBelowEqual = kX86CondBE, //!< Unsigned `a <= b` (BE or NA ). + kX86CondAbove = kX86CondA , //!< Unsigned `a > b` (A or NBE). + kX86CondAboveEqual = kX86CondAE, //!< Unsigned `a >= b` (AE or NB ). + kX86CondEqual = kX86CondE , //!< Equal `a == b` (E or Z ). + kX86CondNotEqual = kX86CondNE, //!< Not Equal `a != b` (NE or NZ ). + + kX86CondParityEven = kX86CondP, + kX86CondParityOdd = kX86CondPO, + + // Aliases. + kX86CondZero = kX86CondZ, + kX86CondNotZero = kX86CondNZ, + kX86CondNegative = kX86CondS, + kX86CondPositive = kX86CondNS, + + // Fpu-only. + kX86CondFpuUnordered = 0x10, + kX86CondFpuNotUnordered = 0x11, + + //! No condition code. + kX86CondNone = 0x12 +}; + +// ============================================================================ +// [asmjit::kX86EFlags] +// ============================================================================ + +//! X86/X64 EFLAGs bits (AsmJit specific). +//! +//! Each instruction stored in AsmJit database contains flags that instruction +//! uses (reads) and flags that instruction modifies (writes). This is used by +//! instruction reordering, but can be used by third parties as it's part of +//! AsmJit API. +//! +//! \note Flags defined here don't correspond to real flags used by X86/X64 +//! architecture, defined in Intel's Manual Section `3.4.3 - EFLAGS Register`. +//! +//! \note Flags are designed to fit in an 8-bit integer. +ASMJIT_ENUM(kX86EFlags) { + // -------------------------------------------------------------------------- + // src-gendefs.js relies on the values of these masks, the tool has to be + // changed as you plan to modify `kX86EFlags`. + // -------------------------------------------------------------------------- + + //! Overflow flag (OF). + //! + //! Set if the integer result is too large a positive number or too small a + //! negative number (excluding the sign-bit) to fit in the destination + //! operand; cleared otherwise. This flag indicates an overflow condition for + //! signed-integer arithmetic. + kX86EFlagO = 0x01, + + //! Sign flag (SF). + //! + //! Set equal to the most-significant bit of the result, which is the sign + //! bit of a signed integer (0 == positive value, 1 == negative value). + kX86EFlagS = 0x02, + + //! Zero flag (ZF). + //! + //! Set if the result is zero; cleared otherwise. + kX86EFlagZ = 0x04, + + //! Adjust flag (AF). + //! + //! Set if an arithmetic operation generates a carry or a borrow out of bit + //! 3 of the result; cleared otherwise. This flag is used in binary-coded + //! decimal (BCD) arithmetic. + kX86EFlagA = 0x08, + + //! Parity flag (PF). + //! + //! Set if the least-significant byte of the result contains an even number + //! of 1 bits; cleared otherwise. + kX86EFlagP = 0x10, + + //! Carry flag (CF). + //! + //! Set if an arithmetic operation generates a carry or a borrow out of the + //! mostsignificant bit of the result; cleared otherwise. + kX86EFlagC = 0x20, + + //! Direction flag (DF). + //! + //! The direction flag controls string instructions `movs`, `cmps`, `scas, + //! `lods` and `stos`. + kX86EFlagD = 0x40, + + //! Any other flag that AsmJit doesn't use to keep track of. + kX86EFlagX = 0x80 +}; + +// ============================================================================ +// [asmjit::kX86FpSw] +// ============================================================================ + +//! X86/X64 FPU status word. +ASMJIT_ENUM(kX86FpSw) { + kX86FpSw_Invalid = 0x0001, + kX86FpSw_Denormalized = 0x0002, + kX86FpSw_DivByZero = 0x0004, + kX86FpSw_Overflow = 0x0008, + kX86FpSw_Underflow = 0x0010, + kX86FpSw_Precision = 0x0020, + kX86FpSw_StackFault = 0x0040, + kX86FpSw_Interrupt = 0x0080, + kX86FpSw_C0 = 0x0100, + kX86FpSw_C1 = 0x0200, + kX86FpSw_C2 = 0x0400, + kX86FpSw_Top = 0x3800, + kX86FpSw_C3 = 0x4000, + kX86FpSw_Busy = 0x8000 +}; + +// ============================================================================ +// [asmjit::kX86FpCw] +// ============================================================================ + +//! X86/X64 FPU control word. +ASMJIT_ENUM(kX86FpCw) { + kX86FpCw_EM_Mask = 0x003F, // Bits 0-5. + kX86FpCw_EM_Invalid = 0x0001, + kX86FpCw_EM_Denormal = 0x0002, + kX86FpCw_EM_DivByZero = 0x0004, + kX86FpCw_EM_Overflow = 0x0008, + kX86FpCw_EM_Underflow = 0x0010, + kX86FpCw_EM_Inexact = 0x0020, + + kX86FpCw_PC_Mask = 0x0300, // Bits 8-9. + kX86FpCw_PC_Float = 0x0000, + kX86FpCw_PC_Reserved = 0x0100, + kX86FpCw_PC_Double = 0x0200, + kX86FpCw_PC_Extended = 0x0300, + + kX86FpCw_RC_Mask = 0x0C00, // Bits 10-11. + kX86FpCw_RC_Nearest = 0x0000, + kX86FpCw_RC_Down = 0x0400, + kX86FpCw_RC_Up = 0x0800, + kX86FpCw_RC_Truncate = 0x0C00, + + kX86FpCw_IC_Mask = 0x1000, // Bit 12. + kX86FpCw_IC_Projective = 0x0000, + kX86FpCw_IC_Affine = 0x1000 +}; + +// ============================================================================ +// [asmjit::kX86Cmp] +// ============================================================================ + +//! X86/X64 Comparison predicate used by CMP[PD/PS/SD/SS] family instructions. +ASMJIT_ENUM(kX86Cmp) { + kX86CmpEQ = 0x00, //!< Equal (Quite). + kX86CmpLT = 0x01, //!< Less (Signaling). + kX86CmpLE = 0x02, //!< Less/Equal (Signaling). + kX86CmpUNORD = 0x03, //!< Unordered (Quite). + kX86CmpNEQ = 0x04, //!< Not Equal (Quite). + kX86CmpNLT = 0x05, //!< Not Less (Signaling). + kX86CmpNLE = 0x06, //!< Not Less/Equal (Signaling). + kX86CmpORD = 0x07 //!< Ordered (Quite). +}; + +// ============================================================================ +// [asmjit::kX86VCmp] +// ============================================================================ + +//! X86/X64 Comparison predicate used by VCMP[PD/PS/SD/SS] family instructions. +//! +//! The first 8 are compatible with \ref kX86Cmp. +ASMJIT_ENUM(kX86VCmp) { + kX86VCmpEQ_OQ = 0x00, //!< Equal (Quite, Ordered). + kX86VCmpLT_OS = 0x01, //!< Less (Signaling, Ordered). + kX86VCmpLE_OS = 0x02, //!< Less/Equal (Signaling, Ordered). + kX86VCmpUNORD_Q = 0x03, //!< Unordered (Quite). + kX86VCmpNEQ_UQ = 0x04, //!< Not Equal (Quite, Unordered). + kX86VCmpNLT_US = 0x05, //!< Not Less (Signaling, Unordered). + kX86VCmpNLE_US = 0x06, //!< Not Less/Equal (Signaling, Unordered). + kX86VCmpORD_Q = 0x07, //!< Ordered (Quite). + + kX86VCmpEQ_UQ = 0x08, //!< Equal (Quite, Unordered). + kX86VCmpNGE_US = 0x09, //!< Not Greater/Equal (Signaling, Unordered). + kX86VCmpNGT_US = 0x0A, //!< Not Greater (Signaling, Unordered). + kX86VCmpFALSE_OQ = 0x0B, //!< False (Quite, Ordered). + kX86VCmpNEQ_OQ = 0x0C, //!< Not Equal (Quite, Ordered). + kX86VCmpGE_OS = 0x0D, //!< Greater/Equal (Signaling, Ordered). + kX86VCmpGT_OS = 0x0E, //!< Greater (Signaling, Ordered). + kX86VCmpTRUE_UQ = 0x0F, //!< True (Quite, Unordered). + kX86VCmpEQ_OS = 0x10, //!< Equal (Signaling, Ordered). + kX86VCmpLT_OQ = 0x11, //!< Less (Quite, Ordered). + kX86VCmpLE_OQ = 0x12, //!< Less/Equal (Quite, Ordered). + kX86VCmpUNORD_S = 0x13, //!< Unordered (Signaling). + kX86VCmpNEQ_US = 0x14, //!< Not Equal (Signaling, Unordered). + kX86VCmpNLT_UQ = 0x15, //!< Not Less (Quite, Unordered). + kX86VCmpNLE_UQ = 0x16, //!< Not Less/Equal (Quite, Unordered). + kX86VCmpORD_S = 0x17, //!< Ordered (Signaling). + kX86VCmpEQ_US = 0x18, //!< Equal (Signaling, Unordered). + kX86VCmpNGE_UQ = 0x19, //!< Not Greater/Equal (Quite, Unordered). + kX86VCmpNGT_UQ = 0x1A, //!< Not Greater (Quite, Unordered). + kX86VCmpFALSE_OS = 0x1B, //!< False (Signaling, Ordered). + kX86VCmpNEQ_OS = 0x1C, //!< Not Equal (Signaling, Ordered). + kX86VCmpGE_OQ = 0x1D, //!< Greater/Equal (Quite, Ordered). + kX86VCmpGT_OQ = 0x1E, //!< Greater (Quite, Ordered). + kX86VCmpTRUE_US = 0x1F //!< True (Signaling, Unordered). +}; + +// ============================================================================ +// [asmjit::kX86Prefetch] +// ============================================================================ + +//! X86/X64 Prefetch hints. +ASMJIT_ENUM(kX86Prefetch) { + //! Prefetch using NT hint. + kX86PrefetchNTA = 0, + //! Prefetch to L0 cache. + kX86PrefetchT0 = 1, + //! Prefetch to L1 cache. + kX86PrefetchT1 = 2, + //! Prefetch to L2 cache. + kX86PrefetchT2 = 3 +}; + +// ============================================================================ +// [asmjit::X86InstExtendedInfo] +// ============================================================================ + +//! X86/X64 instruction extended information. +//! +//! Extended information has been introduced to minimize data needed for a +//! single instruction, because two or more instructions can share the common +//! data, for example operands definition or secondary opcode, which is only +//! used by few instructions. +struct X86InstExtendedInfo { + // -------------------------------------------------------------------------- + // [Accessors - Instruction Encoding] + // -------------------------------------------------------------------------- + + //! Get instruction encoding, see \ref kX86InstEncoding. + ASMJIT_INLINE uint32_t getEncodingId() const { + return _encodingId; + } + + // -------------------------------------------------------------------------- + // [Accessors - Instruction Flags] + // -------------------------------------------------------------------------- + + //! Get whether the instruction has a `flag`, see `kX86InstFlags`. + ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { + return (_instFlags & flag) != 0; + } + + //! Get all instruction flags, see `kX86InstFlags`. + ASMJIT_INLINE uint32_t getInstFlags() const { + return _instFlags; + } + + //! Get whether the instruction is a control-flow intruction. + //! + //! Control flow instruction is instruction that can perform a branch, + //! typically `jmp`, `jcc`, `call`, or `ret`. + ASMJIT_INLINE bool isFlow() const { + return (getInstFlags() & kX86InstFlagFlow) != 0; + } + + //! Get whether the instruction is a compare/test like intruction. + ASMJIT_INLINE bool isTest() const { + return (getInstFlags() & kX86InstFlagTest) != 0; + } + + //! Get whether the instruction is a typical move instruction. + //! + //! Move instructions overwrite the first operand or at least part of it, + //! This is a very useful hint that is used by variable liveness analysis + //! and `Compiler` in general to know which variable is completely + //! overwritten. + //! + //! All AVX/XOP instructions that have 3 or more operands are considered to + //! have move semantics move by default. + ASMJIT_INLINE bool isMove() const { + return (getInstFlags() & kX86InstFlagMove) != 0; + } + + //! Get whether the instruction is a typical Exchange instruction. + //! + //! Exchange instructios are 'xchg' and 'xadd'. + ASMJIT_INLINE bool isXchg() const { + return (getInstFlags() & kX86InstFlagXchg) != 0; + } + + //! Get whether the instruction accesses Fp register(s). + ASMJIT_INLINE bool isFp() const { + return (getInstFlags() & kX86InstFlagFp) != 0; + } + + //! Get whether the instruction can be prefixed by LOCK prefix. + ASMJIT_INLINE bool isLockable() const { + return (getInstFlags() & kX86InstFlagLock) != 0; + } + + //! Get whether the instruction is special type (this is used by `Compiler` + //! to manage additional variables or functionality). + ASMJIT_INLINE bool isSpecial() const { + return (getInstFlags() & kX86InstFlagSpecial) != 0; + } + + //! Get whether the instruction is special type and it performs memory access. + ASMJIT_INLINE bool isSpecialMem() const { + return (getInstFlags() & kX86InstFlagSpecialMem) != 0; + } + + //! Get whether the move instruction zeroes the rest of the register + //! if the source is memory operand. + //! + //! Basically flag needed only to support `movsd` and `movss` instructions. + ASMJIT_INLINE bool isZeroIfMem() const { + return (getInstFlags() & kX86InstFlagZ) != 0; + } + + // -------------------------------------------------------------------------- + // [Accessors - EFlags] + // -------------------------------------------------------------------------- + + //! Get EFLAGS that the instruction reads, see \ref kX86EFlags. + ASMJIT_INLINE uint32_t getEFlagsIn() const { + return _eflagsIn; + } + + //! Get EFLAGS that the instruction writes, see \ref kX86EFlags. + ASMJIT_INLINE uint32_t getEFlagsOut() const { + return _eflagsOut; + } + + // -------------------------------------------------------------------------- + // [Accessors - Write Index/Size] + // -------------------------------------------------------------------------- + + //! Get the destination index of WRITE operation. + ASMJIT_INLINE uint32_t getWriteIndex() const { + return _writeIndex; + } + + //! Get the number of bytes that will be written by a WRITE operation. + ASMJIT_INLINE uint32_t getWriteSize() const { + return _writeSize; + } + + // -------------------------------------------------------------------------- + // [Accessors - Operand-Flags] + // -------------------------------------------------------------------------- + + //! Get flags of operand at index `index`. + //! + //! See \ref X86InstInfo::getOperandFlags() for more details. + ASMJIT_INLINE uint16_t getOperandFlags(uint32_t index) const { + ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_opFlags)); + return _opFlags[index]; + } + + // -------------------------------------------------------------------------- + // [Accessors - OpCode] + // -------------------------------------------------------------------------- + + //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + //! + //! See \ref X86InstInfo::getSecondaryOpCode() for more details. + ASMJIT_INLINE uint32_t getSecondaryOpCode() const { + return _secondaryOpCode; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Instruction encoding ID. + uint8_t _encodingId; + + //! Destination index of WRITE operation, default 0. + uint8_t _writeIndex; + + //! Count of bytes affected by a write operation, needed by analysis for all + //! instructions that do not read the register overwritten. Only used with + //! `kX86InstFlagMove` flag. If `_writeSize` is zero it is automatically + //! deduced from the size of the destination register. + //! + //! In general most of SSE write-only instructions should use 16 bytes as + //! this is the size of the register (and of Ymm/Zmm registers). This means + //! that 16-bytes of the register are changed, the rest remains unchanged. + //! However, AVX instructions should use the size of Zmm register as every + //! AVX instruction zeroes the rest of the register (AVX/AVX2 instructions + //! zero the HI part of Zmm if available). + uint8_t _writeSize; + + //! EFlags read by the instruction. + uint8_t _eflagsIn; + //! EFlags written by the instruction. + uint8_t _eflagsOut; + + //! \internal + uint8_t _reserved; + + //! Operands' flags, up to 5 operands. + uint16_t _opFlags[5]; + + //! Instruction flags. + uint32_t _instFlags; + + //! Secondary opcode. + uint32_t _secondaryOpCode; +}; + +// ============================================================================ +// [asmjit::X86InstInfo] +// ============================================================================ + +//! X86/X64 instruction information. +struct X86InstInfo { + // -------------------------------------------------------------------------- + // [Accessors - Instruction Name] + // -------------------------------------------------------------------------- + +#if !defined(ASMJIT_DISABLE_NAMES) + //! Get instruction name string (null terminated). + ASMJIT_INLINE const char* getInstName() const { + return _x86InstName + static_cast(_nameIndex); + } + + //! Get instruction name index to `_x86InstName` array. + ASMJIT_INLINE uint32_t _getNameIndex() const { + return _nameIndex; + } +#endif // !ASMJIT_DISABLE_NAMES + + // -------------------------------------------------------------------------- + // [Accessors - Extended-Info] + // -------------------------------------------------------------------------- + + //! Get `X86InstExtendedInfo` for this instruction. + ASMJIT_INLINE const X86InstExtendedInfo& getExtendedInfo() const { + return _x86InstExtendedInfo[_extendedIndex]; + } + + //! Get index to the `_x86InstExtendedInfo` table. + ASMJIT_INLINE uint32_t _getExtendedIndex() const { + return _extendedIndex; + } + + // -------------------------------------------------------------------------- + // [Accessors - Instruction Encoding] + // -------------------------------------------------------------------------- + + //! Get instruction group, see \ref kX86InstEncodingId. + ASMJIT_INLINE uint32_t getEncodingId() const { + return getExtendedInfo().getEncodingId(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Instruction Flags] + // -------------------------------------------------------------------------- + + //! Get instruction flags, see `kX86InstFlags`. + ASMJIT_INLINE uint32_t getInstFlags() const { + return getExtendedInfo().getInstFlags(); + } + + //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { + return (getInstFlags() & flag) != 0; + } + + // -------------------------------------------------------------------------- + // [Accessors - EFlags] + // -------------------------------------------------------------------------- + + //! Get EFLAGS that the instruction reads, see \ref kX86EFlags. + ASMJIT_INLINE uint32_t getEFlagsIn() const { + return getExtendedInfo().getEFlagsIn(); + } + + //! Get EFLAGS that the instruction writes, see \ref kX86EFlags. + ASMJIT_INLINE uint32_t getEFlagsOut() const { + return getExtendedInfo().getEFlagsOut(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Write Index/Size] + // -------------------------------------------------------------------------- + + //! Get the destination index of WRITE operation. + ASMJIT_INLINE uint32_t getWriteIndex() const { + return getExtendedInfo().getWriteIndex(); + } + + //! Get the number of bytes that will be written by a WRITE operation. + ASMJIT_INLINE uint32_t getWriteSize() const { + return getExtendedInfo().getWriteSize(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Operand-Flags] + // -------------------------------------------------------------------------- + + //! Get flags of operand at index `index`. + ASMJIT_INLINE uint32_t getOperandFlags(uint32_t index) const { + return getExtendedInfo().getOperandFlags(index); + } + + // -------------------------------------------------------------------------- + // [Accessors - OpCode] + // -------------------------------------------------------------------------- + + //! Get the primary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getPrimaryOpCode() const { + return _primaryOpCode; + } + + //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getSecondaryOpCode() const { + return getExtendedInfo().getSecondaryOpCode(); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Instruction name index in `_x86InstName[]` array. + uint16_t _nameIndex; + //! Extended information name index in `_x86InstExtendedInfo[]` array. + uint16_t _extendedIndex; + + //! Primary opcode, secondary opcode is stored in `X86InstExtendedInfo` table. + uint32_t _primaryOpCode; +}; + +// ============================================================================ +// [asmjit::X86Util] +// ============================================================================ + +struct X86Util { + // -------------------------------------------------------------------------- + // [Instruction Info] + // -------------------------------------------------------------------------- + + //! Get instruction information based on `instId`. + //! + //! \note `instId` has to be valid instruction ID, it can't be greater than + //! or equal to `_kX86InstIdCount`. It asserts in debug mode. + static ASMJIT_INLINE const X86InstInfo& getInstInfo(uint32_t instId) { + ASMJIT_ASSERT(instId < _kX86InstIdCount); + return _x86InstInfo[instId]; + } + +#if !defined(ASMJIT_DISABLE_NAMES) + //! Get an instruction ID from a given instruction `name`. + //! + //! If there is an exact match the instruction id is returned, otherwise + //! `kInstIdNone` (zero) is returned. + //! + //! The given `name` doesn't have to be null-terminated if `len` is provided. + ASMJIT_API static uint32_t getInstIdByName( + const char* name, size_t len = kInvalidIndex); +#endif // !ASMJIT_DISABLE_NAMES + + // -------------------------------------------------------------------------- + // [Condition Codes] + // -------------------------------------------------------------------------- + + //! Corresponds to transposing the operands of a comparison. + static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) { + ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond)); + return _x86ReverseCond[cond]; + } + + //! Get the equivalent of negated condition code. + static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) { + ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond)); + return static_cast(cond ^ static_cast(cond < kX86CondNone)); + } + + //! Translate condition code `cc` to `cmovcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdCmovcc. + static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToCmovcc)); + return _x86CondToCmovcc[cond]; + } + + //! Translate condition code `cc` to `jcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdJcc. + static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToJcc)); + return _x86CondToJcc[cond]; + } + + //! Translate condition code `cc` to `setcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdSetcc. + static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToSetcc)); + return _x86CondToSetcc[cond]; + } + + // -------------------------------------------------------------------------- + // [MmShuffle] + // -------------------------------------------------------------------------- + + //! Pack a shuffle constant to be used with multimedia instrutions (2 values). + //! + //! \param x First component position, number at interval [0, 1] inclusive. + //! \param y Second component position, number at interval [0, 1] inclusive. + //! + //! Shuffle constants can be used to make immediate value for these intrinsics: + //! - `X86Assembler::shufpd()` and `X86Compiler::shufpd()` + static ASMJIT_INLINE int mmShuffle(uint32_t x, uint32_t y) { + return static_cast((x << 1) | y); + } + + //! Pack a shuffle constant to be used with multimedia instrutions (4 values). + //! + //! \param z First component position, number at interval [0, 3] inclusive. + //! \param x Second component position, number at interval [0, 3] inclusive. + //! \param y Third component position, number at interval [0, 3] inclusive. + //! \param w Fourth component position, number at interval [0, 3] inclusive. + //! + //! Shuffle constants can be used to make immediate value for these intrinsics: + //! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()` + //! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()` + //! - `X86Assembler::pshufhw()` and `X86Compiler::pshufhw()` + //! - `X86Assembler::pshuflw()` and `X86Compiler::pshuflw()` + //! - `X86Assembler::shufps()` and `X86Compiler::shufps()` + static ASMJIT_INLINE int mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) { + return static_cast((z << 6) | (y << 4) | (x << 2) | w); + } +}; + +//! \} + +} // asmjit namespace + +#undef _OP_ID + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86INST_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86operand.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86operand.h new file mode 100644 index 0000000..9d9cedc --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86operand.h @@ -0,0 +1,1974 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86OPERAND_H +#define _ASMJIT_X86_X86OPERAND_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/compiler.h" +#include "../base/globals.h" +#include "../base/intutil.h" +#include "../base/operand.h" +#include "../base/vectypes.h" + +// [Api-Begin] +#include "../apibegin.h" + +//! \internal +//! +//! Internal macro to get an operand ID casting it to `Operand`. Basically +//! allows to get an id of operand that has been just 'typedef'ed. +#define ASMJIT_OP_ID(_Op_) reinterpret_cast(_Op_).getId() + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86Reg; +struct X86RipReg; +struct X86SegReg; +struct X86GpReg; +struct X86FpReg; +struct X86MmReg; +struct X86KReg; +struct X86XmmReg; +struct X86YmmReg; +struct X86ZmmReg; + +#if !defined(ASMJIT_DISABLE_COMPILER) +struct X86Var; +struct X86GpVar; +struct X86MmVar; +struct X86KVar; +struct X86XmmVar; +struct X86YmmVar; +struct X86ZmmVar; +#endif // !ASMJIT_DISABLE_COMPILER + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::kX86RegClass] +// ============================================================================ + +//! X86/X64 variable class. +ASMJIT_ENUM(kX86RegClass) { + // -------------------------------------------------------------------------- + // [Regs & Vars] + // -------------------------------------------------------------------------- + + //! X86/X64 Gp register class (compatible with universal \ref kRegClassGp). + kX86RegClassGp = kRegClassGp, + //! X86/X64 Mm register class. + kX86RegClassMm = 1, + //! X86/X64 K register class. + kX86RegClassK = 2, + //! X86/X64 Xmm/Ymm/Zmm register class. + kX86RegClassXyz = 3, + + //! \internal + //! + //! Last register class that is managed by `X86Compiler`, used by asserts. + _kX86RegClassManagedCount = 4, + + // -------------------------------------------------------------------------- + // [Regs Only] + // -------------------------------------------------------------------------- + + //! X86/X64 Fp register class. + kX86RegClassFp = 4, + + //! Count of X86/X64 register classes. + kX86RegClassCount = 5 +}; + +// ============================================================================ +// [asmjit::kX86RegType] +// ============================================================================ + +//! X86/X64 register type. +ASMJIT_ENUM(kX86RegType) { + //! Gpb-lo register (AL, BL, CL, DL, ...). + kX86RegTypeGpbLo = 0x01, + //! Gpb-hi register (AH, BH, CH, DH only). + kX86RegTypeGpbHi = 0x02, + + //! \internal + //! + //! Gpb-hi register patched to native index (4-7). + _kX86RegTypePatchedGpbHi = kX86RegTypeGpbLo | kX86RegTypeGpbHi, + + //! Gpw register. + kX86RegTypeGpw = 0x10, + //! Gpd register. + kX86RegTypeGpd = 0x20, + //! Gpq register (X64). + kX86RegTypeGpq = 0x30, + + //! Fp register. + kX86RegTypeFp = 0x40, + //! Mm register (MMX+). + kX86RegTypeMm = 0x50, + + //! K register (AVX512+). + kX86RegTypeK = 0x60, + + //! Xmm register (SSE+). + kX86RegTypeXmm = 0x70, + //! Ymm register (AVX+). + kX86RegTypeYmm = 0x80, + //! Zmm register (AVX512+). + kX86RegTypeZmm = 0x90, + + //! Instruction pointer (RIP). + kX86RegTypeRip = 0xE0, + //! Segment register. + kX86RegTypeSeg = 0xF0 +}; + +// ============================================================================ +// [asmjit::kX86RegIndex] +// ============================================================================ + +//! X86/X64 register indexes. +//! +//! \note Register indexes have been reduced to only support general purpose +//! registers. There is no need to have enumerations with number suffix that +//! expands to the exactly same value as the suffix value itself. +ASMJIT_ENUM(kX86RegIndex) { + //! Index of Al/Ah/Ax/Eax/Rax registers. + kX86RegIndexAx = 0, + //! Index of Cl/Ch/Cx/Ecx/Rcx registers. + kX86RegIndexCx = 1, + //! Index of Dl/Dh/Dx/Edx/Rdx registers. + kX86RegIndexDx = 2, + //! Index of Bl/Bh/Bx/Ebx/Rbx registers. + kX86RegIndexBx = 3, + //! Index of Spl/Sp/Esp/Rsp registers. + kX86RegIndexSp = 4, + //! Index of Bpl/Bp/Ebp/Rbp registers. + kX86RegIndexBp = 5, + //! Index of Sil/Si/Esi/Rsi registers. + kX86RegIndexSi = 6, + //! Index of Dil/Di/Edi/Rdi registers. + kX86RegIndexDi = 7, + //! Index of R8b/R8w/R8d/R8 registers (64-bit only). + kX86RegIndexR8 = 8, + //! Index of R9B/R9w/R9d/R9 registers (64-bit only). + kX86RegIndexR9 = 9, + //! Index of R10B/R10w/R10D/R10 registers (64-bit only). + kX86RegIndexR10 = 10, + //! Index of R11B/R11w/R11d/R11 registers (64-bit only). + kX86RegIndexR11 = 11, + //! Index of R12B/R12w/R12d/R12 registers (64-bit only). + kX86RegIndexR12 = 12, + //! Index of R13B/R13w/R13d/R13 registers (64-bit only). + kX86RegIndexR13 = 13, + //! Index of R14B/R14w/R14d/R14 registers (64-bit only). + kX86RegIndexR14 = 14, + //! Index of R15B/R15w/R15d/R15 registers (64-bit only). + kX86RegIndexR15 = 15 +}; + +// ============================================================================ +// [asmjit::kX86Seg] +// ============================================================================ + +//! X86/X64 segment codes. +ASMJIT_ENUM(kX86Seg) { + //! No/Default segment. + kX86SegDefault = 0, + //! Es segment. + kX86SegEs = 1, + //! Cs segment. + kX86SegCs = 2, + //! Ss segment. + kX86SegSs = 3, + //! Ds segment. + kX86SegDs = 4, + //! Fs segment. + kX86SegFs = 5, + //! Gs segment. + kX86SegGs = 6, + + //! Count of X86 segment registers supported by AsmJit. + //! + //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS. + //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7 + //! segment registers - all addressable in both X86 and X64 modes and one + //! extra called `kX86SegDefault`, which is AsmJit specific and means that there + //! is no segment register specified so the segment prefix will not be emitted. + kX86SegCount = 7 +}; + +// ============================================================================ +// [asmjit::kX86MemVSib] +// ============================================================================ + +//! X86/X64 index register legacy and AVX2 (VSIB) support. +ASMJIT_ENUM(kX86MemVSib) { + //! Memory operand uses Gpd/Gpq index (or no index register). + kX86MemVSibGpz = 0, + //! Memory operand uses Xmm index (or no index register). + kX86MemVSibXmm = 1, + //! Memory operand uses Ymm index (or no index register). + kX86MemVSibYmm = 2, + //! Memory operand uses Zmm index (or no index register). + kX86MemVSibZmm = 3 +}; + +// ============================================================================ +// [asmjit::kX86MemFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 specific memory flags. +ASMJIT_ENUM(kX86MemFlags) { + kX86MemSegBits = 0x7, + kX86MemSegIndex = 0, + kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex, + + kX86MemGpdBits = 0x1, + kX86MemGpdIndex = 3, + kX86MemGpdMask = kX86MemGpdBits << kX86MemGpdIndex, + + kX86MemVSibBits = 0x3, + kX86MemVSibIndex = 4, + kX86MemVSibMask = kX86MemVSibBits << kX86MemVSibIndex, + + kX86MemShiftBits = 0x3, + kX86MemShiftIndex = 6, + kX86MemShiftMask = kX86MemShiftBits << kX86MemShiftIndex +}; + +// This is only defined by `x86operand_regs.cpp` when exporting registers. +#if defined(ASMJIT_EXPORTS_X86OPERAND_REGS) + +// Remap all classes to POD structs so they can be statically initialized +// without calling a constructor. Compiler will store these in .DATA section. +struct X86RipReg { Operand::VRegOp data; }; +struct X86SegReg { Operand::VRegOp data; }; +struct X86GpReg { Operand::VRegOp data; }; +struct X86FpReg { Operand::VRegOp data; }; +struct X86KReg { Operand::VRegOp data; }; +struct X86MmReg { Operand::VRegOp data; }; +struct X86XmmReg { Operand::VRegOp data; }; +struct X86YmmReg { Operand::VRegOp data; }; +struct X86ZmmReg { Operand::VRegOp data; }; + +#else + +// ============================================================================ +// [asmjit::X86RegCount] +// ============================================================================ + +//! \internal +//! +//! X86/X64 registers count (Gp, Mm, K, Xmm/Ymm/Zmm). +//! +//! Since the number of registers changed across CPU generations `X86RegCount` +//! class is used by `X86Assembler` and `X86Compiler` to provide a way to get +//! number of available registers dynamically. 32-bit mode offers always only +//! 8 registers of all classes, however, 64-bit mode offers 16 Gp registers and +//! 16 Xmm/Ymm/Zmm registers. AVX512 instruction set doubles the number of SIMD +//! registers (Xmm/Ymm/Zmm) to 32, this mode has to be explicitly enabled to +//! take effect as it changes some assumptions. +//! +//! `X86RegCount` is also used extensively by `X86Compiler`'s register allocator +//! and data structures. Fp registers were omitted as they are never mapped to +//! variables, thus, not needed to be managed. +//! +//! \note At the moment `X86RegCount` can fit into 32-bits, having 8-bits for +//! all register classes (except Fp). This can change in the future after a +//! new instruction set is announced. +struct X86RegCount { + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + //! Reset all counters to zero. + ASMJIT_INLINE void reset() { + _packed = 0; + } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + //! Get register count by `classId`. + ASMJIT_INLINE uint32_t get(uint32_t classId) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + return _regs[classId]; + } + + //! Get Gp register count. + ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; } + //! Get Mm register count. + ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; } + //! Get K register count. + ASMJIT_INLINE uint32_t getK() const { return _regs[kX86RegClassK]; } + //! Get Xmm/Ymm/Zmm register count. + ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + //! Set register count by `classId`. + ASMJIT_INLINE void set(uint32_t classId, uint32_t n) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + ASMJIT_ASSERT(n <= 0xFF); + + _regs[classId] = static_cast(n); + } + + //! Set Gp register count. + ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); } + //! Set Mm register count. + ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); } + //! Set K register count. + ASMJIT_INLINE void setK(uint32_t n) { set(kX86RegClassK, n); } + //! Set Xmm/Ymm/Zmm register count. + ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + //! Add register count by `classId`. + ASMJIT_INLINE void add(uint32_t classId, uint32_t n = 1) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + ASMJIT_ASSERT(0xFF - static_cast(_regs[classId]) >= n); + + _regs[classId] += static_cast(n); + } + + //! Add Gp register count. + ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); } + //! Add Mm register count. + ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); } + //! Add K register count. + ASMJIT_INLINE void addK(uint32_t n) { add(kX86RegClassK, n); } + //! Add Xmm/Ymm/Zmm register count. + ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Misc] + // -------------------------------------------------------------------------- + + //! Build a register indexes, based on register's `count`. + //! + //! Register index is used by \ref `X86Compiler` in per-instruction register + //! data. Indexes are sorted by register class in Gp, Mm, K, and Xmm/Ymm/Zmm + //! order. + ASMJIT_INLINE void indexFromRegCount(const X86RegCount& count) { + uint32_t x = count._regs[0]; + uint32_t y; + + _regs[0] = static_cast(0); + _regs[1] = static_cast(x); + + x = x + count._regs[1]; + y = x + count._regs[2]; + + ASMJIT_ASSERT(x <= 0xFF); + ASMJIT_ASSERT(y <= 0xFF); + + _regs[2] = static_cast(x); + _regs[3] = static_cast(y); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Count of Gp registers. + uint8_t _gp; + //! Count of Mm registers. + uint8_t _mm; + //! Count of K registers. + uint8_t _k; + //! Count of Xmm/Ymm/Zmm registers. + uint8_t _xyz; + //! \internal + uint8_t _reserved[3]; + }; + + uint8_t _regs[4]; + uint32_t _packed; + }; +}; + +// ============================================================================ +// [asmjit::X86RegMask] +// ============================================================================ + +//! \internal +//! +//! X86/X64 registers mask (Gp, Mm, K, Xmm/Ymm/Zmm). +struct X86RegMask { + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset all register masks to zero. + ASMJIT_INLINE void reset() { + _packed.reset(); + } + + // -------------------------------------------------------------------------- + // [IsEmpty / Has] + // -------------------------------------------------------------------------- + + //! Get whether all register masks are zero (empty). + ASMJIT_INLINE bool isEmpty() const { + return _packed.isZero(); + } + + ASMJIT_INLINE bool has(uint32_t classId, uint32_t mask = 0xFFFFFFFF) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : return (static_cast(_gp ) & mask) != 0; + case kX86RegClassMm : return (static_cast(_mm ) & mask) != 0; + case kX86RegClassK : return (static_cast(_k ) & mask) != 0; + case kX86RegClassXyz: return (static_cast(_xyz) & mask) != 0; + } + + return false; + } + + ASMJIT_INLINE bool hasGp(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassGp, mask); } + ASMJIT_INLINE bool hasMm(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassMm, mask); } + ASMJIT_INLINE bool hasK(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassK, mask); } + ASMJIT_INLINE bool hasXyz(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t get(uint32_t classId) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : return _gp; + case kX86RegClassMm : return _mm; + case kX86RegClassK : return _k; + case kX86RegClassXyz: return _xyz; + } + + return 0; + } + + ASMJIT_INLINE uint32_t getGp() const { return get(kX86RegClassGp); } + ASMJIT_INLINE uint32_t getMm() const { return get(kX86RegClassMm); } + ASMJIT_INLINE uint32_t getK() const { return get(kX86RegClassK); } + ASMJIT_INLINE uint32_t getXyz() const { return get(kX86RegClassXyz); } + + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void zero(uint32_t classId) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp = 0; break; + case kX86RegClassMm : _mm = 0; break; + case kX86RegClassK : _k = 0; break; + case kX86RegClassXyz: _xyz = 0; break; + } + } + + ASMJIT_INLINE void zeroGp() { zero(kX86RegClassGp); } + ASMJIT_INLINE void zeroMm() { zero(kX86RegClassMm); } + ASMJIT_INLINE void zeroK() { zero(kX86RegClassK); } + ASMJIT_INLINE void zeroXyz() { zero(kX86RegClassXyz); } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void set(const X86RegMask& other) { + _packed = other._packed; + } + + ASMJIT_INLINE void set(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp = static_cast(mask); break; + case kX86RegClassMm : _mm = static_cast(mask); break; + case kX86RegClassK : _k = static_cast(mask); break; + case kX86RegClassXyz: _xyz = static_cast(mask); break; + } + } + + ASMJIT_INLINE void setGp(uint32_t mask) { return set(kX86RegClassGp, mask); } + ASMJIT_INLINE void setMm(uint32_t mask) { return set(kX86RegClassMm, mask); } + ASMJIT_INLINE void setK(uint32_t mask) { return set(kX86RegClassK, mask); } + ASMJIT_INLINE void setXyz(uint32_t mask) { return set(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [And] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void and_(const X86RegMask& other) { + _packed.and_(other._packed); + } + + ASMJIT_INLINE void and_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp &= static_cast(mask); break; + case kX86RegClassMm : _mm &= static_cast(mask); break; + case kX86RegClassK : _k &= static_cast(mask); break; + case kX86RegClassXyz: _xyz &= static_cast(mask); break; + } + } + + ASMJIT_INLINE void andGp(uint32_t mask) { and_(kX86RegClassGp, mask); } + ASMJIT_INLINE void andMm(uint32_t mask) { and_(kX86RegClassMm, mask); } + ASMJIT_INLINE void andK(uint32_t mask) { and_(kX86RegClassK, mask); } + ASMJIT_INLINE void andXyz(uint32_t mask) { and_(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [AndNot] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void andNot(const X86RegMask& other) { + _packed.andNot(other._packed); + } + + ASMJIT_INLINE void andNot(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp &= ~static_cast(mask); break; + case kX86RegClassMm : _mm &= ~static_cast(mask); break; + case kX86RegClassK : _k &= ~static_cast(mask); break; + case kX86RegClassXyz: _xyz &= ~static_cast(mask); break; + } + } + + ASMJIT_INLINE void andNotGp(uint32_t mask) { andNot(kX86RegClassGp, mask); } + ASMJIT_INLINE void andNotMm(uint32_t mask) { andNot(kX86RegClassMm, mask); } + ASMJIT_INLINE void andNotK(uint32_t mask) { andNot(kX86RegClassK, mask); } + ASMJIT_INLINE void andNotXyz(uint32_t mask) { andNot(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [Or] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void or_(const X86RegMask& other) { + _packed.or_(other._packed); + } + + ASMJIT_INLINE void or_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + switch (classId) { + case kX86RegClassGp : _gp |= static_cast(mask); break; + case kX86RegClassMm : _mm |= static_cast(mask); break; + case kX86RegClassK : _k |= static_cast(mask); break; + case kX86RegClassXyz: _xyz |= static_cast(mask); break; + } + } + + ASMJIT_INLINE void orGp(uint32_t mask) { return or_(kX86RegClassGp, mask); } + ASMJIT_INLINE void orMm(uint32_t mask) { return or_(kX86RegClassMm, mask); } + ASMJIT_INLINE void orK(uint32_t mask) { return or_(kX86RegClassK, mask); } + ASMJIT_INLINE void orXyz(uint32_t mask) { return or_(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [Xor] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void xor_(const X86RegMask& other) { + _packed.xor_(other._packed); + } + + ASMJIT_INLINE void xor_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp ^= static_cast(mask); break; + case kX86RegClassMm : _mm ^= static_cast(mask); break; + case kX86RegClassK : _k ^= static_cast(mask); break; + case kX86RegClassXyz: _xyz ^= static_cast(mask); break; + } + } + + ASMJIT_INLINE void xorGp(uint32_t mask) { xor_(kX86RegClassGp, mask); } + ASMJIT_INLINE void xorMm(uint32_t mask) { xor_(kX86RegClassMm, mask); } + ASMJIT_INLINE void xorK(uint32_t mask) { xor_(kX86RegClassK, mask); } + ASMJIT_INLINE void xorXyz(uint32_t mask) { xor_(kX86RegClassXyz, mask); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Gp registers mask (16 bits). + uint16_t _gp; + //! Mm registers mask (8 bits). + uint8_t _mm; + //! K registers mask (8 bits). + uint8_t _k; + //! Xmm/Ymm/Zmm registers mask (32 bits). + uint32_t _xyz; + }; + + //! Packed masks. + UInt64 _packed; + }; +}; + +// ============================================================================ +// [asmjit::X86Reg] +// ============================================================================ + +//! X86/X86 register base class. +struct X86Reg : public Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy X86 register. + ASMJIT_INLINE X86Reg() : Reg() {} + //! Create a reference to `other` X86 register. + ASMJIT_INLINE X86Reg(const X86Reg& other) : Reg(other) {} + //! Create a reference to `other` X86 register and change the index to `index`. + ASMJIT_INLINE X86Reg(const X86Reg& other, uint32_t index) : Reg(other, index) {} + //! Create a custom X86 register. + ASMJIT_INLINE X86Reg(uint32_t type, uint32_t index, uint32_t size) : Reg(type, index, size) {} + //! Create non-initialized X86 register. + explicit ASMJIT_INLINE X86Reg(const _NoInit&) : Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Reg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86Reg) + + //! Get whether the register is Gp register. + ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; } + //! Get whether the register is Gp byte (8-bit) register. + ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; } + //! Get whether the register is Gp lo-byte (8-bit) register. + ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; } + //! Get whether the register is Gp hi-byte (8-bit) register. + ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; } + //! Get whether the register is Gp word (16-bit) register. + ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; } + //! Get whether the register is Gp dword (32-bit) register. + ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; } + //! Get whether the register is Gp qword (64-bit) register. + ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; } + + //! Get whether the register is Fp register. + ASMJIT_INLINE bool isFp() const { return _vreg.type == kX86RegTypeFp; } + //! Get whether the register is Mm (64-bit) register. + ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + + //! Get whether the register is K (64-bit) register. + ASMJIT_INLINE bool isK() const { return _vreg.type == kX86RegTypeK; } + + //! Get whether the register is Xmm (128-bit) register. + ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } + //! Get whether the register is Ymm (256-bit) register. + ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; } + //! Get whether the register is Zmm (512-bit) register. + ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; } + + //! Get whether the register is RIP. + ASMJIT_INLINE bool isRip() const { return _vreg.type == kX86RegTypeRip; } + //! Get whether the register is Segment. + ASMJIT_INLINE bool isSeg() const { return _vreg.type == kX86RegTypeSeg; } + + // -------------------------------------------------------------------------- + // [Statics] + // -------------------------------------------------------------------------- + + //! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register. + static ASMJIT_INLINE bool isGpbReg(const Operand& op) { + const uint32_t mask = IntUtil::pack32_2x8_1x16( + 0xFF, 0xFF, ~(_kX86RegTypePatchedGpbHi << 8) & 0xFF00); + + return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000); + } +}; + +// ============================================================================ +// [asmjit::X86RipReg] +// ============================================================================ + +//! X86/X64 RIP register. +struct X86RipReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a RIP register. + ASMJIT_INLINE X86RipReg() : X86Reg(kX86RegTypeRip, 0, 0) {} + //! Create a reference to `other` RIP register. + ASMJIT_INLINE X86RipReg(const X86RipReg& other) : X86Reg(other) {} + //! Create non-initialized RIP register. + explicit ASMJIT_INLINE X86RipReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86RipReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86RipReg) +}; + +// ============================================================================ +// [asmjit::X86SegReg] +// ============================================================================ + +//! X86/X64 segment register. +struct X86SegReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy segment register. + ASMJIT_INLINE X86SegReg() : X86Reg() {} + //! Create a reference to `other` segment register. + ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {} + //! Create a reference to `other` segment register and change the index to `index`. + ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom segment register. + ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized segment register. + explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86SegReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86SegReg) +}; + +// ============================================================================ +// [asmjit::X86GpReg] +// ============================================================================ + +//! X86/X64 Gpb/Gpw/Gpd/Gpq register. +struct X86GpReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Gp register. + ASMJIT_INLINE X86GpReg() : X86Reg() {} + //! Create a reference to `other` Gp register. + ASMJIT_INLINE X86GpReg(const X86GpReg& other) : X86Reg(other) {} + //! Create a reference to `other` Gp register and change the index to `index`. + ASMJIT_INLINE X86GpReg(const X86GpReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Gp register. + ASMJIT_INLINE X86GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Gp register. + explicit ASMJIT_INLINE X86GpReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86GpReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86GpReg) +}; + +// ============================================================================ +// [asmjit::X86FpReg] +// ============================================================================ + +//! X86/X64 80-bit Fp register. +struct X86FpReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Fp register. + ASMJIT_INLINE X86FpReg() : X86Reg() {} + //! Create a reference to `other` Fp register. + ASMJIT_INLINE X86FpReg(const X86FpReg& other) : X86Reg(other) {} + //! Create a reference to `other` Fp register and change the index to `index`. + ASMJIT_INLINE X86FpReg(const X86FpReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Fp register. + ASMJIT_INLINE X86FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Fp register. + explicit ASMJIT_INLINE X86FpReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86FpReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86FpReg) +}; + +// ============================================================================ +// [asmjit::X86MmReg] +// ============================================================================ + +//! X86/X64 64-bit Mm register (MMX+). +//! +//! Structure of MMX register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07| +//! +--+--+--+--+--+--+--+--+ +//! +//! MMX Register +//! +-----------------------+ +//! | QWord | +//! +-----------+-----------+ +//! | HI-DWord | LO-DWord | +//! +-----------+-----------+ +//! | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+ +//! |07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+ +//! ~~~ +//! +//! Move instruction semantics: +//! +//! - `movd` - writes 4-bytes in `LO-DWord` and zeroes `HI-DWord`. +//! - `movq` - writes 8-bytes in `QWord`. +struct X86MmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Mm register. + ASMJIT_INLINE X86MmReg() : X86Reg() {} + //! Create a reference to `other` Mm register. + ASMJIT_INLINE X86MmReg(const X86MmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Mm register and change the index to `index`. + ASMJIT_INLINE X86MmReg(const X86MmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Mm register. + ASMJIT_INLINE X86MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Mm register. + explicit ASMJIT_INLINE X86MmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86MmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86MmReg) +}; + +// ============================================================================ +// [asmjit::X86KReg] +// ============================================================================ + +//! X86/X64 64-bit K register (AVX512+). +struct X86KReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy K register. + ASMJIT_INLINE X86KReg() : X86Reg() {} + //! Create a reference to `other` K register. + ASMJIT_INLINE X86KReg(const X86KReg& other) : X86Reg(other) {} + //! Create a reference to `other` K register and change the index to `index`. + ASMJIT_INLINE X86KReg(const X86KReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom K register. + ASMJIT_INLINE X86KReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized K register. + explicit ASMJIT_INLINE X86KReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86KReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86KReg) +}; + +// ============================================================================ +// [asmjit::X86XmmReg] +// ============================================================================ + +//! X86/X64 128-bit Xmm register (SSE+). +//! +//! Structure of XMM register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! +//! XMM Register +//! +-----------------------------------------------+ +//! | OWord | +//! +-----------------------+-----------------------+ +//! | HI-QWord/PD | LO-QWord/SD | +//! +-----------+-----------+-----------+-----------+ +//! | D3/PS | D2/PS | D1/PS | D0/SS | +//! +-----------+-----------+-----------+-----------+ +//! | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! ~~~ +//! +//! Move instruction semantics: +//! +//! - `movd` - writes 4-bytes in `D0` and zeroes the rest. +//! - `movq` - writes 8-bytes in `Lo-QWord` and zeroes the rest. +//! - `movq2dq` - writes 8 bytes in `Lo-QWord` and zeroes the rest. +//! +//! - `movss` - writes 4-bytes in `D0` +//! (the rest is zeroed only if the source operand is a memory location). +//! - `movsd` - writes 8-bytes in `Lo-QWord` +//! (the rest is zeroed only if the source operand is a memory location). +//! +//! - `movaps`, +//! `movups`, +//! `movapd`, +//! `movupd`, +//! `movdqu`, +//! `movdqa`, +//! `lddqu` - writes 16-bytes in `OWord`. +//! +//! - `movlps`, +//! `movlpd`, +//! `movhlps` - writes 8-bytes in `Lo-QWord` and keeps the rest untouched. +//! +//! - `movhps`, +//! `movhpd`, +//! `movlhps` - writes 8-bytes in `Hi-QWord` and keeps the rest untouched. +//! +//! - `movddup`, +//! - `movsldup`, +//! - `movshdup` - writes 16 bytes in `OWord`. +struct X86XmmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Xmm register. + ASMJIT_INLINE X86XmmReg() : X86Reg() {} + //! Create a reference to `other` Xmm register. + ASMJIT_INLINE X86XmmReg(const X86XmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Xmm register and change the index to `index`. + ASMJIT_INLINE X86XmmReg(const X86XmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Xmm register. + ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Xmm register. + explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86XmmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86XmmReg) +}; + +// ============================================================================ +// [asmjit::X86YmmReg] +// ============================================================================ + +//! X86/X64 256-bit Ymm register (AVX+). +//! +//! Structure of YMM register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! +//! YMM Register +//! +-----------------------------------------------+-----------------------------------------------+ +//! | HI-DQWord | LO-DQWord | +//! +-----------------------+-----------------------+-----------------------+-----------------------+ +//! | Q3/PD | Q2/PD | Q1/PD | Q0/SD | +//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+ +//! | D7/PS | D6/PS | D5/PS | D4/PS | D3/PS | D2/PS | D1/PS | D0/SS | +//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+ +//! | W15 | W14 | W13 | W12 | W11 | W10 | W9 | W8 | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! ~~~ +struct X86YmmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Ymm register. + ASMJIT_INLINE X86YmmReg() : X86Reg() {} + //! Create a reference to `other` Ymm register. + ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Ymm register and change the index to `index`. + ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Ymm register. + ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Ymm register. + explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86YmmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86YmmReg) +}; + +// ============================================================================ +// [asmjit::X86ZmmReg] +// ============================================================================ + +//! X86/X64 512-bit Zmm register (AVX512+). +struct X86ZmmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Zmm register. + ASMJIT_INLINE X86ZmmReg() : X86Reg() {} + //! Create a reference to `other` Zmm register. + ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Zmm register and change the index to `index`. + ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Zmm register. + ASMJIT_INLINE X86ZmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Zmm register. + explicit ASMJIT_INLINE X86ZmmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86ZmmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86ZmmReg) +}; + +// ============================================================================ +// [asmjit::X86Mem] +// ============================================================================ + +//! X86 memory operand. +struct X86Mem : public BaseMem { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem() : BaseMem(NoInit) { + reset(); + } + + ASMJIT_INLINE X86Mem(const Label& label, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, 0, label._base.id); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + label.getId()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibGpz << kX86MemVSibIndex), + base.getRegIndex()); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86XmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibXmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86YmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibYmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + +#if !defined(ASMJIT_DISABLE_COMPILER) + ASMJIT_INLINE X86Mem(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + label.getId()); + _vmem.index = ASMJIT_OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibGpz << kX86MemVSibIndex), + ASMJIT_OP_ID(base)); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (shift << kX86MemShiftIndex), + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86XmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibXmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86YmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibYmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, ASMJIT_OP_ID(base)); + _vmem.index = kInvalidValue; + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); + _vmem.displacement = disp; + } +#endif // !ASMJIT_DISABLE_COMPILER + + ASMJIT_INLINE X86Mem(const X86Mem& other) : BaseMem(other) {} + explicit ASMJIT_INLINE X86Mem(const _NoInit&) : BaseMem(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Mem Specific] + // -------------------------------------------------------------------------- + + //! Clone X86Mem operand. + ASMJIT_INLINE X86Mem clone() const { + return X86Mem(*this); + } + + //! Reset X86Mem operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, 0); + } + + //! \internal + ASMJIT_INLINE void _init(uint32_t memType, uint32_t base, int32_t disp, uint32_t size) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, base); + _vmem.index = kInvalidValue; + _vmem.displacement = disp; + } + + // -------------------------------------------------------------------------- + // [Segment] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has segment override prefix. + ASMJIT_INLINE bool hasSegment() const { + return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex); + } + + //! Get memory operand segment, see `kX86Seg`. + ASMJIT_INLINE uint32_t getSegment() const { + return (static_cast(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits; + } + + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) { + _vmem.flags = static_cast( + (static_cast(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex)); + return *this; + } + + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) { + return setSegment(seg.getRegIndex()); + } + + // -------------------------------------------------------------------------- + // [Gpd] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has 32-bit GP base. + ASMJIT_INLINE bool hasGpdBase() const { + return (_packed[0].u32[0] & IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask)) != 0; + } + + //! Set whether the memory operand has 32-bit GP base. + ASMJIT_INLINE X86Mem& setGpdBase() { + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask); + return *this; + } + + //! Set whether the memory operand has 32-bit GP base to `b`. + ASMJIT_INLINE X86Mem& setGpdBase(uint32_t b) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, b << kX86MemGpdIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [VSib] + // -------------------------------------------------------------------------- + + //! Get V-SIB type. + ASMJIT_INLINE uint32_t getVSib() const { + return (static_cast(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits; + } + + //! Set V-SIB type. + ASMJIT_INLINE X86Mem& _setVSib(uint32_t vsib) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemVSibMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kX86MemVSibIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [Size] + // -------------------------------------------------------------------------- + + //! Set memory operand size. + ASMJIT_INLINE X86Mem& setSize(uint32_t size) { + _vmem.size = static_cast(size); + return *this; + } + + // -------------------------------------------------------------------------- + // [Base] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has base register. + ASMJIT_INLINE bool hasBase() const { + return _vmem.base != kInvalidValue; + } + + //! Get memory operand base register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE uint32_t getBase() const { + return _vmem.base; + } + + //! Set memory operand base register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE X86Mem& setBase(uint32_t base) { + _vmem.base = base; + return *this; + } + + // -------------------------------------------------------------------------- + // [Index] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has index. + ASMJIT_INLINE bool hasIndex() const { + return _vmem.index != kInvalidValue; + } + + //! Get memory operand index register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE uint32_t getIndex() const { + return _vmem.index; + } + + //! Set memory operand index register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE X86Mem& setIndex(uint32_t index) { + _vmem.index = index; + return *this; + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibGpz); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibGpz).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibXmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibXmm).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibYmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } + +#if !defined(ASMJIT_DISABLE_COMPILER) + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibGpz); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibGpz).setShift(shift); + } + + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibXmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibXmm).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibYmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) { + _vmem.index = ASMJIT_OP_ID(index); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } +#endif // !ASMJIT_DISABLE_COMPILER + + //! Reset memory index. + ASMJIT_INLINE X86Mem& resetIndex() { + _vmem.index = kInvalidValue; + return _setVSib(kX86MemVSibGpz); + } + + // -------------------------------------------------------------------------- + // [Misc] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has base and index register. + ASMJIT_INLINE bool hasBaseOrIndex() const { + return _vmem.base != kInvalidValue || _vmem.index != kInvalidValue; + } + + //! Get whether the memory operand has base and index register. + ASMJIT_INLINE bool hasBaseAndIndex() const { + return _vmem.base != kInvalidValue && _vmem.index != kInvalidValue; + } + + // -------------------------------------------------------------------------- + // [Shift] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has shift used. + ASMJIT_INLINE bool hasShift() const { + return (_vmem.flags & kX86MemShiftMask) != 0; + } + + //! Get memory operand index scale (0, 1, 2 or 3). + ASMJIT_INLINE uint32_t getShift() const { + return _vmem.flags >> kX86MemShiftIndex; + } + + //! Set memory operand index scale (0, 1, 2 or 3). + ASMJIT_INLINE X86Mem& setShift(uint32_t shift) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemShiftMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, shift << kX86MemShiftIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [Displacement] + // -------------------------------------------------------------------------- + + //! Get memory operand relative displacement. + ASMJIT_INLINE int32_t getDisplacement() const { + return _vmem.displacement; + } + + //! Set memory operand relative displacement. + ASMJIT_INLINE X86Mem& setDisplacement(int32_t disp) { + _vmem.displacement = disp; + return *this; + } + + //! Reset memory operand relative displacement. + ASMJIT_INLINE X86Mem& resetDisplacement(int32_t disp) { + _vmem.displacement = 0; + return *this; + } + + //! Adjust memory operand relative displacement by `disp`. + ASMJIT_INLINE X86Mem& adjust(int32_t disp) { + _vmem.displacement += disp; + return *this; + } + + //! Get new memory operand adjusted by `disp`. + ASMJIT_INLINE X86Mem adjusted(int32_t disp) const { + X86Mem result(*this); + result.adjust(disp); + return result; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) { + _copy(other); + return *this; + } + + ASMJIT_INLINE bool operator==(const X86Mem& other) const { + return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]) ; + } + + ASMJIT_INLINE bool operator!=(const X86Mem& other) const { + return !(*this == other); + } + + // -------------------------------------------------------------------------- + // [Static] + // -------------------------------------------------------------------------- + + static ASMJIT_INLINE uint32_t _getGpdFlags(const Operand& base) { + return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2); + } +}; +#endif // ASMJIT_EXPORTS_X86OPERAND_REGS + +// ============================================================================ +// [asmjit::X86RegData] +// ============================================================================ + +struct X86RegData { + X86RipReg rip; + X86GpReg noGp; + + X86SegReg seg[7]; + + X86GpReg gpbLo[16]; + X86GpReg gpbHi[4]; + + X86GpReg gpw[16]; + X86GpReg gpd[16]; + X86GpReg gpq[16]; + + X86FpReg fp[8]; + X86MmReg mm[8]; + X86KReg k[8]; + + X86XmmReg xmm[32]; + X86YmmReg ymm[32]; + X86ZmmReg zmm[32]; +}; + +ASMJIT_VAR const X86RegData x86RegData; + +// ============================================================================ +// [asmjit::x86] +// ============================================================================ + +namespace x86 { + +// ============================================================================ +// [asmjit::x86 - Reg] +// ============================================================================ + +#define ASMJIT_DEF_REG(_Type_, _Name_, _Field_) \ + static const _Type_& _Name_ = x86RegData._Field_ + +ASMJIT_DEF_REG(X86RipReg, rip, rip); //!< RIP register. +ASMJIT_DEF_REG(X86GpReg , noGpReg, noGp); //!< No GP register (for `X86Mem` operand.). + +ASMJIT_DEF_REG(X86SegReg, es , seg[1]); //!< Cs segment register. +ASMJIT_DEF_REG(X86SegReg, cs , seg[2]); //!< Ss segment register. +ASMJIT_DEF_REG(X86SegReg, ss , seg[3]); //!< Ds segment register. +ASMJIT_DEF_REG(X86SegReg, ds , seg[4]); //!< Es segment register. +ASMJIT_DEF_REG(X86SegReg, fs , seg[5]); //!< Fs segment register. +ASMJIT_DEF_REG(X86SegReg, gs , seg[6]); //!< Gs segment register. + +ASMJIT_DEF_REG(X86GpReg , al , gpbLo[0]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , cl , gpbLo[1]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , dl , gpbLo[2]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , bl , gpbLo[3]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , spl , gpbLo[4]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , bpl , gpbLo[5]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , sil , gpbLo[6]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , dil , gpbLo[7]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r8b , gpbLo[8]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r9b , gpbLo[9]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r10b , gpbLo[10]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r11b , gpbLo[11]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r12b , gpbLo[12]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r13b , gpbLo[13]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r14b , gpbLo[14]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r15b , gpbLo[15]);//!< 8-bit Gpb-lo register (X64). + +ASMJIT_DEF_REG(X86GpReg , ah , gpbHi[0]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , ch , gpbHi[1]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , dh , gpbHi[2]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , bh , gpbHi[3]); //!< 8-bit Gpb-hi register. + +ASMJIT_DEF_REG(X86GpReg , ax , gpw[0]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , cx , gpw[1]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , dx , gpw[2]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , bx , gpw[3]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , sp , gpw[4]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , bp , gpw[5]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , si , gpw[6]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , di , gpw[7]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , r8w , gpw[8]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r9w , gpw[9]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r10w , gpw[10]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r11w , gpw[11]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r12w , gpw[12]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r13w , gpw[13]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r14w , gpw[14]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r15w , gpw[15]); //!< 16-bit Gpw register (X64). + +ASMJIT_DEF_REG(X86GpReg , eax , gpd[0]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ecx , gpd[1]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , edx , gpd[2]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ebx , gpd[3]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , esp , gpd[4]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ebp , gpd[5]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , esi , gpd[6]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , edi , gpd[7]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , r8d , gpd[8]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r9d , gpd[9]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r10d , gpd[10]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r11d , gpd[11]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r12d , gpd[12]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r13d , gpd[13]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r14d , gpd[14]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r15d , gpd[15]); //!< 32-bit Gpd register (X64). + +ASMJIT_DEF_REG(X86GpReg , rax , gpq[0]); //!< 64-bit Gpq register (X64). +ASMJIT_DEF_REG(X86GpReg , rcx , gpq[1]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rdx , gpq[2]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rbx , gpq[3]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rsp , gpq[4]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rbp , gpq[5]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rsi , gpq[6]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rdi , gpq[7]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r8 , gpq[8]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r9 , gpq[9]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r10 , gpq[10]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r11 , gpq[11]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r12 , gpq[12]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r13 , gpq[13]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r14 , gpq[14]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r15 , gpq[15]); //!< 64-bit Gpq register (X64) + +ASMJIT_DEF_REG(X86FpReg , fp0 , fp[0]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp1 , fp[1]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp2 , fp[2]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp3 , fp[3]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp4 , fp[4]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp5 , fp[5]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp6 , fp[6]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp7 , fp[7]); //!< 80-bit Fp register. + +ASMJIT_DEF_REG(X86MmReg , mm0 , mm[0]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm1 , mm[1]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm2 , mm[2]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm3 , mm[3]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm4 , mm[4]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm5 , mm[5]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm6 , mm[6]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm7 , mm[7]); //!< 64-bit Mm register. + +ASMJIT_DEF_REG(X86KReg , k0 , k[0]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k1 , k[1]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k2 , k[2]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k3 , k[3]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k4 , k[4]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k5 , k[5]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k6 , k[6]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k7 , k[7]); //!< 64-bit K register. + +ASMJIT_DEF_REG(X86XmmReg, xmm0 , xmm[0]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm1 , xmm[1]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm2 , xmm[2]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm3 , xmm[3]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm4 , xmm[4]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm5 , xmm[5]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm6 , xmm[6]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm7 , xmm[7]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm8 , xmm[8]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm9 , xmm[9]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm10, xmm[10]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm11, xmm[11]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm12, xmm[12]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm13, xmm[13]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm14, xmm[14]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm15, xmm[15]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm16, xmm[16]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm17, xmm[17]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm18, xmm[18]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm19, xmm[19]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm20, xmm[20]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm21, xmm[21]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm22, xmm[22]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm23, xmm[23]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm24, xmm[24]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm25, xmm[25]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm26, xmm[26]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm27, xmm[27]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm28, xmm[28]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm29, xmm[29]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm30, xmm[30]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm31, xmm[31]); //!< 128-bit Xmm register (X64 & AVX512VL+). + +ASMJIT_DEF_REG(X86YmmReg, ymm0 , ymm[0]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm1 , ymm[1]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm2 , ymm[2]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm3 , ymm[3]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm4 , ymm[4]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm5 , ymm[5]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm6 , ymm[6]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm7 , ymm[7]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm8 , ymm[8]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm9 , ymm[9]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm10, ymm[10]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm11, ymm[11]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm12, ymm[12]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm13, ymm[13]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm14, ymm[14]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm15, ymm[15]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm16, ymm[16]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm17, ymm[17]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm18, ymm[18]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm19, ymm[19]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm20, ymm[20]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm21, ymm[21]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm22, ymm[22]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm23, ymm[23]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm24, ymm[24]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm25, ymm[25]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm26, ymm[26]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm27, ymm[27]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm28, ymm[28]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm29, ymm[29]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm30, ymm[30]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm31, ymm[31]); //!< 256-bit Ymm register (X64 & AVX512VL+). + +ASMJIT_DEF_REG(X86ZmmReg, zmm0 , zmm[0]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm1 , zmm[1]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm2 , zmm[2]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm3 , zmm[3]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm4 , zmm[4]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm5 , zmm[5]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm6 , zmm[6]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm7 , zmm[7]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm8 , zmm[8]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm9 , zmm[9]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm10, zmm[10]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm11, zmm[11]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm12, zmm[12]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm13, zmm[13]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm14, zmm[14]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm15, zmm[15]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm16, zmm[16]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm17, zmm[17]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm18, zmm[18]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm19, zmm[19]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm20, zmm[20]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm21, zmm[21]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm22, zmm[22]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm23, zmm[23]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm24, zmm[24]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm25, zmm[25]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm26, zmm[26]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm27, zmm[27]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm28, zmm[28]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm29, zmm[29]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm30, zmm[30]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm31, zmm[31]); //!< 512-bit Zmm register (X64 & AVX512+). +#undef ASMJIT_DEF_REG + +// This is only defined by `x86operand_regs.cpp` when exporting registers. +#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) + +//! Create 8-bit Gpb-lo register operand. +static ASMJIT_INLINE X86GpReg gpb_lo(uint32_t index) { return X86GpReg(kX86RegTypeGpbLo, index, 1); } +//! Create 8-bit Gpb-hi register operand. +static ASMJIT_INLINE X86GpReg gpb_hi(uint32_t index) { return X86GpReg(kX86RegTypeGpbHi, index, 1); } +//! Create 16-bit Gpw register operand. +static ASMJIT_INLINE X86GpReg gpw(uint32_t index) { return X86GpReg(kX86RegTypeGpw, index, 2); } +//! Create 32-bit Gpd register operand. +static ASMJIT_INLINE X86GpReg gpd(uint32_t index) { return X86GpReg(kX86RegTypeGpd, index, 4); } +//! Create 64-bit Gpq register operand (X64). +static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeGpq, index, 8); } +//! Create 80-bit Fp register operand. +static ASMJIT_INLINE X86FpReg fp(uint32_t index) { return X86FpReg(kX86RegTypeFp, index, 10); } +//! Create 64-bit Mm register operand. +static ASMJIT_INLINE X86MmReg mm(uint32_t index) { return X86MmReg(kX86RegTypeMm, index, 8); } +//! Create 64-bit K register operand. +static ASMJIT_INLINE X86KReg k(uint32_t index) { return X86KReg(kX86RegTypeK, index, 8); } +//! Create 128-bit Xmm register operand. +static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) { return X86XmmReg(kX86RegTypeXmm, index, 16); } +//! Create 256-bit Ymm register operand. +static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) { return X86YmmReg(kX86RegTypeYmm, index, 32); } +//! Create 512-bit Zmm register operand. +static ASMJIT_INLINE X86ZmmReg zmm(uint32_t index) { return X86ZmmReg(kX86RegTypeZmm, index, 64); } + +// ============================================================================ +// [asmjit::x86 - Ptr (Reg)] +// ============================================================================ + +//! Create `[base.reg + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, disp, size); +} +//! Create `[base.reg + (index.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[label + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(label, disp, size); +} +//! Create `[label + (index.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ + return X86Mem(label, index, shift, disp, size); \ +} + +//! Create `[pAbs + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0); +//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); + +//! \internal +#define ASMJIT_EXPAND_PTR_REG(_Prefix_, _Size_) \ + /*! Create `[base.reg + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, int32_t disp = 0) { \ + return X86Mem(base, disp, _Size_); \ + } \ + /*! Create `[base.reg + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[label + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, int32_t disp = 0) { \ + return ptr(label, disp, _Size_); \ + } \ + /*! Create `[label + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \ + return ptr(label, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \ + return ptr_abs(pAbs, disp, _Size_); \ + } \ + /*! Create `[pAbs + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (xmm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (ymm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } + +ASMJIT_EXPAND_PTR_REG(byte, 1) +ASMJIT_EXPAND_PTR_REG(word, 2) +ASMJIT_EXPAND_PTR_REG(dword, 4) +ASMJIT_EXPAND_PTR_REG(qword, 8) +ASMJIT_EXPAND_PTR_REG(tword, 10) +ASMJIT_EXPAND_PTR_REG(oword, 16) +ASMJIT_EXPAND_PTR_REG(yword, 32) +ASMJIT_EXPAND_PTR_REG(zword, 64) +#undef ASMJIT_EXPAND_PTR_REG + +// ============================================================================ +// [asmjit::x86 - Ptr (Var)] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_COMPILER) +//! Create `[base.var + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, disp, size); +} +//! Create `[base.var + (index.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.var + (xmm.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.var + (ymm.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[label + (index.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ + return X86Mem(label, index, shift, disp, size); \ +} + +//! Create `[pAbs + (index.var << shift) + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); + +//! \internal +#define ASMJIT_EXPAND_PTR_VAR(_Prefix_, _Size_) \ + /*! Create `[base.var + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, int32_t disp = 0) { \ + return X86Mem(base, disp, _Size_); \ + } \ + /*! Create `[base.var + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.var + (xmm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.var + (ymm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[label + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { \ + return ptr(label, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (xmm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (ymm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } + +ASMJIT_EXPAND_PTR_VAR(byte, 1) +ASMJIT_EXPAND_PTR_VAR(word, 2) +ASMJIT_EXPAND_PTR_VAR(dword, 4) +ASMJIT_EXPAND_PTR_VAR(qword, 8) +ASMJIT_EXPAND_PTR_VAR(tword, 10) +ASMJIT_EXPAND_PTR_VAR(oword, 16) +ASMJIT_EXPAND_PTR_VAR(yword, 32) +ASMJIT_EXPAND_PTR_VAR(zword, 64) +#undef ASMJIT_EXPAND_PTR_VAR +#endif // !ASMJIT_DISABLE_COMPILER + +#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS + +} // x86 namespace + +//! \} + +} // asmjit namespace + +// [Cleanup] +#undef ASMJIT_OP_ID + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86OPERAND_H diff --git a/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86scheduler_p.h b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86scheduler_p.h new file mode 100644 index 0000000..1afeb90 --- /dev/null +++ b/Andromeda-Injector/Andromeda-Injector/Common/Include/3rd_party/AsmJit/x86/x86scheduler_p.h @@ -0,0 +1,63 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86SCHEDULER_P_H +#define _ASMJIT_X86_X86SCHEDULER_P_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../x86/x86compiler.h" +#include "../x86/x86context_p.h" +#include "../x86/x86cpuinfo.h" +#include "../x86/x86inst.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::X86Scheduler] +// ============================================================================ + +//! \internal +//! +//! X86 scheduler. +struct X86Scheduler { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo); + ~X86Scheduler(); + + // -------------------------------------------------------------------------- + // [Run] + // -------------------------------------------------------------------------- + + Error run(Node* start, Node* stop); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Attached compiler. + X86Compiler* _compiler; + //! CPU information used for scheduling. + const X86CpuInfo* _cpuInfo; +}; + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86SCHEDULER_P_H