From fa955663e3165c937ea19ba4d7c12c2f4813b3cb Mon Sep 17 00:00:00 2001 From: kobalicek Date: Sat, 12 Jul 2014 17:50:35 +0200 Subject: [PATCH] Changed asmjit namespaces, each architecture has now only one namespace for registers / memory operands. Changed instruction table schema to minimize its size and added use of EFLAGS register (for scheduler). Changed the rest of intrinsics accepting `void*` to accept `Ptr` instead. Changed clear()/reset() concept - only `reset()` now exists and accepts a `releaseMemory` argument. Changed unit tests to use bundled `Broken` framework. Moved podvector and podlist to base/containers. Added CMPS, LODS, MOVS, SCAS, STOS instructions. Added Label::isInitialized() and Var::isInitialized(). Added X86Scheduler stub - preparing for instruction reordering. Added support for tracing (see ASMJIT_TRACE) to allow consumers to find bugs in AsmJit quicker. Fixed possible Zone memory leak. Fixed and improved alloc/spill (added support for home register which asmjit honors from now). Fixed Assembler `LEA REG, [LABEL]` bug. Fixed [Mem, Imm] instructions with zero-sized operand to return error instead of emitting garbage. Fixed minor bug in VMemMgr - always point to a correct hProcess so it can be used properly (#41). --- .travis.yml | 29 +- CMakeLists.txt | 62 +- README.md | 210 +- src/app/test/benchx86.cpp | 24 +- src/app/test/genblend.h | 38 +- src/app/test/genopcode.h | 76 +- src/app/test/testopcode.cpp | 2 +- src/app/test/testx86.cpp | 520 +- src/asmjit/apibegin.h | 58 +- src/asmjit/apiend.h | 32 +- src/asmjit/asmjit.h | 86 +- src/asmjit/base.h | 4 +- src/asmjit/base/assembler.cpp | 114 +- src/asmjit/base/assembler.h | 44 +- src/asmjit/base/codegen.cpp | 10 +- src/asmjit/base/codegen.h | 57 +- src/asmjit/base/compiler.cpp | 136 +- src/asmjit/base/compiler.h | 1225 +++- src/asmjit/base/constpool.cpp | 4 +- .../base/{podvector.cpp => containers.cpp} | 22 +- src/asmjit/base/{podvector.h => containers.h} | 134 +- src/asmjit/base/context.cpp | 252 +- src/asmjit/base/context_p.h | 59 +- src/asmjit/base/cpuinfo.cpp | 16 +- src/asmjit/base/cpuinfo.h | 24 +- src/asmjit/base/error.cpp | 51 +- src/asmjit/base/error.h | 20 +- src/asmjit/base/func.cpp | 20 - src/asmjit/base/func.h | 651 -- src/asmjit/base/globals.h | 2 + src/asmjit/base/lock.h | 8 +- src/asmjit/base/logger.h | 24 +- src/asmjit/base/operand.cpp | 16 +- src/asmjit/base/operand.h | 286 +- src/asmjit/base/podlist.h | 117 - src/asmjit/base/runtime.cpp | 6 +- src/asmjit/base/runtime.h | 16 +- src/asmjit/base/vectypes.h | 240 +- src/asmjit/base/vmem.cpp | 1215 ++- src/asmjit/base/vmem.h | 103 +- src/asmjit/base/zone.cpp | 49 +- src/asmjit/base/zone.h | 22 +- src/asmjit/build.h | 118 +- src/asmjit/config.h | 35 +- src/asmjit/contrib/winremoteruntime.cpp | 5 +- src/asmjit/host.h | 57 +- src/asmjit/test/broken.cpp | 279 + src/asmjit/test/broken.h | 115 + src/asmjit/test/main.cpp | 252 +- src/asmjit/test/test.cpp | 112 - src/asmjit/test/test.h | 99 - src/asmjit/x86.h | 3 - src/asmjit/x86/x86assembler.cpp | 1430 ++-- src/asmjit/x86/x86assembler.h | 6488 ++++++++--------- src/asmjit/x86/x86compiler.cpp | 962 ++- src/asmjit/x86/x86compiler.h | 6319 +++++++++------- src/asmjit/x86/x86context.cpp | 2670 +++---- src/asmjit/x86/x86context_p.h | 131 +- src/asmjit/x86/x86cpuinfo.cpp | 137 +- src/asmjit/x86/x86cpuinfo.h | 128 +- src/asmjit/x86/x86func.cpp | 547 -- src/asmjit/x86/x86func.h | 492 -- src/asmjit/x86/x86inst.cpp | 5914 +++++++++------ src/asmjit/x86/x86inst.h | 3257 +++++---- src/asmjit/x86/x86operand.cpp | 155 +- src/asmjit/x86/x86operand.h | 2111 +++--- src/asmjit/x86/x86operand_regs.cpp | 188 + src/asmjit/x86/x86regs.cpp | 216 - src/asmjit/x86/x86regs.h | 412 -- src/asmjit/x86/x86scheduler.cpp | 94 + src/asmjit/x86/x86scheduler_p.h | 63 + src/asmjit/x86/x86util.cpp | 90 - src/asmjit/x86/x86util.h | 394 - tools/src-gendefs.js | 218 +- 74 files changed, 21072 insertions(+), 18503 deletions(-) rename src/asmjit/base/{podvector.cpp => containers.cpp} (81%) rename src/asmjit/base/{podvector.h => containers.h} (67%) delete mode 100644 src/asmjit/base/func.cpp delete mode 100644 src/asmjit/base/func.h delete mode 100644 src/asmjit/base/podlist.h create mode 100644 src/asmjit/test/broken.cpp create mode 100644 src/asmjit/test/broken.h delete mode 100644 src/asmjit/test/test.cpp delete mode 100644 src/asmjit/test/test.h delete mode 100644 src/asmjit/x86/x86func.cpp delete mode 100644 src/asmjit/x86/x86func.h create mode 100644 src/asmjit/x86/x86operand_regs.cpp delete mode 100644 src/asmjit/x86/x86regs.cpp delete mode 100644 src/asmjit/x86/x86regs.h create mode 100644 src/asmjit/x86/x86scheduler.cpp create mode 100644 src/asmjit/x86/x86scheduler_p.h delete mode 100644 src/asmjit/x86/x86util.cpp delete mode 100644 src/asmjit/x86/x86util.h diff --git a/.travis.yml b/.travis.yml index 4e49b40..2aee7d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,14 +6,33 @@ compiler: before_install: - sudo add-apt-repository ppa:kubuntu-ppa/backports -y - - sudo apt-get update -qq - - sudo apt-get install -qq cmake + - sudo apt-get -qq update + - sudo apt-get -qq install cmake valgrind before_script: - - mkdir build - - cd build + - mkdir build_dbg + - mkdir build_rel + + - cd build_dbg - cmake .. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DASMJIT_BUILD_TEST=1 -DASMJIT_BUILD_SAMPLES=1 + - cd .. + + - cd build_rel + - cmake .. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DASMJIT_BUILD_TEST=1 -DASMJIT_BUILD_SAMPLES=1 + - cd .. script: + - cd build_dbg - make - - ./asmjit_test + - cd .. + + - cd build_rel + - make + - cd .. + + - ./build_dbg/asmjit_test + - ./build_rel/asmjit_test + +after_success: + - valgrind --leak-check=full --show-reachable=yes ./build_dbg/asmjit_test + - valgrind --leak-check=full --show-reachable=yes ./build_rel/asmjit_test diff --git a/CMakeLists.txt b/CMakeLists.txt index 67ce5cd..971f060 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ Set(ASMJIT_CFLAGS_REL) Set(ASMJIT_DEFINE "-D") # MSVC. -If(MSVC) +If("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") Message("-- Using MSVC") Set(ASMJIT_DEFINE "/D") @@ -91,35 +91,46 @@ If(MSVC) Set(ASMJIT_CFLAGS_DBG /DASMJIT_DEBUG /GS /GR-) Set(ASMJIT_CFLAGS_REL /DASMJIT_RELEASE /Oi /Oy /GS- /GR-) - # Use Unicode by default on Windows target. - If(WIN32) - List(APPEND ASMJIT_CFLAGS /D_UNICODE) - EndIf() - # Enable multi-process compilation. If(NOT MSVC60 AND NOT MSVC70 AND NOT MSVC71) List(APPEND ASMJIT_CFLAGS /MP) EndIf() EndIf() -# GCC. -If(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) +# GCC +If("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") Message("-- Using GCC") Set(ASMJIT_CFLAGS -fno-exceptions) - Set(ASMJIT_CFLAGS_DBG -DASMJIT_DEBUG -O0 - -fno-inline-functions) - Set(ASMJIT_CFLAGS_REL -DASMJIT_RELEASE -O2 + Set(ASMJIT_CFLAGS_DBG + -DASMJIT_DEBUG -O0) + Set(ASMJIT_CFLAGS_REL + -DASMJIT_RELEASE -O2 -finline-functions -fomit-frame-pointer -fmerge-all-constants -fno-keep-static-consts) +EndIf() - # Use Unicode by default on Windows target. - If(WIN32) - List(APPEND ASMJIT_CFLAGS -D_UNICODE) - EndIf() +# Clang. +If("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + Message("-- Using Clang") + + Set(ASMJIT_CFLAGS + -fno-exceptions) + Set(ASMJIT_CFLAGS_DBG + -DASMJIT_DEBUG -O0) + Set(ASMJIT_CFLAGS_REL + -DASMJIT_RELEASE -O2 + -finline-functions + -fomit-frame-pointer + -fmerge-all-constants) +EndIf() + +# Use Unicode by default on Windows target. +If(WIN32) + List(APPEND ASMJIT_CFLAGS "${ASMJIT_DEFINE}_UNICODE") EndIf() # Static library. @@ -228,6 +239,8 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/base compiler.h constpool.cpp constpool.h + containers.cpp + containers.h context.cpp context_p.h cpuinfo.cpp @@ -236,8 +249,6 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/base cputicks.h error.cpp error.h - func.cpp - func.h globals.cpp globals.h intutil.cpp @@ -247,9 +258,6 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/base logger.h operand.cpp operand.h - podlist.h - podvector.cpp - podvector.h runtime.cpp runtime.h string.cpp @@ -270,16 +278,13 @@ AsmJit_AddSource(ASMJIT_SRC asmjit/x86 x86context_p.h x86cpuinfo.cpp x86cpuinfo.h - x86func.cpp - x86func.h x86inst.cpp x86inst.h x86operand.cpp + x86operand_regs.cpp x86operand.h - x86regs.cpp - x86regs.h - x86util.cpp - x86util.h + x86scheduler.cpp + x86scheduler_p.h ) If(ASMJIT_BUILD_CONTRIB) @@ -327,10 +332,7 @@ EndIf() # AsmJit library is always embedded into the tests executable. This way it's # much easier to test private functions compared to just linking to AsmJit. If(ASMJIT_BUILD_TEST) - AsmJit_AddSource(ASMJIT_TEST_SRC asmjit/test - main.cpp - test.cpp - test.h) + AsmJit_AddSource(ASMJIT_TEST_SRC asmjit/test broken.cpp broken.h main.cpp) Set(ASMJIT_TEST_CFLAGS ${ASMJIT_CFLAGS} diff --git a/README.md b/README.md index 04be5d2..2bd3d4a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,22 @@ AsmJit -====== +------ Complete x86/x64 JIT and Remote Assembler for C++. +[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)]( + https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QDRM6SRNG7378&lc=EN;&item_name=asmjit¤cy_code=EUR) + Official Repository ------------------- https://github.com/kobalicek/asmjit -Support the Project -------------------- - -[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)]( - https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QDRM6SRNG7378&lc=EN;&item_name=asmjit¤cy_code=EUR) - Introduction ------------ -AsmJit is a complete JIT and remote assembler for C++ language. It can generate native code for x86 and x64 architectures and supports the whole x86/x64 instruction set (from legacy MMX to the newest AVX2). It has a type-safe API that allows C++ compiler to do a semantic checks at compile-time even before the assembled code is generated or run. +AsmJit is a complete JIT and remote assembler for C++ language. It can generate native code for x86 and x64 architectures and supports the whole x86/x64 instruction set - from legacy MMX to the newest AVX2. It has a type-safe API that allows C++ compiler to do a semantic checks at compile-time even before the assembled code is generated or run. -AsmJit is not a virtual machine nor tries to be. It's a general purpose tool that can be used to encode assembly instructions into their machine code representations and tries to make such process easy and fun. AsmJit has been used so far in software encryption, image/sound processing, emulators and as a JIT backend in virtual machines. +AsmJit is not a virtual machine nor tries to be. It's a tool that can be used to encode instructions into their machine code representations and tries to make such process easy and fun. AsmJit has been used so far in software encryption, image/sound processing, emulators and as a JIT backend in virtual machines. Features -------- @@ -45,9 +42,11 @@ Supported Environments ### C++ Compilers * BorlandC++ - * GNU (3.4.X+, 4.0+, MinGW) - * MSVC (VS2005+) - * Other compilers require testing + * Clang (Travis-CI) + * Gcc (Travis-CI) + * MinGW + * MSVC + * Other compilers require testing and support in `asmjit/build.h` header ### Backends @@ -57,77 +56,85 @@ Supported Environments Project Organization -------------------- - - project root / - - src - Source code - - asmjit - Public header files (always include from here) - - base - Base files, used by the AsmJit and all backends - - contrib - Contributions that extends base functionality - - x86 - X86/X64 specific files, used only by X86/X64 backend - - tools - Tools used for configuring, documenting and generating files + * `/` - Project root + * `src` - Source code + * `asmjit` - Public header files (always include from here) + * `base` - Base files, used by the AsmJit and all backends + * `contrib` - Contributions that extends base functionality + * `test` - Unit testing support (don't include in your project) + * `x86` - X86/X64 specific files, used only by X86/X64 backend + * `tools` - Tools used for configuring, documenting and generating files Code Generation Concepts ------------------------ -AsmJit has two completely different code generation concepts. The difference is in how the code is generated. The first concept, also referred as the low level concept, is called 'Assembler' and it's the same as writing RAW assembly by using physical registers directly. In this case AsmJit does only instruction encoding, verification and relocation. +AsmJit has two completely different code generation concepts. The difference is in how the code is generated. The first concept, also referred as the low level concept, is called `Assembler` and it's the same as writing RAW assembly by using physical registers directly. In this case AsmJit does only instruction encoding, verification and optionally code-relocation. -The second concept, also referred as the high level concept, is called 'Compiler'. Compiler lets you use virtually unlimited number of registers (called variables) significantly simplifying the code generation process. Compiler allocates these virtual registers to physical registers after the code generation is done. This requires some extra effort - Compiler has to generate information for each node (instruction, function declaration, function call) in the code, perform a variable liveness analysis and translate the code having variables into code having only registers. +The second concept, also referred as the high level concept, is called `Compiler`. Compiler lets you use virtually unlimited number of registers (called variables) significantly simplifying the code generation process. Compiler allocates these virtual registers to physical registers after the code generation is done. This requires some extra effort - Compiler has to generate information for each node (instruction, function declaration, function call) in the code, perform a variable liveness analysis and translate the code having variables into code having only registers. -In addition, Compiler understands functions and function calling conventions. It has been designed in a way that the code generated is always a function having prototype like in a programming language. By having a function prototype the Compiler is able to insert prolog and epilog to a function being generated and it is able to call a function inside a generated one. +In addition, Compiler understands functions and function calling conventions. It has been designed in a way that the code generated is always a function having a prototype like in a programming language. By having a function prototype the Compiler is able to insert prolog and epilog to a function being generated and it is able to call a function inside a generated one. -There is no conclusion on which concept is better. Assembler brings full control on how the code is generated, while Compiler makes the generation easier and more portable. +There is no conclusion on which concept is better. Assembler brings full control on how the code is generated, while Compiler makes the generation easier and more portable. However, Compiler does sometimes relatively bad job when it comes to register allocation, so for projects where there is already an analysis perfored, pure Assembler code generator is the preffered way. Configuring & Building ---------------------- -AsmJit is designed to be easy embeddable in any project. However, it has some compile-time flags that can be used to build a specific version of AsmJit including or omitting certain features: +AsmJit is designed to be easy embeddable in any kind project. However, it has some compile-time flags that can be used to build a specific version of AsmJit including or omitting certain features. A typical way to build AsmJit is to use [cmake](http://www.cmake.org), but it's also possible to just include AsmJit source code in our project and build it with it optionally editing its `asmjit/config.h` file to turn on/off some specific features. The most easies way to include AsmJit in your project is to just copy AsmJit source somewhere into it and to define globally `ASMJIT_STATIC` macro. This way AsmJit can be just updated from time to time without any changes to it. Please do not include / compile AsmJit test files (`asmjit/test` directory) when embedding. -### Library Type +### Build Type - * *ASMJIT_EMBED* - Parameter that can be set to cmake to turn off building library, useful if you want to include asmjit in your project without building the library. - * *ASMJIT_STATIC* - Define when building AsmJit as a static library. No symbols will be exported by AsmJit by default. - * *ASMJIT_API* - This is AsmJit API decorator that is used in all functions that has to be exported. It can be redefined, however it's not a recommended way. - * By default AsmJit build is configured as a shared library and *ASMJIT_API* contains compiler specific attributes to import/export AsmJit symbols. + * `ASMJIT_EMBED` - Parameter that can be set to cmake to turn off building library, useful if you want to include asmjit in your project without building the library. `ASMJIT_EMBED` behaves identically as `ASMJIT_STATIC`. + * `ASMJIT_STATIC` - Define when building AsmJit as a static library. No symbols will be exported by AsmJit by default. -### Backends - - * *ASMJIT_BUILD_X86* - Always build x86 backend regardless of host architecture. - * *ASMJIT_BUILD_X64* - Always build x64 backend regardless of host architecture. - * *ASMJIT_BUILD_HOST* - Always build host backand, if only *ASMJIT_BUILD_HOST* is used only the host architecture detected at compile-time will be included. - * By default only *ASMJIT_BUILD_HOST* is defined. + * By default AsmJit build is configured as a shared library so none of `ASMJIT_EMBED` and `ASMJIT_STATIC` have to be defined explicitly. ### Build Mode - * *ASMJIT_DEBUG* - Define to always turn debugging on (regardless of build-mode). - * *ASMJIT_RELEASE* - Define to always turn debugging off (regardless of build-mode). + * `ASMJIT_DEBUG` - Define to always turn debugging on (regardless of build-mode). + * `ASMJIT_RELEASE` - Define to always turn debugging off (regardless of build-mode). + * `ASMJIT_TRACE` - Define to enable AsmJit tracing. Tracing is used to catch bugs in AsmJit and it has to be enabled explicitly. When AsmJit is compiled with `ASMJIT_TRACE` it uses `stdout` to log information related to AsmJit execution. This log can be helpful when examining liveness analysis, register allocation or any other part of AsmJit. + * By default none of these is defined, AsmJit detects mode based on compile-time macros (useful when using IDE that has switches for Debug/Release/etc...). -To build AsmJit please use cmake that will generate project files for your favorite IDE and platform. If you don't use cmake and you still want to include AsmJit in your project it's perfectly fine by just including it there, probably defining *ASMJIT_STATIC* to prevent AsmJit trying to export the API. +### Architectures + + * `ASMJIT_BUILD_X86` - Always build x86 backend regardless of host architecture. + * `ASMJIT_BUILD_X64` - Always build x64 backend regardless of host architecture. + * `ASMJIT_BUILD_HOST` - Always build host backand, if only `ASMJIT_BUILD_HOST` is used only the host architecture detected at compile-time will be included. + + * By default only `ASMJIT_BUILD_HOST` is defined. + +### Features + + * `ASMJIT_DISABLE_COMPILER` - Disable `Compiler` completely. Use this flag if you don't use Compiler and want slimmer binary. + + * `ASMJIT_DISABLE_LOGGER` - Disable `Logger` completely. Use this flag if you don't need `Logger` functionality and want slimmer binary. AsmJit compiled with or without `Logger` support is binary compatible (all classes that use Logger pointer will simply use `void*`), but the Logger interface and in general instruction dumps are not available. + + * `ASMJIT_DISABLE_NAMES` = Disable everything that uses strings and that causes that certain strings are stored in the resulting binary. For example when this flag is enabled instruction or error names (and related APIs) will not be available. This flag has to be disabled together with `ASMJIT_DISABLE_LOGGER`. Using AsmJit ------------ -AsmJit test suite contains up-to-date tests that can be used as a starting point. Base concepts are discussed below. Most of the constructs will work in pure Assembler if variables are replaced by registers and functions prologs/epilogs hand coded. The Compiler is used just to make things simple and most of users prefer it anyway. To use AsmJit basic skills to setup your environment are required and not discussed here. - -AsmJit library uses one global namespace called `asmjit` which contains the basics. Architecture specific code is nested, for example x86 support is in `asmjit::x86`, x64 support is in `asmjit::x64` and shared x86/x64 in `asmjit::x86x64`. To make things simple AsmJit provides `asmjit::host` namespace which imports namespace of the detected host architecture automatically. Nested namespaces were introduced to enable support of multiple architectures in the future and to make JIT code generation a special case, not a mandatory requirement. To use AsmJit include only the main `asmjit.h` header usually in form ``, don't include headers found in subdirectories. +AsmJit library uses one global namespace called `asmjit`, which contains the basics. Architecture specific code is prefixed by the architecture and architecture registers and operand builders are in its own namespace. For example classes for both x86 and x64 code generation are prefixed by `X86`, enums by `kX86`, registers and operand builders are accessible through `x86` namespace. This design is very different from the initial version of AsmJit and it seems now as the most convenient one. ### Runtime & Code-Generators -AsmJit contains two classes that are required to generate machine code. Runtime specifies where the code is generated and acts as a storage, while Code-Generator specifies how the code is generated and acts as a machine code stream. All the examples here use `asmjit::host::Compiler` class to generate the code and 'asmjit::JitRuntime` to store and run it. +AsmJit contains two classes that are required to generate a machine code. `Runtime` specifies where the code is generated and acts as a storage, while `CodeGen` specifies how the code is generated and acts as a machine code stream. All the examples here use `Compiler` code-generator to generate the code and `JitRuntime` to store and run it. ### Instruction Operands Operand is a part of CPU instruction which specifices the data the instruction will operate on. There are five types of operands in AsmJit: - * *Register* - Physical register (used only by Assember) - * *Variable* - Virtual register (used only by Compiler) - * *Memory* - Location in memory - * *Label* - Location in code - * *Immediate* - Constant that is encoded with the instruction itself + * `Reg` - Physical register, used only by `Assember` + * `Var` - Virtual register, used only by `Compiler` + * `Mem` - Used to reference memory location + * `Label` - Used to reference a location in code + * `Imm` - Immediate value that is encoded with the instruction itself -Base class for all operands is `asmjit::Operand`, but it contains only interface that can be used by all of them. Operand is a statically allocated structure that acts lika a value, not a pointer - just copy if you need multiple instances of the same operand. Since the most of the operands are architecture dependent,AsmJit always contain a base-operand structure - for example `asmjit::BaseReg` or `asmjit::BaseMem` and their architecture specific counterparts `asmjit::x86x64::GpReg` or `asmjit::x86x64::Mem`. +Base class for all operands is `Operand`. It contains interface that can be used by all types of operands only and it is typically pased by value, not as a pointer. The classes `Reg`, `Var`, `BaseMem`, `Label` and `Imm` all inherit `Operand` and provide an operand specific functionality. Architecture specific operands are prefixed by the architecture like `X86Reg` or `X86Mem`. Most of the architectures provide several types of registers, for example x86/x64 architecture has `X86GpReg`, `X86MmReg`, `X86FpReg`, `X86XmmReg` and `X86YmmReg` registers plus some extras including segment registers and `rip` (relative instruction pointer). -When using a code-generator some operands have to be created explicitly, for example use `newLabel()` to create a label and `newGpVar()` to create a virtual general purpose register. +When using a code-generator some operands have to be created explicitly by using its interface. For example labels are created by using `newLabel()` method of the code-generator and variables are used by using architecture specific methods like `newGpVar()`, `newMmVar()` or `newXmmVar()`. ### Function Prototypes @@ -146,7 +153,7 @@ using namespace asmjit::host; int main(int argc, char* argv[]) { // Create JitRuntime and host specific Compiler. JitRuntime runtime; - Compiler c(&runtime); + X86Compiler c(&runtime); // Build function having two arguments and a return value of type 'int'. // First type in function builder describes the return value. kFuncConvHost @@ -156,8 +163,8 @@ int main(int argc, char* argv[]) { // Create 32-bit variables (virtual registers) and assign some names to // them. Using names is purely optional and only greatly helps while // debugging. - GpVar a(c, kVarTypeInt32, "a"); - GpVar b(c, kVarTypeInt32, "b"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar b(c, kVarTypeInt32, "b"); // Tell asmjit to use these variables as function arguments. c.setArg(0, a); @@ -215,7 +222,7 @@ The function starts with `c.addFunc()` and ends with `c.endFunc()`. It's not all ### Using Labels -Labels are essential for making jumps, function calls or to refer to a data that is embedded in the code section. Label has to be explicitly created by using `newLabel()` member function of your code generator in order to be used. The following example executes a code that depends on the condition by using a `Label` and conditional jump instruction. If the first parameter is zero it returns `a + b`, otherwise `a - b`. +Labels are essential for making jumps, function calls or to refer to a data that is embedded in the code section. Label has to be explicitly created by using `newLabel()` method of your code generator in order to be used. The following example executes a code that depends on the condition by using a `Label` and conditional jump instruction. If the first parameter is zero it returns `a + b`, otherwise `a - b`. ```C++ #include @@ -225,15 +232,15 @@ using namespace asmjit::host; int main(int argc, char* argv[]) { JitRuntime runtime; - Compiler c(&runtime); + X86Compiler c(&runtime); // This function uses 3 arguments. c.addFunc(kFuncConvHost, FuncBuilder3()); // New variable 'op' added. - GpVar op(c, kVarTypeInt32, "op"); - GpVar a(c, kVarTypeInt32, "a"); - GpVar b(c, kVarTypeInt32, "b"); + X86GpVar op(c, kVarTypeInt32, "op"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar b(c, kVarTypeInt32, "b"); c.setArg(0, op); c.setArg(1, a); @@ -297,21 +304,21 @@ using namespace asmjit::host; int main(int argc, char* argv[]) { JitRuntime runtime; - Compiler c(&runtime); + X86Compiler c(&runtime); // Function returning 'int' accepting pointer and two indexes. c.addFunc(kFuncConvHost, FuncBuilder3()); - GpVar p(c, kVarTypeIntPtr, "p"); - GpVar aIndex(c, kVarTypeIntPtr, "aIndex"); - GpVar bIndex(c, kVarTypeIntPtr, "bIndex"); + X86GpVar p(c, kVarTypeIntPtr, "p"); + X86GpVar aIndex(c, kVarTypeIntPtr, "aIndex"); + X86GpVar bIndex(c, kVarTypeIntPtr, "bIndex"); c.setArg(0, p); c.setArg(1, aIndex); c.setArg(2, bIndex); - GpVar a(c, kVarTypeInt32, "a"); - GpVar b(c, kVarTypeInt32, "b"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar b(c, kVarTypeInt32, "b"); // Read 'a' by using a memory operand having base register, index register // and scale. Translates to 'mov a, dword ptr [p + aIndex << 2]'. @@ -326,11 +333,11 @@ int main(int argc, char* argv[]) { c.add(p, bIndex); // Read 'b'. - c.mov(b, ptr(p)); - + c.mov(b, ptr(p)); + // a = a + b; c.add(a, b); - + c.ret(a); c.endFunc(); @@ -354,7 +361,7 @@ int main(int argc, char* argv[]) { ### Using Stack -AsmJit uses stack automatically to spill variables if there is not enough registers to keep them all allocated. Stack is allocated automatically by Compiler and it's not allowed to manipulate it directly. However, Compiler provides an interface to allocate chunks of memory of user specified size and alignment on the stack. +AsmJit uses stack automatically to spill variables if there is not enough registers to keep them all allocated. The stack frame is managed by `Compiler` that provides also an interface to allocate chunks of memory of user specified size and alignment. In the following example a stack of 256 bytes size is allocated, filled by bytes starting from 0 to 255 and then iterated again to sum all the values. @@ -366,16 +373,16 @@ using namespace asmjit::host; int main(int argc, char* argv[]) { JitRuntime runtime; - Compiler c(&runtime); + X86Compiler c(&runtime); // Function returning 'int' without any arguments. c.addFunc(kFuncConvHost, FuncBuilder0()); // Allocate a function stack of size 256 aligned to 4 bytes. - Mem stack = c.newStack(256, 4); + X86Mem stack = c.newStack(256, 4); - GpVar p(c, kVarTypeIntPtr, "p"); - GpVar i(c, kVarTypeIntPtr, "i"); + X86GpVar p(c, kVarTypeIntPtr, "p"); + X86GpVar i(c, kVarTypeIntPtr, "i"); // Load a stack address to 'p'. This step is purely optional and shows // that 'lea' is useful to load a memory operands address (even absolute) @@ -404,8 +411,8 @@ int main(int argc, char* argv[]) { c.jb(L1); // Second loop, sum all bytes stored in 'stack'. - GpVar a(c, kVarTypeInt32, "a"); - GpVar t(c, kVarTypeInt32, "t"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar t(c, kVarTypeInt32, "t"); c.xor_(i, i); c.xor_(a, a); @@ -448,30 +455,71 @@ AsmJit offers much more, but not everything can fit into the introduction. The f ### Logging and Error Handling -Failures are common when working at machine level. AsmJit does already a good job by using overloaded functions per instruction to prevent from emitting semantically incorrect code. However, AsmJit can't prevent you from emitting code that is semantically correct, but doesn't do what it it supposed to do. Logging has always been an important part of AsmJit's infrastructure and the output can be very valuable after something went wrong. +Failures are common when working at machine level. AsmJit does already a good job with function overloading to prevent from emitting semantically incorrect instructions; however, AsmJit can't prevent from emitting code that is semantically correct, but contains bug(s). Logging has always been an important part of AsmJit's infrastructure and the output can be very valuable after something went wrong. -To be documented. +AsmJit contains extensible logging interface defined by `Logger` class and implemented by `FileLogger` and `StringLogger`. `FileLogger` can log into a standard C-based `FILE*` stream while `StringLogger` logs to an internal buffer that can be used after the code generation is done. + +Loggers can be assigned to any code generator and there is no restriction of assigning a single logger to multiple code generators, but this is not practical when running these in multiple threads. `FileLogger` is thread-safe since it uses plain C `FILE*` stream, but `StringLogger` is not! + +The following snippet describes how to log into `FILE*`: + +```C++ +// Create logger logging to `stdout`. Logger life-time should always be +// greater than lifetime of the code generator. +FileLogger logger(stdout); + +// Create a code generator and assign our logger into it. +X86Compiler c(...); +c.setLogger(&logger); + +// ... Generate the code ... +``` + +The following snippet describes how to log into a string: + +```C++ +StringLogger logger; + +// Create a code generator and assign our logger into it. +X86Compiler c(...); +c.setLogger(&logger); + +// ... Generate the code ... + +printf("Logger Content:\n%s", logger.getString()); + +// You can also use `logger.clearString()` if the logger +// instance will be reused. +``` + +Logger can be configured to show more information by using `logger.setOption()` method. The following options are available: + + * `kLoggerOptionBinaryForm` - Log also binary sequence for each instruction generated. + * `kLoggerOptionHexImmediate` - Format immediate values to base16 (hex) form. + * `kLoggerOptionHexDisplacement` - Format memory displacements to base16 (hex) form. + +TODO: Liveness analysis and instruction scheduling options. ### Code Injection Code injection was one of key concepts of Compiler from the beginning. Compiler records all emitted instructions in a double-linked list which can be manipulated before `make()` is called. Any call to Compiler that adds instruction, function or anything else in fact manipulates this list by inserting nodes into it. -To manipulate the current cursor use Compiler's `getCursor()` and `setCursor()` member functions. The following snippet demonstrates the proper way of code injection. +To manipulate the current cursor use Compiler's `getCursor()` and `setCursor()` methods. The following snippet demonstrates the proper way of code injection. ```C++ -Compiler c(...); +X86Compiler c(...); -GpVar a(c, kVarTypeInt32, "a"); -GpVar b(c, kVarTypeInt32, "b"); +X86GpVar a(c, kVarTypeInt32, "a"); +X86GpVar b(c, kVarTypeInt32, "b"); -BaseNode* here = c.getCursor(); +Node* here = c.getCursor(); c.mov(b, 2); // Now, 'here' can be used to inject something before 'mov b, 2'. To inject // anything it's good to remember the current cursor so it can be set back // after the injecting is done. When setCursor() is called it returns the old // cursor. -BaseNode* oldCursor = c.setCursor(here); +Node* oldCursor = c.setCursor(here); c.mov(a, 1); c.setCursor(oldCursor); ``` diff --git a/src/app/test/benchx86.cpp b/src/app/test/benchx86.cpp index 7eb436e..ef7b97a 100644 --- a/src/app/test/benchx86.cpp +++ b/src/app/test/benchx86.cpp @@ -53,17 +53,21 @@ struct Performance { // [Main] // ============================================================================ +static uint32_t instPerMs(uint32_t time, uint32_t numIterations, uint32_t instPerIteration) { + return static_cast( + static_cast(numIterations) * instPerIteration * 1000 / time); +} + int main(int argc, char* argv[]) { using namespace asmjit; - using namespace asmjit::host; Performance perf; uint32_t kNumRepeats = 10; - uint32_t kNumIterations = 100000; + uint32_t kNumIterations = 10000; JitRuntime runtime; - Assembler a(&runtime); - Compiler c(&runtime); + X86Assembler a(&runtime); + X86Compiler c(&runtime); uint32_t r, i; @@ -80,11 +84,13 @@ int main(int argc, char* argv[]) { void *p = a.make(); runtime.release(p); - a.clear(); + a.reset(); } perf.end(); } - printf("Opcode | Time: %u [ms]\n", perf.best); + + printf("Opcode | Time: %-6u [ms] | Speed: %-9u [inst/s]\n", + perf.best, instPerMs(perf.best, kNumIterations, asmgen::kGenOpCodeInstCount)); // -------------------------------------------------------------------------- // [Bench - Blend] @@ -99,11 +105,13 @@ int main(int argc, char* argv[]) { void* p = c.make(); runtime.release(p); - c.clear(); + c.reset(); } perf.end(); } - printf("Blend | Time: %u [ms]\n", perf.best); + + printf("Blend | Time: %-6u [ms] | Speed: %-9u [inst/s]\n", + perf.best, instPerMs(perf.best, kNumIterations, asmgen::kGenBlendInstCount)); return 0; } diff --git a/src/app/test/genblend.h b/src/app/test/genblend.h index 0fcd375..83d5e41 100644 --- a/src/app/test/genblend.h +++ b/src/app/test/genblend.h @@ -13,29 +13,31 @@ namespace asmgen { +enum { kGenBlendInstCount = 65 }; + // Generate a typical alpha blend function using SSE2 instruction set. Used // for benchmarking and also in test86. The generated code should be stable // and fully functional. -static void blend(asmjit::host::Compiler& c) { +static void blend(asmjit::X86Compiler& c) { using namespace asmjit; - using namespace asmjit::host; + using namespace asmjit::x86; - GpVar dst(c, kVarTypeIntPtr, "dst"); - GpVar src(c, kVarTypeIntPtr, "src"); + X86GpVar dst(c, kVarTypeIntPtr, "dst"); + X86GpVar src(c, kVarTypeIntPtr, "src"); - GpVar i(c, kVarTypeIntPtr, "i"); - GpVar j(c, kVarTypeIntPtr, "j"); - GpVar t(c, kVarTypeIntPtr, "t"); + X86GpVar i(c, kVarTypeIntPtr, "i"); + X86GpVar j(c, kVarTypeIntPtr, "j"); + X86GpVar t(c, kVarTypeIntPtr, "t"); - XmmVar cZero(c, kVarTypeXmm, "cZero"); - XmmVar cMul255A(c, kVarTypeXmm, "cMul255A"); - XmmVar cMul255M(c, kVarTypeXmm, "cMul255M"); + X86XmmVar cZero(c, kX86VarTypeXmm, "cZero"); + X86XmmVar cMul255A(c, kX86VarTypeXmm, "cMul255A"); + X86XmmVar cMul255M(c, kX86VarTypeXmm, "cMul255M"); - XmmVar x0(c, kVarTypeXmm, "x0"); - XmmVar x1(c, kVarTypeXmm, "x1"); - XmmVar y0(c, kVarTypeXmm, "y0"); - XmmVar a0(c, kVarTypeXmm, "a0"); - XmmVar a1(c, kVarTypeXmm, "a1"); + X86XmmVar x0(c, kX86VarTypeXmm, "x0"); + X86XmmVar x1(c, kX86VarTypeXmm, "x1"); + X86XmmVar y0(c, kX86VarTypeXmm, "y0"); + X86XmmVar a0(c, kX86VarTypeXmm, "a0"); + X86XmmVar a1(c, kX86VarTypeXmm, "a1"); Label L_SmallLoop(c); Label L_SmallEnd(c); @@ -45,7 +47,7 @@ static void blend(asmjit::host::Compiler& c) { Label L_Data(c); - c.addFunc(kFuncConvHost, FuncBuilder3()); + c.addFunc(kFuncConvHost, FuncBuilder3()); c.setArg(0, dst); c.setArg(1, src); @@ -168,8 +170,8 @@ static void blend(asmjit::host::Compiler& c) { // Data. c.align(kAlignData, 16); c.bind(L_Data); - c.dxmm(XmmData::fromSw(0x0080)); - c.dxmm(XmmData::fromSw(0x0101)); + c.dxmm(Vec128::fromSw(0x0080)); + c.dxmm(Vec128::fromSw(0x0101)); } } // asmgen namespace diff --git a/src/app/test/genopcode.h b/src/app/test/genopcode.h index f2ae7fc..4a95032 100644 --- a/src/app/test/genopcode.h +++ b/src/app/test/genopcode.h @@ -13,10 +13,21 @@ namespace asmgen { +enum { kGenOpCodeInstCount = 2640 }; + // Generate all instructions asmjit can emit. -static void opcode(asmjit::host::Assembler& a) { +static void opcode(asmjit::X86Assembler& a) { using namespace asmjit; - using namespace asmjit::host; + using namespace asmjit::x86; + + const X86GpReg& zax = a.zax; + const X86GpReg& zdx = a.zdx; + const X86GpReg& zcx = a.zcx; + const X86GpReg& zbx = a.zbx; + const X86GpReg& zsp = a.zsp; + const X86GpReg& zbp = a.zbp; + const X86GpReg& zsi = a.zsi; + const X86GpReg& zdi = a.zdi; // Prevent crashing when the generated function is called (for debugging to // see disassembly). @@ -24,18 +35,18 @@ static void opcode(asmjit::host::Assembler& a) { // When any problem is found this section can be used to customize the index // of the registers used. - GpReg gp0 = zax; - GpReg gp1 = zsi; - FpReg fpx = fp6; + X86GpReg gp0 = zax; + X86GpReg gp1 = zsi; + X86FpReg fpx = fp6; - Mem ptr_gp0 = ptr(gp0); - Mem ptr_gp1 = ptr(gp1); + X86Mem ptr_gp0 = ptr(gp0); + X86Mem ptr_gp1 = ptr(gp1); - Mem vm32x = ptr(gp0, xmm1); - Mem vm32y = ptr(gp0, ymm1); + X86Mem vm32x = ptr(gp0, xmm1); + X86Mem vm32y = ptr(gp0, ymm1); - Mem intptr_gp0 = intptr_ptr(gp0); - Mem intptr_gp1 = intptr_ptr(gp1); + X86Mem intptr_gp0 = a.intptr_ptr(gp0); + X86Mem intptr_gp1 = a.intptr_ptr(gp1); // Base. a.adc(al, 1); @@ -268,6 +279,49 @@ static void opcode(asmjit::host::Assembler& a) { a.xor_(intptr_gp0, gp1); a.xor_(intptr_gp0, 0); + a.nop(); + + a.lodsb(); + a.lodsd(); + a.lodsw(); + a.rep_lodsb(); + a.rep_lodsd(); + a.rep_lodsw(); + + a.movsb(); + a.movsd(); + a.movsw(); + a.rep_movsb(); + a.rep_movsd(); + a.rep_movsw(); + + a.stosb(); + a.stosd(); + a.stosw(); + a.rep_stosb(); + a.rep_stosd(); + a.rep_stosw(); + + a.cmpsb(); + a.cmpsd(); + a.cmpsw(); + a.repe_cmpsb(); + a.repe_cmpsd(); + a.repe_cmpsw(); + a.repne_cmpsb(); + a.repne_cmpsd(); + a.repne_cmpsw(); + + a.scasb(); + a.scasd(); + a.scasw(); + a.repe_scasb(); + a.repe_scasd(); + a.repe_scasw(); + a.repne_scasb(); + a.repne_scasd(); + a.repne_scasw(); + // Label...Jcc/Jecxz/Jmp. { a.nop(); diff --git a/src/app/test/testopcode.cpp b/src/app/test/testopcode.cpp index dd5332b..eb71d40 100644 --- a/src/app/test/testopcode.cpp +++ b/src/app/test/testopcode.cpp @@ -29,7 +29,7 @@ int main(int argc, char* argv[]) { logger.setOption(kLoggerOptionBinaryForm, true); JitRuntime runtime; - Assembler a(&runtime); + X86Assembler a(&runtime); a.setLogger(&logger); asmgen::opcode(a); diff --git a/src/app/test/testx86.cpp b/src/app/test/testx86.cpp index 3687af7..1a0fddd 100644 --- a/src/app/test/testx86.cpp +++ b/src/app/test/testx86.cpp @@ -16,7 +16,6 @@ #include using namespace asmjit; -using namespace asmjit::host; // ============================================================================ // [X86Test] @@ -29,7 +28,7 @@ struct X86Test { ASMJIT_INLINE const char* getName() const { return _name.getData(); } - virtual void compile(Compiler& c) = 0; + virtual void compile(X86Compiler& c) = 0; virtual bool run(void* func, StringBuilder& result, StringBuilder& expect) = 0; StringBuilder _name; @@ -49,7 +48,7 @@ struct X86Test_AlignBase : public X86Test { _name.setFormat("[Align] Args=%u Vars=%u Naked=%c PushPop=%c", argCount, varCount, - naked ? 'Y' : 'N', + naked ? 'Y' : 'N', pushPop ? 'Y' : 'N'); } @@ -64,7 +63,7 @@ struct X86Test_AlignBase : public X86Test { } } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { switch (_argCount) { case 0: c.addFunc(kFuncConvHost, FuncBuilder0()); break; case 1: c.addFunc(kFuncConvHost, FuncBuilder1()); break; @@ -76,14 +75,15 @@ struct X86Test_AlignBase : public X86Test { } c.getFunc()->setHint(kFuncHintNaked, _naked); - c.getFunc()->setHint(kFuncHintPushPop, _pushPop); + c.getFunc()->setHint(kX86FuncHintPushPop, _pushPop); - GpVar gpVar(c, kVarTypeIntPtr); - GpVar gpSum(c, kVarTypeInt32); - XmmVar xmmVar(c, kVarTypeXmm); + X86GpVar gpVar(c, kVarTypeIntPtr); + X86GpVar gpSum(c, kVarTypeInt32); + X86XmmVar xmmVar(c, kX86VarTypeXmm); // Alloc, use and spill preserved registers. if (_varCount) { + uint32_t gpCount = c.getRegCount().getGp(); c.comment("Var"); uint32_t varIndex = 0; @@ -92,8 +92,8 @@ struct X86Test_AlignBase : public X86Test { uint32_t preservedMask = c.getFunc()->getDecl()->getPreserved(kRegClassGp); do { - if ((preservedMask & regMask) != 0 && (regIndex != kRegIndexSp && regIndex != kRegIndexBp)) { - GpVar tmp(c, kVarTypeInt32); + if ((preservedMask & regMask) != 0 && (regIndex != kX86RegIndexSp && regIndex != kX86RegIndexBp)) { + X86GpVar tmp(c, kVarTypeInt32); c.alloc(tmp, regIndex); c.xor_(tmp, tmp); c.spill(tmp); @@ -102,7 +102,7 @@ struct X86Test_AlignBase : public X86Test { regIndex++; regMask <<= 1; - } while (varIndex < _varCount && regIndex < kRegCountGp); + } while (varIndex < _varCount && regIndex < gpCount); } // Do a sum of arguments to verify possible relocation when misaligned. @@ -113,7 +113,7 @@ struct X86Test_AlignBase : public X86Test { c.xor_(gpSum, gpSum); for (argIndex = 0; argIndex < _argCount; argIndex++) { - GpVar gpArg(c, kVarTypeInt32); + X86GpVar gpArg(c, kVarTypeInt32); c.setArg(argIndex, gpArg); c.add(gpSum, gpArg); @@ -200,8 +200,8 @@ struct X86Test_JumpCross : public X86Test { tests.append(new X86Test_JumpCross()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder0()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder0()); Label L_1(c); Label L_2(c); @@ -241,8 +241,8 @@ struct X86Test_JumpUnreachable1 : public X86Test { tests.append(new X86Test_JumpUnreachable1()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder0()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder0()); Label L_1(c); Label L_2(c); @@ -252,8 +252,8 @@ struct X86Test_JumpUnreachable1 : public X86Test { Label L_6(c); Label L_7(c); - GpVar v0(c, kVarTypeUInt32, "v0"); - GpVar v1(c, kVarTypeUInt32, "v1"); + X86GpVar v0(c, kVarTypeUInt32, "v0"); + X86GpVar v1(c, kVarTypeUInt32, "v1"); c.bind(L_2); c.bind(L_3); @@ -302,14 +302,14 @@ struct X86Test_JumpUnreachable2 : public X86Test { tests.append(new X86Test_JumpUnreachable2()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder0()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder0()); Label L_1(c); Label L_2(c); - GpVar v0(c, kVarTypeUInt32, "v0"); - GpVar v1(c, kVarTypeUInt32, "v1"); + X86GpVar v0(c, kVarTypeUInt32, "v0"); + X86GpVar v1(c, kVarTypeUInt32, "v1"); c.jmp(L_1); c.bind(L_2); @@ -348,14 +348,14 @@ struct X86Test_AllocBase : public X86Test { tests.append(new X86Test_AllocBase()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); - GpVar v0(c, kVarTypeInt32, "v0"); - GpVar v1(c, kVarTypeInt32, "v1"); - GpVar v2(c, kVarTypeInt32, "v2"); - GpVar v3(c, kVarTypeInt32, "v3"); - GpVar v4(c, kVarTypeInt32, "v4"); + X86GpVar v0(c, kVarTypeInt32, "v0"); + X86GpVar v1(c, kVarTypeInt32, "v1"); + X86GpVar v2(c, kVarTypeInt32, "v2"); + X86GpVar v3(c, kVarTypeInt32, "v3"); + X86GpVar v4(c, kVarTypeInt32, "v4"); c.xor_(v0, v0); @@ -398,12 +398,12 @@ struct X86Test_AllocManual : public X86Test { tests.append(new X86Test_AllocManual()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); - GpVar v0(c, kVarTypeInt32, "v0"); - GpVar v1(c, kVarTypeInt32, "v1"); - GpVar cnt(c, kVarTypeInt32, "cnt"); + X86GpVar v0(c, kVarTypeInt32, "v0"); + X86GpVar v1(c, kVarTypeInt32, "v1"); + X86GpVar cnt(c, kVarTypeInt32, "cnt"); c.xor_(v0, v0); c.xor_(v1, v1); @@ -453,14 +453,14 @@ struct X86Test_AllocUseMem : public X86Test { tests.append(new X86Test_AllocUseMem()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar iIdx(c, kVarTypeInt32); - GpVar iEnd(c, kVarTypeInt32); + X86GpVar iIdx(c, kVarTypeInt32); + X86GpVar iEnd(c, kVarTypeInt32); - GpVar aIdx(c, kVarTypeInt32); - GpVar aEnd(c, kVarTypeInt32); + X86GpVar aIdx(c, kVarTypeInt32); + X86GpVar aEnd(c, kVarTypeInt32); Label L_1(c); @@ -507,18 +507,18 @@ struct X86Test_AllocMany1 : public X86Test { tests.append(new X86Test_AllocMany1()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder2()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar a0(c, kVarTypeIntPtr, "a0"); - GpVar a1(c, kVarTypeIntPtr, "a1"); + X86GpVar a0(c, kVarTypeIntPtr, "a0"); + X86GpVar a1(c, kVarTypeIntPtr, "a1"); c.setArg(0, a0); c.setArg(1, a1); // Create some variables. - GpVar t(c, kVarTypeInt32); - GpVar x[kCount]; + X86GpVar t(c, kVarTypeInt32); + X86GpVar x[kCount]; uint32_t i; for (i = 0; i < kCount; i++) { @@ -537,7 +537,7 @@ struct X86Test_AllocMany1 : public X86Test { } // Store result to a given pointer in first argument. - c.mov(dword_ptr(a0), t); + c.mov(x86::dword_ptr(a0), t); // Clear t. c.xor_(t, t); @@ -548,7 +548,7 @@ struct X86Test_AllocMany1 : public X86Test { } // Store result to a given pointer in second argument. - c.mov(dword_ptr(a1), t); + c.mov(x86::dword_ptr(a1), t); // End of function. c.endFunc(); @@ -584,11 +584,11 @@ struct X86Test_AllocMany2 : public X86Test { tests.append(new X86Test_AllocMany2()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder1()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder1()); - GpVar var[32]; - GpVar a(c, kVarTypeIntPtr, "a"); + X86GpVar var[32]; + X86GpVar a(c, kVarTypeIntPtr, "a"); c.setArg(0, a); @@ -601,7 +601,7 @@ struct X86Test_AllocMany2 : public X86Test { c.xor_(var[i], var[i]); } - GpVar v0(c, kVarTypeInt32); + X86GpVar v0(c, kVarTypeInt32); Label L(c); c.mov(v0, 32); @@ -615,7 +615,7 @@ struct X86Test_AllocMany2 : public X86Test { c.jnz(L); for (i = 0; i < ASMJIT_ARRAY_SIZE(var); i++) { - c.mov(dword_ptr(a, i * 4), var[i]); + c.mov(x86::dword_ptr(a, i * 4), var[i]); } c.endFunc(); @@ -658,15 +658,15 @@ struct X86Test_AllocImul1 : public X86Test { tests.append(new X86Test_AllocImul1()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder4()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder4()); - GpVar dstHi(c, kVarTypeIntPtr, "dstHi"); - GpVar dstLo(c, kVarTypeIntPtr, "dstLo"); + X86GpVar dstHi(c, kVarTypeIntPtr, "dstHi"); + X86GpVar dstLo(c, kVarTypeIntPtr, "dstLo"); - GpVar vHi(c, kVarTypeInt32, "vHi"); - GpVar vLo(c, kVarTypeInt32, "vLo"); - GpVar src(c, kVarTypeInt32, "src"); + X86GpVar vHi(c, kVarTypeInt32, "vHi"); + X86GpVar vLo(c, kVarTypeInt32, "vLo"); + X86GpVar src(c, kVarTypeInt32, "src"); c.setArg(0, dstHi); c.setArg(1, dstLo); @@ -675,8 +675,8 @@ struct X86Test_AllocImul1 : public X86Test { c.imul(vHi, vLo, src); - c.mov(dword_ptr(dstHi), vHi); - c.mov(dword_ptr(dstLo), vLo); + c.mov(x86::dword_ptr(dstHi), vHi); + c.mov(x86::dword_ptr(dstLo), vLo); c.endFunc(); } @@ -713,26 +713,26 @@ struct X86Test_AllocImul2 : public X86Test { tests.append(new X86Test_AllocImul2()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder2()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar dst(c, kVarTypeIntPtr, "dst"); - GpVar src(c, kVarTypeIntPtr, "src"); + X86GpVar dst(c, kVarTypeIntPtr, "dst"); + X86GpVar src(c, kVarTypeIntPtr, "src"); c.setArg(0, dst); c.setArg(1, src); for (unsigned int i = 0; i < 4; i++) { - GpVar x(c, kVarTypeInt32, "x"); - GpVar y(c, kVarTypeInt32, "y"); - GpVar hi(c, kVarTypeInt32, "hi"); + X86GpVar x(c, kVarTypeInt32, "x"); + X86GpVar y(c, kVarTypeInt32, "y"); + X86GpVar hi(c, kVarTypeInt32, "hi"); - c.mov(x, dword_ptr(src, 0)); - c.mov(y, dword_ptr(src, 4)); + c.mov(x, x86::dword_ptr(src, 0)); + c.mov(y, x86::dword_ptr(src, 4)); c.imul(hi, x, y); - c.add(dword_ptr(dst, 0), hi); - c.add(dword_ptr(dst, 4), x); + c.add(x86::dword_ptr(dst, 0), hi); + c.add(x86::dword_ptr(dst, 4), x); } c.endFunc(); @@ -766,19 +766,19 @@ struct X86Test_AllocSetz : public X86Test { tests.append(new X86Test_AllocSetz()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder3()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder3()); - GpVar src0(c, kVarTypeInt32, "src0"); - GpVar src1(c, kVarTypeInt32, "src1"); - GpVar dst0(c, kVarTypeIntPtr, "dst0"); + X86GpVar src0(c, kVarTypeInt32, "src0"); + X86GpVar src1(c, kVarTypeInt32, "src1"); + X86GpVar dst0(c, kVarTypeIntPtr, "dst0"); c.setArg(0, src0); c.setArg(1, src1); c.setArg(2, dst0); c.cmp(src0, src1); - c.setz(byte_ptr(dst0)); + c.setz(x86::byte_ptr(dst0)); c.endFunc(); } @@ -816,13 +816,13 @@ struct X86Test_AllocShlRor : public X86Test { tests.append(new X86Test_AllocShlRor()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder4()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder4()); - GpVar dst(c, kVarTypeIntPtr, "dst"); - GpVar var(c, kVarTypeInt32, "var"); - GpVar vShlParam(c, kVarTypeInt32, "vShlParam"); - GpVar vRorParam(c, kVarTypeInt32, "vRorParam"); + X86GpVar dst(c, kVarTypeIntPtr, "dst"); + X86GpVar var(c, kVarTypeInt32, "var"); + X86GpVar vShlParam(c, kVarTypeInt32, "vShlParam"); + X86GpVar vRorParam(c, kVarTypeInt32, "vRorParam"); c.setArg(0, dst); c.setArg(1, var); @@ -832,7 +832,7 @@ struct X86Test_AllocShlRor : public X86Test { c.shl(var, vShlParam); c.ror(var, vRorParam); - c.mov(dword_ptr(dst), var); + c.mov(x86::dword_ptr(dst), var); c.endFunc(); } @@ -867,15 +867,15 @@ struct X86Test_AllocGpLo : public X86Test { tests.append(new X86Test_AllocGpLo()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder1()); - GpVar rPtr(c, kVarTypeUIntPtr); - GpVar rSum(c, kVarTypeUInt32); + X86GpVar rPtr(c, kVarTypeUIntPtr); + X86GpVar rSum(c, kVarTypeUInt32); c.setArg(0, rPtr); - GpVar rVar[kCount]; + X86GpVar rVar[kCount]; uint32_t i; for (i = 0; i < kCount; i++) { @@ -884,7 +884,7 @@ struct X86Test_AllocGpLo : public X86Test { // Init pseudo-regs with values from our array. for (i = 0; i < kCount; i++) { - c.mov(rVar[i], dword_ptr(rPtr, i * 4)); + c.mov(rVar[i], x86::dword_ptr(rPtr, i * 4)); } for (i = 2; i < kCount; i++) { @@ -949,18 +949,18 @@ struct X86Test_AllocGpLo : public X86Test { // ============================================================================ struct X86Test_AllocRepMovsb : public X86Test { - X86Test_AllocRepMovsb() : X86Test("[Alloc] Rep Movsb") {} + X86Test_AllocRepMovsb() : X86Test("[Alloc] Rep MovsB") {} static void add(PodVector& tests) { - tests.append(new X86Test_AllocSetz()); + tests.append(new X86Test_AllocRepMovsb()); } - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder3()); + virtual void compile(X86Compiler& c) { + c.addFunc(kFuncConvHost, FuncBuilder3()); - GpVar dst(c, kVarTypeIntPtr, "dst"); - GpVar src(c, kVarTypeIntPtr, "src"); - GpVar cnt(c, kVarTypeIntPtr, "cnt"); + X86GpVar dst(c, kVarTypeIntPtr, "dst"); + X86GpVar src(c, kVarTypeIntPtr, "src"); + X86GpVar cnt(c, kVarTypeIntPtr, "cnt"); c.setArg(0, dst); c.setArg(1, src); @@ -974,7 +974,7 @@ struct X86Test_AllocRepMovsb : public X86Test { typedef void (*Func)(void*, void*, size_t); Func func = asmjit_cast(_func); - char dst[20]; + char dst[20] = { 0 }; char src[20] = "Hello AsmJit!"; func(dst, src, strlen(src) + 1); @@ -996,11 +996,11 @@ struct X86Test_AllocIfElse1 : public X86Test { tests.append(new X86Test_AllocIfElse1()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar v1(c, kVarTypeInt32); - GpVar v2(c, kVarTypeInt32); + X86GpVar v1(c, kVarTypeInt32); + X86GpVar v2(c, kVarTypeInt32); Label L_1(c); Label L_2(c); @@ -1047,11 +1047,11 @@ struct X86Test_AllocIfElse2 : public X86Test { tests.append(new X86Test_AllocIfElse2()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar v1(c, kVarTypeInt32); - GpVar v2(c, kVarTypeInt32); + X86GpVar v1(c, kVarTypeInt32); + X86GpVar v2(c, kVarTypeInt32); Label L_1(c); Label L_2(c); @@ -1107,12 +1107,12 @@ struct X86Test_AllocIfElse3 : public X86Test { tests.append(new X86Test_AllocIfElse3()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar v1(c, kVarTypeInt32); - GpVar v2(c, kVarTypeInt32); - GpVar counter(c, kVarTypeInt32); + X86GpVar v1(c, kVarTypeInt32); + X86GpVar v2(c, kVarTypeInt32); + X86GpVar counter(c, kVarTypeInt32); Label L_1(c); Label L_Loop(c); @@ -1167,12 +1167,12 @@ struct X86Test_AllocIfElse4 : public X86Test { tests.append(new X86Test_AllocIfElse4()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar v1(c, kVarTypeInt32); - GpVar v2(c, kVarTypeInt32); - GpVar counter(c, kVarTypeInt32); + X86GpVar v1(c, kVarTypeInt32); + X86GpVar v2(c, kVarTypeInt32); + X86GpVar counter(c, kVarTypeInt32); Label L_1(c); Label L_Loop1(c); @@ -1232,12 +1232,12 @@ struct X86Test_AllocArgsIntPtr : public X86Test { tests.append(new X86Test_AllocArgsIntPtr()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, - FuncBuilder8()); + FuncBuilder8()); uint32_t i; - GpVar var[8]; + X86GpVar var[8]; for (i = 0; i < 8; i++) { var[i] = c.newGpVar(); @@ -1251,7 +1251,7 @@ struct X86Test_AllocArgsIntPtr : public X86Test { // Move some data into buffer provided by arguments so we can verify if it // really works without looking into assembler output. for (i = 0; i < 8; i++) { - c.add(byte_ptr(var[i]), static_cast(i + 1)); + c.add(x86::byte_ptr(var[i]), static_cast(i + 1)); } c.endFunc(); @@ -1291,17 +1291,17 @@ struct X86Test_AllocArgsFloat : public X86Test { tests.append(new X86Test_AllocArgsFloat()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, - FuncBuilder8()); + FuncBuilder8()); uint32_t i; - XmmVar xv[7]; - GpVar p(c); + X86XmmVar xv[7]; + X86GpVar p(c); for (i = 0; i < 7; i++) { - xv[i] = c.newXmmVar(kVarTypeXmmSs); + xv[i] = c.newXmmVar(kX86VarTypeXmmSs); c.setArg(i, xv[i]); } @@ -1314,7 +1314,7 @@ struct X86Test_AllocArgsFloat : public X86Test { c.addss(xv[0], xv[5]); c.addss(xv[0], xv[6]); - c.movss(ptr(p), xv[0]); + c.movss(x86::ptr(p), xv[0]); c.endFunc(); } @@ -1345,17 +1345,17 @@ struct X86Test_AllocArgsDouble : public X86Test { tests.append(new X86Test_AllocArgsDouble()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, - FuncBuilder8()); + FuncBuilder8()); uint32_t i; - XmmVar xv[7]; - GpVar p(c); + X86XmmVar xv[7]; + X86GpVar p(c); for (i = 0; i < 7; i++) { - xv[i] = c.newXmmVar(kVarTypeXmmSd); + xv[i] = c.newXmmVar(kX86VarTypeXmmSd); c.setArg(i, xv[i]); } @@ -1368,7 +1368,7 @@ struct X86Test_AllocArgsDouble : public X86Test { c.addsd(xv[0], xv[5]); c.addsd(xv[0], xv[6]); - c.movsd(ptr(p), xv[0]); + c.movsd(x86::ptr(p), xv[0]); c.endFunc(); } @@ -1399,11 +1399,11 @@ struct X86Test_AllocRetFloat : public X86Test { tests.append(new X86Test_AllocRetFloat()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - XmmVar a(c, kVarTypeXmmSs); - XmmVar b(c, kVarTypeXmmSs); + X86XmmVar a(c, kX86VarTypeXmmSs); + X86XmmVar b(c, kX86VarTypeXmmSs); c.setArg(0, a); c.setArg(1, b); @@ -1439,11 +1439,11 @@ struct X86Test_AllocRetDouble : public X86Test { tests.append(new X86Test_AllocRetDouble()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - XmmVar a(c, kVarTypeXmmSd); - XmmVar b(c, kVarTypeXmmSd); + X86XmmVar a(c, kX86VarTypeXmmSd); + X86XmmVar b(c, kX86VarTypeXmmSd); c.setArg(0, a); c.setArg(1, b); @@ -1481,13 +1481,13 @@ struct X86Test_AllocStack : public X86Test { tests.append(new X86Test_AllocStack()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); - Mem stack = c.newStack(kSize, 1).setSize(1); - GpVar i(c, kVarTypeIntPtr, "i"); - GpVar a(c, kVarTypeInt32, "a"); - GpVar b(c, kVarTypeInt32, "b"); + X86Mem stack = c.newStack(kSize, 1).setSize(1); + X86GpVar i(c, kVarTypeIntPtr, "i"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar b(c, kVarTypeInt32, "b"); Label L_1(c); Label L_2(c); @@ -1543,15 +1543,15 @@ struct X86Test_AllocMemcpy : public X86Test { tests.append(new X86Test_AllocMemcpy()); } - virtual void compile(Compiler& c) { - GpVar dst(c, kVarTypeIntPtr, "dst"); - GpVar src(c, kVarTypeIntPtr, "src"); - GpVar cnt(c, kVarTypeUIntPtr, "cnt"); + virtual void compile(X86Compiler& c) { + X86GpVar dst(c, kVarTypeIntPtr, "dst"); + X86GpVar src(c, kVarTypeIntPtr, "src"); + X86GpVar cnt(c, kVarTypeUIntPtr, "cnt"); Label L_Loop(c); // Create base labels we use Label L_Exit(c); // in our function. - c.addFunc(kFuncConvHost, FuncBuilder3()); + c.addFunc(kFuncConvHost, FuncBuilder3()); c.setArg(0, dst); c.setArg(1, src); c.setArg(2, cnt); @@ -1565,9 +1565,9 @@ struct X86Test_AllocMemcpy : public X86Test { c.bind(L_Loop); // Bind the loop label here. - GpVar tmp(c, kVarTypeInt32); // Copy a single dword (4 bytes). - c.mov(tmp, dword_ptr(src)); - c.mov(dword_ptr(dst), tmp); + X86GpVar tmp(c, kVarTypeInt32); // Copy a single dword (4 bytes). + c.mov(tmp, x86::dword_ptr(src)); + c.mov(x86::dword_ptr(dst), tmp); c.add(src, 4); // Increment dst/src pointers. c.add(dst, 4); @@ -1643,7 +1643,7 @@ struct X86Test_AllocBlend : public X86Test { return d_20 + d_31 + s; } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { asmgen::blend(c); } @@ -1651,10 +1651,20 @@ struct X86Test_AllocBlend : public X86Test { typedef void (*Func)(void*, const void*, size_t); Func func = asmjit_cast(_func); - uint32_t i; + static const uint32_t dstConstData[] = { 0x00000000, 0x10101010, 0x20100804, 0x30200003, 0x40204040, 0x5000004D, 0x60302E2C, 0x706F6E6D, 0x807F4F2F, 0x90349001, 0xA0010203, 0xB03204AB, 0xC023AFBD, 0xD0D0D0C0, 0xE0AABBCC, 0xFFFFFFFF, 0xF8F4F2F1 }; + static const uint32_t srcConstData[] = { 0xE0E0E0E0, 0xA0008080, 0x341F1E1A, 0xFEFEFEFE, 0x80302010, 0x49490A0B, 0x998F7798, 0x00000000, 0x01010101, 0xA0264733, 0xBAB0B1B9, 0xFF000000, 0xDAB0A0C1, 0xE0BACFDA, 0x99887766, 0xFFFFFF80, 0xEE0A5FEC }; - uint32_t dstBuffer[kCount] = { 0x00000000, 0x10101010, 0x20100804, 0x30200003, 0x40204040, 0x5000004D, 0x60302E2C, 0x706F6E6D, 0x807F4F2F, 0x90349001, 0xA0010203, 0xB03204AB, 0xC023AFBD, 0xD0D0D0C0, 0xE0AABBCC, 0xFFFFFFFF, 0xF8F4F2F1 }; - uint32_t srcBuffer[kCount] = { 0xE0E0E0E0, 0xA0008080, 0x341F1E1A, 0xFEFEFEFE, 0x80302010, 0x49490A0B, 0x998F7798, 0x00000000, 0x01010101, 0xA0264733, 0xBAB0B1B9, 0xFF000000, 0xDAB0A0C1, 0xE0BACFDA, 0x99887766, 0xFFFFFF80, 0xEE0A5FEC }; + uint32_t _dstBuffer[kCount + 3]; + uint32_t _srcBuffer[kCount + 3]; + + // Has to be aligned. + uint32_t* dstBuffer = (uint32_t*)IntUtil::alignTo((intptr_t)_dstBuffer, 16); + uint32_t* srcBuffer = (uint32_t*)IntUtil::alignTo((intptr_t)_srcBuffer, 16); + + ::memcpy(dstBuffer, dstConstData, sizeof(dstConstData)); + ::memcpy(srcBuffer, srcConstData, sizeof(srcConstData)); + + uint32_t i; uint32_t expBuffer[kCount]; for (i = 0; i < kCount; i++) { @@ -1694,10 +1704,10 @@ struct X86Test_CallBase : public X86Test { tests.append(new X86Test_CallBase()); } - virtual void compile(Compiler& c) { - GpVar v0(c, kVarTypeInt32, "v0"); - GpVar v1(c, kVarTypeInt32, "v1"); - GpVar v2(c, kVarTypeInt32, "v2"); + virtual void compile(X86Compiler& c) { + X86GpVar v0(c, kVarTypeInt32, "v0"); + X86GpVar v1(c, kVarTypeInt32, "v1"); + X86GpVar v2(c, kVarTypeInt32, "v2"); c.addFunc(kFuncConvHost, FuncBuilder3()); c.setArg(0, v0); @@ -1710,10 +1720,10 @@ struct X86Test_CallBase : public X86Test { c.shl(v2, 1); // Call function. - GpVar fn(c, kVarTypeIntPtr, "fn"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); c.mov(fn, imm_ptr((void*)calledFunc)); - X86X64CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder3()); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder3()); call->setArg(0, v2); call->setArg(1, v1); call->setArg(2, v0); @@ -1750,15 +1760,15 @@ struct X86Test_CallFast : public X86Test { tests.append(new X86Test_CallFast()); } - virtual void compile(Compiler& c) { - GpVar var(c, kVarTypeInt32, "var"); - GpVar fn(c, kVarTypeIntPtr, "fn"); + virtual void compile(X86Compiler& c) { + X86GpVar var(c, kVarTypeInt32, "var"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); c.addFunc(kFuncConvHost, FuncBuilder1()); c.setArg(0, var); c.mov(fn, imm_ptr((void*)calledFunc)); - X86X64CallNode* call; + X86CallNode* call; call = c.call(fn, kFuncConvHostFastCall, FuncBuilder1()); call->setArg(0, var); @@ -1806,21 +1816,21 @@ struct X86Test_CallManyArgs : public X86Test { return (a * b * c * d * e) + (f * g * h * i * j); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); // Prepare. - GpVar fn(c, kVarTypeIntPtr, "fn"); - GpVar va(c, kVarTypeInt32, "va"); - GpVar vb(c, kVarTypeInt32, "vb"); - GpVar vc(c, kVarTypeInt32, "vc"); - GpVar vd(c, kVarTypeInt32, "vd"); - GpVar ve(c, kVarTypeInt32, "ve"); - GpVar vf(c, kVarTypeInt32, "vf"); - GpVar vg(c, kVarTypeInt32, "vg"); - GpVar vh(c, kVarTypeInt32, "vh"); - GpVar vi(c, kVarTypeInt32, "vi"); - GpVar vj(c, kVarTypeInt32, "vj"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); + X86GpVar va(c, kVarTypeInt32, "va"); + X86GpVar vb(c, kVarTypeInt32, "vb"); + X86GpVar vc(c, kVarTypeInt32, "vc"); + X86GpVar vd(c, kVarTypeInt32, "vd"); + X86GpVar ve(c, kVarTypeInt32, "ve"); + X86GpVar vf(c, kVarTypeInt32, "vf"); + X86GpVar vg(c, kVarTypeInt32, "vg"); + X86GpVar vh(c, kVarTypeInt32, "vh"); + X86GpVar vi(c, kVarTypeInt32, "vi"); + X86GpVar vj(c, kVarTypeInt32, "vj"); c.mov(fn, imm_ptr((void*)calledFunc)); c.mov(va, 0x03); @@ -1835,7 +1845,7 @@ struct X86Test_CallManyArgs : public X86Test { c.mov(vj, 0x1E); // Call function. - X86X64CallNode* call = c.call(fn, kFuncConvHost, + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder10()); call->setArg(0, va); call->setArg(1, vb); @@ -1882,18 +1892,18 @@ struct X86Test_CallDuplicateArgs : public X86Test { return (a * b * c * d * e) + (f * g * h * i * j); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); // Prepare. - GpVar fn(c, kVarTypeIntPtr, "fn"); - GpVar a(c, kVarTypeInt32, "a"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); + X86GpVar a(c, kVarTypeInt32, "a"); c.mov(fn, imm_ptr((void*)calledFunc)); c.mov(a, 3); // Call function. - X86X64CallNode* call = c.call(fn, kFuncConvHost, + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder10()); call->setArg(0, a); call->setArg(1, a); @@ -1936,17 +1946,17 @@ struct X86Test_CallImmArgs : public X86Test { tests.append(new X86Test_CallImmArgs()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); // Prepare. - GpVar fn(c, kVarTypeIntPtr, "fn"); - GpVar rv(c, kVarTypeInt32, "rv"); + X86GpVar fn(c, kVarTypeIntPtr, "fn"); + X86GpVar rv(c, kVarTypeInt32, "rv"); c.mov(fn, imm_ptr((void*)X86Test_CallManyArgs::calledFunc)); // Call function. - X86X64CallNode* call = c.call(fn, kFuncConvHost, + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder10()); call->setArg(0, imm(0x03)); call->setArg(1, imm(0x12)); @@ -1993,22 +2003,22 @@ struct X86Test_CallFloatAsXmmRet : public X86Test { return a * b; } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - XmmVar a(c, kVarTypeXmmSs, "a"); - XmmVar b(c, kVarTypeXmmSs, "b"); - XmmVar ret(c, kVarTypeXmmSs, "ret"); + X86XmmVar a(c, kX86VarTypeXmmSs, "a"); + X86XmmVar b(c, kX86VarTypeXmmSs, "b"); + X86XmmVar ret(c, kX86VarTypeXmmSs, "ret"); c.setArg(0, a); c.setArg(1, b); // Prepare. - GpVar fn(c); + X86GpVar fn(c); c.mov(fn, imm_ptr((void*)calledFunc)); // Call function. - X86X64CallNode* call = c.call(fn, kFuncConvHost, + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); call->setArg(0, a); @@ -2048,20 +2058,20 @@ struct X86Test_CallDoubleAsXmmRet : public X86Test { return a * b; } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder2()); - XmmVar a(c, kVarTypeXmmSd, "a"); - XmmVar b(c, kVarTypeXmmSd, "b"); - XmmVar ret(c, kVarTypeXmmSd, "ret"); + X86XmmVar a(c, kX86VarTypeXmmSd, "a"); + X86XmmVar b(c, kX86VarTypeXmmSd, "b"); + X86XmmVar ret(c, kX86VarTypeXmmSd, "ret"); c.setArg(0, a); c.setArg(1, b); - GpVar fn(c); + X86GpVar fn(c); c.mov(fn, imm_ptr((void*)calledFunc)); - X86X64CallNode* call = c.call(fn, kFuncConvHost, + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); call->setArg(0, a); @@ -2097,13 +2107,13 @@ struct X86Test_CallConditional : public X86Test { tests.append(new X86Test_CallConditional()); } - virtual void compile(Compiler& c) { - GpVar x(c, kVarTypeInt32, "x"); - GpVar y(c, kVarTypeInt32, "y"); - GpVar op(c, kVarTypeInt32, "op"); + virtual void compile(X86Compiler& c) { + X86GpVar x(c, kVarTypeInt32, "x"); + X86GpVar y(c, kVarTypeInt32, "y"); + X86GpVar op(c, kVarTypeInt32, "op"); - X86X64CallNode* call; - GpVar result; + X86CallNode* call; + X86GpVar result; c.addFunc(kFuncConvHost, FuncBuilder3()); c.setArg(0, x); @@ -2125,7 +2135,7 @@ struct X86Test_CallConditional : public X86Test { c.bind(opAdd); result = c.newGpVar(kVarTypeInt32, "result"); - call = c.call((void*)calledFuncAdd, kFuncConvHost, FuncBuilder2()); + call = c.call((Ptr)calledFuncAdd, kFuncConvHost, FuncBuilder2()); call->setArg(0, x); call->setArg(1, y); call->setRet(0, result); @@ -2134,7 +2144,7 @@ struct X86Test_CallConditional : public X86Test { c.bind(opMul); result = c.newGpVar(kVarTypeInt32, "result"); - call = c.call((void*)calledFuncMul, kFuncConvHost, FuncBuilder2()); + call = c.call((Ptr)calledFuncMul, kFuncConvHost, FuncBuilder2()); call->setArg(0, x); call->setArg(1, y); call->setRet(0, result); @@ -2181,12 +2191,12 @@ struct X86Test_CallMultiple : public X86Test { return pInt[index]; } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { unsigned int i; - GpVar buf(c, kVarTypeIntPtr, "buf"); - GpVar acc0(c, kVarTypeInt32, "acc0"); - GpVar acc1(c, kVarTypeInt32, "acc1"); + X86GpVar buf(c, kVarTypeIntPtr, "buf"); + X86GpVar acc0(c, kVarTypeInt32, "acc0"); + X86GpVar acc1(c, kVarTypeInt32, "acc1"); c.addFunc(kFuncConvHost, FuncBuilder1()); c.setArg(0, buf); @@ -2195,15 +2205,15 @@ struct X86Test_CallMultiple : public X86Test { c.mov(acc1, 0); for (i = 0; i < 4; i++) { - GpVar ret(c, kVarTypeInt32); - GpVar ptr(c, kVarTypeIntPtr); - GpVar idx(c, kVarTypeInt32); - X86X64CallNode* call; + X86GpVar ret(c, kVarTypeInt32); + X86GpVar ptr(c, kVarTypeIntPtr); + X86GpVar idx(c, kVarTypeInt32); + X86CallNode* call; c.mov(ptr, buf); c.mov(idx, static_cast(i)); - call = c.call((void*)calledFunc, kFuncConvHostFastCall, FuncBuilder2()); + call = c.call((Ptr)calledFunc, kFuncConvHostFastCall, FuncBuilder2()); call->setArg(0, ptr); call->setArg(1, idx); call->setRet(0, ret); @@ -2213,7 +2223,7 @@ struct X86Test_CallMultiple : public X86Test { c.mov(ptr, buf); c.mov(idx, static_cast(i)); - call = c.call((void*)calledFunc, kFuncConvHostFastCall, FuncBuilder2()); + call = c.call((Ptr)calledFunc, kFuncConvHostFastCall, FuncBuilder2()); call->setArg(0, ptr); call->setArg(1, idx); call->setRet(0, ret); @@ -2253,21 +2263,21 @@ struct X86Test_CallRecursive : public X86Test { tests.append(new X86Test_CallRecursive()); } - virtual void compile(Compiler& c) { - GpVar val(c, kVarTypeInt32, "val"); + virtual void compile(X86Compiler& c) { + X86GpVar val(c, kVarTypeInt32, "val"); Label skip(c); - X86X64FuncNode* func = c.addFunc(kFuncConvHost, FuncBuilder1()); + X86FuncNode* func = c.addFunc(kFuncConvHost, FuncBuilder1()); c.setArg(0, val); c.cmp(val, 1); c.jle(skip); - GpVar tmp(c, kVarTypeInt32, "tmp"); + X86GpVar tmp(c, kVarTypeInt32, "tmp"); c.mov(tmp, val); c.dec(tmp); - X86X64CallNode* call = c.call(func->getEntryLabel(), kFuncConvHost, FuncBuilder1()); + X86CallNode* call = c.call(func->getEntryLabel(), kFuncConvHost, FuncBuilder1()); call->setArg(0, tmp); call->setRet(0, tmp); c.mul(c.newGpVar(kVarTypeInt32), val, tmp); @@ -2304,27 +2314,27 @@ struct X86Test_CallMisc1 : public X86Test { static void dummy(int a, int b) {} - virtual void compile(Compiler& c) { - GpVar val(c, kVarTypeInt32, "val"); + virtual void compile(X86Compiler& c) { + X86GpVar val(c, kVarTypeInt32, "val"); Label skip(c); - X86X64FuncNode* func = c.addFunc(kFuncConvHost, FuncBuilder2()); + X86FuncNode* func = c.addFunc(kFuncConvHost, FuncBuilder2()); - GpVar a(c, kVarTypeInt32, "a"); - GpVar b(c, kVarTypeInt32, "b"); - GpVar r(c, kVarTypeInt32, "r"); + X86GpVar a(c, kVarTypeInt32, "a"); + X86GpVar b(c, kVarTypeInt32, "b"); + X86GpVar r(c, kVarTypeInt32, "r"); c.setArg(0, a); c.setArg(1, b); - c.alloc(a, eax); - c.alloc(b, ebx); + c.alloc(a, x86::eax); + c.alloc(b, x86::ebx); - X86X64CallNode* call = c.call(imm_ptr((void*)dummy), kFuncConvHost, FuncBuilder2()); + X86CallNode* call = c.call(imm_ptr((void*)dummy), kFuncConvHost, FuncBuilder2()); call->setArg(0, a); call->setArg(1, b); - c.lea(r, ptr(a, b)); + c.lea(r, x86::ptr(a, b)); c.ret(r); c.endFunc(); @@ -2355,14 +2365,14 @@ struct X86Test_ConstPoolBase : public X86Test { tests.append(new X86Test_ConstPoolBase()); } - virtual void compile(Compiler& c) { + virtual void compile(X86Compiler& c) { c.addFunc(kFuncConvHost, FuncBuilder0()); - GpVar v0(c, kVarTypeInt32, "v0"); - GpVar v1(c, kVarTypeInt32, "v1"); + X86GpVar v0(c, kVarTypeInt32, "v0"); + X86GpVar v1(c, kVarTypeInt32, "v1"); - Mem c0(c.newInt32Const(kConstScopeLocal, 200)); - Mem c1(c.newInt32Const(kConstScopeLocal, 33)); + X86Mem c0(c.newInt32Const(kConstScopeLocal, 200)); + X86Mem c1(c.newInt32Const(kConstScopeLocal, 33)); c.mov(v0, c0); c.mov(v1, c1); @@ -2386,49 +2396,6 @@ struct X86Test_ConstPoolBase : public X86Test { } }; -// ============================================================================ -// [X86Test_Dummy] -// ============================================================================ - -struct X86Test_Dummy : public X86Test { - X86Test_Dummy() : X86Test("[Dummy] Dummy") {} - - static void add(PodVector& tests) { - tests.append(new X86Test_Dummy()); - } - - virtual void compile(Compiler& c) { - c.addFunc(kFuncConvHost, FuncBuilder0()); - - GpVar r(c, kVarTypeUInt32); - GpVar a(c, kVarTypeUInt32); - GpVar b(c, kVarTypeUInt32); - - c.alloc(r, eax); - c.alloc(a, ecx); - c.alloc(b, edx); - - c.mov(a, 16); - c.mov(b, 99); - - c.mul(r, a, b); - c.alloc(a, esi); - c.alloc(b, ecx); - c.alloc(r, edi); - c.mul(a, b, r); - - c.ret(b); - c.endFunc(); - } - - virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) { - typedef uint32_t (*Func)(void); - Func func = asmjit_cast(_func); - - return func() == 0; - } -}; - // ============================================================================ // [X86TestSuite] // ============================================================================ @@ -2513,9 +2480,6 @@ X86TestSuite::X86TestSuite() : ADD_TEST(X86Test_CallRecursive); ADD_TEST(X86Test_CallMisc1); ADD_TEST(X86Test_ConstPoolBase); - - // Dummy. - // ADD_TEST(X86Test_Dummy); } X86TestSuite::~X86TestSuite() { @@ -2542,7 +2506,7 @@ int X86TestSuite::run() { for (i = 0; i < count; i++) { JitRuntime runtime; - Compiler compiler(&runtime); + X86Compiler compiler(&runtime); if (alwaysPrintLog) { fprintf(file, "\n"); diff --git a/src/asmjit/apibegin.h b/src/asmjit/apibegin.h index 0baf057..b025e2e 100644 --- a/src/asmjit/apibegin.h +++ b/src/asmjit/apibegin.h @@ -13,47 +13,37 @@ // ============================================================================ #if defined(_MSC_VER) - // Disable some warnings we know about -#pragma warning(push) -#pragma warning(disable: 4127) // conditional expression is constant -#pragma warning(disable: 4201) // nameless struct/union -#pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible - // loss of data -#pragma warning(disable: 4251) // struct needs to have dll-interface to be used - // by clients of struct ... -#pragma warning(disable: 4275) // non dll-interface struct ... used as base for - // dll-interface struct -#pragma warning(disable: 4355) // this used in base member initializer list -#pragma warning(disable: 4480) // specifying underlying type for enum -#pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4201) // nameless struct/union +# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible + // loss of data +# pragma warning(disable: 4251) // struct needs to have dll-interface to be used + // by clients of struct ... +# pragma warning(disable: 4275) // non dll-interface struct ... used as base for + // dll-interface struct +# pragma warning(disable: 4355) // this used in base member initializer list +# pragma warning(disable: 4480) // specifying underlying type for enum +# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' // Rename symbols. -#if !defined(vsnprintf) -#define ASMJIT_DEFINED_VSNPRINTF -#define vsnprintf _vsnprintf -#endif // !vsnprintf - -#if !defined(snprintf) -#define ASMJIT_DEFINED_SNPRINTF -#define snprintf _snprintf -#endif // !snprintf - +# if !defined(vsnprintf) +# define ASMJIT_DEFINED_VSNPRINTF +# define vsnprintf _vsnprintf +# endif // !vsnprintf +# if !defined(snprintf) +# define ASMJIT_DEFINED_SNPRINTF +# define snprintf _snprintf +# endif // !snprintf #endif // _MSC_VER // ============================================================================ // [GNUC] // ============================================================================ -#if defined(__GNUC__) -// GCC warnings fix: I can't understand why GCC has no interface to push/pop -// specific warnings. -// # if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 402001 -// # pragma GCC diagnostic ignored "-w" -// # endif - -#if __GNUC__ >= 4 -# pragma GCC visibility push(hidden) -#endif // __GNUC__ >= 4 - +#if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ >= 4 && !defined(__MINGW32__) +# pragma GCC visibility push(hidden) +# endif // __GNUC__ >= 4 #endif // __GNUC__ diff --git a/src/asmjit/apiend.h b/src/asmjit/apiend.h index e44a82a..4ec7834 100644 --- a/src/asmjit/apiend.h +++ b/src/asmjit/apiend.h @@ -9,31 +9,25 @@ // ============================================================================ #if defined(_MSC_VER) - // Pop disabled warnings by ApiBegin.h -#pragma warning(pop) - +# pragma warning(pop) // Rename symbols back. -#if defined(ASMJIT_DEFINED_VSNPRINTF) -#undef ASMJIT_DEFINED_VSNPRINTF -#undef vsnprintf -#endif // ASMJIT_DEFINED_VSNPRINTF - -#if defined(ASMJIT_DEFINED_SNPRINTF) -#undef ASMJIT_DEFINED_SNPRINTF -#undef snprintf -#endif // ASMJIT_DEFINED_SNPRINTF - +# if defined(ASMJIT_DEFINED_VSNPRINTF) +# undef ASMJIT_DEFINED_VSNPRINTF +# undef vsnprintf +# endif // ASMJIT_DEFINED_VSNPRINTF +# if defined(ASMJIT_DEFINED_SNPRINTF) +# undef ASMJIT_DEFINED_SNPRINTF +# undef snprintf +# endif // ASMJIT_DEFINED_SNPRINTF #endif // _MSC_VER // ============================================================================ // [GNUC] // ============================================================================ -#if defined(__GNUC__) - -#if __GNUC__ >= 4 -# pragma GCC visibility pop -#endif // __GNUC__ >= 4 - +#if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ >= 4 && !defined(__MINGW32__) +# pragma GCC visibility pop +# endif // __GNUC__ >= 4 #endif // __GNUC__ diff --git a/src/asmjit/asmjit.h b/src/asmjit/asmjit.h index 81f567e..5737ff8 100644 --- a/src/asmjit/asmjit.h +++ b/src/asmjit/asmjit.h @@ -64,7 +64,7 @@ //! //! @section AsmJit_Main_HomePage AsmJit Homepage //! -//! - https://github.com/kobalicekp/asmjit +//! - https://github.com/kobalicek/asmjit // ============================================================================ // [asmjit_base] @@ -85,10 +85,10 @@ //! //! Contains all `asmjit` classes and helper functions that are architecture //! independent or abstract. Abstract classes are implemented by the backend, -//! for example `BaseAssembler` is implemented by `x86x64::X86X64Assembler`. +//! for example `Assembler` is implemented by `X86Assembler`. //! -//! - See `BaseAssembler` for low level code generation documentation. -//! - See `BaseCompiler` for high level code generation documentation. +//! - See `Assembler` for low level code generation documentation. +//! - See `Compiler` for high level code generation documentation. //! - See `Operand` for operand's overview. //! //! Logging and Error Handling @@ -117,10 +117,10 @@ //! \sa \ref Logger, \ref FileLogger, \ref StringLogger. // ============================================================================ -// [asmjit_base_tree] +// [asmjit_base_compiler] // ============================================================================ -//! \defgroup asmjit_base_tree AsmJit Code-Tree +//! \defgroup asmjit_base_compiler AsmJit Compiler //! \ingroup asmjit_base //! //! \brief AsmJit code-tree used by Compiler. @@ -128,7 +128,7 @@ //! AsmJit intermediate code-tree is a double-linked list that is made of nodes //! that represent assembler instructions, directives, labels and high-level //! constructs compiler is using to represent functions and function calls. The -//! node list can only be used together with \ref BaseCompiler. +//! node list can only be used together with \ref Compiler. //! //! TODO @@ -181,8 +181,8 @@ //! ---------------- //! //! SIMD code generation often requires to embed constants after each function -//! or a block of functions generated. AsmJit contains classes `Vec64Data`, -//! `Vec128Data` and `Vec256Data` that can be used to prepare data useful when +//! or a block of functions generated. AsmJit contains classes `Vec64`, +//! `Vec128` and `Vec256` that can be used to prepare data useful when //! generating SIMD code. //! //! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm` @@ -193,19 +193,19 @@ //! embedding constants manually after the function body. // ============================================================================ -// [asmjit_x86x64] +// [asmjit_x86] // ============================================================================ -//! \defgroup asmjit_x86x64 X86/X64 +//! \defgroup asmjit_x86 X86/X64 //! //! \brief X86/X64 module // ============================================================================ -// [asmjit_x86x64_general] +// [asmjit_x86_general] // ============================================================================ -//! \defgroup asmjit_x86x64_general X86/X64 General API -//! \ingroup asmjit_x86x64 +//! \defgroup asmjit_x86_general X86/X64 General API +//! \ingroup asmjit_x86 //! //! \brief X86/X64 general API. //! @@ -243,15 +243,14 @@ //! - `asmjit::tword_ptr()` //! - `asmjit::oword_ptr()` //! - `asmjit::yword_ptr()` -//! - `asmjit::intptr_ptr()` +//! - `asmjit::zword_ptr()` //! //! Most useful function to make pointer should be `asmjit::ptr()`. It creates //! pointer to the target with unspecified size. Unspecified size works in all //! intrinsics where are used registers (this means that size is specified by //! register operand or by instruction itself). For example `asmjit::ptr()` -//! can't be used with @c asmjit::Assembler::inc() instruction. In this case -//! size must be specified and it's also reason to make difference between -//! pointer sizes. +//! can't be used with `Assembler::inc()` instruction. In this case size must +//! be specified and it's also reason to make difference between pointer sizes. //! //! Supported are simple address forms `[base + displacement]` and complex //! address forms `[base + index * scale + displacement]`. @@ -260,8 +259,8 @@ //! ------------------ //! //! Immediate values are constants thats passed directly after instruction -//! opcode. To create such value use @c asmjit::imm() or @c asmjit::imm_u() -//! methods to create signed or unsigned immediate value. +//! opcode. To create such value use `imm()` or `imm_u()` methods to create +//! signed or unsigned immediate value. //! //! X86/X64 CPU Information //! ----------------------- @@ -270,22 +269,22 @@ //! the host X86/X64 processor. AsmJit contains utilities that can get the most //! important information related to the features supported by the CPU and the //! host operating system, in addition to host processor name and number of -//! cores. Class `CpuInfo` extends `BaseCpuInfo` and provides functionality +//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality //! specific to X86 and X64. //! //! By default AsmJit queries the CPU information after the library is loaded //! and the queried information is reused by all instances of `JitRuntime`. -//! The global instance of `CpuInfo` can't be changed, because it will affect +//! The global instance of `X86CpuInfo` can't be changed, because it will affect //! the code generation of all `Runtime`s. If there is a need to have a //! specific CPU information which contains modified features or processor -//! vendor it's possible by creating a new instance of `CpuInfo` and setting -//! up its members. `CpuUtil::detect` can be used to detect CPU features into -//! an existing `CpuInfo` instance - it may become handly if only one property +//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting +//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into +//! an existing `X86CpuInfo` instance - it may become handly if only one property //! has to be turned on/off. //! -//! If the high-level interface `CpuInfo` offers is not enough there is also -//! `CpuUtil::callCpuId` helper that can be used to call CPUID instruction with -//! a given parameters and to consume the output. +//! If the high-level interface `X86CpuInfo` offers is not enough there is also +//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction +//! with a given parameters and to consume the output. //! //! Cpu detection is important when generating a JIT code that may or may not //! use certain CPU features. For example there used to be a SSE/SSE2 detection @@ -295,15 +294,14 @@ //! //! ~~~ //! using namespace asmjit; -//! using namespace asmjit::host; //! -//! // Get `CpuInfo` global instance. -//! const CpuInfo* cpuInfo = CpuInfo::getHost(); +//! // Get `X86CpuInfo` global instance. +//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost(); //! -//! if (cpuInfo->hasFeature(kCpuFeatureSse2)) { +//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) { //! // Processor has SSE2. //! } -//! else if (cpuInfo->hasFeature(kCpuFeatureMmx)) { +//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) { //! // Processor doesn't have SSE2, but has MMX. //! } //! else { @@ -317,8 +315,8 @@ //! using namespace asmjit; //! //! // Call cpuid, first two arguments are passed in Eax/Ecx. -//! CpuId out; -//! CpuUtil::callCpuId(0, 0, &out); +//! X86CpuId out; +//! X86CpuUtil::callCpuId(0, 0, &out); //! //! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor. //! char cpuVendor[13]; @@ -332,29 +330,29 @@ //! ~~~ // ============================================================================ -// [asmjit_x86x64_tree] +// [asmjit_x86_compiler] // ============================================================================ -//! \defgroup asmjit_x86x64_tree X86/X64 Code-Tree -//! \ingroup asmjit_x86x64 +//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree +//! \ingroup asmjit_x86 //! //! \brief X86/X64 code-tree and helpers. // ============================================================================ -// [asmjit_x86x64_inst] +// [asmjit_x86_inst] // ============================================================================ -//! \defgroup asmjit_x86x64_inst X86/X64 Instructions -//! \ingroup asmjit_x86x64 +//! \defgroup asmjit_x86_inst X86/X64 Instructions +//! \ingroup asmjit_x86 //! //! \brief X86/X64 low-level instruction definitions. // ============================================================================ -// [asmjit_x86x64_util] +// [asmjit_x86_util] // ============================================================================ -//! \defgroup asmjit_x86x64_util X86/X64 Utilities -//! \ingroup asmjit_x86x64 +//! \defgroup asmjit_x86_util X86/X64 Utilities +//! \ingroup asmjit_x86 //! //! \brief X86/X64 utility classes. diff --git a/src/asmjit/base.h b/src/asmjit/base.h index de448da..47e1bfe 100644 --- a/src/asmjit/base.h +++ b/src/asmjit/base.h @@ -15,17 +15,15 @@ #include "base/codegen.h" #include "base/compiler.h" #include "base/constpool.h" +#include "base/containers.h" #include "base/cpuinfo.h" #include "base/cputicks.h" #include "base/error.h" -#include "base/func.h" #include "base/globals.h" #include "base/intutil.h" #include "base/lock.h" #include "base/logger.h" #include "base/operand.h" -#include "base/podlist.h" -#include "base/podvector.h" #include "base/runtime.h" #include "base/string.h" #include "base/vectypes.h" diff --git a/src/asmjit/base/assembler.cpp b/src/asmjit/base/assembler.cpp index a28b726..7a27ced 100644 --- a/src/asmjit/base/assembler.cpp +++ b/src/asmjit/base/assembler.cpp @@ -21,10 +21,10 @@ namespace asmjit { // ============================================================================ -// [asmjit::BaseAssembler - Construction / Destruction] +// [asmjit::Assembler - Construction / Destruction] // ============================================================================ -BaseAssembler::BaseAssembler(Runtime* runtime) : +Assembler::Assembler(Runtime* runtime) : CodeGen(runtime), _buffer(NULL), _end(NULL), @@ -33,56 +33,42 @@ BaseAssembler::BaseAssembler(Runtime* runtime) : _comment(NULL), _unusedLinks(NULL) {} -BaseAssembler::~BaseAssembler() { - if (_buffer != NULL) - ASMJIT_FREE(_buffer); +Assembler::~Assembler() { + reset(true); } // ============================================================================ -// [asmjit::BaseAssembler - Clear / Reset] +// [asmjit::Assembler - Clear / Reset] // ============================================================================ -void BaseAssembler::clear() { - _purge(); -} +void Assembler::reset(bool releaseMemory) { + // CodeGen members. + _error = kErrorOk; + _options = 0; + _baseZone.reset(releaseMemory); -void BaseAssembler::reset() { - _purge(); - _baseZone.reset(); - - if (_buffer != NULL) { + // Assembler members. + if (releaseMemory && _buffer != NULL) { ASMJIT_FREE(_buffer); - _buffer = NULL; _end = NULL; - _cursor = NULL; } - _labels.reset(); - _relocData.reset(); -} - -void BaseAssembler::_purge() { - _baseZone.clear(); _cursor = _buffer; - - _options = 0; _trampolineSize = 0; _comment = NULL; _unusedLinks = NULL; - _labels.clear(); - _relocData.clear(); - - clearError(); + _labels.reset(releaseMemory); + _relocData.reset(releaseMemory); } // ============================================================================ -// [asmjit::BaseAssembler - Buffer] +// [asmjit::Assembler - Buffer] // ============================================================================ -Error BaseAssembler::_grow(size_t n) { +Error Assembler::_grow(size_t n) { size_t capacity = getCapacity(); size_t after = getOffset() + n; @@ -117,7 +103,7 @@ Error BaseAssembler::_grow(size_t n) { return _reserve(capacity); } -Error BaseAssembler::_reserve(size_t n) { +Error Assembler::_reserve(size_t n) { size_t capacity = getCapacity(); if (n <= capacity) return kErrorOk; @@ -141,10 +127,10 @@ Error BaseAssembler::_reserve(size_t n) { } // ============================================================================ -// [asmjit::BaseAssembler - Label] +// [asmjit::Assembler - Label] // ============================================================================ -Error BaseAssembler::_registerIndexedLabels(size_t index) { +Error Assembler::_registerIndexedLabels(size_t index) { size_t i = _labels.getLength(); if (index < i) return kErrorOk; @@ -163,7 +149,7 @@ Error BaseAssembler::_registerIndexedLabels(size_t index) { return kErrorOk; } -Error BaseAssembler::_newLabel(Label* dst) { +Error Assembler::_newLabel(Label* dst) { dst->_label.op = kOperandTypeLabel; dst->_label.size = 0; dst->_label.id = OperandUtil::makeLabelId(static_cast(_labels.getLength())); @@ -181,7 +167,7 @@ _NoMemory: return setError(kErrorNoHeapMemory); } -LabelLink* BaseAssembler::_newLabelLink() { +LabelLink* Assembler::_newLabelLink() { LabelLink* link = _unusedLinks; if (link) { @@ -202,10 +188,10 @@ LabelLink* BaseAssembler::_newLabelLink() { } // ============================================================================ -// [asmjit::BaseAssembler - Embed] +// [asmjit::Assembler - Embed] // ============================================================================ -Error BaseAssembler::embed(const void* data, uint32_t size) { +Error Assembler::embed(const void* data, uint32_t size) { if (getRemainingSpace() < size) { Error error = _grow(size); if (error != kErrorOk) @@ -225,10 +211,10 @@ Error BaseAssembler::embed(const void* data, uint32_t size) { } // ============================================================================ -// [asmjit::BaseAssembler - Make] +// [asmjit::Assembler - Make] // ============================================================================ -void* BaseAssembler::make() { +void* Assembler::make() { // Do nothing on error condition or if no instruction has been emitted. if (_error != kErrorOk || getCodeSize() == 0) return NULL; @@ -243,57 +229,65 @@ void* BaseAssembler::make() { } // ============================================================================ -// [asmjit::BaseAssembler - Emit (Helpers)] +// [asmjit::Assembler - Emit (Helpers)] // ============================================================================ #define no noOperand -Error BaseAssembler::emit(uint32_t code) { +Error Assembler::emit(uint32_t code) { return _emit(code, no, no, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0) { +Error Assembler::emit(uint32_t code, const Operand& o0) { return _emit(code, o0, no, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1) { +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1) { return _emit(code, o0, o1, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { return _emit(code, o0, o1, o2, no); } -Error BaseAssembler::emit(uint32_t code, int o0_) { - return _emit(code, Imm(o0_), no, no, no); +Error Assembler::emit(uint32_t code, int o0) { + Imm imm(o0); + return _emit(code, imm, no, no, no); } -Error BaseAssembler::emit(uint32_t code, uint64_t o0_) { - return _emit(code, Imm(o0_), no, no, no); +Error Assembler::emit(uint32_t code, uint64_t o0) { + Imm imm(o0); + return _emit(code, imm, no, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, int o1_) { - return _emit(code, o0, Imm(o1_), no, no); +Error Assembler::emit(uint32_t code, const Operand& o0, int o1) { + Imm imm(o1); + return _emit(code, o0, imm, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, uint64_t o1_) { - return _emit(code, o0, Imm(o1_), no, no); +Error Assembler::emit(uint32_t code, const Operand& o0, uint64_t o1) { + Imm imm(o1); + return _emit(code, o0, imm, no, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2_) { - return _emit(code, o0, o1, Imm(o2_), no); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) { + Imm imm(o2); + return _emit(code, o0, o1, imm, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2_) { - return _emit(code, o0, o1, Imm(o2_), no); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2) { + Imm imm(o2); + return _emit(code, o0, o1, imm, no); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3_) { - return _emit(code, o0, o1, o2, Imm(o3_)); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) { + Imm imm(o3); + return _emit(code, o0, o1, o2, imm); } -Error BaseAssembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3_) { - return _emit(code, o0, o1, o2, Imm(o3_)); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3) { + Imm imm(o3); + return _emit(code, o0, o1, o2, imm); } #undef no diff --git a/src/asmjit/base/assembler.h b/src/asmjit/base/assembler.h index 21de496..82d7412 100644 --- a/src/asmjit/base/assembler.h +++ b/src/asmjit/base/assembler.h @@ -10,11 +10,10 @@ // [Dependencies - AsmJit] #include "../base/codegen.h" +#include "../base/containers.h" #include "../base/error.h" #include "../base/logger.h" #include "../base/operand.h" -#include "../base/podlist.h" -#include "../base/podvector.h" #include "../base/runtime.h" #include "../base/zone.h" @@ -27,13 +26,13 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kInstCode] +// [asmjit::kInstId] // ============================================================================ //! Instruction codes (stub). -ASMJIT_ENUM(kInstCode) { +ASMJIT_ENUM(kInstId) { //! No instruction. - kInstNone = 0 + kInstIdNone = 0 }; // ============================================================================ @@ -132,7 +131,7 @@ struct RelocData { }; // ============================================================================ -// [asmjit::BaseAssembler] +// [asmjit::Assembler] // ============================================================================ //! Base assembler. @@ -140,30 +139,27 @@ struct RelocData { //! This class implements the base interface to an assembler. The architecture //! specific API is implemented by backends. //! -//! @sa BaseCompiler. -struct BaseAssembler : public CodeGen { - ASMJIT_NO_COPY(BaseAssembler) +//! \sa Compiler. +struct ASMJIT_VCLASS Assembler : public CodeGen { + ASMJIT_NO_COPY(Assembler) // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - //! Create a new `BaseAssembler` instance. - ASMJIT_API BaseAssembler(Runtime* runtime); - //! Destroy the `BaseAssembler` instance. - ASMJIT_API virtual ~BaseAssembler(); + //! Create a new `Assembler` instance. + ASMJIT_API Assembler(Runtime* runtime); + //! Destroy the `Assembler` instance. + ASMJIT_API virtual ~Assembler(); // -------------------------------------------------------------------------- - // [Clear / Reset] + // [Reset] // -------------------------------------------------------------------------- - //! Clear everything, but not deallocate buffers. - ASMJIT_API void clear(); - //! Reset everything (means also to free all buffers). - ASMJIT_API void reset(); - //! Called by clear() and reset() to clear all data related to derived class - //! implementation. - ASMJIT_API virtual void _purge(); + //! Reset the assembler. + //! + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); // -------------------------------------------------------------------------- // [Buffer] @@ -486,8 +482,8 @@ struct BaseAssembler : public CodeGen { //! \overload ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3); - //! Emit an instruction (virtual). - virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0; + //! Emit an instruction (virtual). + virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0; // -------------------------------------------------------------------------- // [Members] @@ -526,7 +522,7 @@ struct BaseAssembler : public CodeGen { // [Defined-Later] // ============================================================================ -ASMJIT_INLINE Label::Label(BaseAssembler& a) : Operand(NoInit) { +ASMJIT_INLINE Label::Label(Assembler& a) : Operand(NoInit) { a._newLabel(this); } diff --git a/src/asmjit/base/codegen.cpp b/src/asmjit/base/codegen.cpp index bd3ba69..ce31c6e 100644 --- a/src/asmjit/base/codegen.cpp +++ b/src/asmjit/base/codegen.cpp @@ -57,12 +57,20 @@ Error CodeGen::setError(Error error, const char* message) { return kErrorOk; } - if (message == NULL) + if (message == NULL) { +#if !defined(ASMJIT_DISABLE_NAMES) message = ErrorUtil::asString(error); +#else + static const char noMessage[] = ""; + message = noMessage; +#endif // ASMJIT_DISABLE_NAMES + } // Error handler is called before logger so logging can be skipped if error // has been handled. ErrorHandler* handler = _errorHandler; + ASMJIT_TLOG("[ERROR] %s %s\n", message, !handler ? "(Possibly unhandled?)" : ""); + if (handler != NULL && handler->handleError(error, message)) return error; diff --git a/src/asmjit/base/codegen.h b/src/asmjit/base/codegen.h index 7a46786..3632c56 100644 --- a/src/asmjit/base/codegen.h +++ b/src/asmjit/base/codegen.h @@ -28,8 +28,10 @@ namespace asmjit { //! Features of \ref CodeGen. ASMJIT_ENUM(kCodeGen) { - //! Emit optimized code-alignment sequences (true by default). + //! Emit optimized code-alignment sequences (`Assembler` and `Compiler`). //! + //! Default `true`. + //! //! X86/X64 //! ------- //! @@ -37,12 +39,14 @@ ASMJIT_ENUM(kCodeGen) { //! opcode that is mostly shown by disassemblers as nop. However there are //! more optimized align sequences for 2-11 bytes that may execute faster. //! If this feature is enabled asmjit will generate specialized sequences - //! for alignment between 1 to 11 bytes. Also when `x86x64::Compiler` is - //! used, it may add rex prefixes into the code to make some instructions - //! greater so no alignment sequences are needed. + //! for alignment between 1 to 11 bytes. Also when `X86Compiler` is used, + //! it can add REX prefixes into the code to make some instructions greater + //! so no alignment sequence is needed. kCodeGenOptimizedAlign = 0, - //! Emit jump-prediction hints (false by default). + //! Emit jump-prediction hints (`Assembler` and `Compiler`). + //! + //! Default `false`. //! //! X86/X64 //! ------- @@ -55,9 +59,24 @@ ASMJIT_ENUM(kCodeGen) { //! If this option is enabled these hints will be emitted. //! //! This feature is disabled by default, because the only processor that - //! used to take into consideration prediction hints was P4 that is not used - //! anymore. - kCodeGenPredictedJumps = 1 + //! used to take into consideration prediction hints was P4. Newer processors + //! implement heuristics for branch prediction that ignores any static hints. + kCodeGenPredictedJumps = 1, + + //! Schedule instructions so they can be executed faster (`Compiler` only). + //! + //! Default `false`, has to be explicitly enabled because it scheduler needs + //! some time to run. + //! + //! X86/X64 + //! ------- + //! + //! If scheduling is enabled AsmJit will try to reorder instructions to + //! minimize dependency chain. Scheduler always runs after the registers are + //! allocated so it doesn't change count of register allocs/spills. + //! + //! This feature is highly experimental and untested. + kCodeGenEnableScheduler = 2 }; // ============================================================================ @@ -66,7 +85,9 @@ ASMJIT_ENUM(kCodeGen) { //! Code aligning mode. ASMJIT_ENUM(kAlignMode) { + //! Align by emitting a sequence that can be executed (code). kAlignCode = 0, + //! Align by emitting sequence that shouldn't be executed (data). kAlignData = 1 }; @@ -86,8 +107,8 @@ ASMJIT_ENUM(kRelocMode) { // [asmjit::CodeGen] // ============================================================================ -//! Abstract class defining basics of \ref Assembler and \ref BaseCompiler. -struct CodeGen { +//! Abstract class defining basics of \ref Assembler and \ref Compiler. +struct ASMJIT_VCLASS CodeGen { ASMJIT_NO_COPY(CodeGen) // -------------------------------------------------------------------------- @@ -154,7 +175,7 @@ struct CodeGen { ASMJIT_API Error setError(Error error, const char* message = NULL); //! Clear the last error code. - ASMJIT_INLINE void clearError() { + ASMJIT_INLINE void resetError() { _error = kErrorOk; } @@ -167,7 +188,7 @@ struct CodeGen { ASMJIT_API Error setErrorHandler(ErrorHandler* handler); //! Clear error handler. - ASMJIT_INLINE Error clearErrorHandler() { + ASMJIT_INLINE Error resetErrorHandler() { return setErrorHandler(NULL); } @@ -194,21 +215,13 @@ struct CodeGen { _options = options; } - //! Get options of the next instruction and clear them. - ASMJIT_INLINE uint32_t getOptionsAndClear() { + //! Get options of the next instruction and reset them. + ASMJIT_INLINE uint32_t getOptionsAndReset() { uint32_t options = _options; _options = 0; return options; }; - // -------------------------------------------------------------------------- - // [Purge] - // -------------------------------------------------------------------------- - - //! Called by \ref clear() and \ref reset() to clear all data used by the - //! code generator. - virtual void _purge() = 0; - // -------------------------------------------------------------------------- // [Make] // -------------------------------------------------------------------------- diff --git a/src/asmjit/base/compiler.cpp b/src/asmjit/base/compiler.cpp index 156f568..0f40b74 100644 --- a/src/asmjit/base/compiler.cpp +++ b/src/asmjit/base/compiler.cpp @@ -35,10 +35,10 @@ static const char noName[1] = { '\0' }; enum { kBaseCompilerDefaultLookAhead = 64 }; // ============================================================================ -// [asmjit::BaseCompiler - Construction / Destruction] +// [asmjit::Compiler - Construction / Destruction] // ============================================================================ -BaseCompiler::BaseCompiler(Runtime* runtime) : +Compiler::Compiler(Runtime* runtime) : CodeGen(runtime), _nodeFlowId(0), _nodeFlags(0), @@ -54,40 +54,23 @@ BaseCompiler::BaseCompiler(Runtime* runtime) : _localConstPool(&_localConstZone), _globalConstPool(&_baseZone) {} -BaseCompiler::~BaseCompiler() { +Compiler::~Compiler() { reset(); } // ============================================================================ -// [asmjit::BaseCompiler - Clear / Reset] +// [asmjit::Compiler - Clear / Reset] // ============================================================================ -void BaseCompiler::clear() { - _purge(); -} - -void BaseCompiler::reset() { - _purge(); - - _localConstPool.reset(); - _globalConstPool.reset(); - - _targets.reset(); - _vars.reset(); - - _baseZone.reset(); - _varZone.reset(); - _stringZone.reset(); - _localConstZone.reset(); -} - -void BaseCompiler::_purge() { - _baseZone.clear(); - - _varZone.clear(); - _stringZone.clear(); - +void Compiler::reset(bool releaseMemory) { + // CodeGen members. + _error = kErrorOk; _options = 0; + _baseZone.reset(releaseMemory); + + // Compiler members. + _nodeFlowId = 0; + _nodeFlags = 0; _firstNode = NULL; _lastNode = NULL; @@ -95,23 +78,31 @@ void BaseCompiler::_purge() { _cursor = NULL; _func = NULL; - _targets.clear(); - _vars.clear(); + _localConstPool.reset(); + _globalConstPool.reset(); - clearError(); + _localConstPoolLabel.reset(); + _globalConstPoolLabel.reset(); + + _varZone.reset(releaseMemory); + _stringZone.reset(releaseMemory); + _localConstZone.reset(releaseMemory); + + _targets.reset(releaseMemory); + _vars.reset(releaseMemory); } // ============================================================================ -// [asmjit::BaseCompiler - Node Management] +// [asmjit::Compiler - Node Management] // ============================================================================ -Node* BaseCompiler::setCursor(Node* node) { +Node* Compiler::setCursor(Node* node) { Node* old = _cursor; _cursor = node; return old; } -Node* BaseCompiler::addNode(Node* node) { +Node* Compiler::addNode(Node* node) { ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_next == NULL); @@ -145,7 +136,7 @@ Node* BaseCompiler::addNode(Node* node) { return node; } -Node* BaseCompiler::addNodeBefore(Node* node, Node* ref) { +Node* Compiler::addNodeBefore(Node* node, Node* ref) { ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_next == NULL); @@ -166,7 +157,7 @@ Node* BaseCompiler::addNodeBefore(Node* node, Node* ref) { return node; } -Node* BaseCompiler::addNodeAfter(Node* node, Node* ref) { +Node* Compiler::addNodeAfter(Node* node, Node* ref) { ASMJIT_ASSERT(node != NULL); ASMJIT_ASSERT(node->_prev == NULL); ASMJIT_ASSERT(node->_next == NULL); @@ -187,7 +178,7 @@ Node* BaseCompiler::addNodeAfter(Node* node, Node* ref) { return node; } -static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, Node* node_) { +static ASMJIT_INLINE void BaseCompiler_nodeRemoved(Compiler* self, Node* node_) { if (node_->isJmpOrJcc()) { JumpNode* node = static_cast(node_); TargetNode* target = node->getTarget(); @@ -213,7 +204,7 @@ static ASMJIT_INLINE void BaseCompiler_nodeRemoved(BaseCompiler* self, Node* nod } } -Node* BaseCompiler::removeNode(Node* node) { +Node* Compiler::removeNode(Node* node) { Node* prev = node->_prev; Node* next = node->_next; @@ -237,7 +228,7 @@ Node* BaseCompiler::removeNode(Node* node) { return node; } -void BaseCompiler::removeNodes(Node* first, Node* last) { +void Compiler::removeNodes(Node* first, Node* last) { if (first == last) { removeNode(first); return; @@ -275,10 +266,10 @@ void BaseCompiler::removeNodes(Node* first, Node* last) { } // ============================================================================ -// [asmjit::BaseCompiler - Align] +// [asmjit::Compiler - Align] // ============================================================================ -AlignNode* BaseCompiler::newAlign(uint32_t mode, uint32_t offset) { +AlignNode* Compiler::newAlign(uint32_t mode, uint32_t offset) { AlignNode* node = newNode(mode, offset); if (node == NULL) goto _NoMemory; @@ -289,7 +280,7 @@ _NoMemory: return NULL; } -AlignNode* BaseCompiler::addAlign(uint32_t mode, uint32_t offset) { +AlignNode* Compiler::addAlign(uint32_t mode, uint32_t offset) { AlignNode* node = newAlign(mode, offset); if (node == NULL) return NULL; @@ -297,10 +288,10 @@ AlignNode* BaseCompiler::addAlign(uint32_t mode, uint32_t offset) { } // ============================================================================ -// [asmjit::BaseCompiler - Target] +// [asmjit::Compiler - Target] // ============================================================================ -TargetNode* BaseCompiler::newTarget() { +TargetNode* Compiler::newTarget() { TargetNode* node = newNode( OperandUtil::makeLabelId(static_cast(_targets.getLength()))); @@ -313,7 +304,7 @@ _NoMemory: return NULL; } -TargetNode* BaseCompiler::addTarget() { +TargetNode* Compiler::addTarget() { TargetNode* node = newTarget(); if (node == NULL) return NULL; @@ -321,10 +312,10 @@ TargetNode* BaseCompiler::addTarget() { } // ============================================================================ -// [asmjit::BaseCompiler - Label] +// [asmjit::Compiler - Label] // ============================================================================ -Error BaseCompiler::_newLabel(Label* dst) { +Error Compiler::_newLabel(Label* dst) { dst->_init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue); dst->_init_packed_d2_d3(0, 0); @@ -339,7 +330,7 @@ _NoMemory: return setError(kErrorNoHeapMemory); } -void BaseCompiler::bind(const Label& label) { +void Compiler::bind(const Label& label) { uint32_t index = label.getId(); ASMJIT_ASSERT(index < _targets.getLength()); @@ -347,10 +338,10 @@ void BaseCompiler::bind(const Label& label) { } // ============================================================================ -// [asmjit::BaseCompiler - Embed] +// [asmjit::Compiler - Embed] // ============================================================================ -EmbedNode* BaseCompiler::newEmbed(const void* data, uint32_t size) { +EmbedNode* Compiler::newEmbed(const void* data, uint32_t size) { EmbedNode* node; if (size > EmbedNode::kInlineBufferSize) { @@ -373,7 +364,7 @@ _NoMemory: return NULL; } -EmbedNode* BaseCompiler::addEmbed(const void* data, uint32_t size) { +EmbedNode* Compiler::addEmbed(const void* data, uint32_t size) { EmbedNode* node = newEmbed(data, size); if (node == NULL) return node; @@ -381,10 +372,10 @@ EmbedNode* BaseCompiler::addEmbed(const void* data, uint32_t size) { } // ============================================================================ -// [asmjit::BaseCompiler - Comment] +// [asmjit::Compiler - Comment] // ============================================================================ -CommentNode* BaseCompiler::newComment(const char* str) { +CommentNode* Compiler::newComment(const char* str) { CommentNode* node; if (str != NULL && str[0]) { @@ -403,14 +394,14 @@ _NoMemory: return NULL; } -CommentNode* BaseCompiler::addComment(const char* str) { +CommentNode* Compiler::addComment(const char* str) { CommentNode* node = newComment(str); if (node == NULL) return NULL; return static_cast(addNode(node)); } -CommentNode* BaseCompiler::comment(const char* fmt, ...) { +CommentNode* Compiler::comment(const char* fmt, ...) { char buf[256]; char* p = buf; @@ -431,10 +422,10 @@ CommentNode* BaseCompiler::comment(const char* fmt, ...) { } // ============================================================================ -// [asmjit::BaseCompiler - Hint] +// [asmjit::Compiler - Hint] // ============================================================================ -HintNode* BaseCompiler::newHint(BaseVar& var, uint32_t hint, uint32_t value) { +HintNode* Compiler::newHint(Var& var, uint32_t hint, uint32_t value) { if (var.getId() == kInvalidValue) return NULL; VarData* vd = getVd(var); @@ -449,7 +440,7 @@ _NoMemory: return NULL; } -HintNode* BaseCompiler::addHint(BaseVar& var, uint32_t hint, uint32_t value) { +HintNode* Compiler::addHint(Var& var, uint32_t hint, uint32_t value) { if (var.getId() == kInvalidValue) return NULL; @@ -460,10 +451,10 @@ HintNode* BaseCompiler::addHint(BaseVar& var, uint32_t hint, uint32_t value) { } // ============================================================================ -// [asmjit::BaseCompiler - Vars] +// [asmjit::Compiler - Vars] // ============================================================================ -VarData* BaseCompiler:: _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name) { +VarData* Compiler::_newVd(uint32_t type, uint32_t size, uint32_t c, const char* name) { VarData* vd = reinterpret_cast(_varZone.alloc(sizeof(VarData))); if (vd == NULL) goto _NoMemory; @@ -492,6 +483,7 @@ VarData* BaseCompiler:: _newVd(uint32_t type, uint32_t size, uint32_t c, const c vd->_alignment = static_cast(IntUtil::iMin(size, 64)); vd->_size = size; + vd->_homeMask = 0; vd->_memOffset = 0; vd->_memCell = NULL; @@ -512,31 +504,31 @@ _NoMemory: return NULL; } -void BaseCompiler::alloc(BaseVar& var) { +void Compiler::alloc(Var& var) { addHint(var, kVarHintAlloc, kInvalidValue); } -void BaseCompiler::alloc(BaseVar& var, uint32_t regIndex) { +void Compiler::alloc(Var& var, uint32_t regIndex) { addHint(var, kVarHintAlloc, regIndex); } -void BaseCompiler::alloc(BaseVar& var, const BaseReg& reg) { +void Compiler::alloc(Var& var, const Reg& reg) { addHint(var, kVarHintAlloc, reg.getRegIndex()); } -void BaseCompiler::save(BaseVar& var) { +void Compiler::save(Var& var) { addHint(var, kVarHintSave, kInvalidValue); } -void BaseCompiler::spill(BaseVar& var) { +void Compiler::spill(Var& var) { addHint(var, kVarHintSpill, kInvalidValue); } -void BaseCompiler::unuse(BaseVar& var) { +void Compiler::unuse(Var& var) { addHint(var, kVarHintUnuse, kInvalidValue); } -uint32_t BaseCompiler::getPriority(BaseVar& var) const { +uint32_t Compiler::getPriority(Var& var) const { if (var.getId() == kInvalidValue) return kInvalidValue; @@ -544,7 +536,7 @@ uint32_t BaseCompiler::getPriority(BaseVar& var) const { return vd->getPriority(); } -void BaseCompiler::setPriority(BaseVar& var, uint32_t priority) { +void Compiler::setPriority(Var& var, uint32_t priority) { if (var.getId() == kInvalidValue) return; @@ -555,7 +547,7 @@ void BaseCompiler::setPriority(BaseVar& var, uint32_t priority) { vd->_priority = static_cast(priority); } -bool BaseCompiler::getSaveOnUnuse(BaseVar& var) const { +bool Compiler::getSaveOnUnuse(Var& var) const { if (var.getId() == kInvalidValue) return false; @@ -563,7 +555,7 @@ bool BaseCompiler::getSaveOnUnuse(BaseVar& var) const { return static_cast(vd->_saveOnUnuse); } -void BaseCompiler::setSaveOnUnuse(BaseVar& var, bool value) { +void Compiler::setSaveOnUnuse(Var& var, bool value) { if (var.getId() == kInvalidValue) return; @@ -571,7 +563,7 @@ void BaseCompiler::setSaveOnUnuse(BaseVar& var, bool value) { vd->_saveOnUnuse = value; } -void BaseCompiler::rename(BaseVar& var, const char* name) { +void Compiler::rename(Var& var, const char* name) { if (var.getId() == kInvalidValue) return; diff --git a/src/asmjit/base/compiler.h b/src/asmjit/base/compiler.h index f521236..7f871d0 100644 --- a/src/asmjit/base/compiler.h +++ b/src/asmjit/base/compiler.h @@ -15,13 +15,10 @@ #include "../base/assembler.h" #include "../base/codegen.h" #include "../base/constpool.h" +#include "../base/containers.h" #include "../base/error.h" -#include "../base/func.h" #include "../base/intutil.h" #include "../base/operand.h" -#include "../base/podlist.h" -#include "../base/podvector.h" -#include "../base/runtime.h" #include "../base/zone.h" // [Api-Begin] @@ -33,12 +30,12 @@ namespace asmjit { // [Forward Declarations] // ============================================================================ -struct BaseCompiler; +struct Compiler; struct VarAttr; struct VarData; -struct BaseVarInst; -struct BaseVarState; +struct VarMap; +struct VarState; struct Node; struct EndNode; @@ -49,7 +46,7 @@ struct JumpNode; // [asmjit::kConstScope] // ============================================================================ -//! \addtogroup asmjit_base_general +//! \addtogroup asmjit_base_compiler //! \{ //! Scope of the constant. @@ -60,15 +57,69 @@ ASMJIT_ENUM(kConstScope) { kConstScopeGlobal = 1 }; -//! \} +// ============================================================================ +// [asmjit::kVarType] +// ============================================================================ + +ASMJIT_ENUM(kVarType) { + //! Variable is 8-bit signed integer. + kVarTypeInt8 = 0, + //! Variable is 8-bit unsigned integer. + kVarTypeUInt8 = 1, + //! Variable is 16-bit signed integer. + kVarTypeInt16 = 2, + //! Variable is 16-bit unsigned integer. + kVarTypeUInt16 = 3, + //! Variable is 32-bit signed integer. + kVarTypeInt32 = 4, + //! Variable is 32-bit unsigned integer. + kVarTypeUInt32 = 5, + //! Variable is 64-bit signed integer. + kVarTypeInt64 = 6, + //! Variable is 64-bit unsigned integer. + kVarTypeUInt64 = 7, + + //! Variable is target `intptr_t`, not compatible with host `intptr_t`. + kVarTypeIntPtr = 8, + //! Variable is target `uintptr_t`, not compatible with host `uintptr_t`. + kVarTypeUIntPtr = 9, + + //! Variable is 32-bit floating point (single precision). + kVarTypeFp32 = 10, + //! Variable is 64-bit floating point (double precision). + kVarTypeFp64 = 11, + + //! \internal + _kVarTypeIntStart = kVarTypeInt8, + //! \internal + _kVarTypeIntEnd = kVarTypeUIntPtr, + + //! \internal + _kVarTypeFpStart = kVarTypeFp32, + //! \internal + _kVarTypeFpEnd = kVarTypeFp64 +}; + +// ============================================================================ +// [asmjit::kVarFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 variable flags. +ASMJIT_ENUM(kVarFlags) { + //! Variable contains single-precision floating-point(s). + kVarFlagSp = 0x10, + //! Variable contains double-precision floating-point(s). + kVarFlagDp = 0x20, + //! Variable is packed, i.e. packed floats, doubles, ... + kVarFlagPacked = 0x40 +}; // ============================================================================ // [asmjit::kVarAttrFlags] // ============================================================================ -//! \addtogroup asmjit_base_tree -//! \{ - //! Variable attribute flags. ASMJIT_ENUM(kVarAttrFlags) { //! Variable is accessed through register on input. @@ -106,8 +157,10 @@ ASMJIT_ENUM(kVarAttrFlags) { //! Variable is a function return value passed in register. kVarAttrOutRet = 0x00000400, + //! Variable should be spilled. + kVarAttrSpill = 0x00000800, //! Variable should be unused at the end of the instruction/node. - kVarAttrUnuse = 0x00000800, + kVarAttrUnuse = 0x00001000, //! \internal //! @@ -138,9 +191,9 @@ ASMJIT_ENUM(kVarAttrFlags) { // [asmjit::kVarHint] // ============================================================================ -//! Variable hint (used by `BaseCompiler)`. +//! Variable hint (used by `Compiler)`. //! -//! @sa `BaseCompiler`. +//! \sa Compiler. ASMJIT_ENUM(kVarHint) { //! Alloc variable. kVarHintAlloc = 0, @@ -178,6 +231,196 @@ ASMJIT_ENUM(kVarState) { kVarStateMem = 2 }; +// ============================================================================ +// [asmjit::kFuncConv] +// ============================================================================ + +//! Function calling convention. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncConv` - X86/X64 calling conventions. +ASMJIT_ENUM(kFuncConv) { + //! Calling convention is invalid (can't be used). + kFuncConvNone = 0, + +#if defined(ASMJIT_DOCGEN) + //! Default calling convention for current platform / operating system. + kFuncConvHost = DependsOnHost, + + //! Default C calling convention based on current compiler's settings. + kFuncConvHostCDecl = DependsOnHost, + + //! Compatibility for `__stdcall` calling convention. + //! + //! \note This enumeration is always set to a value which is compatible with + //! current compilers __stdcall calling convention. In 64-bit mode the value + //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`. + kFuncConvHostStdCall = DependsOnHost, + + //! Compatibility for `__fastcall` calling convention. + //! + //! \note This enumeration is always set to a value which is compatible with + //! current compilers `__fastcall` calling convention. In 64-bit mode the value + //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`. + kFuncConvHostFastCall = DependsOnHost +#endif // ASMJIT_DOCGEN +}; + +// ============================================================================ +// [asmjit::kFuncHint] +// ============================================================================ + +//! Function hints. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncHint` - X86/X64 function hints. +ASMJIT_ENUM(kFuncHint) { + //! Make a naked function (default true). + //! + //! Naked function is function without using standard prolog/epilog sequence). + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Standard prolog sequence is: + //! + //! ~~~ + //! push zbp + //! mov zsp, zbp + //! sub zsp, StackAdjustment + //! ~~~ + //! + //! which is an equivalent to: + //! + //! ~~~ + //! enter StackAdjustment, 0 + //! ~~~ + //! + //! Standard epilog sequence is: + //! + //! ~~~ + //! mov zsp, zbp + //! pop zbp + //! ~~~ + //! + //! which is an equavalent to: + //! + //! ~~~ + //! leave + //! ~~~ + //! + //! Naked functions can omit the prolog/epilog sequence. The advantage of + //! doing such modification is that EBP/RBP register can be used by the + //! register allocator which can result in less spills/allocs. + kFuncHintNaked = 0, + + //! Generate compact function prolog/epilog if possible. + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Use shorter, but possible slower prolog/epilog sequence to save/restore + //! registers. + kFuncHintCompact = 1 +}; + +// ============================================================================ +// [asmjit::kFuncFlags] +// ============================================================================ + +//! Function flags. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncFlags` - X86/X64 function flags. +ASMJIT_ENUM(kFuncFlags) { + //! Whether the function is using naked (minimal) prolog / epilog. + kFuncFlagIsNaked = 0x00000001, + + //! Whether an another function is called from this function. + kFuncFlagIsCaller = 0x00000002, + + //! Whether the stack is not aligned to the required stack alignment, + //! thus it has to be aligned manually. + kFuncFlagIsStackMisaligned = 0x00000004, + + //! Whether the stack pointer is adjusted by the stack size needed + //! to save registers and function variables. + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Stack pointer (ESP/RSP) is adjusted by 'sub' instruction in prolog and by + //! 'add' instruction in epilog (only if function is not naked). If function + //! needs to perform manual stack alignment more instructions are used to + //! adjust the stack (like "and zsp, -Alignment"). + kFuncFlagIsStackAdjusted = 0x00000008, + + //! Whether the function is finished using `Compiler::endFunc()`. + kFuncFlagIsFinished = 0x80000000 +}; + +// ============================================================================ +// [asmjit::kFuncDir] +// ============================================================================ + +//! Function arguments direction. +ASMJIT_ENUM(kFuncDir) { + //! Arguments are passed left to right. + //! + //! This arguments direction is unusual in C, however it's used in Pascal. + kFuncDirLtr = 0, + + //! Arguments are passed right ro left + //! + //! This is the default argument direction in C. + kFuncDirRtl = 1 +}; + +// ============================================================================ +// [asmjit::kFuncArg] +// ============================================================================ + +//! Function argument (lo/hi) specification. +ASMJIT_ENUM(kFuncArg) { + //! Maxumum number of function arguments supported by AsmJit. + kFuncArgCount = 16, + //! Extended maximum number of arguments (used internally). + kFuncArgCountLoHi = kFuncArgCount * 2, + + //! Index to the LO part of function argument (default). + //! + //! This value is typically omitted and added only if there is HI argument + //! accessed. + kFuncArgLo = 0, + //! Index to the HI part of function argument. + //! + //! HI part of function argument depends on target architecture. On x86 it's + //! typically used to transfer 64-bit integers (they form a pair of 32-bit + //! integers). + kFuncArgHi = kFuncArgCount +}; + +// ============================================================================ +// [asmjit::kFuncRet] +// ============================================================================ + +//! Function return value (lo/hi) specification. +ASMJIT_ENUM(kFuncRet) { + //! Index to the LO part of function return value. + kFuncRetLo = 0, + //! Index to the HI part of function return value. + kFuncRetHi = 1 +}; + +// ============================================================================ +// [asmjit::kFuncStackInvalid] +// ============================================================================ + +enum kFuncMisc { + //! Invalid stack offset in function or function parameter. + kFuncStackInvalid = -1 +}; + // ============================================================================ // [asmjit::kNodeType] // ============================================================================ @@ -211,43 +454,45 @@ ASMJIT_ENUM(kNodeType) { }; // ============================================================================ -// [asmjit::kNodeFlag] +// [asmjit::kNodeFlags] // ============================================================================ -ASMJIT_ENUM(kNodeFlag) { - //! Whether the node was translated by `BaseContext`. +ASMJIT_ENUM(kNodeFlags) { + //! Whether the node has been translated, thus contains only registers. kNodeFlagIsTranslated = 0x0001, + //! Whether the node was scheduled - possibly reordered, but basically this + //! is a mark that is set by scheduler after the node has been visited. + kNodeFlagIsScheduled = 0x0002, + + //! Whether the node is informative only and can be safely removed. + kNodeFlagIsInformative = 0x0004, + //! Whether the `InstNode` is a jump. - kNodeFlagIsJmp = 0x0002, + kNodeFlagIsJmp = 0x0008, //! Whether the `InstNode` is a conditional jump. - kNodeFlagIsJcc = 0x0004, + kNodeFlagIsJcc = 0x0010, //! Whether the `InstNode` is an unconditinal jump or conditional //! jump that is likely to be taken. - kNodeFlagIsTaken = 0x0008, + kNodeFlagIsTaken = 0x0020, //! Whether the `Node` will return from a function. //! //! This flag is used by both `EndNode` and `RetNode`. - kNodeFlagIsRet = 0x0010, + kNodeFlagIsRet = 0x0040, //! Whether the instruction is special. - kNodeFlagIsSpecial = 0x0020, + kNodeFlagIsSpecial = 0x0080, //! Whether the instruction is an FPU instruction. - kNodeFlagIsFp = 0x0040 + kNodeFlagIsFp = 0x0100 }; -//! \} - // ============================================================================ // [asmjit::MemCell] // ============================================================================ -//! \addtogroup asmjit_base_tree -//! \{ - struct MemCell { ASMJIT_NO_COPY(MemCell) @@ -285,6 +530,54 @@ struct MemCell { uint32_t _alignment; }; +// ============================================================================ +// [asmjit::Var] +// ============================================================================ + +//! Base class for all variables. +struct Var : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Var() : Operand(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, 0, 0, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, kInvalidValue); + } + + ASMJIT_INLINE Var(const Var& other) : Operand(other) {} + + explicit ASMJIT_INLINE Var(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [Var Specific] + // -------------------------------------------------------------------------- + + //! Clone `Var` operand. + ASMJIT_INLINE Var clone() const { + return Var(*this); + } + + //! Get whether the variable has been initialized by `Compiler`. + ASMJIT_INLINE bool isInitialized() const { + return _vreg.id != kInvalidValue; + } + + //! Get variable type. + ASMJIT_INLINE uint32_t getVarType() const { + return _vreg.vType; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Var& operator=(const Var& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const Var& other) const { return _packed[0] == other._packed[0]; } + ASMJIT_INLINE bool operator!=(const Var& other) const { return !operator==(other); } +}; + // ============================================================================ // [asmjit::VarBits] // ============================================================================ @@ -405,44 +698,125 @@ struct VarBits { //! Base variable data. struct VarData { // -------------------------------------------------------------------------- - // [Accessors] + // [Accessors - Base] // -------------------------------------------------------------------------- //! Get variable name. - ASMJIT_INLINE const char* getName() const { return _name; } - //! Get variable id. - ASMJIT_INLINE uint32_t getId() const { return _id; } + ASMJIT_INLINE const char* getName() const { + return _name; + } - //! Get whether the variable has context id. - ASMJIT_INLINE bool hasContextId() const { return _contextId != kInvalidValue; } - //! Get context variable id (used only by `Context)`. - ASMJIT_INLINE uint32_t getContextId() const { return _contextId; } - //! Set context variable id (used only by `Context)`. - ASMJIT_INLINE void setContextId(uint32_t contextId) { _contextId = contextId; } - //! Reset context variable id (used only by `Context)`. - ASMJIT_INLINE void resetContextId() { _contextId = kInvalidValue; } + //! Get variable id. + ASMJIT_INLINE uint32_t getId() const { + return _id; + } //! Get variable type. - ASMJIT_INLINE uint32_t getType() const { return _type; } + ASMJIT_INLINE uint32_t getType() const { + return _type; + } + //! Get variable class. - ASMJIT_INLINE uint32_t getClass() const { return _class; } - //! Get variable flags. - ASMJIT_INLINE uint32_t getFlags() const { return _flags; } + ASMJIT_INLINE uint32_t getClass() const { + return _class; + } - //! Get variable priority. - ASMJIT_INLINE uint32_t getPriority() const { return _priority; } + // -------------------------------------------------------------------------- + // [Accessors - ContextId] + // -------------------------------------------------------------------------- - //! Get variable state (only used by `Context)`. - ASMJIT_INLINE uint32_t getState() const { return _state; } - //! Set variable state (only used by `Context)`. - ASMJIT_INLINE void setState(uint32_t state) { _state = static_cast(state); } + //! Get whether the variable has context id. + ASMJIT_INLINE bool hasContextId() const { + return _contextId != kInvalidValue; + } + + //! Get context variable id (used only by `Context)`. + ASMJIT_INLINE uint32_t getContextId() const { + return _contextId; + } + + //! Set context variable id (used only by `Context)`. + ASMJIT_INLINE void setContextId(uint32_t contextId) { + _contextId = contextId; + } + + //! Reset context variable id (used only by `Context)`. + ASMJIT_INLINE void resetContextId() { + _contextId = kInvalidValue; + } + + // -------------------------------------------------------------------------- + // [Accessors - Priority] + // -------------------------------------------------------------------------- + + //! Get variable priority, used by compiler to decide which variable to spill. + ASMJIT_INLINE uint32_t getPriority() const { + return _priority; + } + + //! Set variable priority. + ASMJIT_INLINE void setPriority(uint32_t priority) { + ASMJIT_ASSERT(priority <= 0xFF); + _priority = static_cast(priority); + } + + // -------------------------------------------------------------------------- + // [Accessors - State] + // -------------------------------------------------------------------------- + + //! Get variable state, only used by `Context`. + ASMJIT_INLINE uint32_t getState() const { + return _state; + } + + //! Set variable state, only used by `Context`. + ASMJIT_INLINE void setState(uint32_t state) { + ASMJIT_ASSERT(state <= 0xFF); + _state = static_cast(state); + } + + // -------------------------------------------------------------------------- + // [Accessors - RegIndex] + // -------------------------------------------------------------------------- //! Get register index. - ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; } + ASMJIT_INLINE uint32_t getRegIndex() const { + return _regIndex; + } + //! Set register index. - ASMJIT_INLINE void setRegIndex(uint32_t regIndex) { _regIndex = static_cast(regIndex); } + ASMJIT_INLINE void setRegIndex(uint32_t regIndex) { + ASMJIT_ASSERT(regIndex <= 0xFF); + _regIndex = static_cast(regIndex); + } + //! Reset register index. - ASMJIT_INLINE void resetRegIndex() { _regIndex = static_cast(kInvalidReg); } + ASMJIT_INLINE void resetRegIndex() { + _regIndex = static_cast(kInvalidReg); + } + + // -------------------------------------------------------------------------- + // [Accessors - HomeIndex/Mask] + // -------------------------------------------------------------------------- + + //! Get home registers mask. + ASMJIT_INLINE uint32_t getHomeMask() const { + return _homeMask; + } + + //! Add a home register index to the home registers mask. + ASMJIT_INLINE void addHomeIndex(uint32_t regIndex) { + _homeMask |= IntUtil::mask(regIndex); + } + + // -------------------------------------------------------------------------- + // [Accessors - Flags] + // -------------------------------------------------------------------------- + + //! Get variable flags. + ASMJIT_INLINE uint32_t getFlags() const { + return _flags; + } //! Get whether the VarData is only memory allocated on the stack. ASMJIT_INLINE bool isStack() const { return static_cast(_isStack); } @@ -507,7 +881,7 @@ struct VarData { //! Variable priority. uint8_t _priority; - //! Variable state (connected with actual `BaseVarState)`. + //! Variable state (connected with actual `VarState)`. uint8_t _state; //! Actual register index (only used by `Context)`, during translate. uint8_t _regIndex; @@ -524,7 +898,7 @@ struct VarData { uint8_t _isCalculated : 1; //! Save on unuse (at end of the variable scope). uint8_t _saveOnUnuse : 1; - //! Whether variable was changed (connected with actual `BaseVarState)`. + //! Whether variable was changed (connected with actual `VarState)`. uint8_t _modified : 1; //! \internal uint8_t _reserved0 : 3; @@ -534,9 +908,12 @@ struct VarData { //! Variable size. uint32_t _size; + //! Mask of all registers variable has been allocated to. + uint32_t _homeMask; + //! Home memory offset. int32_t _memOffset; - //! Home memory cell, used by `BaseContext` (initially NULL). + //! Home memory cell, used by `Context` (initially NULL). MemCell* _memCell; //! Register read access statistics. @@ -554,7 +931,7 @@ struct VarData { // -------------------------------------------------------------------------- // These variables are only used during register allocation. They are - // initialized by init() phase and cleared by cleanup() phase. + // initialized by init() phase and reset by cleanup() phase. union { //! Temporary link to VarAttr* used by the `Context` used in @@ -728,18 +1105,481 @@ struct VarAttr { }; // ============================================================================ -// [asmjit::BaseVarInst] +// [asmjit::VarMap] // ============================================================================ -//! Variable allocation instructions. -struct BaseVarInst {}; +//! Variables' map related to a single node (instruction / other node). +struct VarMap { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get count of variables (all). + ASMJIT_INLINE uint32_t getVaCount() const { + return _vaCount; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Variables count. + uint32_t _vaCount; +}; // ============================================================================ -// [asmjit::BaseVarState] +// [asmjit::VarState] // ============================================================================ -//! Variable(s) state. -struct BaseVarState {}; +//! Variables' state. +struct VarState {}; + +// ============================================================================ +// [asmjit::TypeId / VarMapping] +// ============================================================================ + +//! Function builder 'void' type. +struct Void {}; + +//! Function builder 'int8_t' type. +struct Int8Type {}; +//! Function builder 'uint8_t' type. +struct UInt8Type {}; + +//! Function builder 'int16_t' type. +struct Int16Type {}; +//! Function builder 'uint16_t' type. +struct UInt16Type {}; + +//! Function builder 'int32_t' type. +struct Int32Type {}; +//! Function builder 'uint32_t' type. +struct UInt32Type {}; + +//! Function builder 'int64_t' type. +struct Int64Type {}; +//! Function builder 'uint64_t' type. +struct UInt64Type {}; + +//! Function builder 'intptr_t' type. +struct IntPtrType {}; +//! Function builder 'uintptr_t' type. +struct UIntPtrType {}; + +//! Function builder 'float' type. +struct FloatType {}; +//! Function builder 'double' type. +struct DoubleType {}; + +#if !defined(ASMJIT_DOCGEN) +template +struct TypeId { + enum { kId = static_cast(::asmjit::kInvalidVar) }; +}; + +template +struct TypeId { + enum { kId = kVarTypeIntPtr }; +}; + +#define ASMJIT_TYPE_ID(_T_, _Id_) \ + template<> \ + struct TypeId<_T_> { enum { kId = _Id_ }; } + +ASMJIT_TYPE_ID(void, kInvalidVar); +ASMJIT_TYPE_ID(Void, kInvalidVar); + +ASMJIT_TYPE_ID(int8_t, kVarTypeInt8); +ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8); + +ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8); +ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int16_t, kVarTypeInt16); +ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16); + +ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8); +ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int32_t, kVarTypeInt32); +ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32); +ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int64_t, kVarTypeInt64); +ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64); +ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(float, kVarTypeFp32); +ASMJIT_TYPE_ID(FloatType, kVarTypeFp32); + +ASMJIT_TYPE_ID(double, kVarTypeFp64); +ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64); +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::FuncInOut] +// ============================================================================ + +//! Function in/out - argument or return value translated from `FuncPrototype`. +struct FuncInOut { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t getVarType() const { return _varType; } + + ASMJIT_INLINE bool hasRegIndex() const { return _regIndex != kInvalidReg; } + ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; } + + ASMJIT_INLINE bool hasStackOffset() const { return _stackOffset != kFuncStackInvalid; } + ASMJIT_INLINE int32_t getStackOffset() const { return static_cast(_stackOffset); } + + //! Get whether the argument / return value is assigned. + ASMJIT_INLINE bool isSet() const { + return (_regIndex != kInvalidReg) | (_stackOffset != kFuncStackInvalid); + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the function argument to "unassigned state". + ASMJIT_INLINE void reset() { _packed = 0xFFFFFFFF; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Variable type, see `kVarType`. + uint8_t _varType; + //! Register index if argument / return value is a register. + uint8_t _regIndex; + //! Stack offset if argument / return value is on the stack. + int16_t _stackOffset; + }; + + //! All members packed into single 32-bit integer. + uint32_t _packed; + }; +}; + +// ============================================================================ +// [asmjit::FuncPrototype] +// ============================================================================ + +//! Function prototype. +//! +//! Function prototype contains information about function return type, count +//! of arguments and their types. Function prototype is a low level structure +//! which doesn't contain platform specific or calling convention specific +//! information. Function prototype is used to create a `FuncDecl`. +struct FuncPrototype { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function return value. + ASMJIT_INLINE uint32_t getRet() const { return _ret; } + + //! Get function arguments' IDs. + ASMJIT_INLINE const uint32_t* getArgList() const { return _argList; } + //! Get count of function arguments. + ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } + + //! Get argument at index `id`. + ASMJIT_INLINE uint32_t getArg(uint32_t id) const { + ASMJIT_ASSERT(id < _argCount); + return _argList[id]; + } + + //! Set function definition - return type and arguments. + ASMJIT_INLINE void _setPrototype(uint32_t ret, const uint32_t* argList, uint32_t argCount) { + _ret = ret; + _argList = argList; + _argCount = argCount; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint32_t _ret; + uint32_t _argCount; + const uint32_t* _argList; +}; + +// ============================================================================ +// [asmjit::FuncBuilderX] +// ============================================================================ + +//! Custom function builder for up to 32 function arguments. +struct FuncBuilderX : public FuncPrototype { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE FuncBuilderX() { + _setPrototype(kInvalidVar, _builderArgList, 0); + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Set return type to `retType`. + ASMJIT_INLINE void setRet(uint32_t retType) { + _ret = retType; + } + + ASMJIT_INLINE void setArg(uint32_t id, uint32_t type) { + ASMJIT_ASSERT(id < _argCount); + _builderArgList[id] = type; + } + + ASMJIT_INLINE void addArg(uint32_t type) { + ASMJIT_ASSERT(_argCount < kFuncArgCount); + _builderArgList[_argCount++] = type; + } + + template + ASMJIT_INLINE void setRetT() { + setRet(TypeId::kId); + } + + template + ASMJIT_INLINE void setArgT(uint32_t id) { + setArg(id, TypeId::kId); + } + + template + ASMJIT_INLINE void addArgT() { + addArg(TypeId::kId); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint32_t _builderArgList[kFuncArgCount]; +}; + +//! \internal +#define T(_Type_) TypeId<_Type_>::kId + +//! Function prototype (no args). +template +struct FuncBuilder0 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder0() { + _setPrototype(T(RET), NULL, 0); + } +}; + +//! Function prototype (1 argument). +template +struct FuncBuilder1 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder1() { + static const uint32_t args[] = { T(P0) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (2 arguments). +template +struct FuncBuilder2 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder2() { + static const uint32_t args[] = { T(P0), T(P1) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (3 arguments). +template +struct FuncBuilder3 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder3() { + static const uint32_t args[] = { T(P0), T(P1), T(P2) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (4 arguments). +template +struct FuncBuilder4 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder4() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (5 arguments). +template +struct FuncBuilder5 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder5() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (6 arguments). +template +struct FuncBuilder6 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder6() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (7 arguments). +template +struct FuncBuilder7 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder7() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (8 arguments). +template +struct FuncBuilder8 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder8() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (9 arguments). +template +struct FuncBuilder9 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder9() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (10 arguments). +template +struct FuncBuilder10 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder10() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8), T(P9) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +#undef T + +// ============================================================================ +// [asmjit::FuncDecl] +// ============================================================================ + +//! Function declaration. +struct FuncDecl { + // -------------------------------------------------------------------------- + // [Accessors - Calling Convention] + // -------------------------------------------------------------------------- + + //! Get function calling convention, see `kFuncConv`. + ASMJIT_INLINE uint32_t getConvention() const { return _convention; } + + //! Get whether the callee pops the stack. + ASMJIT_INLINE uint32_t getCalleePopsStack() const { return _calleePopsStack; } + + //! Get direction of arguments passed on the stack. + //! + //! Direction should be always `kFuncDirRtl`. + //! + //! \note This is related to used calling convention, it's not affected by + //! number of function arguments or their types. + ASMJIT_INLINE uint32_t getDirection() const { return _direction; } + + //! Get stack size needed for function arguments passed on the stack. + ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; } + //! Get size of "Red Zone". + ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; } + //! Get size of "Spill Zone". + ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; } + + // -------------------------------------------------------------------------- + // [Accessors - Arguments and Return] + // -------------------------------------------------------------------------- + + //! Get whether the function has a return value. + ASMJIT_INLINE bool hasRet() const { return _retCount != 0; } + //! Get count of function return values. + ASMJIT_INLINE uint32_t getRetCount() const { return _retCount; } + + //! Get function return value. + ASMJIT_INLINE FuncInOut& getRet(uint32_t index = kFuncRetLo) { return _retList[index]; } + //! Get function return value. + ASMJIT_INLINE const FuncInOut& getRet(uint32_t index = kFuncRetLo) const { return _retList[index]; } + + //! Get count of function arguments. + ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } + + //! Get function arguments array. + ASMJIT_INLINE FuncInOut* getArgList() { return _argList; } + //! Get function arguments array (const). + ASMJIT_INLINE const FuncInOut* getArgList() const { return _argList; } + + //! Get function argument at index `index`. + ASMJIT_INLINE FuncInOut& getArg(size_t index) { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + return _argList[index]; + } + + //! Get function argument at index `index`. + ASMJIT_INLINE const FuncInOut& getArg(size_t index) const { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + return _argList[index]; + } + + ASMJIT_INLINE void resetArg(size_t index) { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + _argList[index].reset(); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Calling convention. + uint8_t _convention; + //! Whether a callee pops stack. + uint8_t _calleePopsStack : 1; + //! Direction for arguments passed on the stack, see `kFuncDir`. + uint8_t _direction : 1; + //! Reserved #0 (alignment). + uint8_t _reserved0 : 6; + + //! Count of arguments in `_argList`. + uint8_t _argCount; + //! Count of return value(s). + uint8_t _retCount; + + //! Count of bytes consumed by arguments on the stack (aligned). + uint32_t _argStackSize; + + //! Size of "Red Zone". + //! + //! \note Used by AMD64-ABI (128 bytes). + uint16_t _redZoneSize; + + //! Size of "Spill Zone". + //! + //! \note Used by WIN64-ABI (32 bytes). + uint16_t _spillZoneSize; + + //! Function arguments (including HI arguments) mapped to physical + //! registers and stack offset. + FuncInOut _argList[kFuncArgCountLoHi]; + + //! Function return value(s). + FuncInOut _retList[2]; +}; // ============================================================================ // [asmjit::Node] @@ -759,44 +1599,95 @@ struct Node { //! Create new `Node`. //! //! \note Always use compiler to create nodes. - ASMJIT_INLINE Node(BaseCompiler* compiler, uint32_t type); // Defined-Later. + ASMJIT_INLINE Node(Compiler* compiler, uint32_t type); // Defined-Later. //! Destroy `Node`. ASMJIT_INLINE ~Node() {} // -------------------------------------------------------------------------- - // [Accessors] + // [Accessors - List] // -------------------------------------------------------------------------- //! Get previous node in the compiler stream. - ASMJIT_INLINE Node* getPrev() const { return _prev; } + ASMJIT_INLINE Node* getPrev() const { + return _prev; + } + //! Get next node in the compiler stream. - ASMJIT_INLINE Node* getNext() const { return _next; } + ASMJIT_INLINE Node* getNext() const { + return _next; + } + + // -------------------------------------------------------------------------- + // [Accessors - Comment] + // -------------------------------------------------------------------------- //! Get comment string. - ASMJIT_INLINE const char* getComment() const { return _comment; } + ASMJIT_INLINE const char* getComment() const { + return _comment; + } + //! Set comment string to `str`. - ASMJIT_INLINE void setComment(const char* comment) { _comment = comment; } + ASMJIT_INLINE void setComment(const char* comment) { + _comment = comment; + } + + // -------------------------------------------------------------------------- + // [Accessors - Type and Flags] + // -------------------------------------------------------------------------- //! Get type of node, see `kNodeType`. - ASMJIT_INLINE uint32_t getType() const { return _type; } + ASMJIT_INLINE uint32_t getType() const { + return _type; + } //! Get node flags. - ASMJIT_INLINE uint32_t getFlags() const { return _flags; } + ASMJIT_INLINE uint32_t getFlags() const { + return _flags; + } + //! Set node flags to `flags`. - ASMJIT_INLINE void setFlags(uint32_t flags) { _flags = static_cast(flags); } + ASMJIT_INLINE void setFlags(uint32_t flags) { + _flags = static_cast(flags); + } //! Get whether the instruction has flag `flag`. - ASMJIT_INLINE bool hasFlag(uint32_t flag) const { return (static_cast(_flags) & flag) != 0; } + ASMJIT_INLINE bool hasFlag(uint32_t flag) const { + return (static_cast(_flags) & flag) != 0; + } + //! Add instruction `flags`. - ASMJIT_INLINE void addFlags(uint32_t flags) { _flags |= static_cast(flags); } + ASMJIT_INLINE void addFlags(uint32_t flags) { + _flags |= static_cast(flags); + } + //! Clear instruction `flags`. - ASMJIT_INLINE void delFlags(uint32_t flags) { _flags &= static_cast(~flags); } + ASMJIT_INLINE void delFlags(uint32_t flags) { + _flags &= static_cast(~flags); + } //! Get whether the node has beed fetched. - ASMJIT_INLINE bool isFetched() const { return _flowId != 0; } + ASMJIT_INLINE bool isFetched() const { + return _flowId != 0; + } + //! Get whether the node has been translated. - ASMJIT_INLINE bool isTranslated() const { return hasFlag(kNodeFlagIsTranslated); } + ASMJIT_INLINE bool isTranslated() const { + return hasFlag(kNodeFlagIsTranslated); + } + + //! Get whether the node has been translated. + ASMJIT_INLINE bool isScheduled() const { + return hasFlag(kNodeFlagIsScheduled); + } + + //! Get whether the node is informative only and can be safely removed after + //! translation. + //! + //! Informative nodes are comments and hints. + ASMJIT_INLINE bool isInformative() const { + return hasFlag(kNodeFlagIsInformative); + } //! Whether the instruction is an unconditional jump. ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); } @@ -812,36 +1703,78 @@ struct Node { //! Get whether the instruction accesses FPU. ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); } + // -------------------------------------------------------------------------- + // [Accessors - FlowId] + // -------------------------------------------------------------------------- + //! Get flow index. ASMJIT_INLINE uint32_t getFlowId() const { return _flowId; } //! Set flow index. ASMJIT_INLINE void setFlowId(uint32_t flowId) { _flowId = flowId; } + // -------------------------------------------------------------------------- + // [Accessors - VarMap] + // -------------------------------------------------------------------------- + //! Get whether node contains variable allocation instructions. - ASMJIT_INLINE bool hasVarInst() const { return _varInst != NULL; } + ASMJIT_INLINE bool hasMap() const { + return _map != NULL; + } //! Get variable allocation instructions. - ASMJIT_INLINE BaseVarInst* getVarInst() const { return _varInst; } + ASMJIT_INLINE VarMap* getMap() const { + return _map; + } + //! Get variable allocation instructions casted to `T*`. template - ASMJIT_INLINE T* getVarInst() const { return static_cast(_varInst); } + ASMJIT_INLINE T* getMap() const { + return static_cast(_map); + } + //! Set variable allocation instructions. - ASMJIT_INLINE void setVarInst(BaseVarInst* vi) { _varInst = vi; } + ASMJIT_INLINE void setMap(VarMap* map) { + _map = map; + } + + // -------------------------------------------------------------------------- + // [Accessors - VarState] + // -------------------------------------------------------------------------- //! Get node state. - ASMJIT_INLINE BaseVarState* getState() const { return _state; } + ASMJIT_INLINE VarState* getState() const { + return _state; + } + //! Get node state casted to `T*`. template - ASMJIT_INLINE T* getState() const { return static_cast(_state); } + ASMJIT_INLINE T* getState() const { + return static_cast(_state); + } + //! Set node state. - ASMJIT_INLINE void setState(BaseVarState* state) { _state = state; } + ASMJIT_INLINE void setState(VarState* state) { + _state = state; + } + + // -------------------------------------------------------------------------- + // [Accessors - Liveness] + // -------------------------------------------------------------------------- //! Get whether the node has variable liveness bits. - ASMJIT_INLINE bool hasLiveness() const { return _liveness != NULL; } + ASMJIT_INLINE bool hasLiveness() const { + return _liveness != NULL; + } + //! Get variable liveness bits. - ASMJIT_INLINE VarBits* getLiveness() const { return _liveness; } + ASMJIT_INLINE VarBits* getLiveness() const { + return _liveness; + } + //! Set variable liveness bits. - ASMJIT_INLINE void setLiveness(VarBits* liveness) { _liveness = liveness; } + ASMJIT_INLINE void setLiveness(VarBits* liveness) { + _liveness = liveness; + } // -------------------------------------------------------------------------- // [Members] @@ -865,9 +1798,9 @@ struct Node { //! Inline comment string, initially set to NULL. const char* _comment; - //! Variable allocation instructions (initially NULL, filled by prepare - //! phase). - BaseVarInst* _varInst; + //! Variable mapping (VarAttr to VarData), initially NULL, filled during + //! fetch phase. + VarMap* _map; //! Variable liveness bits (initially NULL, filled by analysis phase). VarBits* _liveness; @@ -876,7 +1809,7 @@ struct Node { //! //! Initially NULL, not all nodes have saved state, only branch/flow control //! nodes. - BaseVarState* _state; + VarState* _state; }; // ============================================================================ @@ -892,7 +1825,7 @@ struct AlignNode : public Node { // -------------------------------------------------------------------------- //! Create a new `AlignNode` instance. - ASMJIT_INLINE AlignNode(BaseCompiler* compiler, uint32_t mode, uint32_t offset) : + ASMJIT_INLINE AlignNode(Compiler* compiler, uint32_t mode, uint32_t offset) : Node(compiler, kNodeTypeAlign) { _mode = mode; @@ -958,7 +1891,7 @@ struct EmbedNode : public Node { // -------------------------------------------------------------------------- //! Create a new `EmbedNode` instance. - ASMJIT_INLINE EmbedNode(BaseCompiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) { + ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) { _size = size; if (size <= kInlineBufferSize) { if (data != NULL) @@ -1013,7 +1946,8 @@ struct CommentNode : public Node { // -------------------------------------------------------------------------- //! Create a new `CommentNode` instance. - ASMJIT_INLINE CommentNode(BaseCompiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) { + ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) { + addFlags(kNodeFlagIsInformative); _comment = comment; } @@ -1034,7 +1968,8 @@ struct HintNode : public Node { // -------------------------------------------------------------------------- //! Create a new `HintNode` instance. - ASMJIT_INLINE HintNode(BaseCompiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) { + ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) { + addFlags(kNodeFlagIsInformative); _vd = vd; _hint = hint; _value = value; @@ -1085,7 +2020,7 @@ struct TargetNode : public Node { // -------------------------------------------------------------------------- //! Create a new `TargetNode` instance. - ASMJIT_INLINE TargetNode(BaseCompiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) { + ASMJIT_INLINE TargetNode(Compiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) { _id = labelId; _numRefs = 0; _from = NULL; @@ -1109,9 +2044,9 @@ struct TargetNode : public Node { //! Get whether the node has assigned state. ASMJIT_INLINE bool hasState() const { return _state != NULL; } //! Get state for this target. - ASMJIT_INLINE BaseVarState* getState() const { return _state; } + ASMJIT_INLINE VarState* getState() const { return _state; } //! Set state for this target. - ASMJIT_INLINE void setState(BaseVarState* state) { _state = state; } + ASMJIT_INLINE void setState(VarState* state) { _state = state; } //! Get number of jumps to this target. ASMJIT_INLINE uint32_t getNumRefs() const { return _numRefs; } @@ -1149,7 +2084,7 @@ struct InstNode : public Node { // -------------------------------------------------------------------------- //! Create a new `InstNode` instance. - ASMJIT_INLINE InstNode(BaseCompiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) { + ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) { _code = static_cast(code); _options = static_cast(options); @@ -1166,7 +2101,7 @@ struct InstNode : public Node { // [Accessors] // -------------------------------------------------------------------------- - //! Get instruction code, see `kInstCode`. + //! Get instruction code, see `kX86InstId`. ASMJIT_INLINE uint32_t getCode() const { return _code; } @@ -1273,7 +2208,7 @@ _Update: // [Members] // -------------------------------------------------------------------------- - //! Instruction code, see `kInstCode`. + //! Instruction code, see `kInstId`. uint16_t _code; //! Instruction options, see `kInstOptions`. uint8_t _options; @@ -1296,7 +2231,7 @@ struct JumpNode : public InstNode { // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE JumpNode(BaseCompiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : + ASMJIT_INLINE JumpNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : InstNode(compiler, code, options, opList, opCount) {} ASMJIT_INLINE ~JumpNode() {} @@ -1339,8 +2274,8 @@ struct FuncNode : public Node { //! Create a new `FuncNode` instance. //! - //! Always use `BaseCompiler::addFunc()` to create a `FuncNode` instance. - ASMJIT_INLINE FuncNode(BaseCompiler* compiler) : + //! Always use `Compiler::addFunc()` to create a `FuncNode` instance. + ASMJIT_INLINE FuncNode(Compiler* compiler) : Node(compiler, kNodeTypeFunc), _entryNode(NULL), _exitNode(NULL), @@ -1547,7 +2482,7 @@ struct EndNode : public Node { // -------------------------------------------------------------------------- //! Create a new `EndNode` instance. - ASMJIT_INLINE EndNode(BaseCompiler* compiler) : Node(compiler, kNodeTypeEnd) { + ASMJIT_INLINE EndNode(Compiler* compiler) : Node(compiler, kNodeTypeEnd) { _flags |= kNodeFlagIsRet; } @@ -1568,7 +2503,7 @@ struct RetNode : public Node { // -------------------------------------------------------------------------- //! Create a new `RetNode` instance. - ASMJIT_INLINE RetNode(BaseCompiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) { + ASMJIT_INLINE RetNode(Compiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) { _flags |= kNodeFlagIsRet; _ret[0] = o0; _ret[1] = o1; @@ -1612,7 +2547,7 @@ struct CallNode : public Node { // -------------------------------------------------------------------------- //! Create a new `CallNode` instance. - ASMJIT_INLINE CallNode(BaseCompiler* compiler, const Operand& target) : + ASMJIT_INLINE CallNode(Compiler* compiler, const Operand& target) : Node(compiler, kNodeTypeCall), _decl(NULL), _target(target), @@ -1683,7 +2618,7 @@ struct SArgNode : public Node { // -------------------------------------------------------------------------- //! Create a new `SArgNode` instance. - ASMJIT_INLINE SArgNode(BaseCompiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) : + ASMJIT_INLINE SArgNode(Compiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) : Node(compiler, kNodeTypeSArg), _call(call), _sVd(sVd), @@ -1722,7 +2657,7 @@ struct SArgNode : public Node { //! \} // ============================================================================ -// [asmjit::BaseCompiler] +// [asmjit::Compiler] // ============================================================================ //! \addtogroup asmjit_base_general @@ -1730,18 +2665,18 @@ struct SArgNode : public Node { //! Base compiler. //! -//! @sa BaseAssembler. -struct BaseCompiler : public CodeGen { - ASMJIT_NO_COPY(BaseCompiler) +//! \sa Assembler. +struct ASMJIT_VCLASS Compiler : public CodeGen { + ASMJIT_NO_COPY(Compiler) // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - //! Create a new `BaseCompiler` instance. - ASMJIT_API BaseCompiler(Runtime* runtime); - //! Destroy the `BaseCompiler` instance. - ASMJIT_API virtual ~BaseCompiler(); + //! Create a new `Compiler` instance. + ASMJIT_API Compiler(Runtime* runtime); + //! Destroy the `Compiler` instance. + ASMJIT_API virtual ~Compiler(); // -------------------------------------------------------------------------- // [LookAhead] @@ -1756,17 +2691,10 @@ struct BaseCompiler : public CodeGen { // [Clear / Reset] // -------------------------------------------------------------------------- - //! Clear everything, but keep buffers allocated. + //! Reset the compiler. //! - //! \note This method will destroy your code. - ASMJIT_API void clear(); - //! Clear everything and reset all buffers. - //! - //! \note This method will destroy your code. - ASMJIT_API void reset(); - //! Called by clear() and reset() to clear all data related to derived - //! class implementation. - ASMJIT_API virtual void _purge(); + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); // -------------------------------------------------------------------------- // [Nodes] @@ -1931,23 +2859,23 @@ struct BaseCompiler : public CodeGen { // -------------------------------------------------------------------------- //! Create a new `HintNode`. - ASMJIT_API HintNode* newHint(BaseVar& var, uint32_t hint, uint32_t value); + ASMJIT_API HintNode* newHint(Var& var, uint32_t hint, uint32_t value); //! Add a new `HintNode`. - ASMJIT_API HintNode* addHint(BaseVar& var, uint32_t hint, uint32_t value); + ASMJIT_API HintNode* addHint(Var& var, uint32_t hint, uint32_t value); // -------------------------------------------------------------------------- // [Vars] // -------------------------------------------------------------------------- //! Get whether variable `var` is created. - ASMJIT_INLINE bool isVarCreated(const BaseVar& var) const { + ASMJIT_INLINE bool isVarCreated(const Var& var) const { return static_cast(var.getId() & kOperandIdNum) < _vars.getLength(); } //! \internal //! //! Get `VarData` by `var`. - ASMJIT_INLINE VarData* getVd(const BaseVar& var) const { + ASMJIT_INLINE VarData* getVd(const Var& var) const { return getVdById(var.getId()); } @@ -1973,36 +2901,36 @@ struct BaseCompiler : public CodeGen { //! Create a new `VarData`. ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name); - //! Create a new `BaseVar`. - virtual Error _newVar(BaseVar* var, uint32_t type, const char* name) = 0; + //! Create a new `Var`. + virtual Error _newVar(Var* var, uint32_t type, const char* name) = 0; //! Alloc variable `var`. - ASMJIT_API void alloc(BaseVar& var); + ASMJIT_API void alloc(Var& var); //! Alloc variable `var` using `regIndex` as a register index. - ASMJIT_API void alloc(BaseVar& var, uint32_t regIndex); + ASMJIT_API void alloc(Var& var, uint32_t regIndex); //! Alloc variable `var` using `reg` as a demanded register. - ASMJIT_API void alloc(BaseVar& var, const BaseReg& reg); + ASMJIT_API void alloc(Var& var, const Reg& reg); //! Spill variable `var`. - ASMJIT_API void spill(BaseVar& var); + ASMJIT_API void spill(Var& var); //! Save variable `var` if modified. - ASMJIT_API void save(BaseVar& var); + ASMJIT_API void save(Var& var); //! Unuse variable `var`. - ASMJIT_API void unuse(BaseVar& var); + ASMJIT_API void unuse(Var& var); //! Get priority of variable `var`. - ASMJIT_API uint32_t getPriority(BaseVar& var) const; + ASMJIT_API uint32_t getPriority(Var& var) const; //! Set priority of variable `var` to `priority`. - ASMJIT_API void setPriority(BaseVar& var, uint32_t priority); + ASMJIT_API void setPriority(Var& var, uint32_t priority); //! Get save-on-unuse `var` property. - ASMJIT_API bool getSaveOnUnuse(BaseVar& var) const; + ASMJIT_API bool getSaveOnUnuse(Var& var) const; //! Set save-on-unuse `var` property to `value`. - ASMJIT_API void setSaveOnUnuse(BaseVar& var, bool value); + ASMJIT_API void setSaveOnUnuse(Var& var, bool value); //! Rename variable `var` to `name`. //! //! \note Only new name will appear in the logger. - ASMJIT_API void rename(BaseVar& var, const char* name); + ASMJIT_API void rename(Var& var, const char* name); // -------------------------------------------------------------------------- // [Stack] @@ -2027,7 +2955,7 @@ struct BaseCompiler : public CodeGen { // -------------------------------------------------------------------------- //! Send assembled code to `assembler`. - virtual Error serialize(BaseAssembler& assembler) = 0; + virtual Error serialize(Assembler& assembler) = 0; // -------------------------------------------------------------------------- // [Members] @@ -2037,6 +2965,7 @@ struct BaseCompiler : public CodeGen { uint32_t _nodeFlowId; //! Flags added to each node created (used only by `Context)`. uint32_t _nodeFlags; + //! Maximum count of nodes to look ahead when allocating/spilling //! registers. uint32_t _maxLookAhead; @@ -2083,11 +3012,11 @@ struct BaseCompiler : public CodeGen { // [Defined-Later] // ============================================================================ -ASMJIT_INLINE Label::Label(BaseCompiler& c) : Operand(NoInit) { +ASMJIT_INLINE Label::Label(Compiler& c) : Operand(NoInit) { c._newLabel(this); } -ASMJIT_INLINE Node::Node(BaseCompiler* compiler, uint32_t type) { +ASMJIT_INLINE Node::Node(Compiler* compiler, uint32_t type) { _prev = NULL; _next = NULL; _type = static_cast(type); @@ -2095,7 +3024,7 @@ ASMJIT_INLINE Node::Node(BaseCompiler* compiler, uint32_t type) { _flags = static_cast(compiler->_nodeFlags); _flowId = compiler->_nodeFlowId; _comment = NULL; - _varInst = NULL; + _map = NULL; _liveness = NULL; _state = NULL; } diff --git a/src/asmjit/base/constpool.cpp b/src/asmjit/base/constpool.cpp index d89f6cc..d85ea31 100644 --- a/src/asmjit/base/constpool.cpp +++ b/src/asmjit/base/constpool.cpp @@ -372,7 +372,7 @@ void ConstPool::fill(void* dst) { #if defined(ASMJIT_TEST) UNIT(base_constpool) { - Zone zone(16192); + Zone zone(32384 - kZoneOverhead); ConstPool pool(&zone); uint32_t i; @@ -455,7 +455,7 @@ UNIT(base_constpool) { "pool.add() - Didn't return aligned offset."); } - INFO("Adding 2 byte constant verify the gap is filled."); + INFO("Adding 2 byte constant to verify the gap is filled."); { uint16_t c = 0xFFFE; size_t offset; diff --git a/src/asmjit/base/podvector.cpp b/src/asmjit/base/containers.cpp similarity index 81% rename from src/asmjit/base/podvector.cpp rename to src/asmjit/base/containers.cpp index 1c4d3cb..b931813 100644 --- a/src/asmjit/base/podvector.cpp +++ b/src/asmjit/base/containers.cpp @@ -8,8 +8,8 @@ #define ASMJIT_EXPORTS // [Dependencies - AsmJit] +#include "../base/containers.h" #include "../base/intutil.h" -#include "../base/podvector.h" // [Api-Begin] #include "../apibegin.h" @@ -22,6 +22,26 @@ namespace asmjit { const PodVectorData PodVectorBase::_nullData = { 0, 0 }; +// ============================================================================ +// [asmjit::PodVectorBase - Reset] +// ============================================================================ + +//! Clear vector data and free internal buffer. +void PodVectorBase::reset(bool releaseMemory) { + PodVectorData* d = _d; + + if (d == &_nullData) + return; + + if (releaseMemory) { + ASMJIT_FREE(d); + _d = const_cast(&_nullData); + return; + } + + d->length = 0; +} + // ============================================================================ // [asmjit::PodVectorBase - Helpers] // ============================================================================ diff --git a/src/asmjit/base/podvector.h b/src/asmjit/base/containers.h similarity index 67% rename from src/asmjit/base/podvector.h rename to src/asmjit/base/containers.h index 81112f3..c6dc70d 100644 --- a/src/asmjit/base/podvector.h +++ b/src/asmjit/base/containers.h @@ -5,11 +5,12 @@ // Zlib - See LICENSE.md file in the package. // [Guard] -#ifndef _ASMJIT_BASE_PODVECTOR_H -#define _ASMJIT_BASE_PODVECTOR_H +#ifndef _ASMJIT_BASE_CONTAINERS_H +#define _ASMJIT_BASE_CONTAINERS_H // [Dependencies - AsmJit] #include "../base/error.h" +#include "../base/globals.h" // [Api-Begin] #include "../apibegin.h" @@ -25,11 +26,19 @@ namespace asmjit { //! \internal struct PodVectorData { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + //! Get data. ASMJIT_INLINE void* getData() const { return (void*)(this + 1); } + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + //! Capacity of the vector. size_t capacity; //! Length of the vector. @@ -54,10 +63,19 @@ struct PodVectorBase { //! Destroy the `PodVectorBase` and data. ASMJIT_INLINE ~PodVectorBase() { - if (_d != &_nullData) - ASMJIT_FREE(_d); + reset(true); } + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the vector data and set its `length` to zero. + //! + //! If `releaseMemory` is true the vector buffer will be released to the + //! system. + ASMJIT_API void reset(bool releaseMemory = false); + // -------------------------------------------------------------------------- // [Grow / Reserve] // -------------------------------------------------------------------------- @@ -127,24 +145,6 @@ struct PodVector : PodVectorBase { return static_cast(_d->getData()); } - // -------------------------------------------------------------------------- - // [Clear / Reset] - // -------------------------------------------------------------------------- - - //! Clear vector data, but don't free an internal buffer. - ASMJIT_INLINE void clear() { - if (_d != &_nullData) - _d->length = 0; - } - - //! Clear vector data and free internal buffer. - ASMJIT_INLINE void reset() { - if (_d != &_nullData) { - ASMJIT_FREE(_d); - _d = const_cast(&_nullData); - } - } - // -------------------------------------------------------------------------- // [Grow / Reserve] // -------------------------------------------------------------------------- @@ -254,19 +254,89 @@ struct PodVector : PodVectorBase { ASMJIT_ASSERT(i < getLength()); return getData()[i]; } +}; - //! Allocate and append a new item and return its address. - T* newElement() { - PodVectorData* d = _d; +// ============================================================================ +// [asmjit::PodList] +// ============================================================================ - if (d->length == d->capacity) { - if (!_grow(1)) - return NULL; - d = _d; - } +//! \internal +template +struct PodList { + ASMJIT_NO_COPY(PodList) - return static_cast(d->getData()) + (d->length++); + // -------------------------------------------------------------------------- + // [Link] + // -------------------------------------------------------------------------- + + struct Link { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get next node. + ASMJIT_INLINE Link* getNext() const { return _next; } + + //! Get value. + ASMJIT_INLINE T getValue() const { return _value; } + //! Set value to `value`. + ASMJIT_INLINE void setValue(const T& value) { _value = value; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + Link* _next; + T _value; + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE PodList() : _first(NULL), _last(NULL) {} + ASMJIT_INLINE ~PodList() {} + + // -------------------------------------------------------------------------- + // [Data] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isEmpty() const { return _first != NULL; } + + ASMJIT_INLINE Link* getFirst() const { return _first; } + ASMJIT_INLINE Link* getLast() const { return _last; } + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _first = NULL; + _last = NULL; } + + ASMJIT_INLINE void prepend(Link* link) { + link->_next = _first; + if (_first == NULL) + _last = link; + _first = link; + } + + ASMJIT_INLINE void append(Link* link) { + link->_next = NULL; + if (_first == NULL) + _first = link; + else + _last->_next = link; + _last = link; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + Link* _first; + Link* _last; }; //! \} @@ -277,4 +347,4 @@ struct PodVector : PodVectorBase { #include "../apiend.h" // [Guard] -#endif // _ASMJIT_BASE_PODVECTOR_H +#endif // _ASMJIT_BASE_CONTAINERS_H diff --git a/src/asmjit/base/context.cpp b/src/asmjit/base/context.cpp index dc6563c..cedec0f 100644 --- a/src/asmjit/base/context.cpp +++ b/src/asmjit/base/context.cpp @@ -21,24 +21,25 @@ namespace asmjit { // ============================================================================ -// [asmjit::BaseContext - Construction / Destruction] +// [asmjit::Context - Construction / Destruction] // ============================================================================ -BaseContext::BaseContext(BaseCompiler* compiler) : +Context::Context(Compiler* compiler) : _compiler(compiler), + _varMapToVaListOffset(0), _baseZone(8192 - kZoneOverhead) { - BaseContext::reset(); + Context::reset(); } -BaseContext::~BaseContext() {} +Context::~Context() {} // ============================================================================ -// [asmjit::BaseContext - Reset] +// [asmjit::Context - Reset] // ============================================================================ -void BaseContext::reset() { - _baseZone.clear(); +void Context::reset(bool releaseMemory) { + _baseZone.reset(releaseMemory); _func = NULL; _start = NULL; @@ -48,7 +49,7 @@ void BaseContext::reset() { _unreachableList.reset(); _jccList.reset(); - _contextVd.clear(); + _contextVd.reset(releaseMemory); _memVarCells = NULL; _memStackCells = NULL; @@ -72,7 +73,7 @@ void BaseContext::reset() { } // ============================================================================ -// [asmjit::BaseContext - Mem] +// [asmjit::Context - Mem] // ============================================================================ static ASMJIT_INLINE uint32_t BaseContext_getDefaultAlignment(uint32_t size) { @@ -92,7 +93,7 @@ static ASMJIT_INLINE uint32_t BaseContext_getDefaultAlignment(uint32_t size) { return 1; } -MemCell* BaseContext::_newVarCell(VarData* vd) { +MemCell* Context::_newVarCell(VarData* vd) { ASMJIT_ASSERT(vd->_memCell == NULL); MemCell* cell; @@ -139,7 +140,7 @@ _NoMemory: return NULL; } -MemCell* BaseContext::_newStackCell(uint32_t size, uint32_t alignment) { +MemCell* Context::_newStackCell(uint32_t size, uint32_t alignment) { MemCell* cell = static_cast(_baseZone.alloc(sizeof(MemCell))); if (cell == NULL) goto _NoMemory; @@ -185,7 +186,7 @@ _NoMemory: return NULL; } -Error BaseContext::resolveCellOffsets() { +Error Context::resolveCellOffsets() { MemCell* varCell = _memVarCells; MemCell* stackCell = _memStackCells; @@ -265,10 +266,10 @@ Error BaseContext::resolveCellOffsets() { } // ============================================================================ -// [asmjit::BaseContext - RemoveUnreachableCode] +// [asmjit::Context - RemoveUnreachableCode] // ============================================================================ -Error BaseContext::removeUnreachableCode() { +Error Context::removeUnreachableCode() { PodList::Link* link = _unreachableList.getFirst(); Node* stop = getStop(); @@ -297,13 +298,211 @@ Error BaseContext::removeUnreachableCode() { } // ============================================================================ -// [asmjit::BaseContext - Cleanup] +// [asmjit::Context - Liveness Analysis] // ============================================================================ //! \internal -//! -//! Translate the given function `func`. -void BaseContext::cleanup() { +struct LivenessTarget { + //! Previous target. + LivenessTarget* prev; + + //! Target node. + TargetNode* node; + //! Jumped from. + JumpNode* from; +}; + +Error Context::livenessAnalysis() { + FuncNode* func = getFunc(); + JumpNode* from = NULL; + + Node* node = func->getEnd(); + uint32_t bLen = static_cast( + ((_contextVd.getLength() + VarBits::kEntityBits - 1) / VarBits::kEntityBits)); + + LivenessTarget* ltCur = NULL; + LivenessTarget* ltUnused = NULL; + + size_t varMapToVaListOffset = _varMapToVaListOffset; + + // No variables. + if (bLen == 0) + return kErrorOk; + + VarBits* bCur = newBits(bLen); + if (bCur == NULL) + goto _NoMemory; + + // Allocate bits for code visited first time. +_OnVisit: + for (;;) { + if (node->hasLiveness()) { + if (bCur->_addBitsDelSource(node->getLiveness(), bCur, bLen)) + goto _OnPatch; + else + goto _OnDone; + } + + VarBits* bTmp = copyBits(bCur, bLen); + if (bTmp == NULL) + goto _NoMemory; + + node->setLiveness(bTmp); + VarMap* map = node->getMap(); + + if (map != NULL) { + uint32_t vaCount = map->getVaCount(); + VarAttr* vaList = reinterpret_cast(((uint8_t*)map) + varMapToVaListOffset); + + for (uint32_t i = 0; i < vaCount; i++) { + VarAttr* va = &vaList[i]; + VarData* vd = va->getVd(); + + uint32_t flags = va->getFlags(); + uint32_t ctxId = vd->getContextId(); + + if ((flags & kVarAttrOutAll) && !(flags & kVarAttrInAll)) { + // Write-Only. + bTmp->setBit(ctxId); + bCur->delBit(ctxId); + } + else { + // Read-Only or Read/Write. + bTmp->setBit(ctxId); + bCur->setBit(ctxId); + } + } + } + + if (node->getType() == kNodeTypeTarget) + goto _OnTarget; + + if (node == func) + goto _OnDone; + + ASMJIT_ASSERT(node->getPrev()); + node = node->getPrev(); + } + + // Patch already generated liveness bits. +_OnPatch: + for (;;) { + ASMJIT_ASSERT(node->hasLiveness()); + VarBits* bNode = node->getLiveness(); + + if (!bNode->_addBitsDelSource(bCur, bLen)) + goto _OnDone; + + if (node->getType() == kNodeTypeTarget) + goto _OnTarget; + + if (node == func) + goto _OnDone; + + node = node->getPrev(); + } + +_OnTarget: + if (static_cast(node)->getNumRefs() != 0) { + // Push a new LivenessTarget onto the stack if needed. + if (ltCur == NULL || ltCur->node != node) { + // Allocate a new LivenessTarget object (from pool or zone). + LivenessTarget* ltTmp = ltUnused; + + if (ltTmp != NULL) { + ltUnused = ltUnused->prev; + } + else { + ltTmp = _baseZone.allocT( + sizeof(LivenessTarget) - sizeof(VarBits) + bLen * sizeof(uintptr_t)); + + if (ltTmp == NULL) + goto _NoMemory; + } + + // Initialize and make current - ltTmp->from will be set later on. + ltTmp->prev = ltCur; + ltTmp->node = static_cast(node); + ltCur = ltTmp; + + from = static_cast(node)->getFrom(); + ASMJIT_ASSERT(from != NULL); + } + else { + from = ltCur->from; + goto _OnJumpNext; + } + + // Visit/Patch. + do { + ltCur->from = from; + bCur->copyBits(node->getLiveness(), bLen); + + if (!from->hasLiveness()) { + node = from; + goto _OnVisit; + } + + // Issue #25: Moved '_OnJumpNext' here since it's important to patch + // code again if there are more live variables than before. +_OnJumpNext: + if (bCur->delBits(from->getLiveness(), bLen)) { + node = from; + goto _OnPatch; + } + + from = from->getJumpNext(); + } while (from != NULL); + + // Pop the current LivenessTarget from the stack. + { + LivenessTarget* ltTmp = ltCur; + + ltCur = ltCur->prev; + ltTmp->prev = ltUnused; + ltUnused = ltTmp; + } + } + + bCur->copyBits(node->getLiveness(), bLen); + node = node->getPrev(); + + if (node->isJmp() || !node->isFetched()) + goto _OnDone; + + if (!node->hasLiveness()) + goto _OnVisit; + + if (bCur->delBits(node->getLiveness(), bLen)) + goto _OnPatch; + +_OnDone: + if (ltCur != NULL) { + node = ltCur->node; + from = ltCur->from; + + goto _OnJumpNext; + } + return kErrorOk; + +_NoMemory: + return setError(kErrorNoHeapMemory); +} + +// ============================================================================ +// [asmjit::Context - Schedule] +// ============================================================================ + +Error Context::schedule() { + // By default there is no instruction scheduler implemented. + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Context - Cleanup] +// ============================================================================ + +void Context::cleanup() { VarData** array = _contextVd.getData(); size_t length = _contextVd.getLength(); @@ -313,15 +512,15 @@ void BaseContext::cleanup() { vd->resetRegIndex(); } - _contextVd.clear(); + _contextVd.reset(false); _extraBlock = NULL; } // ============================================================================ -// [asmjit::BaseContext - CompileFunc] +// [asmjit::Context - CompileFunc] // ============================================================================ -Error BaseContext::compile(FuncNode* func) { +Error Context::compile(FuncNode* func) { Node* end = func->getEnd(); Node* stop = end->getNext(); @@ -331,19 +530,24 @@ Error BaseContext::compile(FuncNode* func) { ASMJIT_PROPAGATE_ERROR(fetch()); ASMJIT_PROPAGATE_ERROR(removeUnreachableCode()); - ASMJIT_PROPAGATE_ERROR(analyze()); + ASMJIT_PROPAGATE_ERROR(livenessAnalysis()); + + Compiler* compiler = getCompiler(); #if !defined(ASMJIT_DISABLE_LOGGER) - if (_compiler->hasLogger()) + if (compiler->hasLogger()) ASMJIT_PROPAGATE_ERROR(annotate()); #endif // !ASMJIT_DISABLE_LOGGER ASMJIT_PROPAGATE_ERROR(translate()); + if (compiler->hasFeature(kCodeGenEnableScheduler)) + ASMJIT_PROPAGATE_ERROR(schedule()); + // We alter the compiler cursor, because it doesn't make sense to reference // it after compilation - some nodes may disappear and it's forbidden to add // new code after the compilation is done. - _compiler->_setCursor(NULL); + compiler->_setCursor(NULL); return kErrorOk; } diff --git a/src/asmjit/base/context_p.h b/src/asmjit/base/context_p.h index 8461a49..bd23501 100644 --- a/src/asmjit/base/context_p.h +++ b/src/asmjit/base/context_p.h @@ -20,40 +20,40 @@ namespace asmjit { -//! \addtogroup asmjit_base_tree +//! \addtogroup asmjit_base_compiler //! \{ // ============================================================================ -// [asmjit::BaseContext] +// [asmjit::Context] // ============================================================================ //! \internal //! -//! Code generation context is the logic behind `BaseCompiler`. The context is -//! used to compile the code stored in `BaseCompiler`. -struct BaseContext { - ASMJIT_NO_COPY(BaseContext) +//! Code generation context is the logic behind `Compiler`. The context is +//! used to compile the code stored in `Compiler`. +struct Context { + ASMJIT_NO_COPY(Context) // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - BaseContext(BaseCompiler* compiler); - virtual ~BaseContext(); + Context(Compiler* compiler); + virtual ~Context(); // -------------------------------------------------------------------------- // [Reset] // -------------------------------------------------------------------------- //! Reset the whole context. - virtual void reset(); + virtual void reset(bool releaseMemory = false); // -------------------------------------------------------------------------- // [Accessors] // -------------------------------------------------------------------------- //! Get compiler. - ASMJIT_INLINE BaseCompiler* getCompiler() const { return _compiler; } + ASMJIT_INLINE Compiler* getCompiler() const { return _compiler; } //! Get function. ASMJIT_INLINE FuncNode* getFunc() const { return _func; } @@ -89,23 +89,24 @@ struct BaseContext { // -------------------------------------------------------------------------- //! Get current state. - ASMJIT_INLINE BaseVarState* getState() const { + ASMJIT_INLINE VarState* getState() const { return _state; } //! Load current state from `target` state. - virtual void loadState(BaseVarState* src) = 0; - //! Save current state, returning new `BaseVarState` instance. - virtual BaseVarState* saveState() = 0; + virtual void loadState(VarState* src) = 0; + + //! Save current state, returning new `VarState` instance. + virtual VarState* saveState() = 0; //! Change the current state to `target` state. - virtual void switchState(BaseVarState* src) = 0; + virtual void switchState(VarState* src) = 0; //! Change the current state to the intersection of two states `a` and `b`. - virtual void intersectStates(BaseVarState* a, BaseVarState* b) = 0; + virtual void intersectStates(VarState* a, VarState* b) = 0; // -------------------------------------------------------------------------- - // [Mem] + // [Context] // -------------------------------------------------------------------------- ASMJIT_INLINE Error _registerContextVar(VarData* vd) { @@ -169,7 +170,7 @@ struct BaseContext { // [Analyze] // -------------------------------------------------------------------------- - //! Preform variable liveness analysis. + //! Perform variable liveness analysis. //! //! Analysis phase iterates over nodes in reverse order and generates a bit //! array describing variables that are alive at every node in the function. @@ -179,7 +180,7 @@ struct BaseContext { //! //! When a label is found all jumps to that label are followed and analysis //! repeats until all variables are resolved. - virtual Error analyze() = 0; + virtual Error livenessAnalysis(); // -------------------------------------------------------------------------- // [Annotate] @@ -194,6 +195,12 @@ struct BaseContext { //! Translate code by allocating registers and handling state changes. virtual Error translate() = 0; + // -------------------------------------------------------------------------- + // [Schedule] + // -------------------------------------------------------------------------- + + virtual Error schedule(); + // -------------------------------------------------------------------------- // [Cleanup] // -------------------------------------------------------------------------- @@ -210,20 +217,28 @@ struct BaseContext { // [Serialize] // -------------------------------------------------------------------------- - virtual Error serialize(BaseAssembler* assembler, Node* start, Node* stop) = 0; + virtual Error serialize(Assembler* assembler, Node* start, Node* stop) = 0; // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- //! Compiler. - BaseCompiler* _compiler; + Compiler* _compiler; //! Function. FuncNode* _func; //! Zone allocator. Zone _baseZone; + //! \internal + //! + //! Offset (how many bytes to add) to `VarMap` to get `VarAttr` array. Used + //! by liveness analysis shared across all backends. This is needed because + //! `VarMap` is a base class for a specialized version that liveness analysis + //! doesn't use, it just needs `VarAttr` array. + uint32_t _varMapToVaListOffset; + //! Start of the current active scope. Node* _start; //! End of the current active scope. @@ -277,7 +292,7 @@ struct BaseContext { uint32_t _annotationLength; //! Current state (used by register allocator). - BaseVarState* _state; + VarState* _state; }; //! \} diff --git a/src/asmjit/base/cpuinfo.cpp b/src/asmjit/base/cpuinfo.cpp index ac19022..365be3a 100644 --- a/src/asmjit/base/cpuinfo.cpp +++ b/src/asmjit/base/cpuinfo.cpp @@ -30,10 +30,10 @@ namespace asmjit { // ============================================================================ -// [asmjit::BaseCpuInfo - DetectNumberOfCores] +// [asmjit::CpuInfo - DetectNumberOfCores] // ============================================================================ -uint32_t BaseCpuInfo::detectNumberOfCores() { +uint32_t CpuInfo::detectHwThreadsCount() { #if defined(ASMJIT_OS_WINDOWS) SYSTEM_INFO info; ::GetSystemInfo(&info); @@ -51,22 +51,22 @@ uint32_t BaseCpuInfo::detectNumberOfCores() { } // ============================================================================ -// [asmjit::BaseCpuInfo - GetHost] +// [asmjit::CpuInfo - GetHost] // ============================================================================ #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) -struct HostCpuInfo : public x86x64::CpuInfo { - ASMJIT_INLINE HostCpuInfo() : CpuInfo() { - x86x64::CpuUtil::detect(this); +struct AutoX86CpuInfo : public X86CpuInfo { + ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() { + X86CpuUtil::detect(this); } }; #else #error "AsmJit - Unsupported CPU." #endif // ASMJIT_HOST || ASMJIT_HOST_X64 -const BaseCpuInfo* BaseCpuInfo::getHost() { +const CpuInfo* CpuInfo::getHost() { #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) - static HostCpuInfo cpuInfo; + static AutoX86CpuInfo cpuInfo; #else #error "AsmJit - Unsupported CPU." #endif // ASMJIT_HOST || ASMJIT_HOST_X64 diff --git a/src/asmjit/base/cpuinfo.h b/src/asmjit/base/cpuinfo.h index af426b7..65f3ca0 100644 --- a/src/asmjit/base/cpuinfo.h +++ b/src/asmjit/base/cpuinfo.h @@ -43,12 +43,12 @@ ASMJIT_ENUM(kCpuVendor) { }; // ============================================================================ -// [asmjit::BaseCpuInfo] +// [asmjit::CpuInfo] // ============================================================================ //! Base cpu information. -struct BaseCpuInfo { - ASMJIT_NO_COPY(BaseCpuInfo) +struct CpuInfo { + ASMJIT_NO_COPY(CpuInfo) //! \internal enum { @@ -59,7 +59,7 @@ struct BaseCpuInfo { // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE BaseCpuInfo(uint32_t size = sizeof(BaseCpuInfo)) : _size(size) {} + ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {} // -------------------------------------------------------------------------- // [Accessors] @@ -78,8 +78,9 @@ struct BaseCpuInfo { ASMJIT_INLINE uint32_t getModel() const { return _model; } //! Get CPU stepping. ASMJIT_INLINE uint32_t getStepping() const { return _stepping; } - //! Get CPU cores count (or sum of all cores of all procesors). - ASMJIT_INLINE uint32_t getCoresCount() const { return _coresCount; } + + //! Get number of hardware threads available. + ASMJIT_INLINE uint32_t getHwThreadsCount() const { return _hwThreadsCount; } //! Get whether CPU has a `feature`. ASMJIT_INLINE bool hasFeature(uint32_t feature) const { @@ -90,7 +91,7 @@ struct BaseCpuInfo { } //! Add a CPU `feature`. - ASMJIT_INLINE BaseCpuInfo& addFeature(uint32_t feature) { + ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) { ASMJIT_ASSERT(feature < sizeof(_features) * 8); _features[feature / kFeaturesPerUInt32] |= (1U << (feature % kFeaturesPerUInt32)); @@ -102,10 +103,10 @@ struct BaseCpuInfo { // -------------------------------------------------------------------------- //! Detect number of cores (or sum of all cores of all processors). - static ASMJIT_API uint32_t detectNumberOfCores(); + static ASMJIT_API uint32_t detectHwThreadsCount(); //! Get host cpu. - static ASMJIT_API const BaseCpuInfo* getHost(); + static ASMJIT_API const CpuInfo* getHost(); // -------------------------------------------------------------------------- // [Members] @@ -127,8 +128,9 @@ struct BaseCpuInfo { uint32_t _model; //! Cpu stepping. uint32_t _stepping; - //! Cpu cores count (or sum of all CPU cores of all processors). - uint32_t _coresCount; + + //! Number of hardware threads. + uint32_t _hwThreadsCount; //! Cpu features bitfield. uint32_t _features[4]; diff --git a/src/asmjit/base/error.cpp b/src/asmjit/base/error.cpp index 0776d52..38c7ad4 100644 --- a/src/asmjit/base/error.cpp +++ b/src/asmjit/base/error.cpp @@ -37,29 +37,42 @@ void ErrorHandler::release() {} // [asmjit::ErrorUtil - AsString] // ============================================================================ -static const char* errorMessages[] = { - "Ok", - - "No heap memory", - "No virtual memory", - - "Invalid argument", - "Invalid state", - - "Unknown instruction", - "Illegal instruction", - "Illegal addressing", - "Illegal displacement", - - "Invalid function", - "Overlapped arguments", - "Unknown error" +#if !defined(ASMJIT_DISABLE_NAMES) +static const char errorMessages[] = { + "Ok\0" + "No heap memory\0" + "No virtual memory\0" + "Invalid argument\0" + "Invalid state\0" + "Unknown instruction\0" + "Illegal instruction\0" + "Illegal addressing\0" + "Illegal displacement\0" + "Invalid function\0" + "Overlapped arguments\0" + "Unknown error\0" }; -const char* ErrorUtil::asString(Error e) { - return errorMessages[IntUtil::iMin(e, kErrorCount)]; +static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId) { + uint32_t i = 0; + + if (id > maxId) + id = maxId; + + while (i < id) { + while (p[0]) + p++; + p++; + } + + return p; } +const char* ErrorUtil::asString(Error e) { + return findPackedString(errorMessages, e, kErrorCount); +} +#endif // ASMJIT_DISABLE_NAMES + } // asmjit namespace // [Api-End] diff --git a/src/asmjit/base/error.h b/src/asmjit/base/error.h index 47cace3..6d71ce6 100644 --- a/src/asmjit/base/error.h +++ b/src/asmjit/base/error.h @@ -109,7 +109,7 @@ typedef uint32_t Error; //! Please note that `addRef` and `release` functions are used, but there is //! no reference counting implemented by default, reimplement to change the //! default behavior. -struct ErrorHandler { +struct ASMJIT_VCLASS ErrorHandler { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- @@ -141,8 +141,8 @@ struct ErrorHandler { //! Error handler (pure). //! //! Error handler is called when an error happened. An error can happen in - //! many places, but error handler is mostly used by `BaseAssembler` and - //! `BaseCompiler` classes to report anything that may cause incorrect code + //! many places, but error handler is mostly used by `Assembler` and + //! `Compiler` classes to report anything that may cause incorrect code //! generation. There are multiple ways how the error handler can be used //! and each has it's pros/cons. //! @@ -151,23 +151,23 @@ struct ErrorHandler { //! exceptions it is exception-safe and handleError() can report an incoming //! error by throwing an exception of any type. It's guaranteed that the //! exception won't be catched by AsmJit and will be propagated to the code - //! calling AsmJit `BaseAssembler` or `BaseCompiler` methods. Alternative to + //! calling AsmJit `Assembler` or `Compiler` methods. Alternative to //! throwing an exception is using `setjmp()` and `longjmp()` pair available //! in the standard C library. //! //! If the exception or setjmp() / longjmp() mechanism is used, the state of - //! the `BaseAssember` or `BaseCompiler` is unchanged and if it's possible the + //! the `BaseAssember` or `Compiler` is unchanged and if it's possible the //! execution (instruction serialization) can continue. However if the error //! happened during any phase that translates or modifies the stored code - //! (for example relocation done by `BaseAssembler` or analysis/translation - //! done by `BaseCompiler`) the execution can't continue and the error will - //! be also stored in `BaseAssembler` or `BaseCompiler`. + //! (for example relocation done by `Assembler` or analysis/translation + //! done by `Compiler`) the execution can't continue and the error will + //! be also stored in `Assembler` or `Compiler`. //! //! Finally, if no exceptions nor setjmp() / longjmp() mechanisms were used, //! you can still implement a compatible handling by returning from your //! error handler. Returning `true` means that error was reported and AsmJit //! should continue execution, but `false` sets the rror immediately to the - //! `BaseAssembler` or `BaseCompiler` and execution shouldn't continue (this + //! `Assembler` or `Compiler` and execution shouldn't continue (this //! is the default behavior in case no error handler is used). virtual bool handleError(Error code, const char* message) = 0; }; @@ -178,8 +178,10 @@ struct ErrorHandler { //! Error utilities. struct ErrorUtil { +#if !defined(ASMJIT_DISABLE_NAMES) //! Get printable version of AsmJit `kError` code. static ASMJIT_API const char* asString(Error code); +#endif // ASMJIT_DISABLE_NAMES }; //! \} diff --git a/src/asmjit/base/func.cpp b/src/asmjit/base/func.cpp deleted file mode 100644 index 3d63b96..0000000 --- a/src/asmjit/base/func.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Export] -#define ASMJIT_EXPORTS - -// [Dependencies - AsmJit] -#include "../base/func.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" diff --git a/src/asmjit/base/func.h b/src/asmjit/base/func.h deleted file mode 100644 index 3ab8ccc..0000000 --- a/src/asmjit/base/func.h +++ /dev/null @@ -1,651 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_BASE_FUNC_H -#define _ASMJIT_BASE_FUNC_H - -#include "../build.h" -#if !defined(ASMJIT_DISABLE_COMPILER) - -// [Dependencies - AsmJit] -#include "../base/operand.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { - -//! \addtogroup asmjit_base_tree -//! \{ - -// ============================================================================ -// [asmjit::kFuncConv] -// ============================================================================ - -//! Function calling convention. -//! -//! For a platform specific calling conventions, see: -//! - `x86x64::kFuncConv` - X86/X64 calling conventions. -ASMJIT_ENUM(kFuncConv) { - //! Calling convention is invalid (can't be used). - kFuncConvNone = 0 -}; - -// ============================================================================ -// [asmjit::kFuncHint] -// ============================================================================ - -//! Function hints. -//! -//! For a platform specific calling conventions, see: -//! - `x86x64::kFuncHint` - X86/X64 function hints. -ASMJIT_ENUM(kFuncHint) { - //! Make a naked function (default true). - //! - //! Naked function is function without using standard prolog/epilog sequence). - //! - //! X86/X64 Specific - //! ---------------- - //! - //! Standard prolog sequence is: - //! - //! ~~~ - //! push zbp - //! mov zsp, zbp - //! sub zsp, StackAdjustment - //! ~~~ - //! - //! which is an equivalent to: - //! - //! ~~~ - //! enter StackAdjustment, 0 - //! ~~~ - //! - //! Standard epilog sequence is: - //! - //! ~~~ - //! mov zsp, zbp - //! pop zbp - //! ~~~ - //! - //! which is an equavalent to: - //! - //! ~~~ - //! leave - //! ~~~ - //! - //! Naked functions can omit the prolog/epilog sequence. The advantage of - //! doing such modification is that EBP/RBP register can be used by the - //! register allocator which can result in less spills/allocs. - kFuncHintNaked = 0, - - //! Generate compact function prolog/epilog if possible. - //! - //! X86/X64 Specific - //! ---------------- - //! - //! Use shorter, but possible slower prolog/epilog sequence to save/restore - //! registers. - kFuncHintCompact = 1 -}; - -// ============================================================================ -// [asmjit::kFuncFlags] -// ============================================================================ - -//! Function flags. -//! -//! For a platform specific calling conventions, see: -//! - `x86x64::kFuncFlags` - X86/X64 function flags. -ASMJIT_ENUM(kFuncFlags) { - //! Whether the function is using naked (minimal) prolog / epilog. - kFuncFlagIsNaked = 0x00000001, - - //! Whether an another function is called from this function. - kFuncFlagIsCaller = 0x00000002, - - //! Whether the stack is not aligned to the required stack alignment, - //! thus it has to be aligned manually. - kFuncFlagIsStackMisaligned = 0x00000004, - - //! Whether the stack pointer is adjusted by the stack size needed - //! to save registers and function variables. - //! - //! X86/X64 Specific - //! ---------------- - //! - //! Stack pointer (ESP/RSP) is adjusted by 'sub' instruction in prolog and by - //! 'add' instruction in epilog (only if function is not naked). If function - //! needs to perform manual stack alignment more instructions are used to - //! adjust the stack (like "and zsp, -Alignment"). - kFuncFlagIsStackAdjusted = 0x00000008, - - //! Whether the function is finished using `BaseCompiler::endFunc()`. - kFuncFlagIsFinished = 0x80000000 -}; - -// ============================================================================ -// [asmjit::kFuncDir] -// ============================================================================ - -//! Function arguments direction. -ASMJIT_ENUM(kFuncDir) { - //! Arguments are passed left to right. - //! - //! This arguments direction is unusual in C, however it's used in Pascal. - kFuncDirLtr = 0, - - //! Arguments are passed right ro left - //! - //! This is the default argument direction in C. - kFuncDirRtl = 1 -}; - -// ============================================================================ -// [asmjit::kFuncArg] -// ============================================================================ - -//! Function argument (lo/hi) specification. -ASMJIT_ENUM(kFuncArg) { - //! Maxumum number of function arguments supported by AsmJit. - kFuncArgCount = 16, - //! Extended maximum number of arguments (used internally). - kFuncArgCountLoHi = kFuncArgCount * 2, - - //! Index to the LO part of function argument (default). - //! - //! This value is typically omitted and added only if there is HI argument - //! accessed. - kFuncArgLo = 0, - //! Index to the HI part of function argument. - //! - //! HI part of function argument depends on target architecture. On x86 it's - //! typically used to transfer 64-bit integers (they form a pair of 32-bit - //! integers). - kFuncArgHi = kFuncArgCount -}; - -// ============================================================================ -// [asmjit::kFuncRet] -// ============================================================================ - -//! Function return value (lo/hi) specification. -ASMJIT_ENUM(kFuncRet) { - //! Index to the LO part of function return value. - kFuncRetLo = 0, - //! Index to the HI part of function return value. - kFuncRetHi = 1 -}; - -// ============================================================================ -// [asmjit::kFuncStackInvalid] -// ============================================================================ - -enum kFuncMisc { - //! Invalid stack offset in function or function parameter. - kFuncStackInvalid = -1 -}; - -// ============================================================================ -// [asmjit::FnTypeId] -// ============================================================================ - -//! Function builder 'void' type. -struct FnVoid {}; - -//! Function builder 'int8_t' type. -struct FnInt8 {}; -//! Function builder 'uint8_t' type. -struct FnUInt8 {}; - -//! Function builder 'int16_t' type. -struct FnInt16 {}; -//! Function builder 'uint16_t' type. -struct FnUInt16 {}; - -//! Function builder 'int32_t' type. -struct FnInt32 {}; -//! Function builder 'uint32_t' type. -struct FnUInt32 {}; - -//! Function builder 'int64_t' type. -struct FnInt64 {}; -//! Function builder 'uint64_t' type. -struct FnUInt64 {}; - -//! Function builder 'intptr_t' type. -struct FnIntPtr {}; -//! Function builder 'uintptr_t' type. -struct FnUIntPtr {}; - -//! Function builder 'float' type. -struct FnFloat {}; -//! Function builder 'double' type. -struct FnDouble {}; - -#if !defined(ASMJIT_DOCGEN) -template -struct FnTypeId; - -#define ASMJIT_DECLARE_TYPE_CORE(_PtrId_) \ - template \ - struct TypeId { enum { kId = static_cast(::asmjit::kVarTypeInvalid) }; }; \ - \ - template \ - struct TypeId { enum { kId = _PtrId_ }; } - -#define ASMJIT_DECLARE_TYPE_ID(_T_, _Id_) \ - template<> \ - struct TypeId<_T_> { enum { kId = _Id_ }; } - -ASMJIT_DECLARE_TYPE_CORE(kVarTypeIntPtr); - -ASMJIT_DECLARE_TYPE_ID(void, kVarTypeInvalid); -ASMJIT_DECLARE_TYPE_ID(FnVoid, kVarTypeInvalid); - -ASMJIT_DECLARE_TYPE_ID(int8_t, kVarTypeInt8); -ASMJIT_DECLARE_TYPE_ID(FnInt8, kVarTypeInt8); - -ASMJIT_DECLARE_TYPE_ID(uint8_t, kVarTypeUInt8); -ASMJIT_DECLARE_TYPE_ID(FnUInt8, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(int16_t, kVarTypeInt16); -ASMJIT_DECLARE_TYPE_ID(FnInt16, kVarTypeInt16); - -ASMJIT_DECLARE_TYPE_ID(uint16_t, kVarTypeUInt8); -ASMJIT_DECLARE_TYPE_ID(FnUInt16, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(int32_t, kVarTypeInt32); -ASMJIT_DECLARE_TYPE_ID(FnInt32, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(uint32_t, kVarTypeUInt32); -ASMJIT_DECLARE_TYPE_ID(FnUInt32, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(int64_t, kVarTypeInt64); -ASMJIT_DECLARE_TYPE_ID(FnInt64, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(uint64_t, kVarTypeUInt64); -ASMJIT_DECLARE_TYPE_ID(FnUInt64, kVarTypeUInt8); - -ASMJIT_DECLARE_TYPE_ID(float, kVarTypeFp32); -ASMJIT_DECLARE_TYPE_ID(FnFloat, kVarTypeFp32); - -ASMJIT_DECLARE_TYPE_ID(double, kVarTypeFp64); -ASMJIT_DECLARE_TYPE_ID(FnDouble, kVarTypeFp64); -#endif // !ASMJIT_DOCGEN - -// ============================================================================ -// [asmjit::FuncInOut] -// ============================================================================ - -//! Function in/out - argument or return value translated from `FuncPrototype`. -struct FuncInOut { - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE uint32_t getVarType() const { return _varType; } - - ASMJIT_INLINE bool hasRegIndex() const { return _regIndex != kInvalidReg; } - ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; } - - ASMJIT_INLINE bool hasStackOffset() const { return _stackOffset != kFuncStackInvalid; } - ASMJIT_INLINE int32_t getStackOffset() const { return static_cast(_stackOffset); } - - //! Get whether the argument / return value is assigned. - ASMJIT_INLINE bool isSet() const { - return (_regIndex != kInvalidReg) | (_stackOffset != kFuncStackInvalid); - } - - // -------------------------------------------------------------------------- - // [Reset] - // -------------------------------------------------------------------------- - - //! Reset the function argument to "unassigned state". - ASMJIT_INLINE void reset() { _packed = 0xFFFFFFFF; } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - union { - struct { - //! Variable type, see `kVarType`. - uint8_t _varType; - //! Register index if argument / return value is a register. - uint8_t _regIndex; - //! Stack offset if argument / return value is on the stack. - int16_t _stackOffset; - }; - - //! All members packed into single 32-bit integer. - uint32_t _packed; - }; -}; - -// ============================================================================ -// [asmjit::FuncPrototype] -// ============================================================================ - -//! Function prototype. -//! -//! Function prototype contains information about function return type, count -//! of arguments and their types. Function prototype is a low level structure -//! which doesn't contain platform specific or calling convention specific -//! information. Function prototype is used to create a `FuncDecl`. -struct FuncPrototype { - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Get function return value. - ASMJIT_INLINE uint32_t getRet() const { return _ret; } - - //! Get function arguments' IDs. - ASMJIT_INLINE const uint32_t* getArgList() const { return _argList; } - //! Get count of function arguments. - ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } - - //! Get argument at index `id`. - ASMJIT_INLINE uint32_t getArg(uint32_t id) const { - ASMJIT_ASSERT(id < _argCount); - return _argList[id]; - } - - //! Set function definition - return type and arguments. - ASMJIT_INLINE void _setPrototype(uint32_t ret, const uint32_t* argList, uint32_t argCount) { - _ret = ret; - _argList = argList; - _argCount = argCount; - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - uint32_t _ret; - uint32_t _argCount; - const uint32_t* _argList; -}; - -// ============================================================================ -// [asmjit::FuncDecl] -// ============================================================================ - -//! Function declaration. -struct FuncDecl { - // -------------------------------------------------------------------------- - // [Accessors - Calling Convention] - // -------------------------------------------------------------------------- - - //! Get function calling convention, see `kFuncConv`. - ASMJIT_INLINE uint32_t getConvention() const { return _convention; } - - //! Get whether the callee pops the stack. - ASMJIT_INLINE uint32_t getCalleePopsStack() const { return _calleePopsStack; } - - //! Get direction of arguments passed on the stack. - //! - //! Direction should be always `kFuncDirRtl`. - //! - //! \note This is related to used calling convention, it's not affected by - //! number of function arguments or their types. - ASMJIT_INLINE uint32_t getDirection() const { return _direction; } - - //! Get stack size needed for function arguments passed on the stack. - ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; } - //! Get size of "Red Zone". - ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; } - //! Get size of "Spill Zone". - ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; } - - // -------------------------------------------------------------------------- - // [Accessors - Arguments and Return] - // -------------------------------------------------------------------------- - - //! Get whether the function has a return value. - ASMJIT_INLINE bool hasRet() const { return _retCount != 0; } - //! Get count of function return values. - ASMJIT_INLINE uint32_t getRetCount() const { return _retCount; } - - //! Get function return value. - ASMJIT_INLINE FuncInOut& getRet(uint32_t index = kFuncRetLo) { return _retList[index]; } - //! Get function return value. - ASMJIT_INLINE const FuncInOut& getRet(uint32_t index = kFuncRetLo) const { return _retList[index]; } - - //! Get count of function arguments. - ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } - - //! Get function arguments array. - ASMJIT_INLINE FuncInOut* getArgList() { return _argList; } - //! Get function arguments array (const). - ASMJIT_INLINE const FuncInOut* getArgList() const { return _argList; } - - //! Get function argument at index `index`. - ASMJIT_INLINE FuncInOut& getArg(size_t index) { - ASMJIT_ASSERT(index < kFuncArgCountLoHi); - return _argList[index]; - } - - //! Get function argument at index `index`. - ASMJIT_INLINE const FuncInOut& getArg(size_t index) const { - ASMJIT_ASSERT(index < kFuncArgCountLoHi); - return _argList[index]; - } - - ASMJIT_INLINE void resetArg(size_t index) { - ASMJIT_ASSERT(index < kFuncArgCountLoHi); - _argList[index].reset(); - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - //! Calling convention. - uint8_t _convention; - //! Whether a callee pops stack. - uint8_t _calleePopsStack : 1; - //! Direction for arguments passed on the stack, see `kFuncDir`. - uint8_t _direction : 1; - //! Reserved #0 (alignment). - uint8_t _reserved0 : 6; - - //! Count of arguments in `_argList`. - uint8_t _argCount; - //! Count of return value(s). - uint8_t _retCount; - - //! Count of bytes consumed by arguments on the stack (aligned). - uint32_t _argStackSize; - - //! Size of "Red Zone". - //! - //! \note Used by AMD64-ABI (128 bytes). - uint16_t _redZoneSize; - - //! Size of "Spill Zone". - //! - //! \note Used by WIN64-ABI (32 bytes). - uint16_t _spillZoneSize; - - //! Function arguments (including HI arguments) mapped to physical - //! registers and stack offset. - FuncInOut _argList[kFuncArgCountLoHi]; - - //! Function return value(s). - FuncInOut _retList[2]; -}; - -// ============================================================================ -// [asmjit::FuncBuilderX] -// ============================================================================ - -//! Custom function builder for up to 32 function arguments. -struct FuncBuilderX : public FuncPrototype { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE FuncBuilderX() { - _setPrototype(kVarTypeInvalid, _builderArgList, 0); - } - - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Set return type to `retType`. - ASMJIT_INLINE void setRet(uint32_t retType) { - _ret = retType; - } - - ASMJIT_INLINE void setArg(uint32_t id, uint32_t type) { - ASMJIT_ASSERT(id < _argCount); - _builderArgList[id] = type; - } - - ASMJIT_INLINE void addArg(uint32_t type) { - ASMJIT_ASSERT(_argCount < kFuncArgCount); - _builderArgList[_argCount++] = type; - } - - template - ASMJIT_INLINE void setRetT() { - setRet(TypeId::kId); - } - - template - ASMJIT_INLINE void setArgT(uint32_t id) { - setArg(id, TypeId::kId); - } - - template - ASMJIT_INLINE void addArgT() { - addArg(TypeId::kId); - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - uint32_t _builderArgList[kFuncArgCount]; -}; - -//! \internal -#define _TID(_T_) TypeId<_T_>::kId - -//! Function builder (no args). -template -struct FuncBuilder0 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder0() { - _setPrototype(_TID(RET), NULL, 0); - } -}; - -//! Function builder (1 argument). -template -struct FuncBuilder1 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder1() { - static const uint32_t args[] = { _TID(P0) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (2 arguments). -template -struct FuncBuilder2 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder2() { - static const uint32_t args[] = { _TID(P0), _TID(P1) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (3 arguments). -template -struct FuncBuilder3 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder3() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (4 arguments). -template -struct FuncBuilder4 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder4() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (5 arguments). -template -struct FuncBuilder5 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder5() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3), _TID(P4) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (6 arguments). -template -struct FuncBuilder6 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder6() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3), _TID(P4), _TID(P5) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (7 arguments). -template -struct FuncBuilder7 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder7() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3), _TID(P4), _TID(P5), _TID(P6) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (8 arguments). -template -struct FuncBuilder8 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder8() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2),_TID(P3), _TID(P4), _TID(P5), _TID(P6), _TID(P7) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (9 arguments). -template -struct FuncBuilder9 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder9() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3), _TID(P4), _TID(P5), _TID(P6), _TID(P7), _TID(P8) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -//! Function builder (10 arguments). -template -struct FuncBuilder10 : public FuncPrototype { - ASMJIT_INLINE FuncBuilder10() { - static const uint32_t args[] = { _TID(P0), _TID(P1), _TID(P2), _TID(P3), _TID(P4), _TID(P5), _TID(P6), _TID(P7), _TID(P8), _TID(P9) }; - _setPrototype(_TID(RET), args, ASMJIT_ARRAY_SIZE(args)); - } -}; - -#undef _TID - -//! \} - -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // !ASMJIT_DISABLE_COMPILER -#endif // _ASMJIT_BASE_FUNC_H diff --git a/src/asmjit/base/globals.h b/src/asmjit/base/globals.h index ba9d0d5..81b96b0 100644 --- a/src/asmjit/base/globals.h +++ b/src/asmjit/base/globals.h @@ -37,6 +37,8 @@ ASMJIT_ENUM(kGlobals) { //! Invalid register index. kInvalidReg = 0xFF, + //! Invalid variable type. + kInvalidVar = 0xFF, //! Host memory allocator overhead. //! diff --git a/src/asmjit/base/lock.h b/src/asmjit/base/lock.h index a9a449e..f2e2042 100644 --- a/src/asmjit/base/lock.h +++ b/src/asmjit/base/lock.h @@ -74,9 +74,13 @@ struct Lock { // -------------------------------------------------------------------------- //! Get handle. - ASMJIT_INLINE Handle& getHandle() { return _handle; } + ASMJIT_INLINE Handle& getHandle() { + return _handle; + } //! \overload - ASMJIT_INLINE const Handle& getHandle() const { return _handle; } + ASMJIT_INLINE const Handle& getHandle() const { + return _handle; + } // -------------------------------------------------------------------------- // [Members] diff --git a/src/asmjit/base/logger.h b/src/asmjit/base/logger.h index 310df68..eb940b8 100644 --- a/src/asmjit/base/logger.h +++ b/src/asmjit/base/logger.h @@ -70,7 +70,7 @@ ASMJIT_ENUM(kLoggerStyle) { //! //! This class also contain `_enabled` member that can be used to enable //! or disable logging. -struct Logger { +struct ASMJIT_VCLASS Logger { ASMJIT_NO_COPY(Logger) // -------------------------------------------------------------------------- @@ -117,11 +117,17 @@ struct Logger { // -------------------------------------------------------------------------- //! Get indentation. - ASMJIT_INLINE const char* getIndentation() const { return _indentation; } + ASMJIT_INLINE const char* getIndentation() const { + return _indentation; + } + //! Set indentation. ASMJIT_API void setIndentation(const char* indentation); + //! Reset indentation. - ASMJIT_INLINE void resetIndentation() { setIndentation(NULL); } + ASMJIT_INLINE void resetIndentation() { + setIndentation(NULL); + } // -------------------------------------------------------------------------- // [Members] @@ -139,7 +145,7 @@ struct Logger { // ============================================================================ //! Logger that can log to standard C `FILE*` stream. -struct FileLogger : public Logger { +struct ASMJIT_VCLASS FileLogger : public Logger { ASMJIT_NO_COPY(FileLogger) // -------------------------------------------------------------------------- @@ -184,7 +190,7 @@ struct FileLogger : public Logger { // ============================================================================ //! String logger. -struct StringLogger : public Logger { +struct ASMJIT_VCLASS StringLogger : public Logger { ASMJIT_NO_COPY(StringLogger) // -------------------------------------------------------------------------- @@ -205,10 +211,14 @@ struct StringLogger : public Logger { //! string. //! //! The pointer is owned by `StringLogger`, it can't be modified or freed. - ASMJIT_INLINE const char* getString() const { return _stringBuilder.getData(); } + ASMJIT_INLINE const char* getString() const { + return _stringBuilder.getData(); + } //! Clear the resulting string. - ASMJIT_INLINE void clearString() { _stringBuilder.clear(); } + ASMJIT_INLINE void clearString() { + _stringBuilder.clear(); + } // -------------------------------------------------------------------------- // [Logging] diff --git a/src/asmjit/base/operand.cpp b/src/asmjit/base/operand.cpp index 2dc82b7..ed67f90 100644 --- a/src/asmjit/base/operand.cpp +++ b/src/asmjit/base/operand.cpp @@ -8,7 +8,7 @@ #define ASMJIT_EXPORTS // [Dependencies - AsmJit] -#include "../base/operand.h" +#include "../base/globals.h" // [Api-Begin] #include "../apibegin.h" @@ -19,7 +19,19 @@ namespace asmjit { // [asmjit::Operand] // ============================================================================ -const Operand noOperand; +// Prevent static initialization. +struct Operand { + uint8_t op; + uint8_t size; + uint8_t reserved_2_1; + uint8_t reserved_3_1; + uint32_t id; + uint32_t reserved_8_4; + uint32_t reserved_12_4; +}; + +ASMJIT_VAR const Operand noOperand; +const Operand noOperand = { 0, 0, 0, 0, kInvalidValue, 0, 0 }; } // asmjit namespace diff --git a/src/asmjit/base/operand.h b/src/asmjit/base/operand.h index 426a04c..4553e33 100644 --- a/src/asmjit/base/operand.h +++ b/src/asmjit/base/operand.h @@ -20,8 +20,8 @@ namespace asmjit { // [Forward Declarations] // ============================================================================ -struct BaseAssembler; -struct BaseCompiler; +struct Assembler; +struct Compiler; //! \addtogroup asmjit_base_general //! \{ @@ -52,7 +52,7 @@ ASMJIT_ENUM(kOperandType) { //! Operand id masks used to determine the operand type. ASMJIT_ENUM(kOperandId) { - //! Operand id refers to `BaseVar`. + //! Operand id refers to `Var`. kOperandIdVar = 0x80000000U, //! Operand id to real index mask. kOperandIdNum = 0x7FFFFFFFU @@ -64,11 +64,8 @@ ASMJIT_ENUM(kOperandId) { //! Register class. ASMJIT_ENUM(kRegClass) { - //! Gp register class (any architecture). - kRegClassGp = 0, - - //! Invalid register class. - kRegClassInvalid = 0xFF + //! Gp register class, compatible with all architectures. + kRegClassGp = 0 }; // ============================================================================ @@ -102,7 +99,7 @@ ASMJIT_ENUM(kMemType) { //! Memory operand is a combination of base register and optional index register //! and displacement. //! - //! The `BaseAssembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` + //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` //! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`. kMemTypeBaseIndex = 0, @@ -110,8 +107,8 @@ ASMJIT_ENUM(kMemType) { //! Memory operand is a combination of variable's memory location, //! optional index register and displacement. //! - //! The `BaseAssembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` - //! types in the same way, but `BaseCompiler` interprets `kMemTypeBaseIndex` as + //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` + //! types in the same way, but `Compiler` interprets `kMemTypeBaseIndex` as //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`. kMemTypeStackIndex = 1, @@ -124,52 +121,6 @@ ASMJIT_ENUM(kMemType) { kMemTypeAbsolute = 3 }; -// ============================================================================ -// [asmjit::kVarType] -// ============================================================================ - -ASMJIT_ENUM(kVarType) { - //! Variable is 8-bit signed integer. - kVarTypeInt8 = 0, - //! Variable is 8-bit unsigned integer. - kVarTypeUInt8 = 1, - //! Variable is 16-bit signed integer. - kVarTypeInt16 = 2, - //! Variable is 16-bit unsigned integer. - kVarTypeUInt16 = 3, - //! Variable is 32-bit signed integer. - kVarTypeInt32 = 4, - //! Variable is 32-bit unsigned integer. - kVarTypeUInt32 = 5, - //! Variable is 64-bit signed integer. - kVarTypeInt64 = 6, - //! Variable is 64-bit unsigned integer. - kVarTypeUInt64 = 7, - - //! Variable is target `intptr_t`, not compatible with host `intptr_t`. - kVarTypeIntPtr = 8, - //! Variable is target `uintptr_t`, not compatible with host `uintptr_t`. - kVarTypeUIntPtr = 9, - - //! Variable is 32-bit floating point (single precision). - kVarTypeFp32 = 10, - //! Variable is 64-bit floating point (double precision). - kVarTypeFp64 = 11, - - //! Invalid variable type. - kVarTypeInvalid = 0xFF, - - //! \internal - _kVarTypeIntStart = kVarTypeInt8, - //! \internal - _kVarTypeIntEnd = kVarTypeUIntPtr, - - //! \internal - _kVarTypeFpStart = kVarTypeFp32, - //! \internal - _kVarTypeFpEnd = kVarTypeFp64 -}; - // ============================================================================ // [asmjit::Operand] // ============================================================================ @@ -180,19 +131,6 @@ struct Operand { // [Structs] // -------------------------------------------------------------------------- - // \internal - // - // Register operand structure, allows to do register initialization at - // compile time instead of doing it "non-deterministically" at runtime. - struct InitRegOp { - uint8_t op; - uint8_t size; - uint16_t code; - uint32_t id; - uint32_t vType; - uint32_t vUnused; - }; - //! \internal //! //! Base operand data. @@ -201,15 +139,20 @@ struct Operand { uint8_t op; //! Size of operand (register, address, immediate, or variable). uint8_t size; - //! Flags, each operand uses this byte for something else. - uint8_t reserved0; - //! Reserved (not used). - uint8_t reserved1; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; - //! Operand id, identifier used by `BaseAssembler` and `BaseCompiler`. + //! Operand id, identifier used by `Assembler` and `Compiler`. //! //! \note Uninitialized operand has always set id to `kInvalidValue`. uint32_t id; + + //! \internal + uint32_t reserved_8_4; + //! \internal + uint32_t reserved_12_4; }; //! \internal @@ -241,15 +184,24 @@ struct Operand { }; }; - //! Variable id, used by `BaseCompiler` to identify variables. + //! Variable id, used by `Compiler` to identify variables. uint32_t id; - //! Variable type. - uint32_t vType; - //! \internal - //! - //! Unused. - uint32_t vUnused; + union { + struct { + //! Variable type. + uint32_t vType; + //! \internal + uint32_t reserved_12_4; + }; + + //! \internal + //! + //! This is not needed or used, it's just to force compiler to always + //! align this struct to 8-bytes (so the struct is compatible to others + //! when it comes to alignment). It should fix VS linker warning as well. + uint64_t reserved8_8; + }; }; //! \internal @@ -263,7 +215,7 @@ struct Operand { //! Type of the memory operand, see `kMemType`. uint8_t type; //! X86/X64 layout: - //! - segment [3 bits], see `x86x64::kSeg`. + //! - segment [3 bits], see `kX86Seg`. //! - shift [2 bits], index register shift (0 to 3). uint8_t flags; @@ -283,12 +235,12 @@ struct Operand { uint8_t op; //! Size of immediate (or 0 to autodetect). uint8_t size; - //! Reserved (not used). - uint8_t reserved0; - //! Reserved (not used). - uint8_t reserved1; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; - //! Operand id, always set to `kInvalidValue`. + //! Operand id, always set to `kInvalidValue` (immediates don't have IDs). uint32_t id; union { @@ -325,15 +277,21 @@ struct Operand { struct LabelOp { //! Type of operand, `kOperandTypeLabel`. uint8_t op; - //! Reserved (not used). + //! Always zero, labels don't have size. uint8_t size; - //! Reserved (not used). - uint8_t reserved0; - //! Reserved (not used). - uint8_t reserved1; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; - //! Operand id. + //! Operand id (`kInvalidValue` if the label is not initialized by code + //! generator). uint32_t id; + + //! \internal + uint32_t reserved_8_4; + //! \internal + uint32_t reserved_12_4; }; // -------------------------------------------------------------------------- @@ -407,10 +365,14 @@ struct Operand { // -------------------------------------------------------------------------- template - ASMJIT_INLINE T& getData() { return reinterpret_cast(_base); } + ASMJIT_INLINE T& getData() { + return reinterpret_cast(_base); + } template - ASMJIT_INLINE const T& getData() const { return reinterpret_cast(_base); } + ASMJIT_INLINE const T& getData() const { + return reinterpret_cast(_base); + } // -------------------------------------------------------------------------- // [Type] @@ -436,6 +398,16 @@ struct Operand { // [Type - Combined] // -------------------------------------------------------------------------- + //! Get register type. + ASMJIT_INLINE uint32_t getRegType() const { + return _vreg.type; + } + + //! Get register index. + ASMJIT_INLINE uint32_t getRegIndex() const { + return _vreg.index; + } + //! Get whether the operand is register of `type`. ASMJIT_INLINE bool isRegType(uint32_t type) const { return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFF00)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8)); @@ -465,7 +437,9 @@ struct Operand { // -------------------------------------------------------------------------- //! Get size of the operand in bytes. - ASMJIT_INLINE uint32_t getSize() const { return _base.size; } + ASMJIT_INLINE uint32_t getSize() const { + return _base.size; + } // -------------------------------------------------------------------------- // [Id] @@ -473,11 +447,13 @@ struct Operand { //! Get operand id. //! - //! Operand id's are used internally by `BaseAssembler` and `BaseCompiler`. + //! Operand id's are used internally by `Assembler` and `Compiler`. //! //! There is no way to change or remove operand id. Unneeded operands can be //! simply reassigned by `operator=`. - ASMJIT_INLINE uint32_t getId() const { return _base.id; } + ASMJIT_INLINE uint32_t getId() const { + return _base.id; + } // -------------------------------------------------------------------------- // [Members] @@ -521,7 +497,7 @@ struct OperandUtil { return id & 0x7FFFFFFFU; } - //! Get whether the id refers to `BaseVar`. + //! Get whether the id refers to `Var`. //! //! \note The function will never return `true` if the id is `kInvalidValue`. //! The trick is to compare a given id to -1 (kInvalidValue) so we check both @@ -539,39 +515,44 @@ struct OperandUtil { }; // ============================================================================ -// [asmjit::BaseReg] +// [asmjit::Reg] // ============================================================================ //! Base class for all register operands. -struct BaseReg : public Operand { +struct Reg : public Operand { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy base register. - ASMJIT_INLINE BaseReg() : Operand(NoInit) { + ASMJIT_INLINE Reg() : Operand(NoInit) { _init_packed_op_sz_w0_id(kOperandTypeReg, 0, (kInvalidReg << 8) + kInvalidReg, kInvalidValue); - _init_packed_d2_d3(kVarTypeInvalid, 0); + _init_packed_d2_d3(kInvalidVar, 0); } //! Create a new base register. - ASMJIT_INLINE BaseReg(uint32_t type, uint32_t index, uint32_t size) : Operand(NoInit) { + ASMJIT_INLINE Reg(uint32_t type, uint32_t index, uint32_t size) : Operand(NoInit) { _init_packed_op_sz_w0_id(kOperandTypeReg, size, (type << 8) + index, kInvalidValue); - _init_packed_d2_d3(kVarTypeInvalid, 0); + _init_packed_d2_d3(kInvalidVar, 0); } //! Create a new reference to `other`. - ASMJIT_INLINE BaseReg(const BaseReg& other) : Operand(other) {} + ASMJIT_INLINE Reg(const Reg& other) : Operand(other) {} - explicit ASMJIT_INLINE BaseReg(const _NoInit&) : Operand(NoInit) {} + //! Create a new reference to `other` and change the index to `index`. + ASMJIT_INLINE Reg(const Reg& other, uint32_t index) : Operand(other) { + _vreg.index = static_cast(index); + } + + explicit ASMJIT_INLINE Reg(const _NoInit&) : Operand(NoInit) {} // -------------------------------------------------------------------------- - // [BaseReg Specific] + // [Reg Specific] // -------------------------------------------------------------------------- - //! Clone `BaseReg` operand. - ASMJIT_INLINE BaseReg clone() const { - return BaseReg(*this); + //! Clone `Reg` operand. + ASMJIT_INLINE Reg clone() const { + return Reg(*this); } //! Get whether register code is equal to `type`. @@ -679,15 +660,25 @@ struct BaseMem : public Operand { } //! Get the type of the memory operand, see `kMemType`. - ASMJIT_INLINE uint32_t getMemType() const { return _vmem.type; } + ASMJIT_INLINE uint32_t getMemType() const { + return _vmem.type; + } + //! Get whether the type of the memory operand is either `kMemTypeBaseIndex` //! or `kMemTypeStackIndex`. - ASMJIT_INLINE bool isBaseIndexType() const { return _vmem.type <= kMemTypeStackIndex; } + ASMJIT_INLINE bool isBaseIndexType() const { + return _vmem.type <= kMemTypeStackIndex; + } //! Get whether the memory operand has base register. - ASMJIT_INLINE bool hasBase() const { return _vmem.base != kInvalidValue; } + ASMJIT_INLINE bool hasBase() const { + return _vmem.base != kInvalidValue; + } + //! Get memory operand base id, or `kInvalidValue`. - ASMJIT_INLINE uint32_t getBase() const { return _vmem.base; } + ASMJIT_INLINE uint32_t getBase() const { + return _vmem.base; + } //! Set memory operand size. ASMJIT_INLINE BaseMem& setSize(uint32_t size) { @@ -719,53 +710,11 @@ struct BaseMem : public Operand { return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]); } - ASMJIT_INLINE bool operator!=(const BaseMem& other) const { return !(*this == other); } + ASMJIT_INLINE bool operator!=(const BaseMem& other) const { + return !(*this == other); + } }; -// ============================================================================ -// [asmjit::BaseVar] -// ============================================================================ - -#if !defined(ASMJIT_DISABLE_COMPILER) -//! Base class for all variables. -struct BaseVar : public Operand { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE BaseVar() : Operand(NoInit) { - _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, 0, 0, kInvalidValue); - _init_packed_d2_d3(kInvalidValue, kInvalidValue); - } - - ASMJIT_INLINE BaseVar(const BaseVar& other) : Operand(other) {} - - explicit ASMJIT_INLINE BaseVar(const _NoInit&) : Operand(NoInit) {} - - // -------------------------------------------------------------------------- - // [BaseVar Specific] - // -------------------------------------------------------------------------- - - //! Clone `BaseVar` operand. - ASMJIT_INLINE BaseVar clone() const { - return BaseVar(*this); - } - - ASMJIT_INLINE uint32_t getVarType() const { - return _vreg.vType; - } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE BaseVar& operator=(const BaseVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const BaseVar& other) const { return _packed[0] == other._packed[0]; } - ASMJIT_INLINE bool operator!=(const BaseVar& other) const { return !operator==(other); } -}; -#endif // !ASMJIT_DISABLE_COMPILER - // ============================================================================ // [asmjit::Imm] // ============================================================================ @@ -1033,7 +982,7 @@ struct Imm : public Operand { //! Label represents a location in code typically used as jump targets, but may //! be also reference data or static variables. Label has to be explicitly //! created by a code-generator by calling `CodeGen::newLabel()` where `CodeGen` -//! is your code generator, which derives from `BaseAssembler` or `BaseCompiler`. +//! is your code generator, which derives from `Assembler` or `Compiler`. //! //! Example of using labels: //! @@ -1070,9 +1019,9 @@ struct Label : public Operand { } //! Create new initialized label. - explicit ASMJIT_INLINE Label(BaseAssembler& a); + explicit ASMJIT_INLINE Label(Assembler& a); //! Create new initialized label. - explicit ASMJIT_INLINE Label(BaseCompiler& c); + explicit ASMJIT_INLINE Label(Compiler& c); //! Create reference to another label. ASMJIT_INLINE Label(const Label& other) : Operand(other) {} @@ -1088,6 +1037,15 @@ struct Label : public Operand { _init_packed_d2_d3(0, 0); } + // -------------------------------------------------------------------------- + // [Label Specific] + // -------------------------------------------------------------------------- + + //! Get whether the label has been initialized by `Assembler` or `Compiler`. + ASMJIT_INLINE bool isInitialized() const { + return _label.id != kInvalidValue; + } + // -------------------------------------------------------------------------- // [Operator Overload] // -------------------------------------------------------------------------- diff --git a/src/asmjit/base/podlist.h b/src/asmjit/base/podlist.h deleted file mode 100644 index 899e0b9..0000000 --- a/src/asmjit/base/podlist.h +++ /dev/null @@ -1,117 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_BASE_PODLIST_H -#define _ASMJIT_BASE_PODLIST_H - -// [Dependencies - AsmJit] -#include "../base/globals.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { - -//! \addtogroup asmjit_base_util -//! \{ - -// ============================================================================ -// [asmjit::PodList] -// ============================================================================ - -//! \internal -template -struct PodList { - ASMJIT_NO_COPY(PodList) - - // -------------------------------------------------------------------------- - // [Link] - // -------------------------------------------------------------------------- - - struct Link { - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Get next node. - ASMJIT_INLINE Link* getNext() const { return _next; } - - //! Get value. - ASMJIT_INLINE T getValue() const { return _value; } - //! Set value to `value`. - ASMJIT_INLINE void setValue(const T& value) { _value = value; } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - Link* _next; - T _value; - }; - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE PodList() : _first(NULL), _last(NULL) {} - ASMJIT_INLINE ~PodList() {} - - // -------------------------------------------------------------------------- - // [Data] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE bool isEmpty() const { return _first != NULL; } - - ASMJIT_INLINE Link* getFirst() const { return _first; } - ASMJIT_INLINE Link* getLast() const { return _last; } - - // -------------------------------------------------------------------------- - // [Ops] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void clear() { - reset(); - } - - ASMJIT_INLINE void reset() { - _first = NULL; - _last = NULL; - } - - ASMJIT_INLINE void prepend(Link* link) { - link->_next = _first; - if (_first == NULL) - _last = link; - _first = link; - } - - ASMJIT_INLINE void append(Link* link) { - link->_next = NULL; - if (_first == NULL) - _first = link; - else - _last->_next = link; - _last = link; - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - Link* _first; - Link* _last; -}; - -//! \} - -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // _ASMJIT_BASE_PODLIST_H diff --git a/src/asmjit/base/runtime.cpp b/src/asmjit/base/runtime.cpp index d73e508..267b93a 100644 --- a/src/asmjit/base/runtime.cpp +++ b/src/asmjit/base/runtime.cpp @@ -62,15 +62,15 @@ uint32_t JitRuntime::getStackAlignment() { return alignment; } -const BaseCpuInfo* JitRuntime::getCpuInfo() { - return BaseCpuInfo::getHost(); +const CpuInfo* JitRuntime::getCpuInfo() { + return CpuInfo::getHost(); } // ============================================================================ // [asmjit::JitRuntime - Add] // ============================================================================ -Error JitRuntime::add(void** dst, BaseAssembler* assembler) { +Error JitRuntime::add(void** dst, Assembler* assembler) { // Disallow empty code generation. size_t codeSize = assembler->getCodeSize(); diff --git a/src/asmjit/base/runtime.h b/src/asmjit/base/runtime.h index 29c472d..4ebbc26 100644 --- a/src/asmjit/base/runtime.h +++ b/src/asmjit/base/runtime.h @@ -21,8 +21,8 @@ namespace asmjit { // [Forward Declarations] // ============================================================================ -struct BaseAssembler; -struct BaseCpuInfo; +struct Assembler; +struct CpuInfo; //! \addtogroup asmjit_base_general //! \{ @@ -32,7 +32,7 @@ struct BaseCpuInfo; // ============================================================================ //! Base runtime. -struct Runtime { +struct ASMJIT_VCLASS Runtime { ASMJIT_NO_COPY(Runtime) // -------------------------------------------------------------------------- @@ -52,7 +52,7 @@ struct Runtime { virtual uint32_t getStackAlignment() = 0; //! Get CPU information. - virtual const BaseCpuInfo* getCpuInfo() = 0; + virtual const CpuInfo* getCpuInfo() = 0; //! Allocate a memory needed for a code generated by `assembler` and //! relocate it to the target location. @@ -60,7 +60,7 @@ struct Runtime { //! The beginning of the memory allocated for the function is returned in //! `dst`. Returns Status code as \ref kError, on failure `dst` is set to //! `NULL`. - virtual Error add(void** dst, BaseAssembler* assembler) = 0; + virtual Error add(void** dst, Assembler* assembler) = 0; //! Release memory allocated by `add`. virtual Error release(void* p) = 0; @@ -71,7 +71,7 @@ struct Runtime { // ============================================================================ //! JIT runtime. -struct JitRuntime : public Runtime { +struct ASMJIT_VCLASS JitRuntime : public Runtime { ASMJIT_NO_COPY(JitRuntime) // -------------------------------------------------------------------------- @@ -112,9 +112,9 @@ struct JitRuntime : public Runtime { // -------------------------------------------------------------------------- ASMJIT_API virtual uint32_t getStackAlignment(); - ASMJIT_API virtual const BaseCpuInfo* getCpuInfo(); + ASMJIT_API virtual const CpuInfo* getCpuInfo(); - ASMJIT_API virtual Error add(void** dst, BaseAssembler* assembler); + ASMJIT_API virtual Error add(void** dst, Assembler* assembler); ASMJIT_API virtual Error release(void* p); //! Flush instruction cache. diff --git a/src/asmjit/base/vectypes.h b/src/asmjit/base/vectypes.h index 930df03..d675ec2 100644 --- a/src/asmjit/base/vectypes.h +++ b/src/asmjit/base/vectypes.h @@ -20,164 +20,164 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::Vec64Data] +// [asmjit::Vec64] // ============================================================================ //! 64-bit vector register data. -union Vec64Data { +union Vec64 { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Set all eight 8-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSb( + static ASMJIT_INLINE Vec64 fromSb( int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) { - Vec64Data self; + Vec64 self; self.setSb(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 8-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSb( + static ASMJIT_INLINE Vec64 fromSb( int8_t x0) { - Vec64Data self; + Vec64 self; self.setSb(x0); return self; } //! Set all eight 8-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUb( + static ASMJIT_INLINE Vec64 fromUb( uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) { - Vec64Data self; + Vec64 self; self.setUb(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 8-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUb( + static ASMJIT_INLINE Vec64 fromUb( uint8_t x0) { - Vec64Data self; + Vec64 self; self.setUb(x0); return self; } //! Set all four 16-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSw( + static ASMJIT_INLINE Vec64 fromSw( int16_t x0, int16_t x1, int16_t x2, int16_t x3) { - Vec64Data self; + Vec64 self; self.setSw(x0, x1, x2, x3); return self; } //! Set all four 16-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSw( + static ASMJIT_INLINE Vec64 fromSw( int16_t x0) { - Vec64Data self; + Vec64 self; self.setSw(x0); return self; } //! Set all four 16-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUw( + static ASMJIT_INLINE Vec64 fromUw( uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) { - Vec64Data self; + Vec64 self; self.setUw(x0, x1, x2, x3); return self; } //! Set all four 16-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUw( + static ASMJIT_INLINE Vec64 fromUw( uint16_t x0) { - Vec64Data self; + Vec64 self; self.setUw(x0); return self; } //! Set all two 32-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSd( + static ASMJIT_INLINE Vec64 fromSd( int32_t x0, int32_t x1) { - Vec64Data self; + Vec64 self; self.setSd(x0, x1); return self; } //! Set all two 32-bit signed integers. - static ASMJIT_INLINE Vec64Data fromSd( + static ASMJIT_INLINE Vec64 fromSd( int32_t x0) { - Vec64Data self; + Vec64 self; self.setSd(x0); return self; } //! Set all two 32-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUd( + static ASMJIT_INLINE Vec64 fromUd( uint32_t x0, uint32_t x1) { - Vec64Data self; + Vec64 self; self.setUd(x0, x1); return self; } //! Set all two 32-bit unsigned integers. - static ASMJIT_INLINE Vec64Data fromUd( + static ASMJIT_INLINE Vec64 fromUd( uint32_t x0) { - Vec64Data self; + Vec64 self; self.setUd(x0); return self; } //! Set 64-bit signed integer. - static ASMJIT_INLINE Vec64Data fromSq( + static ASMJIT_INLINE Vec64 fromSq( int64_t x0) { - Vec64Data self; + Vec64 self; self.setSq(x0); return self; } //! Set 64-bit unsigned integer. - static ASMJIT_INLINE Vec64Data fromUq( + static ASMJIT_INLINE Vec64 fromUq( uint64_t x0) { - Vec64Data self; + Vec64 self; self.setUq(x0); return self; } //! Set all two SP-FP values. - static ASMJIT_INLINE Vec64Data fromSf( + static ASMJIT_INLINE Vec64 fromSf( float x0, float x1) { - Vec64Data self; + Vec64 self; self.setSf(x0, x1); return self; } //! Set all two SP-FP values. - static ASMJIT_INLINE Vec64Data fromSf( + static ASMJIT_INLINE Vec64 fromSf( float x0) { - Vec64Data self; + Vec64 self; self.setSf(x0); return self; } //! Set all two SP-FP values. - static ASMJIT_INLINE Vec64Data fromDf( + static ASMJIT_INLINE Vec64 fromDf( double x0) { - Vec64Data self; + Vec64 self; self.setDf(x0); return self; } @@ -351,197 +351,197 @@ union Vec64Data { }; // ============================================================================ -// [asmjit::Vec128Data] +// [asmjit::Vec128] // ============================================================================ //! 128-bit vector register data. -union Vec128Data { +union Vec128 { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Set all sixteen 8-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSb( + static ASMJIT_INLINE Vec128 fromSb( int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, int8_t x12, int8_t x13, int8_t x14, int8_t x15) { - Vec128Data self; + Vec128 self; self.setSb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); return self; } //! Set all sixteen 8-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSb( + static ASMJIT_INLINE Vec128 fromSb( int8_t x0) { - Vec128Data self; + Vec128 self; self.setSb(x0); return self; } //! Set all sixteen 8-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUb( + static ASMJIT_INLINE Vec128 fromUb( uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) { - Vec128Data self; + Vec128 self; self.setUb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); return self; } //! Set all sixteen 8-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUb( + static ASMJIT_INLINE Vec128 fromUb( uint8_t x0) { - Vec128Data self; + Vec128 self; self.setUb(x0); return self; } //! Set all eight 16-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSw( + static ASMJIT_INLINE Vec128 fromSw( int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) { - Vec128Data self; + Vec128 self; self.setSw(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 16-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSw( + static ASMJIT_INLINE Vec128 fromSw( int16_t x0) { - Vec128Data self; + Vec128 self; self.setSw(x0); return self; } //! Set all eight 16-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUw( + static ASMJIT_INLINE Vec128 fromUw( uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) { - Vec128Data self; + Vec128 self; self.setUw(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 16-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUw( + static ASMJIT_INLINE Vec128 fromUw( uint16_t x0) { - Vec128Data self; + Vec128 self; self.setUw(x0); return self; } //! Set all four 32-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSd( + static ASMJIT_INLINE Vec128 fromSd( int32_t x0, int32_t x1, int32_t x2, int32_t x3) { - Vec128Data self; + Vec128 self; self.setSd(x0, x1, x2, x3); return self; } //! Set all four 32-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSd( + static ASMJIT_INLINE Vec128 fromSd( int32_t x0) { - Vec128Data self; + Vec128 self; self.setSd(x0); return self; } //! Set all four 32-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUd( + static ASMJIT_INLINE Vec128 fromUd( uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) { - Vec128Data self; + Vec128 self; self.setUd(x0, x1, x2, x3); return self; } //! Set all four 32-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUd( + static ASMJIT_INLINE Vec128 fromUd( uint32_t x0) { - Vec128Data self; + Vec128 self; self.setUd(x0); return self; } //! Set all two 64-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSq( + static ASMJIT_INLINE Vec128 fromSq( int64_t x0, int64_t x1) { - Vec128Data self; + Vec128 self; self.setSq(x0, x1); return self; } //! Set all two 64-bit signed integers. - static ASMJIT_INLINE Vec128Data fromSq( + static ASMJIT_INLINE Vec128 fromSq( int64_t x0) { - Vec128Data self; + Vec128 self; self.setSq(x0); return self; } //! Set all two 64-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUq( + static ASMJIT_INLINE Vec128 fromUq( uint64_t x0, uint64_t x1) { - Vec128Data self; + Vec128 self; self.setUq(x0, x1); return self; } //! Set all two 64-bit unsigned integers. - static ASMJIT_INLINE Vec128Data fromUq( + static ASMJIT_INLINE Vec128 fromUq( uint64_t x0) { - Vec128Data self; + Vec128 self; self.setUq(x0); return self; } //! Set all four SP-FP floats. - static ASMJIT_INLINE Vec128Data fromSf( + static ASMJIT_INLINE Vec128 fromSf( float x0, float x1, float x2, float x3) { - Vec128Data self; + Vec128 self; self.setSf(x0, x1, x2, x3); return self; } //! Set all four SP-FP floats. - static ASMJIT_INLINE Vec128Data fromSf( + static ASMJIT_INLINE Vec128 fromSf( float x0) { - Vec128Data self; + Vec128 self; self.setSf(x0); return self; } //! Set all two DP-FP floats. - static ASMJIT_INLINE Vec128Data fromDf( + static ASMJIT_INLINE Vec128 fromDf( double x0, double x1) { - Vec128Data self; + Vec128 self; self.setDf(x0, x1); return self; } //! Set all two DP-FP floats. - static ASMJIT_INLINE Vec128Data fromDf( + static ASMJIT_INLINE Vec128 fromDf( double x0) { - Vec128Data self; + Vec128 self; self.setDf(x0); return self; } @@ -764,17 +764,17 @@ union Vec128Data { }; // ============================================================================ -// [asmjit::Vec256Data] +// [asmjit::Vec256] // ============================================================================ //! 256-bit vector register data. -union Vec256Data { +union Vec256 { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Set all thirty two 8-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSb( + static ASMJIT_INLINE Vec256 fromSb( int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, @@ -784,7 +784,7 @@ union Vec256Data { int8_t x24, int8_t x25, int8_t x26, int8_t x27, int8_t x28, int8_t x29, int8_t x30, int8_t x31) { - Vec256Data self; + Vec256 self; self.setSb( x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); @@ -792,16 +792,16 @@ union Vec256Data { } //! Set all thirty two 8-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSb( + static ASMJIT_INLINE Vec256 fromSb( int8_t x0) { - Vec256Data self; + Vec256 self; self.setSb(x0); return self; } //! Set all thirty two 8-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUb( + static ASMJIT_INLINE Vec256 fromUb( uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, @@ -811,7 +811,7 @@ union Vec256Data { uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27, uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) { - Vec256Data self; + Vec256 self; self.setUb( x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); @@ -819,159 +819,159 @@ union Vec256Data { } //! Set all thirty two 8-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUb( + static ASMJIT_INLINE Vec256 fromUb( uint8_t x0) { - Vec256Data self; + Vec256 self; self.setUb(x0); return self; } //! Set all sixteen 16-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSw( + static ASMJIT_INLINE Vec256 fromSw( int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7 , int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15) { - Vec256Data self; + Vec256 self; self.setSw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); return self; } //! Set all sixteen 16-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSw( + static ASMJIT_INLINE Vec256 fromSw( int16_t x0) { - Vec256Data self; + Vec256 self; self.setSw(x0); return self; } //! Set all sixteen 16-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUw( + static ASMJIT_INLINE Vec256 fromUw( uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 , uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15) { - Vec256Data self; + Vec256 self; self.setUw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); return self; } //! Set all sixteen 16-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUw( + static ASMJIT_INLINE Vec256 fromUw( uint16_t x0) { - Vec256Data self; + Vec256 self; self.setUw(x0); return self; } //! Set all eight 32-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSd( + static ASMJIT_INLINE Vec256 fromSd( int32_t x0, int32_t x1, int32_t x2, int32_t x3, int32_t x4, int32_t x5, int32_t x6, int32_t x7) { - Vec256Data self; + Vec256 self; self.setSd(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 32-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSd( + static ASMJIT_INLINE Vec256 fromSd( int32_t x0) { - Vec256Data self; + Vec256 self; self.setSd(x0); return self; } //! Set all eight 32-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUd( + static ASMJIT_INLINE Vec256 fromUd( uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) { - Vec256Data self; + Vec256 self; self.setUd(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight 32-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUd( + static ASMJIT_INLINE Vec256 fromUd( uint32_t x0) { - Vec256Data self; + Vec256 self; self.setUd(x0); return self; } //! Set all four 64-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSq( + static ASMJIT_INLINE Vec256 fromSq( int64_t x0, int64_t x1, int64_t x2, int64_t x3) { - Vec256Data self; + Vec256 self; self.setSq(x0, x1, x2, x3); return self; } //! Set all four 64-bit signed integers. - static ASMJIT_INLINE Vec256Data fromSq( + static ASMJIT_INLINE Vec256 fromSq( int64_t x0) { - Vec256Data self; + Vec256 self; self.setSq(x0); return self; } //! Set all four 64-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUq( + static ASMJIT_INLINE Vec256 fromUq( uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) { - Vec256Data self; + Vec256 self; self.setUq(x0, x1, x2, x3); return self; } //! Set all four 64-bit unsigned integers. - static ASMJIT_INLINE Vec256Data fromUq( + static ASMJIT_INLINE Vec256 fromUq( uint64_t x0) { - Vec256Data self; + Vec256 self; self.setUq(x0); return self; } //! Set all eight SP-FP floats. - static ASMJIT_INLINE Vec256Data fromSf( + static ASMJIT_INLINE Vec256 fromSf( float x0, float x1, float x2, float x3, float x4, float x5, float x6, float x7) { - Vec256Data self; + Vec256 self; self.setSf(x0, x1, x2, x3, x4, x5, x6, x7); return self; } //! Set all eight SP-FP floats. - static ASMJIT_INLINE Vec256Data fromSf( + static ASMJIT_INLINE Vec256 fromSf( float x0) { - Vec256Data self; + Vec256 self; self.setSf(x0); return self; } //! Set all four DP-FP floats. - static ASMJIT_INLINE Vec256Data fromDf( + static ASMJIT_INLINE Vec256 fromDf( double x0, double x1, double x2, double x3) { - Vec256Data self; + Vec256 self; self.setDf(x0, x1, x2, x3); return self; } //! Set all four DP-FP floats. - static ASMJIT_INLINE Vec256Data fromDf( + static ASMJIT_INLINE Vec256 fromDf( double x0) { - Vec256Data self; + Vec256 self; self.setDf(x0); return self; } diff --git a/src/asmjit/base/vmem.cpp b/src/asmjit/base/vmem.cpp index fb512f8..f0c45d9 100644 --- a/src/asmjit/base/vmem.cpp +++ b/src/asmjit/base/vmem.cpp @@ -72,78 +72,87 @@ namespace asmjit { // Windows specific implementation using `VirtualAllocEx` and `VirtualFree`. #if defined(ASMJIT_OS_WINDOWS) struct VMemLocal { - VMemLocal() { - SYSTEM_INFO info; - GetSystemInfo(&info); - - hProcess = GetCurrentProcess(); - alignment = info.dwAllocationGranularity; - pageSize = IntUtil::alignToPowerOf2(info.dwPageSize); + // AsmJit allows to pass a `NULL` handle to `VMemUtil`. This function is just + // a convenient way to convert such handle to the current process one. + ASMJIT_INLINE HANDLE getSafeProcessHandle(HANDLE hParam) const { + return hParam != NULL ? hParam : hProcess; } - HANDLE hProcess; - size_t alignment; size_t pageSize; + size_t pageGranularity; + HANDLE hProcess; }; +static VMemLocal vMemLocal; -static VMemLocal& vm() { - static VMemLocal vm; - return vm; +static const VMemLocal& vMemGet() { + VMemLocal& vMem = vMemLocal; + + if (!vMem.hProcess) { + SYSTEM_INFO info; + ::GetSystemInfo(&info); + + vMem.pageSize = IntUtil::alignToPowerOf2(info.dwPageSize); + vMem.pageGranularity = info.dwAllocationGranularity; + + vMem.hProcess = ::GetCurrentProcess(); + } + + return vMem; }; -size_t VMemUtil::getAlignment() { - return vm().alignment; -} - size_t VMemUtil::getPageSize() { - return vm().pageSize; + const VMemLocal& vMem = vMemGet(); + return vMem.pageSize; +} + +size_t VMemUtil::getPageGranularity() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageGranularity; } void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) { return allocProcessMemory(static_cast(0), length, allocated, flags); } -void VMemUtil::release(void* addr, size_t length) { - return releaseProcessMemory(static_cast(0), addr, length); -} - void* VMemUtil::allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags) { - VMemLocal& vmLocal = vm(); + if (length == 0) + return NULL; - if (hProcess == static_cast(0)) - hProcess = vmLocal.hProcess; + const VMemLocal& vMem = vMemGet(); + hProcess = vMem.getSafeProcessHandle(hProcess); // VirtualAlloc rounds allocated size to a page size automatically. - size_t mSize = IntUtil::alignTo(length, vmLocal.pageSize); + size_t mSize = IntUtil::alignTo(length, vMem.pageSize); // Windows XP SP2 / Vista allow Data Excution Prevention (DEP). DWORD protectFlags = 0; - if (flags & kVMemFlagExecutable) { - protectFlags |= (flags & kVMemFlagWritable) - ? PAGE_EXECUTE_READWRITE - : PAGE_EXECUTE_READ; - } - else { - protectFlags |= (flags & kVMemFlagWritable) - ? PAGE_READWRITE - : PAGE_READONLY; - } + if (flags & kVMemFlagExecutable) + protectFlags |= (flags & kVMemFlagWritable) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + else + protectFlags |= (flags & kVMemFlagWritable) ? PAGE_READWRITE : PAGE_READONLY; - LPVOID mBase = VirtualAllocEx(hProcess, NULL, mSize, MEM_COMMIT | MEM_RESERVE, protectFlags); + LPVOID mBase = ::VirtualAllocEx(hProcess, NULL, mSize, MEM_COMMIT | MEM_RESERVE, protectFlags); if (mBase == NULL) return NULL; ASMJIT_ASSERT(IntUtil::isAligned( - reinterpret_cast(mBase), vmLocal.alignment)); + reinterpret_cast(mBase), vMem.pageSize)); if (allocated != NULL) *allocated = mSize; return mBase; } -void VMemUtil::releaseProcessMemory(HANDLE hProcess, void* addr, size_t /* length */) { - VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE); +Error VMemUtil::release(void* addr, size_t length) { + return releaseProcessMemory(static_cast(0), addr, length); +} + +Error VMemUtil::releaseProcessMemory(HANDLE hProcess, void* addr, size_t /* length */) { + hProcess = vMemGet().getSafeProcessHandle(hProcess); + if (!::VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE)) + return kErrorInvalidState; + return kErrorOk; } #endif // ASMJIT_OS_WINDOWS @@ -160,29 +169,36 @@ void VMemUtil::releaseProcessMemory(HANDLE hProcess, void* addr, size_t /* lengt #endif // MAP_ANONYMOUS struct VMemLocal { - VMemLocal() { - alignment = pageSize = ::getpagesize(); + size_t pageSize; + size_t pageGranularity; +}; +static VMemLocal vMemLocal; + +static const VMemLocal& vMemGet() { + VMemLocal& vMem = vMemLocal; + + if (!vMem.pageSize) { + size_t pageSize = ::getpagesize(); + vMem.pageSize = pageSize; + vMem.pageGranularity = IntUtil::iMax(pageSize, 65536); } - size_t alignment; - size_t pageSize; + return vMem; }; -static VMemLocal& vm() { - static VMemLocal vm; - return vm; -} - -size_t VMemUtil::getAlignment() { - return vm().alignment; -} - size_t VMemUtil::getPageSize() { - return vm().pageSize; + const VMemLocal& vMem = vMemGet(); + return vMem.pageSize; +} + +size_t VMemUtil::getPageGranularity() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageGranularity; } void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) { - size_t msize = IntUtil::alignTo(length, vm().pageSize); + const VMemLocal& vMem = vMemGet(); + size_t msize = IntUtil::alignTo(length, vMem.pageSize); int protection = PROT_READ; if (flags & kVMemFlagWritable ) protection |= PROT_WRITE; @@ -197,15 +213,21 @@ void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) { return mbase; } -void VMemUtil::release(void* addr, size_t length) { - ::munmap(addr, length); +Error VMemUtil::release(void* addr, size_t length) { + if (::munmap(addr, length) != 0) + return kErrorInvalidState; + + return kErrorOk; } #endif // ASMJIT_OS_POSIX // ============================================================================ -// [VMem - Ops] +// [asmjit::VMemMgr - BitOps] // ============================================================================ +#define M_DIV(x, y) ((x) / (y)) +#define M_MOD(x, y) ((x) % (y)) + //! \internal enum { kBitsPerEntity = (sizeof(size_t) * 8) @@ -223,7 +245,8 @@ static void _SetBits(size_t* buf, size_t index, size_t len) { // How many bytes process in the first group. size_t c = kBitsPerEntity - j; - if (c > len) c = len; + if (c > len) + c = len; // Offset. buf += i; @@ -241,34 +264,30 @@ static void _SetBits(size_t* buf, size_t index, size_t len) { } // ============================================================================ -// [asmjit::MemNode] +// [asmjit::VMemMgr::TypeDefs] // ============================================================================ -#define M_DIV(x, y) ((x) / (y)) -#define M_MOD(x, y) ((x) % (y)) +typedef VMemMgr::RbNode RbNode; +typedef VMemMgr::MemNode MemNode; +typedef VMemMgr::PermanentNode PermanentNode; + +// ============================================================================ +// [asmjit::VMemMgr::RbNode] +// ============================================================================ //! \internal //! //! Base red-black tree node. -struct RbNode { - // -------------------------------------------------------------------------- - // [Red-black tree node, key is mem pointer]. - // -------------------------------------------------------------------------- - +struct VMemMgr::RbNode { // Implementation is based on article by Julienne Walker (Public Domain), // including C code and original comments. Thanks for the excellent article. // Left[0] and right[1] nodes. RbNode* node[2]; - // Whether the node is RED. - uint32_t red; - - // -------------------------------------------------------------------------- - // [Chunk Memory] - // -------------------------------------------------------------------------- - // Virtual memory address. uint8_t* mem; + // Whether the node is RED. + uint32_t red; }; //! \internal @@ -278,22 +297,82 @@ static ASMJIT_INLINE bool rbIsRed(RbNode* node) { return node != NULL && node->red; } -struct MemNode : public RbNode { +//! \internal +//! +//! Check whether the RB tree is valid. +static int rbAssert(RbNode* root) { + if (root == NULL) + return 1; + + RbNode* ln = root->node[0]; + RbNode* rn = root->node[1]; + + // Red violation. + ASMJIT_ASSERT( !(rbIsRed(root) && (rbIsRed(ln) || rbIsRed(rn))) ); + + int lh = rbAssert(ln); + int rh = rbAssert(rn); + + // Invalid btree. + ASMJIT_ASSERT(ln == NULL || ln->mem < root->mem); + ASMJIT_ASSERT(rn == NULL || rn->mem > root->mem); + + // Black violation. + ASMJIT_ASSERT( !(lh != 0 && rh != 0 && lh != rh) ); + + // Only count black links. + if (lh != 0 && rh != 0) + return rbIsRed(root) ? lh : lh + 1; + else + return 0; +} + +//! \internal +//! +//! Single rotation. +static ASMJIT_INLINE RbNode* rbRotateSingle(RbNode* root, int dir) { + RbNode* save = root->node[!dir]; + + root->node[!dir] = save->node[dir]; + save->node[dir] = root; + + root->red = 1; + save->red = 0; + + return save; +} + +//! \internal +//! +//! Double rotation. +static ASMJIT_INLINE RbNode* rbRotateDouble(RbNode* root, int dir) { + root->node[!dir] = rbRotateSingle(root->node[!dir], !dir); + return rbRotateSingle(root, dir); +} + +// ============================================================================ +// [asmjit::VMemMgr::MemNode] +// ============================================================================ + +struct VMemMgr::MemNode : public RbNode { // -------------------------------------------------------------------------- // [Helpers] // -------------------------------------------------------------------------- // Get available space. - ASMJIT_INLINE size_t getAvailable() const { return size - used; } + ASMJIT_INLINE size_t getAvailable() const { + return size - used; + } ASMJIT_INLINE void fillData(MemNode* other) { mem = other->mem; size = other->size; + used = other->used; blocks = other->blocks; density = other->density; - used = other->used; largestBlock = other->largestBlock; + baUsed = other->baUsed; baCont = other->baCont; } @@ -302,27 +381,27 @@ struct MemNode : public RbNode { // [Members] // -------------------------------------------------------------------------- - MemNode* prev; // Prev node in list. - MemNode* next; // Next node in list. + MemNode* prev; // Prev node in list. + MemNode* next; // Next node in list. - size_t size; // How many bytes contain this node. - size_t blocks; // How many blocks are here. - size_t density; // Minimum count of allocated bytes in this node (also alignment). - size_t used; // How many bytes are used in this node. - size_t largestBlock; // Contains largest block that can be allocated. + size_t size; // How many bytes contain this node. + size_t used; // How many bytes are used in this node. + size_t blocks; // How many blocks are here. + size_t density; // Minimum count of allocated bytes in this node (also alignment). + size_t largestBlock; // Contains largest block that can be allocated. - size_t* baUsed; // Contains bits about used blocks (0 = unused, 1 = used). - size_t* baCont; // Contains bits about continuous blocks (0 = stop , 1 = continue). + size_t* baUsed; // Contains bits about used blocks (0 = unused, 1 = used). + size_t* baCont; // Contains bits about continuous blocks (0 = stop , 1 = continue). }; // ============================================================================ -// [asmjit::PermanentNode] +// [asmjit::VMemMgr::PermanentNode] // ============================================================================ //! \internal //! //! Permanent node. -struct PermanentNode { +struct VMemMgr::PermanentNode { // -------------------------------------------------------------------------- // [Helpers] // -------------------------------------------------------------------------- @@ -336,148 +415,60 @@ struct PermanentNode { // [Members] // -------------------------------------------------------------------------- - uint8_t* mem; // Base pointer (virtual memory address). - size_t size; // Count of bytes allocated. - size_t used; // Count of bytes used. - PermanentNode* prev; // Pointer to prev chunk or NULL. + PermanentNode* prev; // Pointer to prev chunk or NULL. + uint8_t* mem; // Base pointer (virtual memory address). + size_t size; // Count of bytes allocated. + size_t used; // Count of bytes used. }; // ============================================================================ -// [asmjit::VMemPrivate] +// [asmjit::VMemMgr - Private] // ============================================================================ //! \internal -struct VMemPrivate { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - +//! +//! Helper to avoid `#ifdef`s in the code. +ASMJIT_INLINE uint8_t* vMemMgrAllocVMem(VMemMgr* self, size_t size, size_t* vSize) { + uint32_t flags = kVMemFlagWritable | kVMemFlagExecutable; #if !defined(ASMJIT_OS_WINDOWS) - VMemPrivate(); + return static_cast(VMemUtil::alloc(size, vSize, flags)); #else - VMemPrivate(HANDLE hProcess); -#endif // ASMJIT_OS_WINDOWS - ~VMemPrivate(); - - // -------------------------------------------------------------------------- - // [Allocation] - // -------------------------------------------------------------------------- - - MemNode* createNode(size_t size, size_t density); - - void reset(bool keepVirtualMemory); - - void* allocPermanent(size_t vsize); - void* allocFreeable(size_t vsize); - Error release(void* address); - Error shrink(void* address, size_t used); - - // Helpers to avoid ifdefs in the code. - ASMJIT_INLINE uint8_t* allocVirtualMemory(size_t size, size_t* vsize) { - uint32_t flags = kVMemFlagWritable | kVMemFlagExecutable; -#if !defined(ASMJIT_OS_WINDOWS) - return (uint8_t*)VMemUtil::alloc(size, vsize, flags); -#else - return (uint8_t*)VMemUtil::allocProcessMemory(_hProcess, size, vsize, flags); + return static_cast(VMemUtil::allocProcessMemory(self->_hProcess, size, vSize, flags)); #endif - } - - ASMJIT_INLINE void freeVirtualMemory(void* vmem, size_t vsize) { -#if !defined(ASMJIT_OS_WINDOWS) - VMemUtil::release(vmem, vsize); -#else - VMemUtil::releaseProcessMemory(_hProcess, vmem, vsize); -#endif - } - - // -------------------------------------------------------------------------- - // [NodeList RB-Tree] - // -------------------------------------------------------------------------- - - bool checkTree(); - - void insertNode(MemNode* node); - MemNode* removeNode(MemNode* node); - MemNode* findPtr(uint8_t* mem); - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - -#if defined(ASMJIT_OS_WINDOWS) - HANDLE _hProcess; // Process where to allocate memory. -#endif // ASMJIT_OS_WINDOWS - Lock _lock; // Lock for thread safety. - - size_t _newChunkSize; // Default node size. - size_t _newChunkDensity; // Default node density. - size_t _allocated; // How many bytes are allocated. - size_t _used; // How many bytes are used. - - // Memory nodes list. - MemNode* _first; - MemNode* _last; - MemNode* _optimal; - - // Memory nodes tree. - MemNode* _root; - - // Permanent memory. - PermanentNode* _permanent; - - // Whether to keep virtual memory after destroy. - bool _keepVirtualMemory; -}; - -// ============================================================================ -// [asmjit::VMemPrivate - Construction / Destruction] -// ============================================================================ - -#if !defined(ASMJIT_OS_WINDOWS) -VMemPrivate::VMemPrivate() : -#else -VMemPrivate::VMemPrivate(HANDLE hProcess) : - _hProcess(hProcess), -#endif - _newChunkSize(65536), - _newChunkDensity(64), - _allocated(0), - _used(0), - _root(NULL), - _first(NULL), - _last(NULL), - _optimal(NULL), - _permanent(NULL), - _keepVirtualMemory(false) {} - -VMemPrivate::~VMemPrivate() { - // Freeable memory cleanup - Also frees the virtual memory if configured to. - reset(_keepVirtualMemory); - - // Permanent memory cleanup - Never frees the virtual memory. - PermanentNode* node = _permanent; - while (node) { - PermanentNode* prev = node->prev; - ASMJIT_FREE(node); - node = prev; - } } -// ============================================================================ -// [asmjit::VMemPrivate - Allocation] -// ============================================================================ +//! \internal +//! +//! Helper to avoid `#ifdef`s in the code. +ASMJIT_INLINE Error vMemMgrReleaseVMem(VMemMgr* self, void* p, size_t vSize) { +#if !defined(ASMJIT_OS_WINDOWS) + return VMemUtil::release(p, vSize); +#else + return VMemUtil::releaseProcessMemory(self->_hProcess, p, vSize); +#endif +} -// Allocate virtual memory node and MemNode structure. -// -// Returns MemNode* on success, otherwise NULL. -MemNode* VMemPrivate::createNode(size_t size, size_t density) { - size_t vsize; - uint8_t* vmem = allocVirtualMemory(size, &vsize); +//! \internal +//! +//! Check whether the Red-Black tree is valid. +static bool vMemMgrCheckTree(VMemMgr* self) { + return rbAssert(self->_root) > 0; +} + +//! \internal +//! +//! Alloc virtual memory including a heap memory needed for `MemNode` data. +//! +//! Returns set-up `MemNode*` or NULL if allocation failed. +static MemNode* vMemMgrCreateNode(VMemMgr* self, size_t size, size_t density) { + size_t vSize; + uint8_t* vmem = vMemMgrAllocVMem(self, size, &vSize); // Out of memory. - if (vmem == NULL) return NULL; + if (vmem == NULL) + return NULL; - size_t blocks = (vsize / density); + size_t blocks = (vSize / density); size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~(size_t)(sizeof(size_t) - 1); MemNode* node = static_cast(ASMJIT_ALLOC(sizeof(MemNode))); @@ -485,7 +476,7 @@ MemNode* VMemPrivate::createNode(size_t size, size_t density) { // Out of memory. if (node == NULL || data == NULL) { - freeVirtualMemory(vmem, vsize); + vMemMgrReleaseVMem(self, vmem, vSize); if (node) ASMJIT_FREE(node); if (data) ASMJIT_FREE(data); return NULL; @@ -494,18 +485,18 @@ MemNode* VMemPrivate::createNode(size_t size, size_t density) { // Initialize RbNode data. node->node[0] = NULL; node->node[1] = NULL; - node->red = 1; node->mem = vmem; + node->red = 1; // Initialize MemNode data. node->prev = NULL; node->next = NULL; - node->size = vsize; + node->size = vSize; + node->used = 0; node->blocks = blocks; node->density = density; - node->used = 0; - node->largestBlock = vsize; + node->largestBlock = vSize; ::memset(data, 0, bsize * 2); node->baUsed = reinterpret_cast(data); @@ -514,53 +505,232 @@ MemNode* VMemPrivate::createNode(size_t size, size_t density) { return node; } -void VMemPrivate::reset(bool keepVirtualMemory) { - MemNode* node = _first; +static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { + if (self->_root == NULL) { + // Empty tree case. + self->_root = node; + } + else { + // False tree root. + RbNode head = { 0 }; - while (node) { - MemNode* next = node->next; + // Grandparent & parent. + RbNode* g = NULL; + RbNode* t = &head; - if (!keepVirtualMemory) - freeVirtualMemory(node->mem, node->size); + // Iterator & parent. + RbNode* p = NULL; + RbNode* q = t->node[1] = self->_root; - ASMJIT_FREE(node->baUsed); - ASMJIT_FREE(node); + int dir = 0, last; - node = next; + // Search down the tree. + for (;;) { + if (q == NULL) { + // Insert new node at the bottom. + q = node; + p->node[dir] = node; + } + else if (rbIsRed(q->node[0]) && rbIsRed(q->node[1])) { + // Color flip. + q->red = 1; + q->node[0]->red = 0; + q->node[1]->red = 0; + } + + // Fix red violation. + if (rbIsRed(q) && rbIsRed(p)) { + int dir2 = t->node[1] == g; + t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last); + } + + // Stop if found. + if (q == node) + break; + + last = dir; + dir = q->mem < node->mem; + + // Update helpers. + if (g != NULL) + t = g; + + g = p; + p = q; + q = q->node[dir]; + } + + // Update root. + self->_root = static_cast(head.node[1]); } - _allocated = 0; - _used = 0; + // Make root black. + self->_root->red = 0; - _root = NULL; - _first = NULL; - _last = NULL; - _optimal = NULL; + // Link with others. + node->prev = self->_last; + + if (self->_first == NULL) { + self->_first = node; + self->_last = node; + self->_optimal = node; + } + else { + node->prev = self->_last; + self->_last->next = node; + self->_last = node; + } } -void* VMemPrivate::allocPermanent(size_t vsize) { +//! \internal +//! +//! Remove node from Red-Black tree. +//! +//! Returns node that should be freed, but it doesn't have to be necessarily +//! the `node` passed. +static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) { + // False tree root. + RbNode head = { 0 }; + + // Helpers. + RbNode* q = &head; + RbNode* p = NULL; + RbNode* g = NULL; + + // Found item. + RbNode* f = NULL; + int dir = 1; + + // Set up. + q->node[1] = self->_root; + + // Search and push a red down. + while (q->node[dir] != NULL) { + int last = dir; + + // Update helpers. + g = p; + p = q; + q = q->node[dir]; + dir = q->mem < node->mem; + + // Save found node. + if (q == node) + f = q; + + // Push the red node down. + if (!rbIsRed(q) && !rbIsRed(q->node[dir])) { + if (rbIsRed(q->node[!dir])) { + p = p->node[last] = rbRotateSingle(q, dir); + } + else if (!rbIsRed(q->node[!dir])) { + RbNode* s = p->node[!last]; + + if (s != NULL) { + if (!rbIsRed(s->node[!last]) && !rbIsRed(s->node[last])) { + // Color flip. + p->red = 0; + s->red = 1; + q->red = 1; + } + else { + int dir2 = g->node[1] == p; + + if (rbIsRed(s->node[last])) + g->node[dir2] = rbRotateDouble(p, last); + else if (rbIsRed(s->node[!last])) + g->node[dir2] = rbRotateSingle(p, last); + + // Ensure correct coloring. + q->red = g->node[dir2]->red = 1; + g->node[dir2]->node[0]->red = 0; + g->node[dir2]->node[1]->red = 0; + } + } + } + } + } + + // Replace and remove. + ASMJIT_ASSERT(f != NULL); + ASMJIT_ASSERT(f != &head); + ASMJIT_ASSERT(q != &head); + + if (f != q) { + ASMJIT_ASSERT(f != &head); + static_cast(f)->fillData(static_cast(q)); + } + + p->node[p->node[1] == q] = q->node[q->node[0] == NULL]; + + // Update root and make it black. + self->_root = static_cast(head.node[1]); + if (self->_root != NULL) + self->_root->red = 0; + + // Unlink. + MemNode* next = static_cast(q)->next; + MemNode* prev = static_cast(q)->prev; + + if (prev) + prev->next = next; + else + self->_first = next; + + if (next) + next->prev = prev; + else + self->_last = prev; + + if (self->_optimal == q) + self->_optimal = prev ? prev : next; + + return static_cast(q); +} + +static MemNode* vMemMgrFindNodeByPtr(VMemMgr* self, uint8_t* mem) { + MemNode* node = self->_root; + while (node != NULL) { + uint8_t* nodeMem = node->mem; + + // Go left. + if (mem < nodeMem) { + node = static_cast(node->node[0]); + continue; + } + + // Go right. + uint8_t* nodeEnd = nodeMem + node->size; + if (mem >= nodeEnd) { + node = static_cast(node->node[1]); + continue; + } + + // Match. + break; + } + return node; +} + +static void* vMemMgrAllocPermanent(VMemMgr* self, size_t vSize) { static const size_t permanentAlignment = 32; static const size_t permanentNodeSize = 32768; - size_t over = vsize % permanentAlignment; - if (over) - over = permanentAlignment - over; + vSize = IntUtil::alignTo(vSize, permanentAlignment); - size_t alignedSize = vsize + over; - AutoLock locked(_lock); - - PermanentNode* node = _permanent; + AutoLock locked(self->_lock); + PermanentNode* node = self->_permanent; // Try to find space in allocated chunks. - while (node && alignedSize > node->getAvailable()) + while (node && vSize > node->getAvailable()) node = node->prev; // Or allocate new node. if (node == NULL) { size_t nodeSize = permanentNodeSize; - if (vsize > nodeSize) - nodeSize = vsize; + if (nodeSize < vSize) + nodeSize = vSize; node = static_cast(ASMJIT_ALLOC(sizeof(PermanentNode))); @@ -568,7 +738,7 @@ void* VMemPrivate::allocPermanent(size_t vsize) { if (node == NULL) return NULL; - node->mem = allocVirtualMemory(nodeSize, &node->size); + node->mem = vMemMgrAllocVMem(self, nodeSize, &node->size); // Out of memory. if (node->mem == NULL) { @@ -577,54 +747,60 @@ void* VMemPrivate::allocPermanent(size_t vsize) { } node->used = 0; - node->prev = _permanent; - _permanent = node; + node->prev = self->_permanent; + self->_permanent = node; } // Finally, copy function code to our space we reserved for. uint8_t* result = node->mem + node->used; // Update Statistics. - node->used += alignedSize; - _used += alignedSize; + node->used += vSize; + self->_usedBytes += vSize; // Code can be null to only reserve space for code. return static_cast(result); } -void* VMemPrivate::allocFreeable(size_t vsize) { - size_t i; // Current index. - size_t need; // How many we need to be freed. +static void* vMemMgrAllocFreeable(VMemMgr* self, size_t vSize) { + // Current index. + size_t i; + + // How many we need to be freed. + size_t need; size_t minVSize; - // Align to 32 bytes (our default alignment). - vsize = (vsize + 31) & ~(size_t)31; - if (vsize == 0) return NULL; + // Align to 32 bytes by default. + vSize = IntUtil::alignTo(vSize, 32); + if (vSize == 0) + return NULL; - AutoLock locked(_lock); - MemNode* node = _optimal; - - minVSize = _newChunkSize; + AutoLock locked(self->_lock); + MemNode* node = self->_optimal; + minVSize = self->_blockSize; // Try to find memory block in existing nodes. while (node) { // Skip this node? - if ((node->getAvailable() < vsize) || (node->largestBlock < vsize && node->largestBlock != 0)) { + if ((node->getAvailable() < vSize) || (node->largestBlock < vSize && node->largestBlock != 0)) { MemNode* next = node->next; - if (node->getAvailable() < minVSize && node == _optimal && next) _optimal = next; + + if (node->getAvailable() < minVSize && node == self->_optimal && next) + self->_optimal = next; + node = next; continue; } - size_t* up = node->baUsed; // Current ubits address. - size_t ubits; // Current ubits[0] value. - size_t bit; // Current bit mask. - size_t blocks = node->blocks; // Count of blocks in node. - size_t cont = 0; // How many bits are currently freed in find loop. - size_t maxCont = 0; // Largest continuous block (bits count). + size_t* up = node->baUsed; // Current ubits address. + size_t ubits; // Current ubits[0] value. + size_t bit; // Current bit mask. + size_t blocks = node->blocks; // Count of blocks in node. + size_t cont = 0; // How many bits are currently freed in find loop. + size_t maxCont = 0; // Largest continuous block (bits count). size_t j; - need = M_DIV((vsize + node->density - 1), node->density); + need = M_DIV((vSize + node->density - 1), node->density); i = 0; // Try to find node that is large enough. @@ -633,7 +809,8 @@ void* VMemPrivate::allocFreeable(size_t vsize) { // Fast skip used blocks. if (ubits == ~(size_t)0) { - if (cont > maxCont) maxCont = cont; + if (cont > maxCont) + maxCont = cont; cont = 0; i += kBitsPerEntity; @@ -647,7 +824,12 @@ void* VMemPrivate::allocFreeable(size_t vsize) { for (j = 0, bit = 1; j < max; bit <<= 1) { j++; if ((ubits & bit) == 0) { - if (++cont == need) { i += j; i -= cont; goto _Found; } + if (++cont == need) { + i += j; + i -= cont; + goto _Found; + } + continue; } @@ -658,32 +840,34 @@ void* VMemPrivate::allocFreeable(size_t vsize) { i += kBitsPerEntity; } - // Because we traversed entire node, we can set largest node size that - // will be used to cache next traversing.. + // Because we traversed the entire node, we can set largest node size that + // will be used to cache next traversing. node->largestBlock = maxCont * node->density; node = node->next; } // If we are here, we failed to find existing memory block and we must - // allocate new. + // allocate a new one. { - size_t chunkSize = _newChunkSize; - if (chunkSize < vsize) chunkSize = vsize; + size_t blockSize = self->_blockSize; + if (blockSize < vSize) + blockSize = vSize; - node = createNode(chunkSize, _newChunkDensity); - if (node == NULL) return NULL; + node = vMemMgrCreateNode(self, blockSize, self->_blockDensity); + if (node == NULL) + return NULL; // Update binary tree. - insertNode(node); - ASMJIT_ASSERT(checkTree()); + vMemMgrInsertNode(self, node); + ASMJIT_ASSERT(vMemMgrCheckTree(self)); // Alloc first node at start. i = 0; - need = (vsize + node->density - 1) / node->density; + need = (vSize + node->density - 1) / node->density; // Update statistics. - _allocated += node->size; + self->_allocatedBytes += node->size; } _Found: @@ -696,26 +880,114 @@ _Found: size_t u = need * node->density; node->used += u; node->largestBlock = 0; - _used += u; + self->_usedBytes += u; } // And return pointer to allocated memory. uint8_t* result = node->mem + i * node->density; - ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vsize); + ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize); return result; } -Error VMemPrivate::release(void* address) { - if (address == NULL) +//! \internal +//! +//! Reset the whole `VMemMgr` instance, freeing all heap memory allocated an +//! virtual memory allocated unless `keepVirtualMemory` is true (and this is +//! only used when writing data to a remote process). +static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) { + MemNode* node = self->_first; + + while (node != NULL) { + MemNode* next = node->next; + + if (!keepVirtualMemory) + vMemMgrReleaseVMem(self, node->mem, node->size); + + ASMJIT_FREE(node->baUsed); + ASMJIT_FREE(node); + + node = next; + } + + self->_allocatedBytes = 0; + self->_usedBytes = 0; + + self->_root = NULL; + self->_first = NULL; + self->_last = NULL; + self->_optimal = NULL; +} + +// ============================================================================ +// [asmjit::VMemMgr - Construction / Destruction] +// ============================================================================ + +#if !defined(ASMJIT_OS_WINDOWS) +VMemMgr::VMemMgr() +#else +VMemMgr::VMemMgr(HANDLE hProcess) : + _hProcess(vMemGet().getSafeProcessHandle(hProcess)) +#endif // ASMJIT_OS_WINDOWS +{ + + _blockSize = VMemUtil::getPageGranularity(); + _blockDensity = 64; + + _allocatedBytes = 0; + _usedBytes = 0; + + _root = NULL; + _first = NULL; + _last = NULL; + _optimal = NULL; + + _permanent = NULL; + _keepVirtualMemory = false; +} + +VMemMgr::~VMemMgr() { + // Freeable memory cleanup - Also frees the virtual memory if configured to. + vMemMgrReset(this, _keepVirtualMemory); + + // Permanent memory cleanup - Never frees the virtual memory. + PermanentNode* node = _permanent; + while (node) { + PermanentNode* prev = node->prev; + ASMJIT_FREE(node); + node = prev; + } +} + +// ============================================================================ +// [asmjit::VMemMgr - Reset] +// ============================================================================ + +void VMemMgr::reset() { + vMemMgrReset(this, false); +} + +// ============================================================================ +// [asmjit::VMemMgr - Alloc / Release] +// ============================================================================ + +void* VMemMgr::alloc(size_t size, uint32_t type) { + if (type == kVMemAllocPermanent) + return vMemMgrAllocPermanent(this, size); + else + return vMemMgrAllocFreeable(this, size); +} + +Error VMemMgr::release(void* p) { + if (p == NULL) return kErrorOk; AutoLock locked(_lock); + MemNode* node = vMemMgrFindNodeByPtr(this, static_cast(p)); - MemNode* node = findPtr((uint8_t*)address); if (node == NULL) return kErrorInvalidArgument; - size_t offset = (size_t)((uint8_t*)address - (uint8_t*)node->mem); + size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem); size_t bitpos = M_DIV(offset, node->density); size_t i = (bitpos / kBitsPerEntity); @@ -768,44 +1040,44 @@ Error VMemPrivate::release(void* address) { node->largestBlock = cont; node->used -= cont; - _used -= cont; + _usedBytes -= cont; // If page is empty, we can free it. if (node->used == 0) { // Free memory associated with node (this memory is not accessed // anymore so it's safe). - freeVirtualMemory(node->mem, node->size); + vMemMgrReleaseVMem(this, node->mem, node->size); ASMJIT_FREE(node->baUsed); node->baUsed = NULL; node->baCont = NULL; // Statistics. - _allocated -= node->size; + _allocatedBytes -= node->size; // Remove node. This function can return different node than // passed into, but data is copied into previous node if needed. - ASMJIT_FREE(removeNode(node)); - ASMJIT_ASSERT(checkTree()); + ASMJIT_FREE(vMemMgrRemoveNode(this, node)); + ASMJIT_ASSERT(vMemMgrCheckTree(this)); } return kErrorOk; } -Error VMemPrivate::shrink(void* address, size_t used) { - if (address == NULL) +Error VMemMgr::shrink(void* p, size_t used) { + if (p == NULL) return kErrorOk; if (used == 0) - return release(address); + return release(p); AutoLock locked(_lock); - MemNode* node = findPtr((uint8_t*)address); + MemNode* node = vMemMgrFindNodeByPtr(this, (uint8_t*)p); if (node == NULL) return kErrorInvalidArgument; - size_t offset = (size_t)((uint8_t*)address - (uint8_t*)node->mem); + size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem); size_t bitpos = M_DIV(offset, node->density); size_t i = (bitpos / kBitsPerEntity); @@ -869,356 +1141,11 @@ _EnterFreeLoop: node->largestBlock = cont; node->used -= cont; - _used -= cont; + _usedBytes -= cont; return kErrorOk; } -// ============================================================================ -// [asmjit::VMemPrivate - NodeList RB-Tree] -// ============================================================================ - -static int rbAssert(RbNode* root) { - if (root == NULL) - return 1; - - RbNode* ln = root->node[0]; - RbNode* rn = root->node[1]; - - // Red violation. - ASMJIT_ASSERT( !(rbIsRed(root) && (rbIsRed(ln) || rbIsRed(rn))) ); - - int lh = rbAssert(ln); - int rh = rbAssert(rn); - - // Invalid btree. - ASMJIT_ASSERT(ln == NULL || ln->mem < root->mem); - ASMJIT_ASSERT(rn == NULL || rn->mem > root->mem); - - // Black violation. - ASMJIT_ASSERT( !(lh != 0 && rh != 0 && lh != rh) ); - - // Only count black links. - if (lh != 0 && rh != 0) - return rbIsRed(root) ? lh : lh + 1; - else - return 0; -} - -static ASMJIT_INLINE RbNode* rbRotateSingle(RbNode* root, int dir) { - RbNode* save = root->node[!dir]; - - root->node[!dir] = save->node[dir]; - save->node[dir] = root; - - root->red = 1; - save->red = 0; - - return save; -} - -static ASMJIT_INLINE RbNode* rbRotateDouble(RbNode* root, int dir) { - root->node[!dir] = rbRotateSingle(root->node[!dir], !dir); - return rbRotateSingle(root, dir); -} - -bool VMemPrivate::checkTree() { - return rbAssert(_root) > 0; -} - -void VMemPrivate::insertNode(MemNode* node) { - if (_root == NULL) { - // Empty tree case. - _root = node; - } - else { - // False tree root. - RbNode head = { 0 }; - - // Grandparent & parent. - RbNode* g = NULL; - RbNode* t = &head; - - // Iterator & parent. - RbNode* p = NULL; - RbNode* q = t->node[1] = _root; - - int dir = 0, last; - - // Search down the tree. - for (;;) { - if (q == NULL) { - // Insert new node at the bottom. - q = node; - p->node[dir] = node; - } - else if (rbIsRed(q->node[0]) && rbIsRed(q->node[1])) { - // Color flip. - q->red = 1; - q->node[0]->red = 0; - q->node[1]->red = 0; - } - - // Fix red violation. - if (rbIsRed(q) && rbIsRed(p)) { - int dir2 = t->node[1] == g; - t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last); - } - - // Stop if found. - if (q == node) - break; - - last = dir; - dir = q->mem < node->mem; - - // Update helpers. - if (g != NULL) - t = g; - - g = p; - p = q; - q = q->node[dir]; - } - - // Update root. - _root = static_cast(head.node[1]); - } - - // Make root black. - _root->red = 0; - - // Link with others. - node->prev = _last; - - if (_first == NULL) { - _first = node; - _last = node; - _optimal = node; - } - else { - node->prev = _last; - _last->next = node; - _last = node; - } -} - -MemNode* VMemPrivate::removeNode(MemNode* node) { - // False tree root. - RbNode head = { 0 }; - - // Helpers. - RbNode* q = &head; - RbNode* p = NULL; - RbNode* g = NULL; - - // Found item. - RbNode* f = NULL; - int dir = 1; - - // Set up. - q->node[1] = _root; - - // Search and push a red down. - while (q->node[dir] != NULL) { - int last = dir; - - // Update helpers. - g = p; - p = q; - q = q->node[dir]; - dir = q->mem < node->mem; - - // Save found node. - if (q == node) - f = q; - - // Push the red node down. - if (!rbIsRed(q) && !rbIsRed(q->node[dir])) { - if (rbIsRed(q->node[!dir])) { - p = p->node[last] = rbRotateSingle(q, dir); - } - else if (!rbIsRed(q->node[!dir])) { - RbNode* s = p->node[!last]; - - if (s != NULL) { - if (!rbIsRed(s->node[!last]) && !rbIsRed(s->node[last])) { - // Color flip. - p->red = 0; - s->red = 1; - q->red = 1; - } - else { - int dir2 = g->node[1] == p; - - if (rbIsRed(s->node[last])) - g->node[dir2] = rbRotateDouble(p, last); - else if (rbIsRed(s->node[!last])) - g->node[dir2] = rbRotateSingle(p, last); - - // Ensure correct coloring. - q->red = g->node[dir2]->red = 1; - g->node[dir2]->node[0]->red = 0; - g->node[dir2]->node[1]->red = 0; - } - } - } - } - } - - // Replace and remove. - ASMJIT_ASSERT(f != NULL); - ASMJIT_ASSERT(f != &head); - ASMJIT_ASSERT(q != &head); - - if (f != q) { - ASMJIT_ASSERT(f != &head); - static_cast(f)->fillData(static_cast(q)); - } - - p->node[p->node[1] == q] = q->node[q->node[0] == NULL]; - - // Update root and make it black. - _root = static_cast(head.node[1]); - if (_root != NULL) - _root->red = 0; - - // Unlink. - MemNode* next = static_cast(q)->next; - MemNode* prev = static_cast(q)->prev; - - if (prev) - prev->next = next; - else - _first = next; - - if (next) - next->prev = prev; - else - _last = prev; - - if (_optimal == q) - _optimal = prev ? prev : next; - - return static_cast(q); -} - -MemNode* VMemPrivate::findPtr(uint8_t* mem) { - MemNode* node = _root; - - while (node != NULL) { - uint8_t* nodeMem = node->mem; - - // Go left. - if (mem < nodeMem) { - node = static_cast(node->node[0]); - continue; - } - - // Go right. - uint8_t* nodeEnd = nodeMem + node->size; - if (mem >= nodeEnd) { - node = static_cast(node->node[1]); - continue; - } - - // Match. - break; - } - - return node; -} - -// ============================================================================ -// [asmjit::VMemMgr - Construction / Destruction] -// ============================================================================ - -#if !defined(ASMJIT_OS_WINDOWS) -VMemMgr::VMemMgr() { - VMemPrivate* d = new(std::nothrow) VMemPrivate(); - _d = static_cast(d); -} -#else -VMemMgr::VMemMgr() { - HANDLE hProcess = GetCurrentProcess(); - VMemPrivate* d = new(std::nothrow) VMemPrivate(hProcess); - _d = static_cast(d); -} - -VMemMgr::VMemMgr(HANDLE hProcess) { - VMemPrivate* d = new(std::nothrow) VMemPrivate(hProcess); - _d = static_cast(d); -} -#endif // ASMJIT_OS_WINDOWS - -VMemMgr::~VMemMgr() { - VMemPrivate* d = static_cast(_d); - delete d; -} - -// ============================================================================ -// [asmjit::VMemMgr - Reset] -// ============================================================================ - -void VMemMgr::reset() { - VMemPrivate* d = static_cast(_d); - return d->reset(false); -} - -// ============================================================================ -// [asmjit::VMemMgr - Accessors] -// ============================================================================ - -#if defined(ASMJIT_OS_WINDOWS) -HANDLE VMemMgr::getProcessHandle() const { - VMemPrivate* d = static_cast(_d); - return d->_hProcess; -} -#endif // ASMJIT_OS_WINDOWS - -size_t VMemMgr::getUsedBytes() const { - VMemPrivate* d = static_cast(_d); - return d->_used; -} - -size_t VMemMgr::getAllocatedBytes() const { - VMemPrivate* d = static_cast(_d); - return d->_allocated; -} - -bool VMemMgr::getKeepVirtualMemory() const { - VMemPrivate* d = static_cast(_d); - return d->_keepVirtualMemory; -} - -void VMemMgr::setKeepVirtualMemory(bool keepVirtualMemory) { - VMemPrivate* d = static_cast(_d); - d->_keepVirtualMemory = keepVirtualMemory; -} - -// ============================================================================ -// [asmjit::VMemMgr - Alloc / Release] -// ============================================================================ - -void* VMemMgr::alloc(size_t size, uint32_t type) { - VMemPrivate* d = static_cast(_d); - - if (type == kVMemAllocPermanent) - return d->allocPermanent(size); - else - return d->allocFreeable(size); -} - -Error VMemMgr::release(void* address) { - VMemPrivate* d = static_cast(_d); - return d->release(address); -} - -Error VMemMgr::shrink(void* address, size_t used) { - VMemPrivate* d = static_cast(_d); - return d->shrink(address, used); -} - // ============================================================================ // [asmjit::VMem - Test] // ============================================================================ diff --git a/src/asmjit/base/vmem.h b/src/asmjit/base/vmem.h index 0b115b6..c3ecd7d 100644 --- a/src/asmjit/base/vmem.h +++ b/src/asmjit/base/vmem.h @@ -10,6 +10,7 @@ // [Dependencies] #include "../base/error.h" +#include "../base/lock.h" // [Api-Begin] #include "../apibegin.h" @@ -59,12 +60,12 @@ ASMJIT_ENUM(kVMemFlags) { //! on POSIX. `VirtualAlloc()` and `mmap()` documentation provide a detailed //! overview on how to use a platform specific APIs. struct VMemUtil { - //! Get the alignment guaranteed by alloc(). - static ASMJIT_API size_t getAlignment(); - - //! Get size of the single page. + //! Get a size/alignment of a single virtual memory page. static ASMJIT_API size_t getPageSize(); + //! Get a recommended granularity for a single `alloc` call. + static ASMJIT_API size_t getPageGranularity(); + //! Allocate virtual memory. //! //! Pages are readable/writeable, but they are not guaranteed to be @@ -72,19 +73,21 @@ struct VMemUtil { //! allocated memory, or NULL on failure. static ASMJIT_API void* alloc(size_t length, size_t* allocated, uint32_t flags); - //! Free memory allocated by `alloc()`. - static ASMJIT_API void release(void* addr, size_t length); - #if defined(ASMJIT_OS_WINDOWS) //! Allocate virtual memory of `hProcess`. //! //! \note This function is Windows specific. static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags); +#endif // ASMJIT_OS_WINDOWS - //! Free virtual memory of `hProcess`. + //! Free memory allocated by `alloc()`. + static ASMJIT_API Error release(void* addr, size_t length); + +#if defined(ASMJIT_OS_WINDOWS) + //! Release virtual memory of `hProcess`. //! //! \note This function is Windows specific. - static ASMJIT_API void releaseProcessMemory(HANDLE hProcess, void* addr, size_t length); + static ASMJIT_API Error releaseProcessMemory(HANDLE hProcess, void* addr, size_t length); #endif // ASMJIT_OS_WINDOWS }; @@ -99,15 +102,16 @@ struct VMemMgr { // [Construction / Destruction] // -------------------------------------------------------------------------- +#if !defined(ASMJIT_OS_WINDOWS) //! Create a `VMemMgr` instance. ASMJIT_API VMemMgr(); - -#if defined(ASMJIT_OS_WINDOWS) - //! Create a `VMemMgr` instance for `hProcess`. +#else + //! Create a `VMemMgr` instance. //! - //! This is a specialized version of constructor available only for windows - //! and usable to alloc/free memory of a different process. - explicit ASMJIT_API VMemMgr(HANDLE hProcess); + //! \note When running on Windows it's possible to specify a `hProcess` to + //! be used for memory allocation. This allows to allocate memory of remote + //! process. + ASMJIT_API VMemMgr(HANDLE hProcess = static_cast(0)); #endif // ASMJIT_OS_WINDOWS //! Destroy the `VMemMgr` instance and free all blocks. @@ -126,18 +130,27 @@ struct VMemMgr { #if defined(ASMJIT_OS_WINDOWS) //! Get the handle of the process memory manager is bound to. - ASMJIT_API HANDLE getProcessHandle() const; + ASMJIT_INLINE HANDLE getProcessHandle() const { + return _hProcess; + } #endif // ASMJIT_OS_WINDOWS - //! Get how many bytes are currently used. - ASMJIT_API size_t getUsedBytes() const; //! Get how many bytes are currently allocated. - ASMJIT_API size_t getAllocatedBytes() const; + ASMJIT_INLINE size_t getAllocatedBytes() const { + return _allocatedBytes; + } + + //! Get how many bytes are currently used. + ASMJIT_INLINE size_t getUsedBytes() const { + return _usedBytes; + } //! Get whether to keep allocated memory after the `VMemMgr` is destroyed. //! //! \sa \ref setKeepVirtualMemory. - ASMJIT_API bool getKeepVirtualMemory() const; + ASMJIT_INLINE bool getKeepVirtualMemory() const { + return _keepVirtualMemory; + } //! Set whether to keep allocated memory after memory manager is //! destroyed. @@ -151,7 +164,9 @@ struct VMemMgr { //! \note Memory allocated with kVMemAllocPermanent is always kept. //! //! \sa \ref getKeepVirtualMemory. - ASMJIT_API void setKeepVirtualMemory(bool keepVirtualMemory); + ASMJIT_INLINE void setKeepVirtualMemory(bool keepVirtualMemory) { + _keepVirtualMemory = keepVirtualMemory; + } // -------------------------------------------------------------------------- // [Alloc / Release] @@ -165,19 +180,53 @@ struct VMemMgr { ASMJIT_API void* alloc(size_t size, uint32_t type = kVMemAllocFreeable); //! Free previously allocated memory at a given `address`. - ASMJIT_API Error release(void* address); + ASMJIT_API Error release(void* p); - //! Free some tail memory. - ASMJIT_API Error shrink(void* address, size_t used); + //! Free extra memory allocated with `p`. + ASMJIT_API Error shrink(void* p, size_t used); // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- +#if defined(ASMJIT_OS_WINDOWS) + //! Process passed to `VirtualAllocEx` and `VirtualFree`. + HANDLE _hProcess; +#endif // ASMJIT_OS_WINDOWS + + //! Lock to enable thread-safe functionality. + Lock _lock; + + //! Default block size. + size_t _blockSize; + //! Default block density. + size_t _blockDensity; + + // Whether to keep virtual memory after destroy. + bool _keepVirtualMemory; + + //! How many bytes are currently allocated. + size_t _allocatedBytes; + //! How many bytes are currently used. + size_t _usedBytes; + //! \internal - //! - //! Pointer to a private data hidden from the public API. - void* _d; + //! \{ + + struct RbNode; + struct MemNode; + struct PermanentNode; + + // Memory nodes root. + MemNode* _root; + // Memory nodes list. + MemNode* _first; + MemNode* _last; + MemNode* _optimal; + // Permanent memory. + PermanentNode* _permanent; + + //! \} }; //! \} diff --git a/src/asmjit/base/zone.cpp b/src/asmjit/base/zone.cpp index 3384c70..f182392 100644 --- a/src/asmjit/base/zone.cpp +++ b/src/asmjit/base/zone.cpp @@ -34,41 +34,46 @@ Zone::Zone(size_t blockSize) { } Zone::~Zone() { - reset(); + reset(true); } // ============================================================================ -// [asmjit::Zone - Clear / Reset] +// [asmjit::Zone - Reset] // ============================================================================ -void Zone::clear() { +void Zone::reset(bool releaseMemory) { Block* cur = _block; // Can't be altered. if (cur == &Zone_zeroBlock) return; - while (cur->prev != NULL) - cur = cur->prev; + if (releaseMemory) { + // Since cur can be in the middle of the double-linked list, we have to + // traverse to both directions `prev` and `next` separately. + Block* next = cur->next; + do { + Block* prev = cur->prev; + ASMJIT_FREE(cur); + cur = prev; + } while (cur != NULL); - cur->pos = cur->data; - _block = cur; -} + cur = next; + while (cur != NULL) { + next = cur->next; + ASMJIT_FREE(cur); + cur = next; + } -void Zone::reset() { - Block* cur = _block; + _block = const_cast(&Zone_zeroBlock); + } + else { + while (cur->prev != NULL) + cur = cur->prev; - // Can't be altered. - if (cur == &Zone_zeroBlock) - return; - - do { - Block* prev = cur->prev; - ASMJIT_FREE(cur); - cur = prev; - } while (cur != NULL); - - _block = const_cast(&Zone_zeroBlock); + cur->pos = cur->data; + _block = cur; + } } // ============================================================================ @@ -83,7 +88,7 @@ void* Zone::_alloc(size_t size) { // in the current block, see `alloc()` implementation for more details. ASMJIT_ASSERT(curBlock == &Zone_zeroBlock || curBlock->getRemainingSize() < size); - // If the `Zone` has been cleared the current block doesn't have to be the + // If the `Zone` has been reset the current block doesn't have to be the // last one. Check if there is a block that can be used instead of allocating // a new one. If there is a `next` block it's completely unused, we don't have // to check for remaining bytes. diff --git a/src/asmjit/base/zone.h b/src/asmjit/base/zone.h index b55ac9b..3578902 100644 --- a/src/asmjit/base/zone.h +++ b/src/asmjit/base/zone.h @@ -33,7 +33,7 @@ namespace asmjit { //! Zone memory allocators are designed to allocate data of short lifetime. The //! data used by `Assembler` and `Compiler` has a very short lifetime, thus, is //! allocated by `Zone`. The advantage is that `Zone` can free all of the data -//! allocated at once by calling `clear()` or `reset()`. +//! allocated at once by calling `reset()` or by `Zone` destructor. struct Zone { // -------------------------------------------------------------------------- // [Block] @@ -94,23 +94,17 @@ struct Zone { //! Destroy the `Zone` instance. //! //! This will destroy the `Zone` instance and release all blocks of memory - //! allocated by it. It performs implicit `reset()`. + //! allocated by it. It performs implicit `reset(true)`. ASMJIT_API ~Zone(); // -------------------------------------------------------------------------- - // [Clear / Reset] + // [Reset] // -------------------------------------------------------------------------- - //! Clear the `Zone`, but keep all blocks allocated so they can be reused. + //! Reset the `Zone` invalidating all blocks allocated. //! - //! This is the preferred way of invalidating objects allocated by `Zone`. - ASMJIT_API void clear(); - - //! Reset the `Zone` releasing all blocks allocated. - //! - //! Calling `reset()` does complete cleanup, it releases all blocks allocated - //! by `Zone`. - ASMJIT_API void reset(); + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); // -------------------------------------------------------------------------- // [Accessors] @@ -128,8 +122,8 @@ struct Zone { //! Allocate `size` bytes of memory. //! //! Pointer returned is valid until the `Zone` instance is destroyed or reset - //! by calling `clear()` or `reset()`. If you plan to make an instance of C++ - //! from the given pointer use placement `new` and `delete` operators: + //! by calling `reset()`. If you plan to make an instance of C++ from the + //! given pointer use placement `new` and `delete` operators: //! //! ~~~ //! using namespace asmjit; diff --git a/src/asmjit/build.h b/src/asmjit/build.h index 04ef205..8cb0348 100644 --- a/src/asmjit/build.h +++ b/src/asmjit/build.h @@ -9,9 +9,11 @@ #define _ASMJIT_BUILD_H // [Include] -#if !defined(ASMJIT_CONFIG_FILE) -#include "./config.h" -#endif // !ASMJIT_CONFIG_FILE +#if defined(ASMJIT_CONFIG_FILE) +# include ASMJIT_CONFIG_FILE +#else +# include "./config.h" +#endif // ASMJIT_CONFIG_FILE // Turn off deprecation warnings when compiling AsmJit. #if defined(ASMJIT_EXPORTS) && defined(_MSC_VER) @@ -35,9 +37,9 @@ // [asmjit::build - Sanity] // ============================================================================ -#if defined(ASMJIT_DISABLE_INST_NAMES) && !defined(ASMJIT_DISABLE_LOGGER) -# error "ASMJIT_DISABLE_INST_NAMES requires ASMJIT_DISABLE_LOGGER to be defined." -#endif // ASMJIT_DISABLE_INST_NAMES && !ASMJIT_DISABLE_LOGGER +#if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER) +# error "ASMJIT_DISABLE_NAMES requires ASMJIT_DISABLE_LOGGER to be defined." +#endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER // ============================================================================ // [asmjit::build - OS] @@ -127,35 +129,56 @@ # define ASMJIT_STATIC #endif // ASMJIT_EMBED && !ASMJIT_STATIC -#if !defined(ASMJIT_API) -# if defined(ASMJIT_STATIC) -# define ASMJIT_API -# elif defined(ASMJIT_OS_WINDOWS) -# if defined(__GNUC__) || defined(__clang__) -# if defined(ASMJIT_EXPORTS) -# define ASMJIT_API __attribute__((dllexport)) -# else -# define ASMJIT_API __attribute__((dllimport)) -# endif -# elif defined(ASMJIT_EXPORTS) +#if defined(ASMJIT_STATIC) +# define ASMJIT_API +#elif defined(ASMJIT_OS_WINDOWS) +# if (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__) +# if defined(ASMJIT_EXPORTS) +# define ASMJIT_API __attribute__((dllexport)) +# else +# define ASMJIT_API __attribute__((dllimport)) +# endif // ASMJIT_EXPORTS +# else +# if defined(ASMJIT_EXPORTS) # define ASMJIT_API __declspec(dllexport) # else # define ASMJIT_API __declspec(dllimport) # endif -# else -# if defined(__GNUC__) -# if __GNUC__ >= 4 -# define ASMJIT_API __attribute__((visibility("default"))) -# define ASMJIT_VAR extern ASMJIT_API -# endif -# endif # endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) +# define ASMJIT_API __attribute__((visibility("default"))) +#endif + +#if !defined(ASMJIT_API) +# define ASMJIT_API #endif // ASMJIT_API +// This is basically a workaround. When using MSVC and marking class as DLL +// export everything is exported, which is unwanted since there are many +// inlines which mimic instructions. MSVC automatically exports typeinfo and +// vtable if at least one symbol of that class is exported. However, GCC has +// some strange behavior that even if one or more symbol is exported it doesn't +// export `typeinfo` unless the class itself is marked as "visibility(default)". +#if !defined(ASMJIT_OS_WINDOWS) && (defined(__GNUC__) || defined (__clang__)) +# define ASMJIT_VCLASS ASMJIT_API +#else +# define ASMJIT_VCLASS +#endif + #if !defined(ASMJIT_VAR) # define ASMJIT_VAR extern ASMJIT_API #endif // !ASMJIT_VAR +#if defined(_MSC_VER) +# define ASMJIT_INLINE __forceinline +#elif defined(__clang__) +# define ASMJIT_INLINE inline __attribute__((always_inline)) __attribute__((visibility("hidden"))) +#elif defined(__GNUC__) +# define ASMJIT_INLINE inline __attribute__((always_inline)) +#else +# define ASMJIT_INLINE inline +#endif + #if defined(ASMJIT_HOST_X86) # if defined(__GNUC__) || defined(__clang__) # define ASMJIT_REGPARM_1 __attribute__((regparm(1))) @@ -165,9 +188,9 @@ # define ASMJIT_STDCALL __attribute__((stdcall)) # define ASMJIT_CDECL __attribute__((cdecl)) # else -# define ASMJIT_FASTCALL __fastcall -# define ASMJIT_STDCALL __stdcall -# define ASMJIT_CDECL __cdecl +# define ASMJIT_FASTCALL __fastcall +# define ASMJIT_STDCALL __stdcall +# define ASMJIT_CDECL __cdecl # endif #else # define ASMJIT_FASTCALL @@ -175,14 +198,6 @@ # define ASMJIT_CDECL #endif // ASMJIT_HOST_X86 -#if defined(_MSC_VER) -# define ASMJIT_INLINE __forceinline -#elif (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__) -# define ASMJIT_INLINE inline __attribute__((always_inline)) -#else -# define ASMJIT_INLINE inline -#endif - // ============================================================================ // [asmjit::build - Enum] // ============================================================================ @@ -217,14 +232,23 @@ # define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_)) #endif +// ============================================================================ +// [asmjit::build - BLEND_OFFSET_OF] +// ============================================================================ + +//! Cross-platform solution to get offset of `_Field_` in `_Struct_`. +#define ASMJIT_OFFSET_OF(_Struct_, _Field_) \ + ((size_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1) + // ============================================================================ // [asmjit::build - ASMJIT_ARRAY_SIZE] // ============================================================================ -#define ASMJIT_ARRAY_SIZE(_Array_) (sizeof(_Array_) / sizeof(*_Array_)) +#define ASMJIT_ARRAY_SIZE(_Array_) \ + (sizeof(_Array_) / sizeof(*_Array_)) // ============================================================================ -// [asmjit::build - ASMJIT_DEBUG] +// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE] // ============================================================================ // If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be @@ -236,6 +260,18 @@ # endif // _DEBUG #endif // !ASMJIT_DEBUG && !ASMJIT_RELEASE +// ASMJIT_TRACE is only used by sources and private headers. It's safe to make +// it unavailable outside of AsmJit. +#if defined(ASMJIT_EXPORTS) +# if defined(ASMJIT_TRACE) +# define ASMJIT_TSEC(_Section_) _Section_ +# define ASMJIT_TLOG(...) ::printf(__VA_ARGS__) +# else +# define ASMJIT_TSEC(_Section_) do {} while(0) +# define ASMJIT_TLOG(...) do {} while(0) +# endif // ASMJIT_TRACE +#endif // ASMJIT_EXPORTS + // ============================================================================ // [asmjit::build - ASMJIT_UNUSED] // ============================================================================ @@ -266,9 +302,9 @@ public: // [asmjit::build - StdInt] // ============================================================================ -#if defined(__MINGW32__) || defined(__MINGW64__) +#if defined(__MINGW32__) # include -#endif // __MINGW32__ || __MINGW64__ +#endif // __MINGW32__ #if defined(_MSC_VER) && (_MSC_VER < 1600) # if !defined(ASMJIT_SUPRESS_STD_TYPES) @@ -329,9 +365,9 @@ typedef unsigned __int64 uint64_t; // [asmjit::build - Test] // ============================================================================ -// Include test if building for unit testing. +// Include a unit testing package if this is a `asmjit_test` build. #if defined(ASMJIT_TEST) -#include "./test/test.h" +#include "./test/broken.h" #endif // ASMJIT_TEST // [Guard] diff --git a/src/asmjit/config.h b/src/asmjit/config.h index cc7351c..cdd2565 100644 --- a/src/asmjit/config.h +++ b/src/asmjit/config.h @@ -10,37 +10,44 @@ // This file can be used to modify built-in features of AsmJit. AsmJit is by // default compiled only for host processor to enable JIT compilation. Both -// Assembler and Compiler code generators are compiled by default. However, any -// ASMJIT_BUILD_... flag can be defined to enable building of additional -// backends that can be used for remote code generation. +// Assembler and Compiler code generators are compiled by default. +// +// ASMJIT_BUILD_... flags can be defined to build additional backends that can +// be used for remote code generation. +// +// ASMJIT_DISABLE_... flags can be defined to disable standard features. These +// are handy especially when building asmjit statically and some features are +// not needed or unwanted (like Compiler). // ============================================================================ -// [AsmJit - Debugging] -// ============================================================================ - -// #define ASMJIT_DEBUG // Define to enable debug-mode. -// #define ASMJIT_RELEASE // Define to enable release-mode. - -// ============================================================================ -// [AsmJit - Library] +// [AsmJit - Build-Type] // ============================================================================ // #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC). // #define ASMJIT_STATIC // Define to enable static-library build. +// ============================================================================ +// [AsmJit - Build-Mode] +// ============================================================================ + +// #define ASMJIT_DEBUG // Define to enable debug-mode. +// #define ASMJIT_RELEASE // Define to enable release-mode. +// #define ASMJIT_TRACE // Define to enable tracing. + // ============================================================================ // [AsmJit - Features] // ============================================================================ // If none of these is defined AsmJit will select host architecture by default. - // #define ASMJIT_BUILD_X86 // Define to enable x86 instruction set (32-bit). // #define ASMJIT_BUILD_X64 // Define to enable x64 instruction set (64-bit). // #define ASMJIT_BUILD_HOST // Define to enable host instruction set. -// #define ASMJIT_DISABLE_COMPILER // Disable Compiler. +// AsmJit features are enabled by default. +// #define ASMJIT_DISABLE_COMPILER // Disable Compiler (completely). // #define ASMJIT_DISABLE_LOGGER // Disable Logger (completely). -// #define ASMJIT_DISABLE_INST_NAMES // Disable Instruction names (and API). +// #define ASMJIT_DISABLE_NAMES // Disable everything that uses strings + // (instruction names, error names, ...). // [Guard] #endif // _ASMJIT_CONFIG_H diff --git a/src/asmjit/contrib/winremoteruntime.cpp b/src/asmjit/contrib/winremoteruntime.cpp index 8d62f35..3a2fe53 100644 --- a/src/asmjit/contrib/winremoteruntime.cpp +++ b/src/asmjit/contrib/winremoteruntime.cpp @@ -37,7 +37,6 @@ WinRemoteRuntime::~WinRemoteRuntime() {} uint32_t WinRemoteRuntime::add(void** dest, BaseAssembler* assembler) { // Disallow generation of no code. size_t codeSize = assembler->getCodeSize(); - if (codeSize == 0) { *dest = NULL; return kErrorInvalidState; @@ -45,15 +44,13 @@ uint32_t WinRemoteRuntime::add(void** dest, BaseAssembler* assembler) { // Allocate temporary memory where the code will be stored and relocated. void* codeData = ASMJIT_ALLOC(codeSize); - if (codeData == NULL) { *dest = NULL; return kErrorNoHeapMemory; } - // Allocate a pernament remote process memory. + // Allocate a permanent remote process memory. void* processMemPtr = _memMgr.alloc(codeSize, kVMemAllocPermanent); - if (processMemPtr == NULL) { ASMJIT_FREE(codeData); *dest = NULL; diff --git a/src/asmjit/host.h b/src/asmjit/host.h index 408aa3d..48d8ce4 100644 --- a/src/asmjit/host.h +++ b/src/asmjit/host.h @@ -11,28 +11,49 @@ // [Dependencies - Core] #include "base.h" -// [Host - Helpers] -#define ASMJIT_USE_HOST(_Arch_) \ - namespace asmjit { \ - namespace host { \ - using namespace ::asmjit::_Arch_; \ - } \ - } +// ============================================================================ +// [asmjit::host - X86 / X64] +// ============================================================================ -// [Host - X86] -#if defined(ASMJIT_HOST_X86) +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) #include "x86.h" -ASMJIT_USE_HOST(x86) -#endif // ASMJIT_HOST_X86 -// [Host - X64] -#if defined(ASMJIT_HOST_X64) -#include "x86.h" -ASMJIT_USE_HOST(x64) -#endif // ASMJIT_HOST_X64 +namespace asmjit { -// [Host - Cleanup] -#undef ASMJIT_USE_HOST +// Define `asmjit::host` namespace wrapping `asmjit::x86`. +namespace host { using namespace ::asmjit::x86; } + +// Define host assembler. +typedef X86Assembler HostAssembler; + +// Define host operands. +typedef X86GpReg GpReg; +typedef X86FpReg FpReg; +typedef X86MmReg MmReg; +typedef X86XmmReg XmmReg; +typedef X86YmmReg YmmReg; +typedef X86SegReg SegReg; +typedef X86Mem Mem; + +// Define host utilities. +typedef X86CpuInfo HostCpuInfo; + +// Define host compiler and related. +#if !defined(ASMJIT_DISABLE_COMPILER) +typedef X86Compiler HostCompiler; +typedef X86CallNode HostCallNode; +typedef X86FuncDecl HostFuncDecl; +typedef X86FuncNode HostFuncNode; + +typedef X86GpVar GpVar; +typedef X86MmVar MmVar; +typedef X86XmmVar XmmVar; +typedef X86YmmVar YmmVar; +#endif // !ASMJIT_DISABLE_COMPILER + +} // asmjit namespace + +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 // [Guard] #endif // _ASMJIT_HOST_H diff --git a/src/asmjit/test/broken.cpp b/src/asmjit/test/broken.cpp new file mode 100644 index 0000000..ce2912f --- /dev/null +++ b/src/asmjit/test/broken.cpp @@ -0,0 +1,279 @@ +// [Broken] +// Lightweight Unit Testing for C++. +// +// [License] +// Public Domain (Unlicense) + +#include "./broken.h" + +// ============================================================================ +// [Broken - Global] +// ============================================================================ + +// Zero initialized globals. +struct BrokenGlobal { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + bool hasArg(const char* a) const { + int argc = _argc; + const char** argv = _argv; + + for (int i = 1; i < argc; i++) { + if (::strcmp(argv[i], a) == 0) + return true; + } + + return false; + } + + FILE* getFile() const { + return _file ? _file : stdout; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + // Application arguments. + int _argc; + const char** _argv; + + // Output file. + FILE* _file; + + // Current context. + const char* _currentFile; + int _currentLine; + + // Unit tests. + BrokenAPI::Unit* _unitList; + BrokenAPI::Unit* _unitRunning; +}; +static BrokenGlobal _brokenGlobal; + +// ============================================================================ +// [Broken - API] +// ============================================================================ + +// Get whether the string `a` starts with string `b`. +static bool BrokenAPI_startsWith(const char* a, const char* b) { + for (size_t i = 0; ; i++) { + if (b[i] == '\0') return true; + if (a[i] != b[i]) return false; + } +} + +// Get whether the strings `a` and `b` are equal, ignoring case and treating +// `-` as `_`. +static bool BrokenAPI_matchesFilter(const char* a, const char* b) { + for (size_t i = 0; ; i++) { + unsigned char ca = static_cast(a[i]); + unsigned char cb = static_cast(b[i]); + + // If filter is defined as wildcard the rest automatically matches. + if (cb == '*') + return true; + + if (ca == '-') ca = '_'; + if (cb == '-') cb = '_'; + + if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A'; + if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A'; + + if (ca != cb) + return false; + + if (ca == '\0') + return true; + } +} + +static bool BrokenAPI_canRun(BrokenAPI::Unit* unit) { + BrokenGlobal& global = _brokenGlobal; + + int i, argc = global._argc; + const char** argv = global._argv; + + const char* unitName = unit->name; + bool hasFilter = false; + + for (i = 1; i < argc; i++) { + const char* arg = argv[i]; + + if (BrokenAPI_startsWith(arg, "--run-") && ::strcmp(arg, "--run-all") != 0) { + hasFilter = true; + + if (BrokenAPI_matchesFilter(unitName, arg + 6)) + return true; + } + } + + // If no filter has been specified the default is to run. + return !hasFilter; +} + +static void BrokenAPI_runUnit(BrokenAPI::Unit* unit) { + BrokenAPI::info("Running %s", unit->name); + + _brokenGlobal._unitRunning = unit; + unit->entry(); + _brokenGlobal._unitRunning = NULL; +} + +static void BrokenAPI_runAll() { + BrokenAPI::Unit* unit = _brokenGlobal._unitList; + + if (unit != NULL) { + size_t count = 0; + + do { + if (BrokenAPI_canRun(unit)) { + BrokenAPI_runUnit(unit); + count++; + } + + unit = unit->next; + } while (unit != NULL); + + if (count) { + INFO("\nSuccess:"); + INFO(" All tests passed!"); + } + else { + INFO("\nWarning:"); + INFO(" No units matched the filter!"); + } + } + else { + INFO("\nWarning:"); + INFO(" No units defined!"); + } +} + +static void BrokenAPI_listAll() { + BrokenAPI::Unit* unit = _brokenGlobal._unitList; + + if (unit != NULL) { + INFO("Units:"); + do { + INFO(" %s", unit->name); + unit = unit->next; + } while (unit != NULL); + } + else { + INFO("Warning:"); + INFO(" No units defined!"); + } +} + +void BrokenAPI::add(Unit* unit) { + Unit** pPrev = &_brokenGlobal._unitList; + Unit* current = *pPrev; + + // C++ static initialization doesn't guarantee anything. We sort all units by + // name so the execution will always happen in deterministic order. + while (current != NULL) { + if (::strcmp(current->name, unit->name) >= 0) + break; + + pPrev = ¤t->next; + current = *pPrev; + } + + *pPrev = unit; + unit->next = current; +} + +void BrokenAPI::setOutputFile(FILE* file) { + BrokenGlobal& global = _brokenGlobal; + + global._file = file; +} + +void BrokenAPI::setContext(const char* file, int line) { + BrokenGlobal& global = _brokenGlobal; + + global._currentFile = file; + global._currentLine = line; +} + +int BrokenAPI::run(int argc, const char* argv[], + Entry onBeforeRun, + Entry onAfterRun) { + + BrokenGlobal& global = _brokenGlobal; + + global._argc = argc; + global._argv = argv; + + if (global.hasArg("--help")) { + INFO("Options:"); + INFO(" --help - print this usage"); + INFO(" --list - list all tests"); + INFO(" --run-... - run a test(s), trailing wildcards supported"); + INFO(" --run-all - run all tests"); + return 0; + } + + if (global.hasArg("--list")) { + BrokenAPI_listAll(); + return 0; + } + + if (onBeforeRun) + onBeforeRun(); + + // We don't care about filters here, it's implemented by `runAll`. + BrokenAPI_runAll(); + + if (onAfterRun) + onAfterRun(); + + return 0; +} + +void BrokenAPI::info(const char* fmt, ...) { + BrokenGlobal& global = _brokenGlobal; + FILE* dst = global.getFile(); + + const char* prefix = global._unitRunning ? " " : ""; + size_t len = ::strlen(fmt); + + if (len != 0) { + va_list ap; + va_start(ap, fmt); + ::fputs(prefix, dst); + ::vfprintf(dst, fmt, ap); + va_end(ap); + } + + if (len == 0 || fmt[len - 1] != '\n') + ::fputs("\n", dst); + + ::fflush(dst); +} + +void BrokenAPI::fail(const char* fmt, va_list ap) { + BrokenGlobal& global = _brokenGlobal; + FILE* dst = global.getFile(); + + ::fputs(" Failed!", dst); + if (fmt == NULL) + fmt = ""; + + size_t len = ::strlen(fmt); + if (len != 0) { + ::fputs(" ", dst); + ::vfprintf(dst, fmt, ap); + } + + if (len > 0 && fmt[len - 1] != '\n') + ::fputs("\n", dst); + + ::fprintf(dst, " File: %s (Line: %d)\n", global._currentFile, global._currentLine); + ::fflush(dst); + + ::exit(1); +} diff --git a/src/asmjit/test/broken.h b/src/asmjit/test/broken.h new file mode 100644 index 0000000..e141f07 --- /dev/null +++ b/src/asmjit/test/broken.h @@ -0,0 +1,115 @@ +// [Broken] +// Lightweight Unit Testing for C++. +// +// [License] +// Public Domain (Unlicense) + +// [Guard] +#ifndef BROKEN_INTERNAL_H +#define BROKEN_INTERNAL_H + +// [Dependencies - C] +#include +#include +#include +#include + +// If using Doxygen to document a source-code hide everything. Ideally this +// can be also done by a macro, but there is no global and widely used one. + +//! \internal +//! \{ + +// ============================================================================ +// [Broken - API] +// ============================================================================ + +struct BrokenAPI { + //! Test entry point. + typedef void (*Entry)(void); + + //! Test unit. + struct Unit { + const char* name; + Entry entry; + size_t finished; + Unit* next; + }; + + //! Automatic unit registration by using static initialization. + struct AutoUnit : Unit { + inline AutoUnit(const char* _name, Entry _entry) { + name = _name; + entry = _entry; + finished = false; + next = NULL; + + BrokenAPI::add(this); + } + }; + + //! Register a new test (called automatically by `AutoUnit` and `UNIT`). + static void add(Unit* unit); + + //! Set output file to `file`. + static void setOutputFile(FILE* file); + + //! Set the current context. + static void setContext(const char* file, int line); + + //! Initialize `Broken` framework. + //! + //! Returns `true` if `run()` should be called. + static int run(int argc, const char* argv[], + Entry onBeforeRun = (Entry)NULL, + Entry onAfterRun = (Entry)NULL); + + //! + template + static void expect(const T& exp, const char* fmt = NULL, ...) { + if (exp) + return; + + va_list ap; + va_start(ap, fmt); + fail(fmt, ap); + va_end(ap); + } + + //! Log message, adds automatically new line if not present. + static void info(const char* fmt, ...); + //! Called on `EXPECT()` failure. + static void fail(const char* fmt, va_list ap); +}; + +// ============================================================================ +// [Broken - Macros] +// ============================================================================ + +//! Define a unit. +//! +//! `_Name_` can only contain ASCII characters, numbers and underscore. It has +//! the same rules as identifiers in C and C++. +#define UNIT(_Name_) \ + static void unit_##_Name_##_entry(void); \ + \ + static ::BrokenAPI::AutoUnit unit_##_Name_##_autoinit( \ + #_Name_, unit_##_Name_##_entry); \ + \ + static void unit_##_Name_##_entry(void) + +//! Informative message printed to stdout. +#define INFO(...) \ + ::BrokenAPI::info(__VA_ARGS__) + +//! Expect `_Exp_` to be truthy, fail otherwise. +#define EXPECT(...) \ + do { \ + ::BrokenAPI::setContext(__FILE__, __LINE__); \ + ::BrokenAPI::expect(__VA_ARGS__); \ + } while(0) + +//! \} + +// [Guard] +#endif // BROKEN_INTERNAL_H diff --git a/src/asmjit/test/main.cpp b/src/asmjit/test/main.cpp index 7157dc9..7fad121 100644 --- a/src/asmjit/test/main.cpp +++ b/src/asmjit/test/main.cpp @@ -4,8 +4,7 @@ // [License] // Zlib - See LICENSE.md file in the package. -// [Dependencies - MiniUnit] -#include "./test.h" +// [Dependencies - AsmJit] #include "../asmjit.h" using namespace asmjit; @@ -19,22 +18,22 @@ struct DumpCpuFeature { const char* name; }; -static void dumpCpuFeatures(const BaseCpuInfo* cpuInfo, const DumpCpuFeature* data, size_t count) { +static void dumpCpuFeatures(const CpuInfo* cpuInfo, const DumpCpuFeature* data, size_t count) { for (size_t i = 0; i < count; i++) if (cpuInfo->hasFeature(data[i].feature)) INFO(" %s", data[i].name); } -static void dumpCpu() { - const BaseCpuInfo* cpuInfo_ = BaseCpuInfo::getHost(); +static void dumpCpu(void) { + const CpuInfo* cpu = CpuInfo::getHost(); INFO("Host CPU Info:"); - INFO(" Vendor string : %s", cpuInfo_->getVendorString()); - INFO(" Brand string : %s", cpuInfo_->getBrandString()); - INFO(" Family : %u", cpuInfo_->getFamily()); - INFO(" Model : %u", cpuInfo_->getModel()); - INFO(" Stepping : %u", cpuInfo_->getStepping()); - INFO(" Cores Count : %u", cpuInfo_->getCoresCount()); + INFO(" Vendor string : %s", cpu->getVendorString()); + INFO(" Brand string : %s", cpu->getBrandString()); + INFO(" Family : %u", cpu->getFamily()); + INFO(" Model : %u", cpu->getModel()); + INFO(" Stepping : %u", cpu->getStepping()); + INFO(" HW-Threads Count : %u", cpu->getHwThreadsCount()); INFO(""); // -------------------------------------------------------------------------- @@ -42,63 +41,63 @@ static void dumpCpu() { // -------------------------------------------------------------------------- #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) - const x86x64::CpuInfo* cpuInfo = static_cast(cpuInfo_); + const X86CpuInfo* x86Cpu = static_cast(cpu); - static const DumpCpuFeature featuresList[] = { - { x86x64::kCpuFeatureMultithreading , "Multithreading" }, - { x86x64::kCpuFeatureExecuteDisableBit , "Execute-Disable Bit" }, - { x86x64::kCpuFeatureRdtsc , "Rdtsc" }, - { x86x64::kCpuFeatureRdtscp , "Rdtscp" }, - { x86x64::kCpuFeatureCmov , "Cmov" }, - { x86x64::kCpuFeatureCmpXchg8B , "Cmpxchg8b" }, - { x86x64::kCpuFeatureCmpXchg16B , "Cmpxchg16b" }, - { x86x64::kCpuFeatureClflush , "Clflush" }, - { x86x64::kCpuFeaturePrefetch , "Prefetch" }, - { x86x64::kCpuFeatureLahfSahf , "Lahf/Sahf" }, - { x86x64::kCpuFeatureFxsr , "Fxsave/Fxrstor" }, - { x86x64::kCpuFeatureFfxsr , "Fxsave/Fxrstor Opt." }, - { x86x64::kCpuFeatureMmx , "Mmx" }, - { x86x64::kCpuFeatureMmxExt , "MmxExt" }, - { x86x64::kCpuFeature3dNow , "3dnow" }, - { x86x64::kCpuFeature3dNowExt , "3dnowExt" }, - { x86x64::kCpuFeatureSse , "Sse" }, - { x86x64::kCpuFeatureSse2 , "Sse2" }, - { x86x64::kCpuFeatureSse3 , "Sse3" }, - { x86x64::kCpuFeatureSsse3 , "Ssse3" }, - { x86x64::kCpuFeatureSse4A , "Sse4a" }, - { x86x64::kCpuFeatureSse41 , "Sse4.1" }, - { x86x64::kCpuFeatureSse42 , "Sse4.2" }, - { x86x64::kCpuFeatureMsse , "Misaligned SSE" }, - { x86x64::kCpuFeatureMonitorMWait , "Monitor/MWait" }, - { x86x64::kCpuFeatureMovbe , "Movbe" }, - { x86x64::kCpuFeaturePopcnt , "Popcnt" }, - { x86x64::kCpuFeatureLzcnt , "Lzcnt" }, - { x86x64::kCpuFeatureAesni , "AesNI" }, - { x86x64::kCpuFeaturePclmulqdq , "Pclmulqdq" }, - { x86x64::kCpuFeatureRdrand , "Rdrand" }, - { x86x64::kCpuFeatureAvx , "Avx" }, - { x86x64::kCpuFeatureAvx2 , "Avx2" }, - { x86x64::kCpuFeatureF16C , "F16C" }, - { x86x64::kCpuFeatureFma3 , "Fma3" }, - { x86x64::kCpuFeatureFma4 , "Fma4" }, - { x86x64::kCpuFeatureXop , "Xop" }, - { x86x64::kCpuFeatureBmi , "Bmi" }, - { x86x64::kCpuFeatureBmi2 , "Bmi2" }, - { x86x64::kCpuFeatureHle , "Hle" }, - { x86x64::kCpuFeatureRtm , "Rtm" }, - { x86x64::kCpuFeatureFsGsBase , "FsGsBase" }, - { x86x64::kCpuFeatureRepMovsbStosbExt , "RepMovsbStosbExt" } + static const DumpCpuFeature x86FeaturesList[] = { + { kX86CpuFeatureMultithreading , "Multithreading" }, + { kX86CpuFeatureExecuteDisableBit , "Execute-Disable Bit" }, + { kX86CpuFeatureRdtsc , "Rdtsc" }, + { kX86CpuFeatureRdtscp , "Rdtscp" }, + { kX86CpuFeatureCmov , "Cmov" }, + { kX86CpuFeatureCmpXchg8B , "Cmpxchg8b" }, + { kX86CpuFeatureCmpXchg16B , "Cmpxchg16b" }, + { kX86CpuFeatureClflush , "Clflush" }, + { kX86CpuFeaturePrefetch , "Prefetch" }, + { kX86CpuFeatureLahfSahf , "Lahf/Sahf" }, + { kX86CpuFeatureFxsr , "Fxsave/Fxrstor" }, + { kX86CpuFeatureFfxsr , "Fxsave/Fxrstor Opt." }, + { kX86CpuFeatureMmx , "Mmx" }, + { kX86CpuFeatureMmxExt , "MmxExt" }, + { kX86CpuFeature3dNow , "3dnow" }, + { kX86CpuFeature3dNowExt , "3dnowExt" }, + { kX86CpuFeatureSse , "Sse" }, + { kX86CpuFeatureSse2 , "Sse2" }, + { kX86CpuFeatureSse3 , "Sse3" }, + { kX86CpuFeatureSsse3 , "Ssse3" }, + { kX86CpuFeatureSse4A , "Sse4a" }, + { kX86CpuFeatureSse41 , "Sse4.1" }, + { kX86CpuFeatureSse42 , "Sse4.2" }, + { kX86CpuFeatureMsse , "Misaligned SSE" }, + { kX86CpuFeatureMonitorMWait , "Monitor/MWait" }, + { kX86CpuFeatureMovbe , "Movbe" }, + { kX86CpuFeaturePopcnt , "Popcnt" }, + { kX86CpuFeatureLzcnt , "Lzcnt" }, + { kX86CpuFeatureAesni , "AesNI" }, + { kX86CpuFeaturePclmulqdq , "Pclmulqdq" }, + { kX86CpuFeatureRdrand , "Rdrand" }, + { kX86CpuFeatureAvx , "Avx" }, + { kX86CpuFeatureAvx2 , "Avx2" }, + { kX86CpuFeatureF16C , "F16C" }, + { kX86CpuFeatureFma3 , "Fma3" }, + { kX86CpuFeatureFma4 , "Fma4" }, + { kX86CpuFeatureXop , "Xop" }, + { kX86CpuFeatureBmi , "Bmi" }, + { kX86CpuFeatureBmi2 , "Bmi2" }, + { kX86CpuFeatureHle , "Hle" }, + { kX86CpuFeatureRtm , "Rtm" }, + { kX86CpuFeatureFsGsBase , "FsGsBase" }, + { kX86CpuFeatureRepMovsbStosbExt , "RepMovsbStosbExt" } }; INFO("Host CPU Info (X86/X64):"); - INFO(" Processor Type : %u", cpuInfo->getProcessorType()); - INFO(" Brand Index : %u", cpuInfo->getBrandIndex()); - INFO(" CL Flush Cache Line : %u", cpuInfo->getFlushCacheLineSize()); - INFO(" Max logical Processors: %u", cpuInfo->getMaxLogicalProcessors()); + INFO(" Processor Type : %u", x86Cpu->getProcessorType()); + INFO(" Brand Index : %u", x86Cpu->getBrandIndex()); + INFO(" CL Flush Cache Line : %u", x86Cpu->getFlushCacheLineSize()); + INFO(" Max logical Processors: %u", x86Cpu->getMaxLogicalProcessors()); INFO(""); INFO("Host CPU Features (X86/X64):"); - dumpCpuFeatures(cpuInfo, featuresList, ASMJIT_ARRAY_SIZE(featuresList)); + dumpCpuFeatures(x86Cpu, x86FeaturesList, ASMJIT_ARRAY_SIZE(x86FeaturesList)); INFO(""); #endif // ASMJIT_HOST || ASMJIT_HOST_X64 } @@ -107,68 +106,68 @@ static void dumpCpu() { // [DumpSizeOf] // ============================================================================ -#define DUMP_SIZE(_Type_) \ +#define DUMP_TYPE(_Type_) \ INFO(" %-31s: %u", #_Type_, static_cast(sizeof(_Type_))) -static void dumpSizeOf() { +static void dumpSizeOf(void) { INFO("SizeOf Types:"); - DUMP_SIZE(int8_t); - DUMP_SIZE(int16_t); - DUMP_SIZE(int32_t); - DUMP_SIZE(int64_t); - DUMP_SIZE(int); - DUMP_SIZE(long); - DUMP_SIZE(size_t); - DUMP_SIZE(intptr_t); - DUMP_SIZE(float); - DUMP_SIZE(double); - DUMP_SIZE(void*); - DUMP_SIZE(asmjit::Ptr); - DUMP_SIZE(asmjit::SignedPtr); + DUMP_TYPE(int8_t); + DUMP_TYPE(int16_t); + DUMP_TYPE(int32_t); + DUMP_TYPE(int64_t); + DUMP_TYPE(int); + DUMP_TYPE(long); + DUMP_TYPE(size_t); + DUMP_TYPE(intptr_t); + DUMP_TYPE(float); + DUMP_TYPE(double); + DUMP_TYPE(void*); INFO(""); INFO("SizeOf Base:"); - DUMP_SIZE(asmjit::CodeGen); - DUMP_SIZE(asmjit::ConstPool); - DUMP_SIZE(asmjit::Runtime); - DUMP_SIZE(asmjit::Zone); + DUMP_TYPE(asmjit::CodeGen); + DUMP_TYPE(asmjit::ConstPool); + DUMP_TYPE(asmjit::Runtime); + DUMP_TYPE(asmjit::Zone); + DUMP_TYPE(asmjit::Ptr); + DUMP_TYPE(asmjit::SignedPtr); INFO(""); INFO("SizeOf Operand:"); - DUMP_SIZE(asmjit::Operand); - DUMP_SIZE(asmjit::BaseReg); - DUMP_SIZE(asmjit::BaseVar); - DUMP_SIZE(asmjit::BaseMem); - DUMP_SIZE(asmjit::Imm); - DUMP_SIZE(asmjit::Label); + DUMP_TYPE(asmjit::Operand); + DUMP_TYPE(asmjit::Reg); + DUMP_TYPE(asmjit::Var); + DUMP_TYPE(asmjit::BaseMem); + DUMP_TYPE(asmjit::Imm); + DUMP_TYPE(asmjit::Label); INFO(""); INFO("SizeOf Assembler:"); - DUMP_SIZE(asmjit::BaseAssembler); - DUMP_SIZE(asmjit::LabelData); - DUMP_SIZE(asmjit::RelocData); + DUMP_TYPE(asmjit::Assembler); + DUMP_TYPE(asmjit::LabelData); + DUMP_TYPE(asmjit::RelocData); INFO(""); #if !defined(ASMJIT_DISABLE_COMPILER) INFO("SizeOf Compiler:"); - DUMP_SIZE(asmjit::BaseCompiler); - DUMP_SIZE(asmjit::Node); - DUMP_SIZE(asmjit::AlignNode); - DUMP_SIZE(asmjit::CallNode); - DUMP_SIZE(asmjit::CommentNode); - DUMP_SIZE(asmjit::EmbedNode); - DUMP_SIZE(asmjit::FuncNode); - DUMP_SIZE(asmjit::EndNode); - DUMP_SIZE(asmjit::InstNode); - DUMP_SIZE(asmjit::JumpNode); - DUMP_SIZE(asmjit::TargetNode); - DUMP_SIZE(asmjit::FuncDecl); - DUMP_SIZE(asmjit::FuncInOut); - DUMP_SIZE(asmjit::FuncPrototype); - DUMP_SIZE(asmjit::VarAttr); - DUMP_SIZE(asmjit::VarData); - DUMP_SIZE(asmjit::BaseVarInst); - DUMP_SIZE(asmjit::BaseVarState); + DUMP_TYPE(asmjit::Compiler); + DUMP_TYPE(asmjit::Node); + DUMP_TYPE(asmjit::AlignNode); + DUMP_TYPE(asmjit::CallNode); + DUMP_TYPE(asmjit::CommentNode); + DUMP_TYPE(asmjit::EmbedNode); + DUMP_TYPE(asmjit::FuncNode); + DUMP_TYPE(asmjit::EndNode); + DUMP_TYPE(asmjit::InstNode); + DUMP_TYPE(asmjit::JumpNode); + DUMP_TYPE(asmjit::TargetNode); + DUMP_TYPE(asmjit::FuncDecl); + DUMP_TYPE(asmjit::FuncInOut); + DUMP_TYPE(asmjit::FuncPrototype); + DUMP_TYPE(asmjit::VarAttr); + DUMP_TYPE(asmjit::VarData); + DUMP_TYPE(asmjit::VarMap); + DUMP_TYPE(asmjit::VarState); INFO(""); #endif // !ASMJIT_DISABLE_COMPILER @@ -178,30 +177,33 @@ static void dumpSizeOf() { #if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) INFO("SizeOf X86/X64:"); - DUMP_SIZE(asmjit::x86x64::X86X64Assembler); - DUMP_SIZE(asmjit::x86x64::X86X64Compiler); - DUMP_SIZE(asmjit::x86x64::X86X64CallNode); - DUMP_SIZE(asmjit::x86x64::X86X64FuncNode); - DUMP_SIZE(asmjit::x86x64::X86X64FuncDecl); - DUMP_SIZE(asmjit::x86x64::VarInst); - DUMP_SIZE(asmjit::x86x64::VarState); - DUMP_SIZE(asmjit::x86x64::InstInfo); - DUMP_SIZE(asmjit::x86x64::VarInfo); + DUMP_TYPE(asmjit::X86Assembler); +#if !defined(ASMJIT_DISABLE_COMPILER) + DUMP_TYPE(asmjit::X86Compiler); + DUMP_TYPE(asmjit::X86CallNode); + DUMP_TYPE(asmjit::X86FuncNode); + DUMP_TYPE(asmjit::X86FuncDecl); + DUMP_TYPE(asmjit::X86InstInfo); + DUMP_TYPE(asmjit::X86VarMap); + DUMP_TYPE(asmjit::X86VarInfo); + DUMP_TYPE(asmjit::X86VarState); +#endif // !ASMJIT_DISABLE_COMPILER INFO(""); #endif // ASMJIT_BUILD_X86 } +#undef DUMP_TYPE + // ============================================================================ // [Main] // ============================================================================ -int main(int argc, const char* argv[]) { - if (MiniUnit::init(argc, argv)) { - dumpCpu(); - dumpSizeOf(); - - MiniUnit::run(); - } - - return 0; +static void onBeforeRun(void) { + dumpCpu(); + dumpSizeOf(); +} + +int main(int argc, const char* argv[]) { + INFO("AsmJit Unit-Test\n\n"); + return BrokenAPI::run(argc, argv, onBeforeRun); } diff --git a/src/asmjit/test/test.cpp b/src/asmjit/test/test.cpp deleted file mode 100644 index 9627c35..0000000 --- a/src/asmjit/test/test.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Dependencies - MiniUnit] -#include "./test.h" - -// ============================================================================ -// [MiniUnit - Statics] -// ============================================================================ - -int MiniUnit::argc; -const char** MiniUnit::argv; -FILE* MiniUnit::outFile; - -MiniUnit::Unit* MiniUnit::unitList; -MiniUnit::Unit* MiniUnit::unitRunning; - -// ============================================================================ -// [MiniUnit - Init] -// ============================================================================ - -bool MiniUnit::init(int argc, const char* argv[]) { - MiniUnit::argc = argc; - MiniUnit::argv = argv; - MiniUnit::outFile = stdout; - - return unitList != NULL; -} - -// ============================================================================ -// [MiniUnit - Add] -// ============================================================================ - -void MiniUnit::addUnit(Unit* unit) { - Unit** pPrev = &unitList; - Unit* current = *pPrev; - - while (current != NULL) { - if (::strcmp(current->name, unit->name) >= 0) - break; - - pPrev = ¤t->next; - current = *pPrev; - } - - *pPrev = unit; - unit->next = current; -} - -// ============================================================================ -// [MiniUnit - Run] -// ============================================================================ - -void MiniUnit::run() { - MiniUnit::Unit* unit = unitList; - while (unit != NULL) { - runUnit(unit); - unit = unit->next; - } -} - -void MiniUnit::runUnit(Unit* unit) { - info("[Unit] %s", unit->name); - unitRunning = unit; - unit->entry(); - unitRunning = NULL; -} - -// ============================================================================ -// [MiniUnit - Info] -// ============================================================================ - -void MiniUnit::info(const char* fmt, ...) { - const char* prefix = unitRunning ? " " : ""; - size_t len = ::strlen(fmt); - - if (len != 0) { - va_list ap; - va_start(ap, fmt); - ::fputs(prefix, outFile); - ::vfprintf(outFile, fmt, ap); - va_end(ap); - } - - if (len == 0 || fmt[len - 1] != '\n') - ::fputs("\n", outFile); - - ::fflush(outFile); -} - -void MiniUnit::fail(const char* file, int line, const char* fmt, ...) { - size_t len = ::strlen(fmt); - - if (len != 0) { - va_list ap; - va_start(ap, fmt); - ::fputs("[Fail] ", outFile); - ::vfprintf(outFile, fmt, ap); - va_end(ap); - } - - if (len > 0 && fmt[len - 1] != '\n') - ::fputs("\n", outFile); - - ::fprintf(outFile, "[File] %s (Line: %d)\n", file, line); - - ::fflush(outFile); - ::exit(1); -} diff --git a/src/asmjit/test/test.h b/src/asmjit/test/test.h deleted file mode 100644 index 6c8398c..0000000 --- a/src/asmjit/test/test.h +++ /dev/null @@ -1,99 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef MINIUNIT_H -#define MINIUNIT_H - -// [Dependencies - C] -#include -#include -#include -#include - -//! \internal -//! \{ - -// ============================================================================ -// [MiniUnit] -// ============================================================================ - -//! Define a unit. -//! -//! `_Name_` can only contain ASCII characters, numbers and underscore. -#define UNIT(_Name_) \ - static void unit_##_Name_##_entry(void); \ - static ::MiniUnit::AutoUnit unit_##_Name_##_autoinit(#_Name_, unit_##_Name_##_entry); \ - static void unit_##_Name_##_entry(void) - -//! Informative message printed to stdout. -#define INFO(...) \ - ::MiniUnit::info(__VA_ARGS__) - -//! Expect `_Exp_` to be truthy, fail otherwise. -#define EXPECT(_Exp_, ...) \ - do { \ - if (!(_Exp_)) ::MiniUnit::fail(__FILE__, __LINE__, __VA_ARGS__); \ - } while(0) - -struct MiniUnit { - //! Test entry point. - typedef void (*Entry)(void); - - //! Test unit. - struct Unit { - const char* name; - Entry entry; - size_t finished; - Unit* next; - }; - - //! Automatic unit registration by using static initialization. - struct AutoUnit : Unit { - inline AutoUnit(const char* _name, Entry _entry) { - name = _name; - entry = _entry; - finished = false; - next = NULL; - - MiniUnit::addUnit(this); - } - }; - - //! Test arguments count. - static int argc; - //! Test arguments list. - static const char** argv; - //! File where to log. - static FILE* outFile; - //! Test unit list. - static Unit* unitList; - //! Running test reference. - static Unit* unitRunning; - - //! Initialize MiniUnit framework. - //! - //! Returns `true` if `run()` should be called. - static bool init(int argc, const char* argv[]); - - //! Register a new test. - static void addUnit(Unit* unit); - - //! Run all units. - static void run(); - //! Run a single unit. - static void runUnit(Unit* unit); - - //! Log message, adds automatically new line if not present. - static void info(const char* fmt, ...); - //! Called on `EXPECT()` failure. - static void fail(const char* file, int line, const char* fmt, ...); -}; - -//! \} - -// [Guard] -#endif // MINIUNIT_H diff --git a/src/asmjit/x86.h b/src/asmjit/x86.h index 936bb95..ef5e006 100644 --- a/src/asmjit/x86.h +++ b/src/asmjit/x86.h @@ -14,11 +14,8 @@ #include "x86/x86assembler.h" #include "x86/x86compiler.h" #include "x86/x86cpuinfo.h" -#include "x86/x86func.h" #include "x86/x86inst.h" #include "x86/x86operand.h" -#include "x86/x86regs.h" -#include "x86/x86util.h" // [Guard] #endif // _ASMJIT_X86_H diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index 360e1ad..8ec8571 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -24,7 +24,6 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ // [Constants] @@ -60,7 +59,7 @@ enum kVexVVVV { //! \internal //! //! Instruction 2-byte/3-byte opcode prefix definition. -struct OpCodeMM { +struct X86OpCodeMM { uint8_t len; uint8_t data[3]; }; @@ -83,7 +82,7 @@ static const uint8_t x86OpCodePP[8] = { //! \internal //! //! Instruction 2-byte/3-byte opcode prefix data. -static const OpCodeMM x86OpCodeMM[] = { +static const X86OpCodeMM x86OpCodeMM[] = { { 0, { 0x00, 0x00, 0 } }, { 1, { 0x0F, 0x00, 0 } }, { 2, { 0x0F, 0x38, 0 } }, @@ -117,7 +116,7 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { } // ============================================================================ -// [asmjit::x86x64::Emit] +// [Macros] // ============================================================================ #define ENC_OPS(_Op0_, _Op1_, _Op2_) \ @@ -125,7 +124,12 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { #define ADD_66H_P(_Exp_) \ do { \ - opCode |= (static_cast(_Exp_) << kInstOpCode_PP_Shift); \ + opCode |= (static_cast(_Exp_) << kX86InstOpCode_PP_Shift); \ + } while (0) + +#define ADD_66H_P_BY_SIZE(_Size_) \ + do { \ + opCode |= (static_cast(_Size_) & 0x02) << (kX86InstOpCode_PP_Shift - 1); \ } while (0) #define ADD_REX_W(_Exp_) \ @@ -133,6 +137,13 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { if (Arch == kArchX64) \ opX |= static_cast(_Exp_) << 3; \ } while (0) + +#define ADD_REX_W_BY_SIZE(_Size_) \ + do { \ + if (Arch == kArchX64) \ + opX |= static_cast(_Size_) & 0x08; \ + } while (0) + #define ADD_REX_B(_Reg_) \ do { \ if (Arch == kArchX64) \ @@ -146,7 +157,7 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { #define ADD_VEX_L(_Exp_) \ do { \ - opCode |= static_cast(_Exp_) << kInstOpCode_L_Shift; \ + opCode |= static_cast(_Exp_) << kX86InstOpCode_L_Shift; \ } while (0) #define EMIT_BYTE(_Val_) \ @@ -180,7 +191,7 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { #define EMIT_PP(_Val_) \ do { \ - uint32_t ppIndex = ((_Val_) >> kInstOpCode_PP_Shift) & (kInstOpCode_PP_Mask >> kInstOpCode_PP_Shift); \ + uint32_t ppIndex = ((_Val_) >> kX86InstOpCode_PP_Shift) & (kX86InstOpCode_PP_Mask >> kX86InstOpCode_PP_Shift); \ uint8_t ppCode = x86OpCodePP[ppIndex]; \ \ if (!ppIndex) \ @@ -192,8 +203,8 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { #define EMIT_MM(_Val_) \ do { \ - uint32_t mmIndex = ((_Val_) >> kInstOpCode_MM_Shift) & (kInstOpCode_MM_Mask >> kInstOpCode_MM_Shift); \ - const OpCodeMM& mmCode = x86OpCodeMM[mmIndex]; \ + uint32_t mmIndex = ((_Val_) >> kX86InstOpCode_MM_Shift) & (kX86InstOpCode_MM_Mask >> kX86InstOpCode_MM_Shift); \ + const X86OpCodeMM& mmCode = x86OpCodeMM[mmIndex]; \ \ if (!mmIndex) \ break; \ @@ -204,17 +215,87 @@ static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { } while (0) // ============================================================================ -// [asmjit::x86x64::Assembler - Construction / Destruction] +// [asmjit::X86Assembler - Construction / Destruction] // ============================================================================ -X86X64Assembler::X86X64Assembler(Runtime* runtime) : BaseAssembler(runtime) {} -X86X64Assembler::~X86X64Assembler() {} +X86Assembler::X86Assembler(Runtime* runtime, uint32_t arch) : + Assembler(runtime), + zax(NoInit), + zcx(NoInit), + zdx(NoInit), + zbx(NoInit), + zsp(NoInit), + zbp(NoInit), + zsi(NoInit), + zdi(NoInit) { + + setArch(arch); +} + +X86Assembler::~X86Assembler() {} // ============================================================================ -// [asmjit::x86x64::Assembler - Label] +// [asmjit::X86Assembler - Arch] // ============================================================================ -void X86X64Assembler::_bind(const Label& label) { +Error X86Assembler::setArch(uint32_t arch) { +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + _arch = kArchX86; + _regSize = 4; + + _regCount.reset(); + _regCount._gp = 8; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 8; + + zax = x86::eax; + zcx = x86::ecx; + zdx = x86::edx; + zbx = x86::ebx; + zsp = x86::esp; + zbp = x86::ebp; + zsi = x86::esi; + zdi = x86::edi; + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + _arch = kArchX64; + _regSize = 8; + + _regCount.reset(); + _regCount._gp = 16; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 16; + + zax = x86::rax; + zcx = x86::rcx; + zdx = x86::rdx; + zbx = x86::rbx; + zsp = x86::rsp; + zbp = x86::rbp; + zsi = x86::rsi; + zdi = x86::rdi; + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X64 + + ASMJIT_ASSERT(!"Reached"); + return kErrorInvalidArgument; +} + +// ============================================================================ +// [asmjit::X86Assembler - Label] +// ============================================================================ + +void X86Assembler::_bind(const Label& label) { // Get label data based on label id. uint32_t index = label.getId(); LabelData* data = getLabelDataById(index); @@ -281,10 +362,10 @@ void X86X64Assembler::_bind(const Label& label) { } // ============================================================================ -// [asmjit::x86x64::Assembler - Embed] +// [asmjit::X86Assembler - Embed] // ============================================================================ -Error X86X64Assembler::embedLabel(const Label& op) { +Error X86Assembler::embedLabel(const Label& op) { ASMJIT_ASSERT(op.getId() != kInvalidValue); uint32_t regSize = _regSize; @@ -336,10 +417,10 @@ Error X86X64Assembler::embedLabel(const Label& op) { } // ============================================================================ -// [asmjit::x86x64::Assembler - Align] +// [asmjit::X86Assembler - Align] // ============================================================================ -Error X86X64Assembler::_align(uint32_t mode, uint32_t offset) { +Error X86Assembler::_align(uint32_t mode, uint32_t offset) { #if !defined(ASMJIT_DISABLE_LOGGER) if (_logger) _logger->logFormat(kLoggerStyleDirective, @@ -363,7 +444,7 @@ Error X86X64Assembler::_align(uint32_t mode, uint32_t offset) { alignPattern = 0x90; if (IntUtil::hasBit(_features, kCodeGenOptimizedAlign)) { - const CpuInfo* cpuInfo = static_cast(getRuntime()->getCpuInfo()); + const X86CpuInfo* cpuInfo = static_cast(getRuntime()->getCpuInfo()); // NOPs optimized for Intel: // Intel 64 and IA-32 Architectures Software Developer's Manual @@ -450,34 +531,38 @@ Error X86X64Assembler::_align(uint32_t mode, uint32_t offset) { } // ============================================================================ -// [asmjit::x86x64::Assembler - Reloc] +// [asmjit::X86Assembler - Reloc] // ============================================================================ -template -static ASMJIT_INLINE size_t X86X64Assembler_relocCode(const X86X64Assembler* self, void* _dst, Ptr base) { +size_t X86Assembler::_relocCode(void* _dst, Ptr base) const { + uint32_t arch = getArch(); uint8_t* dst = static_cast(_dst); - size_t codeOffset = self->getOffset(); - size_t codeSize = self->getCodeSize(); +#if !defined(ASMJIT_DISABLE_LOGGER) + Logger* logger = getLogger(); +#endif // ASMJIT_DISABLE_LOGGER + + size_t codeOffset = getOffset(); + size_t codeSize = getCodeSize(); // We will copy the exact size of the generated code. Extra code for trampolines // is generated on-the-fly by the relocator (this code doesn't exist at the moment). - ::memcpy(dst, self->_buffer, codeOffset); + ::memcpy(dst, _buffer, codeOffset); // Trampoline pointer. - uint8_t* tramp; - - if (Arch == kArchX64) - tramp = dst + codeOffset; + uint8_t* tramp = dst + codeOffset; // Relocate all recorded locations. - size_t i, len = self->_relocData.getLength(); + size_t relocIndex; + size_t relocCount = _relocData.getLength(); + const RelocData* relocData = _relocData.getData(); - for (i = 0; i < len; i++) { - const RelocData& r = self->_relocData[i]; + for (relocIndex = 0; relocIndex < relocCount; relocIndex++) { + const RelocData& r = relocData[relocIndex]; Ptr ptr; - // Whether to use trampoline, can be only used if relocation type is kRelocAbsToRel. + // Whether to use trampoline, can be only used if relocation type is + // kRelocAbsToRel on 64-bit. bool useTrampoline = false; // Be sure that reloc data structure is correct. @@ -497,7 +582,7 @@ static ASMJIT_INLINE size_t X86X64Assembler_relocCode(const X86X64Assembler* sel case kRelocTrampoline: ptr = r.data - (base + r.from + 4); - if (Arch == kArchX64 && r.type == kRelocTrampoline && !IntUtil::isInt32(ptr)) { + if (arch == kArchX64 && r.type == kRelocTrampoline && !IntUtil::isInt32(ptr)) { ptr = (Ptr)tramp - (base + r.from + 4); useTrampoline = true; } @@ -508,20 +593,15 @@ static ASMJIT_INLINE size_t X86X64Assembler_relocCode(const X86X64Assembler* sel } switch (r.size) { - case 4: - *reinterpret_cast(dst + offset) = static_cast(ptr); - break; - - case 8: - *reinterpret_cast(dst + offset) = static_cast(ptr); - break; + case 4: *reinterpret_cast(dst + offset) = static_cast(ptr); break; + case 8: *reinterpret_cast(dst + offset) = static_cast(ptr); break; default: ASMJIT_ASSERT(!"Reached"); } // Patch `jmp/call` to use trampoline. - if (Arch == kArchX64 && useTrampoline) { + if (arch == kArchX64 && useTrampoline) { uint32_t byte0 = 0xFF; uint32_t byte1 = dst[offset - 1]; @@ -546,20 +626,20 @@ static ASMJIT_INLINE size_t X86X64Assembler_relocCode(const X86X64Assembler* sel tramp += 8; #if !defined(ASMJIT_DISABLE_LOGGER) - if (self->_logger) - self->_logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", r.data); + if (logger) + logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", r.data); #endif // !ASMJIT_DISABLE_LOGGER } } - if (Arch == kArchX64) + if (arch == kArchX64) return (size_t)(tramp - dst); else return (size_t)(codeOffset); } // ============================================================================ -// [asmjit::x86x64::Assembler - Logging] +// [asmjit::X86Assembler - Logging] // ============================================================================ #if !defined(ASMJIT_DISABLE_LOGGER) @@ -603,7 +683,7 @@ static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t char suffix = '\0'; switch (type) { - case kRegTypeGpbLo: + case kX86RegTypeGpbLo: if (index >= 8) { sb._appendChar('r'); suffix = 'b'; @@ -613,14 +693,14 @@ static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t sb._appendString(®8l[index * 4]); return; - case kRegTypePatchedGpbHi: + case _kX86RegTypePatchedGpbHi: if (index < 4) goto _EmitNE; index -= 4; // ... Fall through ... - case kRegTypeGpbHi: + case kX86RegTypeGpbHi: if (index >= 4) goto _EmitNE; @@ -631,7 +711,7 @@ _EmitNE: sb._appendString("--", 2); return; - case kRegTypeGpw: + case kX86RegTypeGpw: if (index >= 8) { sb._appendChar('r'); suffix = 'w'; @@ -641,7 +721,7 @@ _EmitNE: sb._appendString(®16[index * 4]); return; - case kRegTypeGpd: + case kX86RegTypeGpd: if (index >= 8) { sb._appendChar('r'); suffix = 'd'; @@ -652,7 +732,7 @@ _EmitNE: sb._appendString(®16[index * 4]); return; - case kRegTypeGpq: + case kX86RegTypeGpq: sb._appendChar('r'); if (index >= 8) goto _EmitID; @@ -660,24 +740,24 @@ _EmitNE: sb._appendString(®16[index * 4]); return; - case kRegTypeFp: + case kX86RegTypeFp: sb._appendString("fp", 2); goto _EmitID; - case kRegTypeMm: + case kX86RegTypeMm: sb._appendString("mm", 2); goto _EmitID; - case kRegTypeXmm: + case kX86RegTypeXmm: sb._appendString("xmm", 3); goto _EmitID; - case kRegTypeYmm: + case kX86RegTypeYmm: sb._appendString("ymm", 3); goto _EmitID; - case kRegTypeSeg: - if (index >= kRegCountSeg) + case kX86RegTypeSeg: + if (index >= kX86SegCount) goto _EmitNE; sb._appendString(&X86Assembler_segName[index * 4], 2); @@ -701,25 +781,25 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope static_cast(op)->getRegIndex()); } else if (op->isMem()) { - const Mem* m = static_cast(op); + const X86Mem* m = static_cast(op); - uint32_t type = kRegTypeGpd; + uint32_t type = kX86RegTypeGpd; uint32_t seg = m->getSegment(); bool isAbsolute = false; if (arch == kArchX86) { if (!m->hasGpdBase()) - type = kRegTypeGpw; + type = kX86RegTypeGpw; } else { if (!m->hasGpdBase()) - type = kRegTypeGpq; + type = kX86RegTypeGpq; } if (op->getSize() <= 16) sb._appendString(AssemblerX86_operandSize[op->getSize()]); - if (seg < kRegCountSeg) + if (seg < kX86SegCount) sb._appendString(&X86Assembler_segName[seg * 4]); sb._appendChar('['); @@ -744,8 +824,8 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope if (m->hasIndex()) { switch (m->getVSib()) { - case kMemVSibXmm: type = kRegTypeXmm; break; - case kMemVSibYmm: type = kRegTypeYmm; break; + case kX86MemVSibXmm: type = kX86RegTypeXmm; break; + case kX86MemVSibYmm: type = kX86RegTypeYmm; break; } sb._appendChar('+'); @@ -807,17 +887,17 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb, return false; // Rex, lock and short prefix. - if (options & kInstOptionRex) + if (options & kX86InstOptionRex) sb._appendString("rex ", 4); - if (options & kInstOptionLock) + if (options & kX86InstOptionLock) sb._appendString("lock ", 5); if (options & kInstOptionShortForm) sb._appendString("short ", 6); // Dump instruction name. - sb._appendString(_instInfo[code].getName()); + sb._appendString(_x86InstInfo[code].getInstName()); // Dump operands. if (!o0->isNone()) { @@ -836,7 +916,7 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb, } if (!o3->isNone()) { - sb._appendString(", ", 3); + sb._appendString(", ", 2); X86Assembler_dumpOperand(sb, arch, o3, loggerOptions); } @@ -893,7 +973,7 @@ static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_ #endif // !ASMJIT_DISABLE_LOGGER // ============================================================================ -// [asmjit::x86x64::Assembler - Emit] +// [asmjit::X86Assembler - Emit] // ============================================================================ //! \internal @@ -901,18 +981,25 @@ static const Operand::VRegOp x86PatchedHiRegs[4] = { // --------------+---+--------------------------------+--------------+------+ // Operand | S | Register Code | OperandId |Unused| // --------------+---+--------------------------------+--------------+------+ - { kOperandTypeReg, 1 , (kRegTypePatchedGpbHi << 8) | 4, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (kRegTypePatchedGpbHi << 8) | 5, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (kRegTypePatchedGpbHi << 8) | 6, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (kRegTypePatchedGpbHi << 8) | 7, kInvalidValue, 0, 0 } + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 4, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 5, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 6, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 7, kInvalidValue, 0, 0 } }; template -static ASMJIT_INLINE Error X86X64Assembler_emit(X86X64Assembler* self, uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3) { - uint8_t* cursor = self->getCursor(); +static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3) { + X86Assembler* self = static_cast(self_); + uint8_t* cursor = self->getCursor(); uint32_t encoded = o0->getOp() + (o1->getOp() << 3) + (o2->getOp() << 6); - uint32_t options = self->getOptionsAndClear(); + uint32_t options = self->getOptionsAndReset(); + + // Invalid instruction. + if (code >= _kX86InstIdCount) { + self->_comment = NULL; + return self->setError(kErrorUnknownInst); + } // Instruction opcode. uint32_t opCode; @@ -937,7 +1024,7 @@ static ASMJIT_INLINE Error X86X64Assembler_emit(X86X64Assembler* self, uint32_t // MODR/M - register code. uintptr_t rmReg; // MODR/M - Memory operand. - const Mem* rmMem; + const X86Mem* rmMem; }; // Immediate value. @@ -963,10 +1050,8 @@ static ASMJIT_INLINE Error X86X64Assembler_emit(X86X64Assembler* self, uint32_t bool assertIllegal = false; #endif // ASMJIT_DEBUG - // Invalid instruction. - const InstInfo* info = &_instInfo[code]; - if (code >= _kInstCount) - goto _UnknownInst; + const X86InstInfo& info = _x86InstInfo[code]; + const X86InstExtendedInfo& extendedInfo = info.getExtendedInfo(); // Grow request happens rarely. C++ compiler generates better code if it is // handled at the end of the function. @@ -978,9 +1063,9 @@ static ASMJIT_INLINE Error X86X64Assembler_emit(X86X64Assembler* self, uint32_t // -------------------------------------------------------------------------- _Prepare: - opCode = info->_opCode[0]; - opReg = opCode >> kInstOpCode_O_Shift; - opX = info->getFlags() >> (15 - 3); + opCode = info.getPrimaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + opX = extendedInfo.getInstFlags() >> (15 - 3); if (Arch == kArchX86) { // AVX.W prefix. @@ -989,14 +1074,14 @@ _Prepare: // Check if one or more register operand is one of AH, BH, CH, or DH and // patch them to ensure that the binary code with correct byte-index (4-7) // is generated. - if (o0->isRegType(kRegTypeGpbHi)) + if (o0->isRegType(kX86RegTypeGpbHi)) o0 = (const Operand*)(&x86PatchedHiRegs[static_cast(o0)->getRegIndex()]); - if (o1->isRegType(kRegTypeGpbHi)) + if (o1->isRegType(kX86RegTypeGpbHi)) o1 = (const Operand*)(&x86PatchedHiRegs[static_cast(o1)->getRegIndex()]); } else { - ASMJIT_ASSERT(kInstOptionRex == 0x40); + ASMJIT_ASSERT(kX86InstOptionRex == 0x40); // AVX.W prefix and REX prefix. opX |= options; @@ -1004,7 +1089,7 @@ _Prepare: // Check if one or more register operand is one of BPL, SPL, SIL, DIL and // force a REX prefix in such case. - if (X86Util::isGpbRegOp(*o0)) { + if (X86Reg::isGpbReg(*o0)) { uint32_t index = static_cast(o0)->getRegIndex(); if (static_cast(o0)->isGpbLo()) { opX |= (index >= 4) << kRexShift; @@ -1015,7 +1100,7 @@ _Prepare: } } - if (X86Util::isGpbRegOp(*o1)) { + if (X86Reg::isGpbReg(*o1)) { uint32_t index = static_cast(o1)->getRegIndex(); if (static_cast(o1)->isGpbLo()) { opX |= (index >= 4) << kRexShift; @@ -1031,8 +1116,8 @@ _Prepare: // [Lock-Prefix] // -------------------------------------------------------------------------- - if (options & kInstOptionLock) { - if (!info->isLockable()) + if (options & kX86InstOptionLock) { + if (!extendedInfo.isLockable()) goto _IllegalInst; EMIT_BYTE(0xF0); } @@ -1041,29 +1126,32 @@ _Prepare: // [Group] // -------------------------------------------------------------------------- - switch (info->getGroup()) { - + switch (info.getInstGroup()) { // ------------------------------------------------------------------------ // [None] // ------------------------------------------------------------------------ - case kInstGroupNone: + case kX86InstGroupNone: goto _EmitDone; // ------------------------------------------------------------------------ // [X86] // ------------------------------------------------------------------------ - case kInstGroupX86Op: + case kX86InstGroupX86Op_66H: + ADD_66H_P(true); + // ... Fall through ... + + case kX86InstGroupX86Op: goto _EmitX86Op; - case kInstGroupX86Rm_B: + case kX86InstGroupX86Rm_B: opCode += o0->getSize() != 1; // ... Fall through ... - case kInstGroupX86Rm: - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + case kX86InstGroupX86Rm: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, None, None)) { rmReg = static_cast(o0)->getRegIndex(); @@ -1071,16 +1159,16 @@ _Prepare: } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86RmReg: + case kX86InstGroupX86RmReg: if (encoded == ENC_OPS(Reg, Reg, None)) { opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); opReg = static_cast(o1)->getRegIndex(); rmReg = static_cast(o0)->getRegIndex(); @@ -1089,18 +1177,18 @@ _Prepare: if (encoded == ENC_OPS(Mem, Reg, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86RegRm: - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + case kX86InstGroupX86RegRm: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() != 1); @@ -1114,46 +1202,46 @@ _Prepare: ASMJIT_ASSERT(o0->getSize() != 1); opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupX86M: + case kX86InstGroupX86M: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Arith: + case kX86InstGroupX86Arith: if (encoded == ENC_OPS(Reg, Reg, None)) { opCode +=(o0->getSize() != 1) + 2; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { opCode +=(o0->getSize() != 1) + 2; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } if (encoded == ENC_OPS(Mem, Reg, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } @@ -1163,65 +1251,67 @@ _Prepare: if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(o0->getSize(), 4); - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); // Alternate Form - AL, AX, EAX, RAX. if (rmReg == 0 && (o0->getSize() == 1 || imLen != 1)) { opCode = ((opReg << 3) | (0x04 + (o0->getSize() != 1))); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - imLen = IntUtil::iMin(o0->getSize(), 4); goto _EmitX86OpI; } opCode += o0->getSize() != 1 ? (imLen != 1 ? 1 : 3) : 0; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Imm, None)) { + uint32_t memSize = o0->getSize(); + + if (memSize == 0) + goto _IllegalInst; + imVal = static_cast(o1)->getInt64(); - imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(o0->getSize(), 4); + imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(memSize, 4); - opCode += o0->getSize() != 1 ? (imLen != 1 ? 1 : 3) : 0; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + opCode += memSize != 1 ? (imLen != 1 ? 1 : 3) : 0; + ADD_66H_P_BY_SIZE(memSize); + ADD_REX_W_BY_SIZE(memSize); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86BSwap: + case kX86InstGroupX86BSwap: if (encoded == ENC_OPS(Reg, None, None)) { - opReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); opCode += opReg & 0x7; - ADD_REX_W(o0->getSize() == 8); + ADD_REX_W_BY_SIZE(o0->getSize()); ADD_REX_B(opReg); goto _EmitX86Op; } break; - case kInstGroupX86BTest: + case kX86InstGroupX86BTest: if (encoded == ENC_OPS(Reg, Reg, None)) { - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, None)) { - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } @@ -1229,36 +1319,39 @@ _Prepare: imVal = static_cast(o1)->getInt64(); imLen = 1; - opCode = info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, Imm, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Imm, None)) { - rmMem = static_cast(o0); + if (o0->getSize() == 0) + goto _IllegalInst; + + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Call: + case kX86InstGroupX86Call: if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } // The following instructions use the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Imm, None, None)) { imVal = static_cast(o0)->getInt64(); @@ -1288,7 +1381,7 @@ _Prepare: } break; - case kInstGroupX86Enter: + case kX86InstGroupX86Enter: if (encoded == ENC_OPS(Imm, Imm, None)) { EMIT_BYTE(0xC8); EMIT_WORD(static_cast(o1)->getUInt16()); @@ -1297,63 +1390,55 @@ _Prepare: } break; - case kInstGroupX86Imul: + case kX86InstGroupX86Imul: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + if (encoded == ENC_OPS(Reg, None, None)) { opCode = 0xF6 + (o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - opReg = 5; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { opCode = 0xF6 + (o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - opReg = 5; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } // The following instructions use 0x0FAF opcode. - opCode = kInstOpCode_MM_0F | 0xAF; + opCode &= kX86InstOpCode_PP_66; + opCode |= kX86InstOpCode_MM_0F | 0xAF; if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); goto _EmitX86M; } // The following instructions use 0x69/0x6B opcode. - opCode = 0x6B; + opCode &= kX86InstOpCode_PP_66; + opCode |= 0x6B; if (encoded == ENC_OPS(Reg, Imm, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - imVal = static_cast(o1)->getInt64(); imLen = 1; @@ -1362,7 +1447,7 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); rmReg = opReg; goto _EmitX86R; } @@ -1370,9 +1455,6 @@ _Prepare: if (encoded == ENC_OPS(Reg, Reg, Imm)) { ASMJIT_ASSERT(o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -1381,17 +1463,14 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { ASMJIT_ASSERT(o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -1400,42 +1479,39 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupX86IncDec: + case kX86InstGroupX86IncDec: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); // INC r16|r32 is not encodable in 64-bit mode. if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) { - opCode = info->_opCode[1] + (static_cast(rmReg) & 0x7); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + opCode &= kX86InstOpCode_PP_66; + opCode |= extendedInfo.getSecondaryOpCode() + (static_cast(rmReg) & 0x7); goto _EmitX86Op; } else { opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); goto _EmitX86R; } } if (encoded == ENC_OPS(Mem, None, None)) { opCode += o0->getSize() != 1; - rmMem = static_cast(o0); - - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Int: + case kX86InstGroupX86Int: if (encoded == ENC_OPS(Imm, None, None)) { imVal = static_cast(o0)->getInt64(); uint8_t imm8 = static_cast(imVal & 0xFF); @@ -1451,7 +1527,7 @@ _Prepare: } break; - case kInstGroupX86Jcc: + case kX86InstGroupX86Jcc: if (encoded == ENC_OPS(Label, None, None)) { label = self->getLabelDataById(static_cast(o0)->getId()); @@ -1507,9 +1583,9 @@ _Prepare: } break; - case kInstGroupX86Jecxz: + case kX86InstGroupX86Jecxz: if (encoded == ENC_OPS(Reg, Label, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == kRegIndexCx); + ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == kX86RegIndexCx); if ((Arch == kArchX86 && o0->getSize() == 2) || (Arch == kArchX64 && o0->getSize() == 4)) { @@ -1538,14 +1614,14 @@ _Prepare: } break; - case kInstGroupX86Jmp: + case kX86InstGroupX86Jmp: if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } @@ -1601,18 +1677,18 @@ _Prepare: } break; - case kInstGroupX86Lea: + case kX86InstGroupX86Lea: if (encoded == ENC_OPS(Reg, Mem, None)) { - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupX86Mov: + case kX86InstGroupX86Mov: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -1623,8 +1699,8 @@ _Prepare: static_cast(o1)->isGpd() || static_cast(o1)->isGpq() ); opCode = 0x8E; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); goto _EmitX86R; } @@ -1634,8 +1710,8 @@ _Prepare: static_cast(o0)->isGpd() || static_cast(o0)->isGpq() ); opCode = 0x8C; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); goto _EmitX86R; } // Reg <- Reg @@ -1645,22 +1721,22 @@ _Prepare: static_cast(o0)->isGpd() || static_cast(o0)->isGpq() ); opCode = 0x8A + (o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); goto _EmitX86R; } } if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); // Sreg <- Mem - if (static_cast(o0)->isRegType(kRegTypeSeg)) { + if (static_cast(o0)->isRegType(kX86RegTypeSeg)) { opCode = 0x8E; opReg--; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); goto _EmitX86M; } // Reg <- Mem @@ -1670,32 +1746,32 @@ _Prepare: static_cast(o0)->isGpd() || static_cast(o0)->isGpq() ); opCode = 0x8A + (o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); goto _EmitX86M; } } if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); - // Mem <- Sreg + // X86Mem <- Sreg if (static_cast(o1)->isSeg()) { opCode = 0x8C; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); goto _EmitX86M; } - // Mem <- Reg + // X86Mem <- Reg else { ASMJIT_ASSERT(static_cast(o1)->isGpb() || static_cast(o1)->isGpw() || static_cast(o1)->isGpd() || static_cast(o1)->isGpq() ); opCode = 0x88 + (o1->getSize() != 1); - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); goto _EmitX86M; } } @@ -1706,7 +1782,7 @@ _Prepare: imLen = o0->getSize(); opReg = 0; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); // Optimize instruction size by using 32-bit immediate if possible. if (Arch == kArchX64 && imLen == 8 && IntUtil::isInt32(imVal)) { @@ -1717,73 +1793,78 @@ _Prepare: } else { opCode = 0xB0 + (static_cast(o0->getSize() != 1) << 3) + (static_cast(rmReg) & 0x7); - ADD_REX_W(imLen == 8); + ADD_REX_W_BY_SIZE(imLen); ADD_REX_B(rmReg); goto _EmitX86OpI; } } if (encoded == ENC_OPS(Mem, Imm, None)) { + uint32_t memSize = o0->getSize(); + + if (memSize == 0) + goto _IllegalInst; + imVal = static_cast(o1)->getInt64(); - imLen = IntUtil::iMin(o0->getSize(), 4); + imLen = IntUtil::iMin(memSize, 4); - opCode = 0xC6 + (o0->getSize() != 1); + opCode = 0xC6 + (memSize != 1); opReg = 0; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(memSize); + ADD_REX_W_BY_SIZE(memSize); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86MovSxZx: + case kX86InstGroupX86MovSxZx: if (encoded == ENC_OPS(Reg, Reg, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupX86MovSxd: + case kX86InstGroupX86MovSxd: if (encoded == ENC_OPS(Reg, Reg, None)) { ADD_REX_W(true); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_REX_W(true); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupX86MovPtr: + case kX86InstGroupX86MovPtr: if (encoded == ENC_OPS(Reg, Imm, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == 0); + ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == 0); opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); imVal = static_cast(o1)->getInt64(); imLen = self->_regSize; @@ -1791,14 +1872,14 @@ _Prepare: } // The following instruction uses the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Imm, Reg, None)) { - ASMJIT_ASSERT(static_cast(o1)->getRegIndex() == 0); + ASMJIT_ASSERT(static_cast(o1)->getRegIndex() == 0); opCode += o1->getSize() != 1; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); imVal = static_cast(o0)->getInt64(); imLen = self->_regSize; @@ -1806,13 +1887,13 @@ _Prepare: } break; - case kInstGroupX86Push: + case kX86InstGroupX86Push: if (encoded == ENC_OPS(Reg, None, None)) { - if (o0->isRegType(kRegTypeSeg)) { - uint32_t segment = static_cast(o0)->getRegIndex(); - ASMJIT_ASSERT(segment < kRegCountSeg); + if (o0->isRegType(kX86RegTypeSeg)) { + uint32_t segment = static_cast(o0)->getRegIndex(); + ASMJIT_ASSERT(segment < kX86SegCount); - if (segment >= kSegFs) + if (segment >= kX86SegFs) EMIT_BYTE(0x0F); EMIT_BYTE(x86OpCodePushSeg[segment]); @@ -1832,13 +1913,13 @@ _Prepare: } // ... Fall through ... - case kInstGroupX86Pop: + case kX86InstGroupX86Pop: if (encoded == ENC_OPS(Reg, None, None)) { - if (o0->isRegType(kRegTypeSeg)) { - uint32_t segment = static_cast(o0)->getRegIndex(); - ASMJIT_ASSERT(segment < kRegCountSeg); + if (o0->isRegType(kX86RegTypeSeg)) { + uint32_t segment = static_cast(o0)->getRegIndex(); + ASMJIT_ASSERT(segment < kX86SegCount); - if (segment >= kSegFs) + if (segment >= kX86SegFs) EMIT_BYTE(0x0F); EMIT_BYTE(x86OpCodePopSeg[segment]); @@ -1849,10 +1930,10 @@ _GroupPop_Gp: ASMJIT_ASSERT(static_cast(o0)->getSize() == 2 || static_cast(o0)->getSize() == self->_regSize); - opReg = static_cast(o0)->getRegIndex(); - opCode = info->_opCode[1] + (opReg & 7); + opReg = static_cast(o0)->getRegIndex(); + opCode = extendedInfo.getSecondaryOpCode() + (opReg & 7); - ADD_66H_P(o0->getSize() == 2); + ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_B(opReg); goto _EmitX86Op; @@ -1860,19 +1941,19 @@ _GroupPop_Gp: } if (encoded == ENC_OPS(Mem, None, None)) { - ADD_66H_P(o0->getSize() == 2); + ADD_66H_P_BY_SIZE(o0->getSize()); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Rep: + case kX86InstGroupX86Rep: // Emit REP 0xF2 or 0xF3 prefix first. EMIT_BYTE(0xF2 + opReg); goto _EmitX86Op; - case kInstGroupX86Ret: + case kX86InstGroupX86Ret: if (encoded == ENC_OPS(None, None, None)) { EMIT_BYTE(0xC3); goto _EmitDone; @@ -1892,22 +1973,22 @@ _GroupPop_Gp: } break; - case kInstGroupX86Rot: + case kX86InstGroupX86Rot: opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, Reg, None)) { - ASMJIT_ASSERT(static_cast(o1)->isRegCode(kRegTypeGpbLo, kRegIndexCx)); + ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); opCode += 2; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, None)) { - ASMJIT_ASSERT(static_cast(o1)->isRegCode(kRegTypeGpbLo, kRegIndexCx)); + ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); opCode += 2; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } @@ -1915,22 +1996,25 @@ _GroupPop_Gp: imVal = static_cast(o1)->getInt64() & 0xFF; imLen = imVal != 1; if (imLen) - opCode -= 16; - rmReg = static_cast(o0)->getRegIndex(); + opCode -= 0x10; + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Imm, None)) { + if (o0->getSize() == 0) + goto _IllegalInst; + imVal = static_cast(o1)->getInt64() & 0xFF; imLen = imVal != 1; if (imLen) opCode -= 0x10; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Set: + case kX86InstGroupX86Set: if (encoded == ENC_OPS(Reg, None, None)) { ASMJIT_ASSERT(o0->getSize() == 1); @@ -1941,35 +2025,35 @@ _GroupPop_Gp: if (encoded == ENC_OPS(Mem, None, None)) { ASMJIT_ASSERT(o0->getSize() <= 1); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Shlrd: + case kX86InstGroupX86Shlrd: if (encoded == ENC_OPS(Reg, Reg, Imm)) { ASMJIT_ASSERT(o0->getSize() == o1->getSize()); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, Imm)) { - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } @@ -1977,36 +2061,36 @@ _GroupPop_Gp: opCode++; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - ASMJIT_ASSERT(static_cast(o2)->isRegCode(kRegTypeGpbLo, kRegIndexCx)); + ASMJIT_ASSERT(static_cast(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); ASMJIT_ASSERT(o0->getSize() == o1->getSize()); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, Reg)) { - ASMJIT_ASSERT(static_cast(o2)->isRegCode(kRegTypeGpbLo, kRegIndexCx)); + ASMJIT_ASSERT(static_cast(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Test: + case kX86InstGroupX86Test: if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() == o1->getSize()); opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); opReg = static_cast(o1)->getRegIndex(); rmReg = static_cast(o0)->getRegIndex(); @@ -2015,70 +2099,73 @@ _GroupPop_Gp: if (encoded == ENC_OPS(Mem, Reg, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } // The following instructions use the secondary opcode. - opCode = info->_opCode[1] + (o0->getSize() != 1); - opReg = opCode >> kInstOpCode_O_Shift; + opCode = extendedInfo.getSecondaryOpCode() + (o0->getSize() != 1); + opReg = opCode >> kX86InstOpCode_O_Shift; if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); imLen = IntUtil::iMin(o0->getSize(), 4); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + // Alternate Form - AL, AX, EAX, RAX. - if (static_cast(o0)->getRegIndex() == 0) { - opCode = 0xA8 + (o0->getSize() != 1); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + if (static_cast(o0)->getRegIndex() == 0) { + opCode &= kX86InstOpCode_PP_66; + opCode |= 0xA8 + (o0->getSize() != 1); goto _EmitX86OpI; } - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Imm, None)) { - ASMJIT_ASSERT(o0->getSize() != 0); + if (o0->getSize() == 0) + goto _IllegalInst; imVal = static_cast(o1)->getInt64(); imLen = IntUtil::iMin(o0->getSize(), 4); - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupX86Xchg: + case kX86InstGroupX86Xchg: if (encoded == ENC_OPS(Reg, Mem, None)) { opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } // ... fall through ... - case kInstGroupX86Xadd: + case kX86InstGroupX86Xadd: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); // Special opcode for 'xchg ?ax, reg'. - if (code == kInstXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) { + if (code == kX86InstIdXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) { // One of them is zero, it doesn't matter if the instruction's form is // 'xchg ?ax, reg' or 'xchg reg, ?ax'. opReg += rmReg; @@ -2089,26 +2176,22 @@ _GroupPop_Gp: opReg &= 0x7; } - opCode = 0x90 + opReg; - - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + opCode &= kX86InstOpCode_PP_66; + opCode |= 0x90 + opReg; goto _EmitX86Op; } opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, None)) { opCode += o1->getSize() != 1; - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } break; @@ -2117,13 +2200,13 @@ _GroupPop_Gp: // [Fpu] // ------------------------------------------------------------------------ - case kInstGroupFpuOp: + case kX86InstGroupFpuOp: goto _EmitFpuOp; - case kInstGroupFpuArith: + case kX86InstGroupFpuArith: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); rmReg += opReg; // We switch to the alternative opcode if the first operand is zero. @@ -2143,19 +2226,19 @@ _EmitFpArith_Reg: // set already. _EmitFpArith_Mem: opCode = (o0->getSize() == 4) ? 0xD8 : 0xDC; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupFpuCom: + case kX86InstGroupFpuCom: if (encoded == ENC_OPS(None, None, None)) { rmReg = 1; goto _EmitFpArith_Reg; } if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); goto _EmitFpArith_Reg; } @@ -2164,91 +2247,91 @@ _EmitFpArith_Mem: } break; - case kInstGroupFpuFldFst: + case kX86InstGroupFpuFldFst: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); - if (o0->getSize() == 4 && (info->_flags & kInstFlagMem4)) { + if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) { goto _EmitX86M; } - if (o0->getSize() == 8 && (info->_flags & kInstFlagMem8)) { + if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) { opCode += 4; goto _EmitX86M; } - if (o0->getSize() == 10 && (info->_flags & kInstFlagMem10)) { - opCode = info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + if (o0->getSize() == 10 && info.hasInstFlag(kX86InstFlagMem10)) { + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; goto _EmitX86M; } } if (encoded == ENC_OPS(Reg, None, None)) { - if (code == kInstFld) { - opCode = 0xD9C0 + static_cast(o0)->getRegIndex(); + if (code == kX86InstIdFld) { + opCode = 0xD9C0 + static_cast(o0)->getRegIndex(); goto _EmitFpuOp; } - if (code == kInstFst) { - opCode = 0xDDD0 + static_cast(o0)->getRegIndex(); + if (code == kX86InstIdFst) { + opCode = 0xDDD0 + static_cast(o0)->getRegIndex(); goto _EmitFpuOp; } - if (code == kInstFstp) { - opCode = 0xDDD8 + static_cast(o0)->getRegIndex(); + if (code == kX86InstIdFstp) { + opCode = 0xDDD8 + static_cast(o0)->getRegIndex(); goto _EmitFpuOp; } } break; - case kInstGroupFpuM: + case kX86InstGroupFpuM: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); - if (o0->getSize() == 2 && (info->_flags & kInstFlagMem2)) { + if (o0->getSize() == 2 && info.hasInstFlag(kX86InstFlagMem2)) { opCode += 4; goto _EmitX86M; } - if (o0->getSize() == 4 && (info->_flags & kInstFlagMem4)) { + if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) { goto _EmitX86M; } - if (o0->getSize() == 8 && (info->_flags & kInstFlagMem8)) { - opCode = info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) { + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; goto _EmitX86M; } } break; - case kInstGroupFpuRDef: + case kX86InstGroupFpuRDef: if (encoded == ENC_OPS(None, None, None)) { opCode += 1; goto _EmitFpuOp; } // ... Fall through ... - case kInstGroupFpuR: + case kX86InstGroupFpuR: if (encoded == ENC_OPS(Reg, None, None)) { - opCode += static_cast(o0)->getRegIndex(); + opCode += static_cast(o0)->getRegIndex(); goto _EmitFpuOp; } break; - case kInstGroupFpuStsw: + case kX86InstGroupFpuStsw: if (encoded == ENC_OPS(Reg, None, None)) { - if (static_cast(o0)->getRegIndex() != 0) + if (static_cast(o0)->getRegIndex() != 0) goto _IllegalInst; - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); goto _EmitX86Op; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; @@ -2257,35 +2340,32 @@ _EmitFpArith_Mem: // [Ext] // ------------------------------------------------------------------------ - case kInstGroupExtCrc: + case kX86InstGroupExtCrc: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + if (encoded == ENC_OPS(Reg, Reg, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegType() == kRegTypeGpd || - static_cast(o0)->getRegType() == kRegTypeGpq); + ASMJIT_ASSERT(static_cast(o0)->getRegType() == kX86RegTypeGpd || + static_cast(o0)->getRegType() == kX86RegTypeGpq); opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegType() == kRegTypeGpd || - static_cast(o0)->getRegType() == kRegTypeGpq); + ASMJIT_ASSERT(static_cast(o0)->getRegType() == kX86RegTypeGpd || + static_cast(o0)->getRegType() == kX86RegTypeGpq); opCode += o0->getSize() != 1; - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); - - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupExtExtract: + case kX86InstGroupExtExtract: if (encoded == ENC_OPS(Reg, Reg, Imm)) { ADD_66H_P(static_cast(o1)->isXmm()); @@ -2299,19 +2379,19 @@ _EmitFpArith_Mem: if (encoded == ENC_OPS(Mem, Reg, Imm)) { // Secondary opcode for 'pextrw' instruction (SSE2). - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); ADD_66H_P(static_cast(o1)->isXmm()); imVal = static_cast(o2)->getInt64(); imLen = 1; opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupExtFence: + case kX86InstGroupExtFence: if (Arch == kArchX64 && opX) { EMIT_BYTE(0x40 | opX); } @@ -2321,27 +2401,27 @@ _EmitFpArith_Mem: EMIT_BYTE(0xC0 | (opReg << 3)); goto _EmitDone; - case kInstGroupExtMov: - case kInstGroupExtMovNoRexW: - ASMJIT_ASSERT(info->_opFlags[0] != 0); - ASMJIT_ASSERT(info->_opFlags[1] != 0); + case kX86InstGroupExtMov: + case kX86InstGroupExtMovNoRexW: + ASMJIT_ASSERT(extendedInfo._opFlags[0] != 0); + ASMJIT_ASSERT(extendedInfo._opFlags[1] != 0); - // Check parameters Gpd|Gpq|Mm|Xmm <- Gpd|Gpq|Mm|Xmm|Mem|Imm. - ASMJIT_ASSERT(!((o0->isMem() && (info->_opFlags[0] & kInstOpMem) == 0) || - (o0->isRegType(kRegTypeMm ) && (info->_opFlags[0] & kInstOpMm ) == 0) || - (o0->isRegType(kRegTypeXmm) && (info->_opFlags[0] & kInstOpXmm) == 0) || - (o0->isRegType(kRegTypeGpd) && (info->_opFlags[0] & kInstOpGd ) == 0) || - (o0->isRegType(kRegTypeGpq) && (info->_opFlags[0] & kInstOpGq ) == 0) || - (o1->isMem() && (info->_opFlags[1] & kInstOpMem) == 0) || - (o1->isRegType(kRegTypeMm ) && (info->_opFlags[1] & kInstOpMm ) == 0) || - (o1->isRegType(kRegTypeXmm) && (info->_opFlags[1] & kInstOpXmm) == 0) || - (o1->isRegType(kRegTypeGpd) && (info->_opFlags[1] & kInstOpGd ) == 0) || - (o1->isRegType(kRegTypeGpq) && (info->_opFlags[1] & kInstOpGq ) == 0) )); + // Check parameters Gpd|Gpq|Mm|Xmm <- Gpd|Gpq|Mm|Xmm|X86Mem|Imm. + ASMJIT_ASSERT(!((o0->isMem() && (extendedInfo._opFlags[0] & kX86InstOpMem) == 0) || + (o0->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[0] & kX86InstOpMm ) == 0) || + (o0->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[0] & kX86InstOpXmm) == 0) || + (o0->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[0] & kX86InstOpGd ) == 0) || + (o0->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[0] & kX86InstOpGq ) == 0) || + (o1->isMem() && (extendedInfo._opFlags[1] & kX86InstOpMem) == 0) || + (o1->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[1] & kX86InstOpMm ) == 0) || + (o1->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[1] & kX86InstOpXmm) == 0) || + (o1->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[1] & kX86InstOpGd ) == 0) || + (o1->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[1] & kX86InstOpGq ) == 0) )); // Gp|Mm|Xmm <- Gp|Mm|Xmm if (encoded == ENC_OPS(Reg, Reg, None)) { - ADD_REX_W(static_cast(o0)->isGpq() && (info->getGroup() != kInstGroupExtMovNoRexW)); - ADD_REX_W(static_cast(o1)->isGpq() && (info->getGroup() != kInstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2350,50 +2430,50 @@ _EmitFpArith_Mem: // Gp|Mm|Xmm <- Mem if (encoded == ENC_OPS(Reg, Mem, None)) { - ADD_REX_W(static_cast(o0)->isGpq() && (info->getGroup() != kInstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } // The following instruction uses opCode[1]. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); - // Mem <- Gp|Mm|Xmm + // X86Mem <- Gp|Mm|Xmm if (encoded == ENC_OPS(Mem, Reg, None)) { - ADD_REX_W(static_cast(o1)->isGpq() && (info->getGroup() != kInstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupExtMovBe: + case kX86InstGroupExtMovBe: if (encoded == ENC_OPS(Reg, Mem, None)) { - ADD_66H_P(o0->getSize() == 2); - ADD_REX_W(o0->getSize() == 8); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); goto _EmitX86M; } // The following instruction uses the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Mem, Reg, None)) { - ADD_66H_P(o1->getSize() == 2); - ADD_REX_W(o1->getSize() == 8); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupExtMovD: + case kX86InstGroupExtMovD: _EmitMmMovD: opReg = static_cast(o0)->getRegIndex(); ADD_66H_P(static_cast(o0)->isXmm()); @@ -2406,12 +2486,12 @@ _EmitMmMovD: // Mm/Xmm <- Mem if (encoded == ENC_OPS(Reg, Mem, None)) { - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } // The following instructions use the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); opReg = static_cast(o1)->getRegIndex(); ADD_66H_P(static_cast(o1)->isXmm()); @@ -2421,103 +2501,103 @@ _EmitMmMovD: goto _EmitX86R; } - // Mem <- Mm/Xmm + // X86Mem <- Mm/Xmm if (encoded == ENC_OPS(Mem, Reg, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupExtMovQ: + case kX86InstGroupExtMovQ: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); // Mm <- Mm if (static_cast(o0)->isMm() && static_cast(o1)->isMm()) { - opCode = kInstOpCode_PP_00 | kInstOpCode_MM_0F | 0x6F; + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F; goto _EmitX86R; } // Xmm <- Xmm if (static_cast(o0)->isXmm() && static_cast(o1)->isXmm()) { - opCode = kInstOpCode_PP_F3 | kInstOpCode_MM_0F | 0x7E; + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E; goto _EmitX86R; } // Mm <- Xmm (Movdq2q) if (static_cast(o0)->isMm() && static_cast(o1)->isXmm()) { - opCode = kInstOpCode_PP_F2 | kInstOpCode_MM_0F | 0xD6; + opCode = kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | 0xD6; goto _EmitX86R; } // Xmm <- Mm (Movq2dq) if (static_cast(o0)->isXmm() && static_cast(o1)->isMm()) { - opCode = kInstOpCode_PP_F3 | kInstOpCode_MM_0F | 0xD6; + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0xD6; goto _EmitX86R; } } if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); // Mm <- Mem if (static_cast(o0)->isMm()) { - opCode = kInstOpCode_PP_00 | kInstOpCode_MM_0F | 0x6F; + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F; goto _EmitX86M; } // Xmm <- Mem if (static_cast(o0)->isXmm()) { - opCode = kInstOpCode_PP_F3 | kInstOpCode_MM_0F | 0x7E; + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E; goto _EmitX86M; } } if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); - // Mem <- Mm + // X86Mem <- Mm if (static_cast(o1)->isMm()) { - opCode = kInstOpCode_PP_00 | kInstOpCode_MM_0F | 0x7F; + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x7F; goto _EmitX86M; } - // Mem <- Xmm + // X86Mem <- Xmm if (static_cast(o1)->isXmm()) { - opCode = kInstOpCode_PP_66 | kInstOpCode_MM_0F | 0xD6; + opCode = kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | 0xD6; goto _EmitX86M; } } if (Arch == kArchX64) { - // Movq in other case is simply promoted Movd instruction by REX prefix. + // Movq in other case is simply a promoted MOVD instruction to 64-bit. ADD_REX_W(true); - opCode = kInstOpCode_PP_00 | kInstOpCode_MM_0F | 0x6E; + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6E; goto _EmitMmMovD; } break; - case kInstGroupExtPrefetch: + case kX86InstGroupExtPrefetch: if (encoded == ENC_OPS(Mem, Imm, None)) { opReg = static_cast(o1)->getUInt32() & 0x3; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitX86M; } break; - case kInstGroupExtRm_PQ: - ADD_66H_P(o0->isRegType(kRegTypeXmm) || o1->isRegType(kRegTypeXmm)); + case kX86InstGroupExtRm_PQ: + ADD_66H_P(o0->isRegType(kX86RegTypeXmm) || o1->isRegType(kX86RegTypeXmm)); // ... Fall through ... - case kInstGroupExtRm_Q: - ADD_REX_W(o0->isRegType(kRegTypeGpq) || o1->isRegType(kRegTypeGpq) || (o1->isMem() && o1->getSize() == 8)); + case kX86InstGroupExtRm_Q: + ADD_REX_W(o0->isRegType(kX86RegTypeGpq) || o1->isRegType(kX86RegTypeGpq) || (o1->isMem() && o1->getSize() == 8)); // ... Fall through ... - case kInstGroupExtRm: + case kX86InstGroupExtRm: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2526,14 +2606,14 @@ _EmitMmMovD: if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupExtRm_P: + case kX86InstGroupExtRm_P: if (encoded == ENC_OPS(Reg, Reg, None)) { - ADD_66H_P(static_cast(o0)->isXmm() || static_cast(o1)->isXmm()); + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2544,12 +2624,12 @@ _EmitMmMovD: ADD_66H_P(static_cast(o0)->isXmm()); opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupExtRmRi: + case kX86InstGroupExtRmRi: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2558,13 +2638,13 @@ _EmitMmMovD: if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } // The following instruction uses the secondary opcode. - opCode = info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); @@ -2575,9 +2655,9 @@ _EmitMmMovD: } break; - case kInstGroupExtRmRi_P: + case kX86InstGroupExtRmRi_P: if (encoded == ENC_OPS(Reg, Reg, None)) { - ADD_66H_P(static_cast(o0)->isXmm() || static_cast(o1)->isXmm()); + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2588,13 +2668,13 @@ _EmitMmMovD: ADD_66H_P(static_cast(o0)->isXmm()); opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } // The following instruction uses the secondary opcode. - opCode = info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; if (encoded == ENC_OPS(Reg, Imm, None)) { ADD_66H_P(static_cast(o0)->isXmm()); @@ -2607,7 +2687,7 @@ _EmitMmMovD: } break; - case kInstGroupExtRmi: + case kX86InstGroupExtRmi: imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -2619,17 +2699,17 @@ _EmitMmMovD: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; - case kInstGroupExtRmi_P: + case kX86InstGroupExtRmi_P: imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - ADD_66H_P(static_cast(o0)->isXmm() || static_cast(o1)->isXmm()); + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2640,7 +2720,7 @@ _EmitMmMovD: ADD_66H_P(static_cast(o0)->isXmm()); opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; @@ -2649,13 +2729,13 @@ _EmitMmMovD: // [Group - 3dNow] // ------------------------------------------------------------------------ - case kInstGroup3dNow: + case kX86InstGroup3dNow: // Every 3dNow instruction starts with 0x0F0F and the actual opcode is // stored as 8-bit immediate. imVal = opCode & 0xFF; imLen = 1; - opCode = kInstOpCode_MM_0F | 0x0F; + opCode = kX86InstOpCode_MM_0F | 0x0F; opReg = static_cast(o0)->getRegIndex(); if (encoded == ENC_OPS(Reg, Reg, None)) { @@ -2664,7 +2744,7 @@ _EmitMmMovD: } if (encoded == ENC_OPS(Reg, Mem, None)) { - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitX86M; } break; @@ -2673,21 +2753,21 @@ _EmitMmMovD: // [Avx] // ------------------------------------------------------------------------ - case kInstGroupAvxOp: + case kX86InstGroupAvxOp: goto _EmitAvxOp; - case kInstGroupAvxM: + case kX86InstGroupAvxM: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxMr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxMr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxMr: + case kX86InstGroupAvxMr: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); rmReg = static_cast(o0)->getRegIndex(); @@ -2696,16 +2776,16 @@ _EmitMmMovD: if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxMri_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxMri_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxMri: + case kX86InstGroupAvxMri: imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -2717,16 +2797,16 @@ _EmitMmMovD: if (encoded == ENC_OPS(Mem, Reg, Imm)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxRm_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRm: + case kX86InstGroupAvxRm: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2735,16 +2815,16 @@ _EmitMmMovD: if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRmi: + case kX86InstGroupAvxRmi: imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -2756,16 +2836,16 @@ _EmitMmMovD: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRvm_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvm: + case kX86InstGroupAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Reg)) { _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); @@ -2777,16 +2857,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } break; - case kInstGroupAvxRvmr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvmr: + case kX86InstGroupAvxRvmr: if (!o3->isReg()) goto _IllegalInst; @@ -2803,16 +2883,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } break; - case kInstGroupAvxRvmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvmi: + case kX86InstGroupAvxRvmi: if (!o3->isImm()) goto _IllegalInst; @@ -2829,12 +2909,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } break; - case kInstGroupAvxRmv: + case kX86InstGroupAvxRmv: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2845,12 +2925,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRmvi: + case kX86InstGroupAvxRmvi: if (!o3->isImm()) goto _IllegalInst; @@ -2867,16 +2947,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRmMr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRmMr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRmMr: + case kX86InstGroupAvxRmMr: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -2885,25 +2965,25 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } // The following instruction uses the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxRvmRmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvmRmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvmRmi: + case kX86InstGroupAvxRvmRmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o2)->getRegIndex(); @@ -2914,13 +2994,13 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } // The following instructions use the secondary opcode. - opCode &= kInstOpCode_L_Mask; - opCode |= info->_opCode[1]; + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -2933,12 +3013,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRvmMr: + case kX86InstGroupAvxRvmMr: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o2)->getRegIndex(); @@ -2949,12 +3029,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } // The following instructions use the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); @@ -2964,16 +3044,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxRvmMvr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvmMvr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvmMvr: + case kX86InstGroupAvxRvmMvr: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o2)->getRegIndex(); @@ -2984,27 +3064,27 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } // The following instruction uses the secondary opcode. - opCode &= kInstOpCode_L_Mask; - opCode |= info->_opCode[1]; + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Mem, Reg, Reg)) { opReg = static_cast(o2)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxRvmVmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvmVmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvmVmi: + case kX86InstGroupAvxRvmVmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o2)->getRegIndex(); @@ -3015,14 +3095,14 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } // The following instruction uses the secondary opcode. - opCode &= kInstOpCode_L_Mask; - opCode |= info->_opCode[1]; - opReg = opCode >> kInstOpCode_O_Shift; + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -3035,12 +3115,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxVm: + case kX86InstGroupAvxVm: if (encoded == ENC_OPS(Reg, Reg, None)) { opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; rmReg = static_cast(o1)->getRegIndex(); @@ -3049,16 +3129,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, None)) { opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxVmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxVmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxVmi: + case kX86InstGroupAvxVmi: imVal = static_cast(o3)->getInt64(); imLen = 1; @@ -3070,16 +3150,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } break; - case kInstGroupAvxRvrmRvmr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupAvxRvrmRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupAvxRvrmRvmr: + case kX86InstGroupAvxRvrmRvmr: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { imVal = static_cast(o3)->getRegIndex() << 4; imLen = 1; @@ -3097,7 +3177,7 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + rmMem = static_cast(o3); ADD_VEX_W(true); goto _EmitAvxM; @@ -3109,56 +3189,56 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } break; - case kInstGroupAvxMovSsSd: + case kX86InstGroupAvxMovSsSd: if (encoded == ENC_OPS(Reg, Reg, Reg)) { goto _EmitAvxRvm; } if (encoded == ENC_OPS(Reg, Mem, None)) { opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitAvxM; } if (encoded == ENC_OPS(Mem, Reg, None)) { opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + rmMem = static_cast(o0); goto _EmitAvxM; } break; - case kInstGroupAvxGatherEx: + case kX86InstGroupAvxGatherEx: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); uint32_t vSib = rmMem->getVSib(); - if (vSib == kMemVSibGpz) + if (vSib == kX86MemVSibGpz) goto _IllegalInst; - ADD_VEX_L(vSib == kMemVSibYmm); + ADD_VEX_L(vSib == kX86MemVSibYmm); goto _EmitAvxV; } break; - case kInstGroupAvxGather: + case kX86InstGroupAvxGather: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); uint32_t vSib = rmMem->getVSib(); - if (vSib == kMemVSibGpz) + if (vSib == kX86MemVSibGpz) goto _IllegalInst; - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o2)->isYmm()); + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o2)->isYmm()); goto _EmitAvxV; } break; @@ -3167,12 +3247,12 @@ _EmitAvxRvm: // [FMA4] // ------------------------------------------------------------------------ - case kInstGroupFma4_P: + case kX86InstGroupFma4_P: // It's fine to just check the first operand, second is just for sanity. - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupFma4: + case kX86InstGroupFma4: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { imVal = static_cast(o3)->getRegIndex() << 4; imLen = 1; @@ -3190,7 +3270,7 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + rmMem = static_cast(o3); ADD_VEX_W(true); goto _EmitAvxM; @@ -3202,7 +3282,7 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitAvxM; } @@ -3212,11 +3292,11 @@ _EmitAvxRvm: // [XOP] // ------------------------------------------------------------------------ - case kInstGroupXopRm_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupXopRm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupXopRm: + case kX86InstGroupXopRm: if (encoded == ENC_OPS(Reg, Reg, None)) { opReg = static_cast(o0)->getRegIndex(); rmReg = static_cast(o1)->getRegIndex(); @@ -3225,12 +3305,12 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, None)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitXopM; } break; - case kInstGroupXopRvmRmv: + case kX86InstGroupXopRvmRmv: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; @@ -3242,7 +3322,7 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitXopM; } @@ -3250,7 +3330,7 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); ADD_VEX_W(true); goto _EmitXopM; @@ -3258,7 +3338,7 @@ _EmitAvxRvm: break; - case kInstGroupXopRvmRmi: + case kX86InstGroupXopRvmRmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; @@ -3269,7 +3349,7 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Reg)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitXopM; } @@ -3277,14 +3357,14 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); ADD_VEX_W(true); goto _EmitXopM; } // The following instructions use the secondary opcode. - opCode = info->_opCode[1]; + opCode = extendedInfo.getSecondaryOpCode(); imVal = static_cast(o2)->getInt64(); imLen = 1; @@ -3297,16 +3377,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Mem, Imm)) { opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + rmMem = static_cast(o1); goto _EmitXopM; } break; - case kInstGroupXopRvmr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupXopRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupXopRvmr: + case kX86InstGroupXopRvmr: if (!o3->isReg()) goto _IllegalInst; @@ -3323,16 +3403,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitXopM; } break; - case kInstGroupXopRvmi_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupXopRvmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupXopRvmi: + case kX86InstGroupXopRvmi: if (!o3->isImm()) goto _IllegalInst; @@ -3349,16 +3429,16 @@ _EmitAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Mem)) { opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitXopM; } break; - case kInstGroupXopRvrmRvmr_P: - ADD_VEX_L(static_cast(o0)->isYmm() || static_cast(o1)->isYmm()); + case kX86InstGroupXopRvrmRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kInstGroupXopRvrmRvmr: + case kX86InstGroupXopRvrmRvmr: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { imVal = static_cast(o3)->getRegIndex() << 4; imLen = 1; @@ -3376,7 +3456,7 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + rmMem = static_cast(o3); ADD_VEX_W(true); goto _EmitXopM; @@ -3388,7 +3468,7 @@ _EmitAvxRvm: opReg = static_cast(o0)->getRegIndex(); opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + rmMem = static_cast(o2); goto _EmitXopM; } @@ -3499,7 +3579,7 @@ _EmitX86M: mIndex = rmMem->getIndex(); // Size override prefix. - if (rmMem->hasBaseOrIndex()) { + if (rmMem->hasBaseOrIndex() && rmMem->getMemType() != kMemTypeLabel) { if (Arch == kArchX86) { if (!rmMem->hasGpdBase()) EMIT_BYTE(0x67); @@ -3540,12 +3620,17 @@ _EmitX86M: // Instruction opcodes. EMIT_MM(opCode); EMIT_OP(opCode); + // ... Fall through ... + + // -------------------------------------------------------------------------- + // [Emit - SIB] + // -------------------------------------------------------------------------- _EmitSib: dispOffset = rmMem->getDisplacement(); if (rmMem->isBaseIndexType()) { if (mIndex >= kInvalidReg) { - if (mBase == kRegIndexSp) { + if (mBase == kX86RegIndexSp) { if (dispOffset == 0) { // [Esp/Rsp/R12]. EMIT_BYTE(x86EncodeMod(0, opReg, 4)); @@ -3564,7 +3649,7 @@ _EmitSib: EMIT_DWORD(static_cast(dispOffset)); } } - else if (mBase != kRegIndexBp && dispOffset == 0) { + else if (mBase != kX86RegIndexBp && dispOffset == 0) { // [Base]. EMIT_BYTE(x86EncodeMod(0, opReg, mBase)); } @@ -3583,11 +3668,10 @@ _EmitSib: uint32_t shift = rmMem->getShift(); // Esp/Rsp/R12 register can't be used as an index. - if (Arch == kArchX64) - mIndex &= 0x7; - ASMJIT_ASSERT(mIndex != kRegIndexSp); + mIndex &= 0x7; + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); - if (mBase != kRegIndexBp && dispOffset == 0) { + if (mBase != kX86RegIndexBp && dispOffset == 0) { // [Base + Index * Scale]. EMIT_BYTE(x86EncodeMod(0, opReg, 4)); EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); @@ -3614,7 +3698,7 @@ _EmitSib: else { // [Index * Scale + Disp32]. uint32_t shift = rmMem->getShift(); - ASMJIT_ASSERT(mIndex != kRegIndexSp); + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); EMIT_BYTE(x86EncodeMod(0, opReg, 4)); EMIT_BYTE(x86EncodeSib(shift, mIndex, 5)); @@ -3651,7 +3735,7 @@ _EmitSib: EMIT_DWORD(static_cast(dispOffset)); } } - else { + else /* if (Arch === kArchX64) */ { if (rmMem->getMemType() == kMemTypeLabel) { // [RIP + Disp32]. label = self->getLabelDataById(rmMem->_vmem.base); @@ -3684,7 +3768,7 @@ _EmitSib: else { // [Disp32 + Index * Scale]. mIndex &= 0x7; - ASMJIT_ASSERT(mIndex != kRegIndexSp); + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); uint32_t shift = rmMem->getShift(); EMIT_BYTE(x86EncodeSib(shift, mIndex, 5)); @@ -3745,16 +3829,16 @@ _EmitFpuOp: uint32_t vex_XvvvvLpp; \ uint32_t vex_rxbmmmmm; \ \ - vex_XvvvvLpp = (opCode >> (kInstOpCode_L_Shift - 2)) & 0x04; \ - vex_XvvvvLpp += (opCode >> (kInstOpCode_PP_Shift)) & 0x03; \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ vex_XvvvvLpp += (opX << 4) & 0x80; \ \ - vex_rxbmmmmm = (opCode >> kInstOpCode_MM_Shift) & 0x1F; \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ \ - if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kInstOptionVex3) != 0) { \ + if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { \ vex_rxbmmmmm |= static_cast(opReg << 4) & 0x80; \ vex_rxbmmmmm ^= 0xE0; \ vex_XvvvvLpp ^= 0x78; \ @@ -3781,13 +3865,13 @@ _EmitAvxOp: { uint32_t vex_XvvvvLpp; - vex_XvvvvLpp = (opCode >> (kInstOpCode_L_Shift - 2)) & 0x04; - vex_XvvvvLpp |= (opCode >> (kInstOpCode_PP_Shift)); + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); vex_XvvvvLpp |= 0xF8; // Encode 3-byte VEX prefix only if specified in options. - if ((options & kInstOptionVex3) != 0) { - uint32_t vex_rxbmmmmm = (opCode >> kInstOpCode_MM_Shift) | 0xE0; + if ((options & kX86InstOptionVex3) != 0) { + uint32_t vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) | 0xE0; EMIT_BYTE(kVex3Byte); EMIT_OP(vex_rxbmmmmm); @@ -3807,15 +3891,15 @@ _EmitAvxR: uint32_t vex_XvvvvLpp; uint32_t vex_rxbmmmmm; - vex_XvvvvLpp = (opCode >> (kInstOpCode_L_Shift - 2)) & 0x04; - vex_XvvvvLpp |= (opCode >> (kInstOpCode_PP_Shift)); + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); vex_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); vex_XvvvvLpp |= (opX << 4) & 0x80; - vex_rxbmmmmm = (opCode >> kInstOpCode_MM_Shift) & 0x1F; + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; vex_rxbmmmmm |= (rmReg << 2) & 0x20; - if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kInstOptionVex3) != 0) { + if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { vex_rxbmmmmm |= static_cast(opReg & 0x08) << 4; vex_rxbmmmmm ^= 0xE0; vex_XvvvvLpp ^= 0x78; @@ -3862,7 +3946,7 @@ _EmitAvxV: if (rmMem->isBaseIndexType()) { uint32_t shift = rmMem->getShift(); - if (mBase != kRegIndexBp && dispOffset == 0) { + if (mBase != kX86RegIndexBp && dispOffset == 0) { // [Base + Index * Scale]. EMIT_BYTE(x86EncodeMod(0, opReg, 4)); EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); @@ -3942,12 +4026,12 @@ _EmitAvxV: uint32_t vex_XvvvvLpp; \ uint32_t vex_rxbmmmmm; \ \ - vex_XvvvvLpp = (opCode >> (kInstOpCode_L_Shift - 2)) & 0x04; \ - vex_XvvvvLpp += (opCode >> (kInstOpCode_PP_Shift)) & 0x03; \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ vex_XvvvvLpp += (opX << 4) & 0x80; \ \ - vex_rxbmmmmm = (opCode >> kInstOpCode_MM_Shift) & 0x1F; \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ \ @@ -3969,12 +4053,12 @@ _EmitXopR: uint32_t xop_XvvvvLpp; uint32_t xop_rxbmmmmm; - xop_XvvvvLpp = (opCode >> (kInstOpCode_L_Shift - 2)) & 0x04; - xop_XvvvvLpp |= (opCode >> (kInstOpCode_PP_Shift)); + xop_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + xop_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); xop_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); xop_XvvvvLpp |= (opX << 4) & 0x80; - xop_rxbmmmmm = (opCode >> kInstOpCode_MM_Shift) & 0x1F; + xop_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; xop_rxbmmmmm |= (rmReg << 2) & 0x20; xop_rxbmmmmm |= static_cast(opReg & 0x08) << 4; @@ -4118,10 +4202,6 @@ _EmitDone: return kErrorOk; -_UnknownInst: - self->_comment = NULL; - return self->setError(kErrorUnknownInst); - _GrowBuffer: ASMJIT_PROPAGATE_ERROR(self->_grow(16)); @@ -4129,67 +4209,21 @@ _GrowBuffer: goto _Prepare; } -} // x86x64 namespace +Error X86Assembler::_emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { +#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#elif !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#else + if (_arch == kArchX86) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); + else + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#endif +} + } // asmjit namespace -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -Assembler::Assembler(Runtime* runtime) : X86X64Assembler(runtime) { - _arch = kArchX86; - _regSize = 4; -} - -Assembler::~Assembler() {} - -size_t Assembler::_relocCode(void* dst, Ptr base) const { - return X86X64Assembler_relocCode(this, dst, base); -} - -Error Assembler::_emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { - return X86X64Assembler_emit(this, code, &o0, &o1, &o2, &o3); -} - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -Assembler::Assembler(Runtime* runtime) : X86X64Assembler(runtime) { - _arch = kArchX64; - _regSize = 8; -} - -Assembler::~Assembler() {} - -size_t Assembler::_relocCode(void* dst, Ptr base) const { - return X86X64Assembler_relocCode(this, dst, base); -} - -Error Assembler::_emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { - return X86X64Assembler_emit(this, code, &o0, &o1, &o2, &o3); -} - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - // [Api-End] #include "../apiend.h" diff --git a/src/asmjit/x86/x86assembler.h b/src/asmjit/x86/x86assembler.h index 93d2e28..df86b54 100644 --- a/src/asmjit/x86/x86assembler.h +++ b/src/asmjit/x86/x86assembler.h @@ -12,19 +12,481 @@ #include "../base/assembler.h" #include "../x86/x86inst.h" #include "../x86/x86operand.h" -#include "../x86/x86regs.h" -#include "../x86/x86util.h" // [Api-Begin] #include "../apibegin.h" namespace asmjit { -namespace x86x64 { + +//! \addtogroup asmjit_x86_general +//! \{ // ============================================================================ -// [CodeGen-Begin] +// [asmjit::X86Assembler] // ============================================================================ +// \internal +#define ASMJIT_X86_EMIT_OPTIONS(_Class_) \ + /*! Force short form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& short_() { \ + _options |= kInstOptionShortForm; \ + return *this; \ + } \ + \ + /*! Force long form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& long_() { \ + _options |= kInstOptionLongForm; \ + return *this; \ + } \ + \ + /*! Condition is likely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& taken() { \ + _options |= kInstOptionTaken; \ + return *this; \ + } \ + \ + /*! Condition is unlikely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& notTaken() { \ + _options |= kInstOptionNotTaken; \ + return *this; \ + } \ + \ + /*! Use LOCK prefix. */ \ + ASMJIT_INLINE _Class_& lock() { \ + _options |= kX86InstOptionLock; \ + return *this; \ + } \ + \ + /*! Force REX prefix. */ \ + ASMJIT_INLINE _Class_& rex() { \ + _options |= kX86InstOptionRex; \ + return *this; \ + } \ + \ + /*! Force 3-byte VEX prefix. */ \ + ASMJIT_INLINE _Class_& vex3() { \ + _options |= kX86InstOptionVex3; \ + 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::host; +//! +//! // Create Assembler instance. +//! Assembler 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 emits the binary code for you. All registers +//! are in `asmjit` namespace, so it's very comfortable to use it (look at +//! first line). There is also used method `imm()` to create an immediate value. +//! Use `imm_u()` to create unsigned immediate value. +//! +//! 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 `x86::Assembler` 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: +//! +//! ~~~ +//! // 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 `ptr()` to make memory operand. Some assembler +//! instructions (single operand ones) needs to have specified memory operand +//! size. For example `a.inc(ptr(eax))` can't be called, because the meaning is +//! ambiguous, 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]. +//! ~~~ +//! +//! Calling JIT Code +//! ---------------- +//! +//! While you are over from emitting instructions, you can make your function +//! by using `Assembler::make()` method. This method will use memory +//! manager to allocate virtual memory and relocates generated code to it. For +//! memory allocation is used global memory manager by default and memory is +//! freeable, but of course this default behavior can be overridden specifying +//! your memory manager and allocation type. If you want to do with code +//! something else you can always override make() method and do what you want. +//! +//! You can get size of generated code by `getCodeSize()` or `getOffset()` +//! methods. These methods returns you code size or more precisely the current +//! code offset in bytes. The `takeCode()` function can be used to take the +//! internal buffer and reset the code generator, but the buffer taken 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 `VMem::alloc()` function can be used allocate a memory where the code can +//! be executed or more preferably `VMemMgr` which has interface +//! similar to `malloc/free` and can allocate chunks of various sizes. +//! +//! The next example shows how to allocate memory where the code can be executed: +//! +//! ~~~ +//! using namespace asmjit; +//! +//! JitRuntime runtime; +//! Assembler a(&runtime); +//! +//! // ... Your code generation ... +//! +//! // The function prototype +//! typedef void (*MyFunc)(); +//! +//! // make your function +//! MyFunc func = asmjit_cast(a.make()); +//! +//! // call your function +//! func(); +//! +//! // If you don't need your function again, free it. +//! runtime.release(func); +//! ~~~ +//! +//! This was a very primitive showing how the generated code can be executed. +//! In production noone will probably generate a function that is only called +//! once and nobody will probably free the function right after it was executed. +//! The code just shows the proper way of code generation and cleanup. +//! +//! 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: STDCALL convention is to pop stack in called function. +//! 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 or 32 +//! when AVX512 is available. +//! +//! 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 are functions `fp()`, `mm()`, `xmm()`, `ymm()` and `zmm()` +//! available. +//! +//! \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. + 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); + + // -------------------------------------------------------------------------- + // [Label] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void _bind(const Label& label); + + // -------------------------------------------------------------------------- + // [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 base) 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; + + // -------------------------------------------------------------------------- + // [Base Instructions] + // -------------------------------------------------------------------------- + #define INST_0x(_Inst_, _Code_) \ ASMJIT_INLINE Error _Inst_() { \ return emit(_Code_); \ @@ -230,6143 +692,5765 @@ namespace x86x64 { return emit(_Code_, o0, o1, o2, o3); \ } -#define ASMJIT_X86X64_EMIT_OPTIONS(_Class_) \ - /*! Force short form of jmp/jcc instruction. */ \ - ASMJIT_INLINE _Class_& short_() { \ - _options |= kInstOptionShortForm; \ - return *this; \ - } \ - \ - /*! Force long form of jmp/jcc instruction. */ \ - ASMJIT_INLINE _Class_& long_() { \ - _options |= kInstOptionLongForm; \ - return *this; \ - } \ - \ - /*! Condition is likely to be taken (has only benefit on P4). */ \ - ASMJIT_INLINE _Class_& taken() { \ - _options |= kInstOptionTaken; \ - return *this; \ - } \ - \ - /*! Condition is unlikely to be taken (has only benefit on P4). */ \ - ASMJIT_INLINE _Class_& notTaken() { \ - _options |= kInstOptionNotTaken; \ - return *this; \ - } \ - \ - /*! Use LOCK prefix. */ \ - ASMJIT_INLINE _Class_& lock() { \ - _options |= kInstOptionLock; \ - return *this; \ - } \ - \ - /*! Force REX prefix. */ \ - ASMJIT_INLINE _Class_& rex() { \ - _options |= kInstOptionRex; \ - return *this; \ - } \ - \ - /*! Force 3-byte VEX prefix. */ \ - ASMJIT_INLINE _Class_& vex3() { \ - _options |= kInstOptionVex3; \ - return *this; \ - } - -//! \addtogroup asmjit_x86x64_general -//! \{ - -// ============================================================================ -// [asmjit::x86x64::X86X64Assembler] -// ============================================================================ - -//! 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 `BaseAssembler` -//! instance to an error state in production mode. -//! -//! Code Generation -//! --------------- -//! -//! To generate code is only needed to create instance of `BaseAssembler` -//! and to use intrinsics. See example how to do that: -//! -//! ~~~ -//! // Use asmjit namespace. -//! using namespace asmjit; -//! using namespace asmjit::host; -//! -//! // Create Assembler instance. -//! Assembler 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 emits the binary code for you. All registers -//! are in `asmjit` namespace, so it's very comfortable to use it (look at -//! first line). There is also used method `imm()` to create an immediate value. -//! Use `imm_u()` to create unsigned immediate value. -//! -//! 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 `x86::BaseAssembler` 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: -//! -//! ~~~ -//! // 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 `ptr()` to make memory operand. Some assembler -//! instructions (single operand ones) needs to have specified memory operand -//! size. For example `a.inc(ptr(eax))` can't be called, because the meaning is -//! ambiguous, 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]. -//! ~~~ -//! -//! Calling JIT Code -//! ---------------- -//! -//! While you are over from emitting instructions, you can make your function -//! by using `BaseAssembler::make()` method. This method will use memory -//! manager to allocate virtual memory and relocates generated code to it. For -//! memory allocation is used global memory manager by default and memory is -//! freeable, but of course this default behavior can be overridden specifying -//! your memory manager and allocation type. If you want to do with code -//! something else you can always override make() method and do what you want. -//! -//! You can get size of generated code by `getCodeSize()` or `getOffset()` -//! methods. These methods returns you code size or more precisely the current -//! code offset in bytes. The `takeCode()` function can be used to take the -//! internal buffer and clear the code generator, but the buffer taken has to -//! be freed manually. -//! -//! 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 `VMem::alloc()` function can be used allocate a memory where the code can -//! be executed or more preferably `VMemMgr` which has interface -//! similar to `malloc/free` and can allocate chunks of various sizes. -//! -//! The next example shows how to allocate memory where the code can be executed: -//! -//! ~~~ -//! using namespace asmjit; -//! -//! JitRuntime runtime; -//! Assembler a(&runtime); -//! -//! // ... Your code generation ... -//! -//! // The function prototype -//! typedef void (*MyFunc)(); -//! -//! // make your function -//! MyFunc func = asmjit_cast(a.make()); -//! -//! // call your function -//! func(); -//! -//! // If you don't need your function again, free it. -//! runtime.release(func); -//! ~~~ -//! -//! This was a very primitive showing how the generated code can be executed. -//! In production noone will probably generate a function that is only called -//! once and nobody will probably free the function right after it was executed. -//! The code just shows the proper way of code generation and cleanup. -//! -//! 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: STDCALL convention is to pop stack in called function. -//! 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 @c Compiler class that is designed for higher level code -//! generation. -//! -//! Advanced Code Generation -//! ------------------------ -//! -//! This section describes some advanced generation features of @c 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(BaseAssembler& a, const GpReg& dst, const GpReg& src, const GpReg& 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 `GpReg` 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 registers. The X64 (AMD64) architecture extends count -//! of Gp registers and Xmm registers to 16. Use the \ref kRegCountBase constant to -//! get count of Gp or Xmm registers or \ref kRegCountGp, \ref kRegCountMm and \ref -//! kRegCountXmm constants individually. -//! -//! To build register from index (value from 0 inclusive to `kRegNum...` exclusive) -//! use `gpd()`, `gpq()` or `gpz()` functions. To create a 8 or 16-bit register use -//! `gpw()`, `gpb_lo()` or `gpb_hi()`. To create other registers there are similar -//! methods like `mm()`, `xmm()`, `ymm()` and `fp()`. -//! -//! So our function call to `genCopyDWord` can be also used like this: -//! -//! ~~~ -//! genCopyDWord(a, gpd(kRegIndexDi), gpd(kRegIndexSi), gpd(kRegIndexBx)); -//! ~~~ -//! -//! `kRegIndex...` are constants defined by `kRegIndex` enum. You can use your -//! own register allocator (or register slot manager) to alloc / free registers -//! so `kRegIndex...` values can be replaced by your variables (`0` to -//! `kRegNum...-1`). -//! -//! @sa `X86X64Compiler`. -struct X86X64Assembler : public BaseAssembler { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_API X86X64Assembler(Runtime* runtime); - ASMJIT_API virtual ~X86X64Assembler(); - - // -------------------------------------------------------------------------- - // [Label] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual void _bind(const Label& label); - - // -------------------------------------------------------------------------- - // [Embed] - // -------------------------------------------------------------------------- - - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE void db(uint8_t x) { embed(&x, 1); } - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE void dw(uint16_t x) { embed(&x, 2); } - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE void dd(uint32_t x) { embed(&x, 4); } - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE void dq(uint64_t x) { embed(&x, 8); } - - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE void dint8(int8_t x) { embed(&x, sizeof(int8_t)); } - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE void duint8(uint8_t x) { embed(&x, sizeof(uint8_t)); } - - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE void dint16(int16_t x) { embed(&x, sizeof(int16_t)); } - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE void duint16(uint16_t x) { embed(&x, sizeof(uint16_t)); } - - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE void dint32(int32_t x) { embed(&x, sizeof(int32_t)); } - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE void duint32(uint32_t x) { embed(&x, sizeof(uint32_t)); } - - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE void dint64(int64_t x) { embed(&x, sizeof(int64_t)); } - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE void duint64(uint64_t x) { embed(&x, sizeof(uint64_t)); } - - //! Add float data to the instuction stream. - ASMJIT_INLINE void dfloat(float x) { embed(&x, sizeof(float)); } - //! Add double data to the instuction stream. - ASMJIT_INLINE void ddouble(double x) { embed(&x, sizeof(double)); } - - //! Add pointer data to the instuction stream. - ASMJIT_INLINE void dptr(void* x) { embed(&x, sizeof(void*)); } - - //! Add Mm data to the instuction stream. - ASMJIT_INLINE void dmm(const MmData& x) { embed(&x, sizeof(MmData)); } - //! Add Xmm data to the instuction stream. - ASMJIT_INLINE void dxmm(const XmmData& x) { embed(&x, sizeof(XmmData)); } - //! Add Ymm data to the instuction stream. - ASMJIT_INLINE void dymm(const YmmData& x) { embed(&x, sizeof(YmmData)); } - - //! Add data in a given structure instance to the instuction 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); - - // ------------------------------------------------------------------------- - // [Options] - // ------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(X86X64Assembler) - - // -------------------------------------------------------------------------- - // [Base Instructions] - // -------------------------------------------------------------------------- - //! Add with Carry. - INST_2x(adc, kInstAdc, GpReg, GpReg) + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86GpReg) //! \overload - INST_2x(adc, kInstAdc, GpReg, Mem) + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86Mem) //! \overload - INST_2i(adc, kInstAdc, GpReg, Imm) + INST_2i(adc, kX86InstIdAdc, X86GpReg, Imm) //! \overload - INST_2x(adc, kInstAdc, Mem, GpReg) + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpReg) //! \overload - INST_2i(adc, kInstAdc, Mem, Imm) + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) //! Add. - INST_2x(add, kInstAdd, GpReg, GpReg) + INST_2x(add, kX86InstIdAdd, X86GpReg, X86GpReg) //! \overload - INST_2x(add, kInstAdd, GpReg, Mem) + INST_2x(add, kX86InstIdAdd, X86GpReg, X86Mem) //! \overload - INST_2i(add, kInstAdd, GpReg, Imm) + INST_2i(add, kX86InstIdAdd, X86GpReg, Imm) //! \overload - INST_2x(add, kInstAdd, Mem, GpReg) + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpReg) //! \overload - INST_2i(add, kInstAdd, Mem, Imm) + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) //! And. - INST_2x(and_, kInstAnd, GpReg, GpReg) + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86GpReg) //! \overload - INST_2x(and_, kInstAnd, GpReg, Mem) + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86Mem) //! \overload - INST_2i(and_, kInstAnd, GpReg, Imm) + INST_2i(and_, kX86InstIdAnd, X86GpReg, Imm) //! \overload - INST_2x(and_, kInstAnd, Mem, GpReg) + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpReg) //! \overload - INST_2i(and_, kInstAnd, Mem, Imm) + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) //! Bit scan forward. - INST_2x_(bsf, kInstBsf, GpReg, GpReg, !o0.isGpb()) + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86GpReg, !o0.isGpb()) //! \overload - INST_2x_(bsf, kInstBsf, GpReg, Mem, !o0.isGpb()) + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86Mem, !o0.isGpb()) //! Bit scan reverse. - INST_2x_(bsr, kInstBsr, GpReg, GpReg, !o0.isGpb()) + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86GpReg, !o0.isGpb()) //! \overload - INST_2x_(bsr, kInstBsr, GpReg, Mem, !o0.isGpb()) + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86Mem, !o0.isGpb()) //! Byte swap (32-bit or 64-bit registers only) (i486). - INST_1x_(bswap, kInstBswap, GpReg, o0.getSize() >= 4) + INST_1x_(bswap, kX86InstIdBswap, X86GpReg, o0.getSize() >= 4) //! Bit test. - INST_2x(bt, kInstBt, GpReg, GpReg) + INST_2x(bt, kX86InstIdBt, X86GpReg, X86GpReg) //! \overload - INST_2i(bt, kInstBt, GpReg, Imm) + INST_2i(bt, kX86InstIdBt, X86GpReg, Imm) //! \overload - INST_2x(bt, kInstBt, Mem, GpReg) + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpReg) //! \overload - INST_2i(bt, kInstBt, Mem, Imm) + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) //! Bit test and complement. - INST_2x(btc, kInstBtc, GpReg, GpReg) + INST_2x(btc, kX86InstIdBtc, X86GpReg, X86GpReg) //! \overload - INST_2i(btc, kInstBtc, GpReg, Imm) + INST_2i(btc, kX86InstIdBtc, X86GpReg, Imm) //! \overload - INST_2x(btc, kInstBtc, Mem, GpReg) + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpReg) //! \overload - INST_2i(btc, kInstBtc, Mem, Imm) + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) //! Bit test and reset. - INST_2x(btr, kInstBtr, GpReg, GpReg) + INST_2x(btr, kX86InstIdBtr, X86GpReg, X86GpReg) //! \overload - INST_2i(btr, kInstBtr, GpReg, Imm) + INST_2i(btr, kX86InstIdBtr, X86GpReg, Imm) //! \overload - INST_2x(btr, kInstBtr, Mem, GpReg) + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpReg) //! \overload - INST_2i(btr, kInstBtr, Mem, Imm) + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) //! Bit test and set. - INST_2x(bts, kInstBts, GpReg, GpReg) + INST_2x(bts, kX86InstIdBts, X86GpReg, X86GpReg) //! \overload - INST_2i(bts, kInstBts, GpReg, Imm) + INST_2i(bts, kX86InstIdBts, X86GpReg, Imm) //! \overload - INST_2x(bts, kInstBts, Mem, GpReg) + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpReg) //! \overload - INST_2i(bts, kInstBts, Mem, Imm) + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) //! Call. - INST_1x(call, kInstCall, GpReg) + INST_1x(call, kX86InstIdCall, X86GpReg) //! \overload - INST_1x(call, kInstCall, Mem) + INST_1x(call, kX86InstIdCall, X86Mem) //! \overload - INST_1x(call, kInstCall, Label) + INST_1x(call, kX86InstIdCall, Label) //! \overload - INST_1x(call, kInstCall, Imm) + INST_1x(call, kX86InstIdCall, Imm) //! \overload - ASMJIT_INLINE Error call(void* dst) { return call(Imm((intptr_t)dst)); } + ASMJIT_INLINE Error call(Ptr o0) { return call(Imm(o0)); } //! Clear carry flag. - INST_0x(clc, kInstClc) + INST_0x(clc, kX86InstIdClc) //! Clear direction flag. - INST_0x(cld, kInstCld) + INST_0x(cld, kX86InstIdCld) //! Complement carry flag. - INST_0x(cmc, kInstCmc) + INST_0x(cmc, kX86InstIdCmc) //! Convert BYTE to WORD (AX <- Sign Extend AL). - INST_0x(cbw, kInstCbw) - //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). - INST_0x(cwd, kInstCwd) - //! Convert WORD to DWORD (EAX <- Sign Extend AX). - INST_0x(cwde, kInstCwde) + INST_0x(cbw, kX86InstIdCbw) //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). - INST_0x(cdq, kInstCdq) + 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, kInstCmov, X86Util::condToCmovcc, GpReg, GpReg) + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86GpReg) //! Conditional move. - INST_2cc(cmov, kInstCmov, X86Util::condToCmovcc, GpReg, Mem) + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86Mem) //! Compare two operands. - INST_2x(cmp, kInstCmp, GpReg, GpReg) + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86GpReg) //! \overload - INST_2x(cmp, kInstCmp, GpReg, Mem) + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86Mem) //! \overload - INST_2i(cmp, kInstCmp, GpReg, Imm) + INST_2i(cmp, kX86InstIdCmp, X86GpReg, Imm) //! \overload - INST_2x(cmp, kInstCmp, Mem, GpReg) + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpReg) //! \overload - INST_2i(cmp, kInstCmp, Mem, Imm) + 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, kInstCmpxchg, GpReg, GpReg) + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86GpReg, X86GpReg) //! \overload - INST_2x(cmpxchg, kInstCmpxchg, Mem, GpReg) + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86Mem, X86GpReg) - //! Compares the 64-bit value in EDX:EAX with the memory operand (Pentium). - INST_1x(cmpxchg8b, kInstCmpxchg8b, Mem) + //! 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, kInstCpuid) + INST_0x(cpuid, kX86InstIdCpuid) //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). - INST_2x_(crc32, kInstCrc32, GpReg, GpReg, o0.isRegType(kRegTypeGpd) || o0.isRegType(kRegTypeGpq)) + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) //! \overload - INST_2x_(crc32, kInstCrc32, GpReg, Mem, o0.isRegType(kRegTypeGpd) || o0.isRegType(kRegTypeGpq)) + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! 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, kInstDec, GpReg) + INST_1x(dec, kX86InstIdDec, X86GpReg) //! \overload - INST_1x(dec, kInstDec, Mem) + INST_1x(dec, kX86InstIdDec, X86Mem) //! Unsigned divide (xDX:xAX <- xDX:xAX / o0). - INST_1x(div, kInstDiv, GpReg) + INST_1x(div, kX86InstIdDiv, X86GpReg) //! \overload - INST_1x(div, kInstDiv, Mem) + INST_1x(div, kX86InstIdDiv, X86Mem) //! Make stack frame for procedure parameters. - INST_2x(enter, kInstEnter, Imm, Imm) + INST_2x(enter, kX86InstIdEnter, Imm, Imm) //! Signed divide (xDX:xAX <- xDX:xAX / op). - INST_1x(idiv, kInstIdiv, GpReg) + INST_1x(idiv, kX86InstIdIdiv, X86GpReg) //! \overload - INST_1x(idiv, kInstIdiv, Mem) + INST_1x(idiv, kX86InstIdIdiv, X86Mem) //! Signed multiply (xDX:xAX <- xAX * o0). - INST_1x(imul, kInstImul, GpReg) + INST_1x(imul, kX86InstIdImul, X86GpReg) //! \overload - INST_1x(imul, kInstImul, Mem) + INST_1x(imul, kX86InstIdImul, X86Mem) //! Signed multiply. - INST_2x(imul, kInstImul, GpReg, GpReg) + INST_2x(imul, kX86InstIdImul, X86GpReg, X86GpReg) //! \overload - INST_2x(imul, kInstImul, GpReg, Mem) + INST_2x(imul, kX86InstIdImul, X86GpReg, X86Mem) //! \overload - INST_2i(imul, kInstImul, GpReg, Imm) + INST_2i(imul, kX86InstIdImul, X86GpReg, Imm) //! Signed multiply. - INST_3i(imul, kInstImul, GpReg, GpReg, Imm) + INST_3i(imul, kX86InstIdImul, X86GpReg, X86GpReg, Imm) //! \overload - INST_3i(imul, kInstImul, GpReg, Mem, Imm) + INST_3i(imul, kX86InstIdImul, X86GpReg, X86Mem, Imm) //! Increment by 1. - INST_1x(inc, kInstInc, GpReg) + INST_1x(inc, kX86InstIdInc, X86GpReg) //! \overload - INST_1x(inc, kInstInc, Mem) + INST_1x(inc, kX86InstIdInc, X86Mem) //! Interrupt. - INST_1i(int_, kInstInt, Imm) + 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, kInstJ, X86Util::condToJcc, Label) + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) //! Short jump if CX/ECX/RCX is zero. - INST_2x_(jecxz, kInstJecxz, GpReg, Label, o0.getRegIndex() == kRegIndexCx) + INST_2x_(jecxz, kX86InstIdJecxz, X86GpReg, Label, o0.getRegIndex() == kX86RegIndexCx) //! Jump. - INST_1x(jmp, kInstJmp, GpReg) + INST_1x(jmp, kX86InstIdJmp, X86GpReg) //! \overload - INST_1x(jmp, kInstJmp, Mem) + INST_1x(jmp, kX86InstIdJmp, X86Mem) //! \overload - INST_1x(jmp, kInstJmp, Label) + INST_1x(jmp, kX86InstIdJmp, Label) //! \overload - INST_1x(jmp, kInstJmp, Imm) + INST_1x(jmp, kX86InstIdJmp, Imm) //! \overload - ASMJIT_INLINE Error jmp(void* dst) { return jmp(Imm((intptr_t)dst)); } + ASMJIT_INLINE Error jmp(Ptr dst) { return jmp(Imm(dst)); } //! Load AH from flags. - INST_0x(lahf, kInstLahf) + INST_0x(lahf, kX86InstIdLahf) //! Load effective address - INST_2x(lea, kInstLea, GpReg, Mem) + INST_2x(lea, kX86InstIdLea, X86GpReg, X86Mem) //! High level procedure exit. - INST_0x(leave, kInstLeave) + 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, kInstMov, GpReg, GpReg) + INST_2x(mov, kX86InstIdMov, X86GpReg, X86GpReg) //! \overload - INST_2x(mov, kInstMov, GpReg, Mem) + INST_2x(mov, kX86InstIdMov, X86GpReg, X86Mem) //! \overload - INST_2i(mov, kInstMov, GpReg, Imm) + INST_2i(mov, kX86InstIdMov, X86GpReg, Imm) //! \overload - INST_2x(mov, kInstMov, Mem, GpReg) + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpReg) //! \overload - INST_2i(mov, kInstMov, Mem, Imm) + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) //! Move from segment register. - INST_2x(mov, kInstMov, GpReg, SegReg) + INST_2x(mov, kX86InstIdMov, X86GpReg, X86SegReg) //! \overload - INST_2x(mov, kInstMov, Mem, SegReg) + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) //! Move to segment register. - INST_2x(mov, kInstMov, SegReg, GpReg) + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpReg) //! \overload - INST_2x(mov, kInstMov, SegReg, Mem) + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) //! Move (AL|AX|EAX|RAX <- absolute address in immediate). - ASMJIT_INLINE Error mov_ptr(const GpReg& dst, void* src) { - ASMJIT_ASSERT(dst.getRegIndex() == 0); - - Imm imm(static_cast((intptr_t)src)); - return emit(kInstMovPtr, dst, imm); + 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). - ASMJIT_INLINE Error mov_ptr(void* dst, const GpReg& src) { - ASMJIT_ASSERT(src.getRegIndex() == 0); - - Imm imm(static_cast((intptr_t)dst)); - return emit(kInstMovPtr, imm, src); + 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, kInstMovbe, GpReg, Mem, !o0.isGpb()); + INST_2x_(movbe, kX86InstIdMovbe, X86GpReg, X86Mem, !o0.isGpb()); //! \overload - INST_2x_(movbe, kInstMovbe, Mem, GpReg, !o1.isGpb()); + 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, kInstMovsx, GpReg, GpReg) + INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86GpReg) //! \overload - INST_2x(movsx, kInstMovsx, GpReg, Mem) + 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, kInstMovzx, GpReg, GpReg) + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86GpReg) //! \overload - INST_2x(movzx, kInstMovzx, GpReg, Mem) + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86Mem) //! Unsigned multiply (xDX:xAX <- xAX * o0). - INST_1x(mul, kInstMul, GpReg) + INST_1x(mul, kX86InstIdMul, X86GpReg) //! \overload - INST_1x(mul, kInstMul, Mem) + INST_1x(mul, kX86InstIdMul, X86Mem) //! Two's complement negation. - INST_1x(neg, kInstNeg, GpReg) + INST_1x(neg, kX86InstIdNeg, X86GpReg) //! \overload - INST_1x(neg, kInstNeg, Mem) + INST_1x(neg, kX86InstIdNeg, X86Mem) //! No operation. - INST_0x(nop, kInstNop) + INST_0x(nop, kX86InstIdNop) //! One's complement negation. - INST_1x(not_, kInstNot, GpReg) + INST_1x(not_, kX86InstIdNot, X86GpReg) //! \overload - INST_1x(not_, kInstNot, Mem) + INST_1x(not_, kX86InstIdNot, X86Mem) //! Or. - INST_2x(or_, kInstOr, GpReg, GpReg) + INST_2x(or_, kX86InstIdOr, X86GpReg, X86GpReg) //! \overload - INST_2x(or_, kInstOr, GpReg, Mem) + INST_2x(or_, kX86InstIdOr, X86GpReg, X86Mem) //! \overload - INST_2i(or_, kInstOr, GpReg, Imm) + INST_2i(or_, kX86InstIdOr, X86GpReg, Imm) //! \overload - INST_2x(or_, kInstOr, Mem, GpReg) + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpReg) //! \overload - INST_2i(or_, kInstOr, Mem, Imm) + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) //! Pop a value from the stack. - INST_1x_(pop, kInstPop, GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(pop, kX86InstIdPop, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) //! \overload - INST_1x_(pop, kInstPop, Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + 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, kInstPop, SegReg, o0.getRegIndex() != kSegCs); + 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, kInstPopf) + INST_0x(popf, kX86InstIdPopf) //! Return the count of number of bits set to 1 (SSE4.2). - INST_2x_(popcnt, kInstPopcnt, GpReg, GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) //! \overload - INST_2x_(popcnt, kInstPopcnt, GpReg, Mem, !o0.isGpb()) + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb()) //! Push WORD or DWORD/QWORD on the stack. - INST_1x_(push, kInstPush, GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(push, kX86InstIdPush, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) //! Push WORD or DWORD/QWORD on the stack. - INST_1x_(push, kInstPush, Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(push, kX86InstIdPush, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) //! Push segment register on the stack. - INST_1x(push, kInstPush, SegReg) + INST_1x(push, kX86InstIdPush, X86SegReg) //! Push WORD or DWORD/QWORD on the stack. - INST_1i(push, kInstPush, Imm) + 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, kInstPushf) + INST_0x(pushf, kX86InstIdPushf) //! Rotate bits left. //! //! \note `o1` register can be only `cl`. - INST_2x(rcl, kInstRcl, GpReg, GpReg) + INST_2x(rcl, kX86InstIdRcl, X86GpReg, X86GpReg) //! \overload - INST_2x(rcl, kInstRcl, Mem, GpReg) + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpReg) //! Rotate bits left. - INST_2i(rcl, kInstRcl, GpReg, Imm) + INST_2i(rcl, kX86InstIdRcl, X86GpReg, Imm) //! \overload - INST_2i(rcl, kInstRcl, Mem, Imm) + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) //! Rotate bits right. //! //! \note `o1` register can be only `cl`. - INST_2x(rcr, kInstRcr, GpReg, GpReg) + INST_2x(rcr, kX86InstIdRcr, X86GpReg, X86GpReg) //! \overload - INST_2x(rcr, kInstRcr, Mem, GpReg) + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpReg) //! Rotate bits right. - INST_2i(rcr, kInstRcr, GpReg, Imm) + INST_2i(rcr, kX86InstIdRcr, X86GpReg, Imm) //! \overload - INST_2i(rcr, kInstRcr, Mem, Imm) + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) //! Read time-stamp counter (Pentium). - INST_0x(rdtsc, kInstRdtsc) + INST_0x(rdtsc, kX86InstIdRdtsc) //! Read time-stamp counter and processor id (Pentium). - INST_0x(rdtscp, kInstRdtscp) + INST_0x(rdtscp, kX86InstIdRdtscp) - //! Load ECX/RCX bytes from DS:[ESI/RSI] to AL. - INST_0x(rep_lodsb, kInstRepLodsb) - //! Load ECX/RCX dwords from DS:[ESI/RSI] to EAX. - INST_0x(rep_lodsd, kInstRepLodsd) - //! Load ECX/RCX Words from DS:[ESI/RSI] to AX. - INST_0x(rep_lodsw, kInstRepLodsw) + //! 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) - //! Move ECX/RCX bytes from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_0x(rep_movsb, kInstRepMovsb) - //! Move ECX/RCX dwords from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_0x(rep_movsd, kInstRepMovsd) - //! Move ECX/RCX words from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_0x(rep_movsw, kInstRepMovsw) + //! 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) - //! Fill ECX/RCX bytes at ES:[EDI/RDI] with AL. - INST_0x(rep_stosb, kInstRepStosb) - //! Fill ECX/RCX dwords at ES:[EDI/RDI] with EAX. - INST_0x(rep_stosd, kInstRepStosd) - //! Fill ECX/RCX words at ES:[EDI/RDI] with AX. - INST_0x(rep_stosw, kInstRepStosw) + //! 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 nonmatching bytes in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repe_cmpsb, kInstRepeCmpsb) - //! Repeated find nonmatching dwords in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repe_cmpsd, kInstRepeCmpsd) - //! Repeated find nonmatching words in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repe_cmpsw, kInstRepeCmpsw) + //! 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) - //! Find non-AL byte starting at ES:[EDI/RDI]. - INST_0x(repe_scasb, kInstRepeScasb) - //! Find non-EAX dword starting at ES:[EDI/RDI]. - INST_0x(repe_scasd, kInstRepeScasd) - //! Find non-AX word starting at ES:[EDI/RDI]. - INST_0x(repe_scasw, kInstRepeScasw) + //! 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 nonmatching bytes in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repne_cmpsb, kInstRepneCmpsb) - //! Repeated find nonmatching dwords in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repne_cmpsd, kInstRepneCmpsd) - //! Repeated find nonmatching words in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repne_cmpsw, kInstRepneCmpsw) + //! 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) - //! Find AL, starting at ES:[EDI/RDI]. - INST_0x(repne_scasb, kInstRepneScasb) - //! Find EAX, starting at ES:[EDI/RDI]. - INST_0x(repne_scasd, kInstRepneScasd) - //! Find AX, starting at ES:[EDI/RDI]. - INST_0x(repne_scasw, kInstRepneScasw) + //! 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, kInstRet) + INST_0x(ret, kX86InstIdRet) //! \overload - INST_1i(ret, kInstRet, Imm) + INST_1i(ret, kX86InstIdRet, Imm) //! Rotate bits left. //! //! \note `o1` register can be only `cl`. - INST_2x(rol, kInstRol, GpReg, GpReg) + INST_2x(rol, kX86InstIdRol, X86GpReg, X86GpReg) //! \overload - INST_2x(rol, kInstRol, Mem, GpReg) + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpReg) //! Rotate bits left. - INST_2i(rol, kInstRol, GpReg, Imm) + INST_2i(rol, kX86InstIdRol, X86GpReg, Imm) //! \overload - INST_2i(rol, kInstRol, Mem, Imm) + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) //! Rotate bits right. //! //! \note `o1` register can be only `cl`. - INST_2x(ror, kInstRor, GpReg, GpReg) + INST_2x(ror, kX86InstIdRor, X86GpReg, X86GpReg) //! \overload - INST_2x(ror, kInstRor, Mem, GpReg) + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpReg) //! Rotate bits right. - INST_2i(ror, kInstRor, GpReg, Imm) + INST_2i(ror, kX86InstIdRor, X86GpReg, Imm) //! \overload - INST_2i(ror, kInstRor, Mem, Imm) + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) //! Store AH into flags. - INST_0x(sahf, kInstSahf) + INST_0x(sahf, kX86InstIdSahf) //! Integer subtraction with borrow. - INST_2x(sbb, kInstSbb, GpReg, GpReg) + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86GpReg) //! \overload - INST_2x(sbb, kInstSbb, GpReg, Mem) + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86Mem) //! \overload - INST_2i(sbb, kInstSbb, GpReg, Imm) + INST_2i(sbb, kX86InstIdSbb, X86GpReg, Imm) //! \overload - INST_2x(sbb, kInstSbb, Mem, GpReg) + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpReg) //! \overload - INST_2i(sbb, kInstSbb, Mem, Imm) + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) //! Shift bits left. //! //! \note `o1` register can be only `cl`. - INST_2x(sal, kInstSal, GpReg, GpReg) + INST_2x(sal, kX86InstIdSal, X86GpReg, X86GpReg) //! \overload - INST_2x(sal, kInstSal, Mem, GpReg) + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpReg) //! Shift bits left. - INST_2i(sal, kInstSal, GpReg, Imm) + INST_2i(sal, kX86InstIdSal, X86GpReg, Imm) //! \overload - INST_2i(sal, kInstSal, Mem, Imm) + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) //! Shift bits right. //! //! \note `o1` register can be only `cl`. - INST_2x(sar, kInstSar, GpReg, GpReg) + INST_2x(sar, kX86InstIdSar, X86GpReg, X86GpReg) //! \overload - INST_2x(sar, kInstSar, Mem, GpReg) + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpReg) //! Shift bits right. - INST_2i(sar, kInstSar, GpReg, Imm) + INST_2i(sar, kX86InstIdSar, X86GpReg, Imm) //! \overload - INST_2i(sar, kInstSar, Mem, Imm) + 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, kInstSet, X86Util::condToSetcc, GpReg) + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpReg) //! Set byte on condition. - INST_1cc(set, kInstSet, X86Util::condToSetcc, Mem) + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) //! Shift bits left. //! //! \note `o1` register can be only `cl`. - INST_2x(shl, kInstShl, GpReg, GpReg) + INST_2x(shl, kX86InstIdShl, X86GpReg, X86GpReg) //! \overload - INST_2x(shl, kInstShl, Mem, GpReg) + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpReg) //! Shift bits left. - INST_2i(shl, kInstShl, GpReg, Imm) + INST_2i(shl, kX86InstIdShl, X86GpReg, Imm) //! \overload - INST_2i(shl, kInstShl, Mem, Imm) + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) //! Shift bits right. //! //! \note `o1` register can be only `cl`. - INST_2x(shr, kInstShr, GpReg, GpReg) + INST_2x(shr, kX86InstIdShr, X86GpReg, X86GpReg) //! \overload - INST_2x(shr, kInstShr, Mem, GpReg) + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpReg) //! Shift bits right. - INST_2i(shr, kInstShr, GpReg, Imm) + INST_2i(shr, kX86InstIdShr, X86GpReg, Imm) //! \overload - INST_2i(shr, kInstShr, Mem, Imm) + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) //! Double precision shift left. //! //! \note `o2` register can be only `cl` register. - INST_3x(shld, kInstShld, GpReg, GpReg, GpReg) + INST_3x(shld, kX86InstIdShld, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(shld, kInstShld, Mem, GpReg, GpReg) + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpReg, X86GpReg) //! Double precision shift left. - INST_3i(shld, kInstShld, GpReg, GpReg, Imm) + INST_3i(shld, kX86InstIdShld, X86GpReg, X86GpReg, Imm) //! \overload - INST_3i(shld, kInstShld, Mem, GpReg, Imm) + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpReg, Imm) //! Double precision shift right. //! //! \note `o2` register can be only `cl` register. - INST_3x(shrd, kInstShrd, GpReg, GpReg, GpReg) + INST_3x(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(shrd, kInstShrd, Mem, GpReg, GpReg) + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpReg, X86GpReg) //! Double precision shift right. - INST_3i(shrd, kInstShrd, GpReg, GpReg, Imm) + INST_3i(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, Imm) //! \overload - INST_3i(shrd, kInstShrd, Mem, GpReg, Imm) + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpReg, Imm) //! Set carry flag to 1. - INST_0x(stc, kInstStc) + INST_0x(stc, kX86InstIdStc) //! Set direction flag to 1. - INST_0x(std, kInstStd) + 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, kInstSub, GpReg, GpReg) + INST_2x(sub, kX86InstIdSub, X86GpReg, X86GpReg) //! \overload - INST_2x(sub, kInstSub, GpReg, Mem) + INST_2x(sub, kX86InstIdSub, X86GpReg, X86Mem) //! \overload - INST_2i(sub, kInstSub, GpReg, Imm) + INST_2i(sub, kX86InstIdSub, X86GpReg, Imm) //! \overload - INST_2x(sub, kInstSub, Mem, GpReg) + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpReg) //! \overload - INST_2i(sub, kInstSub, Mem, Imm) + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) //! Logical compare. - INST_2x(test, kInstTest, GpReg, GpReg) + INST_2x(test, kX86InstIdTest, X86GpReg, X86GpReg) //! \overload - INST_2i(test, kInstTest, GpReg, Imm) + INST_2i(test, kX86InstIdTest, X86GpReg, Imm) //! \overload - INST_2x(test, kInstTest, Mem, GpReg) + INST_2x(test, kX86InstIdTest, X86Mem, X86GpReg) //! \overload - INST_2i(test, kInstTest, Mem, Imm) + INST_2i(test, kX86InstIdTest, X86Mem, Imm) //! Undefined instruction - Raise #UD exception. - INST_0x(ud2, kInstUd2) + INST_0x(ud2, kX86InstIdUd2) //! Exchange and Add. - INST_2x(xadd, kInstXadd, GpReg, GpReg) + INST_2x(xadd, kX86InstIdXadd, X86GpReg, X86GpReg) //! \overload - INST_2x(xadd, kInstXadd, Mem, GpReg) + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpReg) //! Exchange register/memory with register. - INST_2x(xchg, kInstXchg, GpReg, GpReg) + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86GpReg) //! \overload - INST_2x(xchg, kInstXchg, Mem, GpReg) + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpReg) //! \overload - INST_2x(xchg, kInstXchg, GpReg, Mem) + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86Mem) //! Xor. - INST_2x(xor_, kInstXor, GpReg, GpReg) + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86GpReg) //! \overload - INST_2x(xor_, kInstXor, GpReg, Mem) + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86Mem) //! \overload - INST_2i(xor_, kInstXor, GpReg, Imm) + INST_2i(xor_, kX86InstIdXor, X86GpReg, Imm) //! \overload - INST_2x(xor_, kInstXor, Mem, GpReg) + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpReg) //! \overload - INST_2i(xor_, kInstXor, Mem, Imm) + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) // -------------------------------------------------------------------------- // [Fpu] // -------------------------------------------------------------------------- //! Compute 2^x - 1 (FPU). - INST_0x(f2xm1, kInstF2xm1) - + INST_0x(f2xm1, kX86InstIdF2xm1) //! Absolute value of fp0 (FPU). - INST_0x(fabs, kInstFabs) + INST_0x(fabs, kX86InstIdFabs) - //! Add `o1` to `o0` and store result in `o0` (FPU). - //! - //! \note One of dst or src must be fp0. - INST_2x_(fadd, kInstFadd, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). - INST_1x(fadd, kInstFadd, Mem) - //! Add fp0 to `o0` and POP register stack (FPU). - INST_1x(faddp, kInstFaddp, FpReg) + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add fp0 to `o0` and pop the FPU stack (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) //! \overload - INST_0x(faddp, kInstFaddp) + INST_0x(faddp, kX86InstIdFaddp) //! Load binary coded decimal (FPU). - INST_1x(fbld, kInstFbld, Mem) + INST_1x(fbld, kX86InstIdFbld, X86Mem) //! Store BCD integer and Pop (FPU). - INST_1x(fbstp, kInstFbstp, Mem) + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) //! Change fp0 sign (FPU). - INST_0x(fchs, kInstFchs) - + INST_0x(fchs, kX86InstIdFchs) //! Clear exceptions (FPU). - INST_0x(fclex, kInstFclex) + INST_0x(fclex, kX86InstIdFclex) - //! FP Conditional move (FPU). - INST_1x(fcmovb, kInstFcmovb, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovbe, kInstFcmovbe, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmove, kInstFcmove, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovnb, kInstFcmovnb, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovnbe, kInstFcmovnbe, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovne, kInstFcmovne, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovnu, kInstFcmovnu, FpReg) - //! FP Conditional move (FPU). - INST_1x(fcmovu, kInstFcmovu, FpReg) + //! Conditional move (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) //! Compare fp0 with `o0` (FPU). - INST_1x(fcom, kInstFcom, FpReg) + INST_1x(fcom, kX86InstIdFcom, X86FpReg) //! Compare fp0 with fp1 (FPU). - INST_0x(fcom, kInstFcom) + INST_0x(fcom, kX86InstIdFcom) //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU). - INST_1x(fcom, kInstFcom, Mem) - //! Compare fp0 with `o0` and pop the stack (FPU). - INST_1x(fcomp, kInstFcomp, FpReg) - //! Compare fp0 with fp1 and pop the stack (FPU). - INST_0x(fcomp, kInstFcomp) - //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the stack (FPU). - INST_1x(fcomp, kInstFcomp, Mem) - //! Compare fp0 with fp1 and pop register stack twice (FPU). - INST_0x(fcompp, kInstFcompp) + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare fp0 with `o0` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare fp0 with fp1 and pop the FPU stack (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) //! Compare fp0 and `o0` and Set EFLAGS (FPU). - INST_1x(fcomi, kInstFcomi, FpReg) - //! Compare fp0 and `o0` and Set EFLAGS and pop the stack (FPU). - INST_1x(fcomip, kInstFcomip, FpReg) + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) //! Calculate cosine of fp0 and store result in fp0 (FPU). - INST_0x(fcos, kInstFcos) + INST_0x(fcos, kX86InstIdFcos) + //! Decrement FPU stack-top pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) - //! Decrement stack-top pointer (FPU). - INST_0x(fdecstp, kInstFdecstp) - - //! Divide `o0` by `o1` (FPU). - //! - //! \note One of `o0` or `o1` register must be fp0. - INST_2x_(fdiv, kInstFdiv, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) //! Divide fp0 by 32-bit or 64-bit FP value (FPU). - INST_1x(fdiv, kInstFdiv, Mem) + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) //! Divide `o0` by fp0 (FPU). - INST_1x(fdivp, kInstFdivp, FpReg) + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) //! \overload - INST_0x(fdivp, kInstFdivp) + INST_0x(fdivp, kX86InstIdFdivp) - //! Reverse divide `o0` by `o1` (FPU). - //! - //! \note One of `o0` or `src` register must be fp0. - INST_2x_(fdivr, kInstFdivr, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). - INST_1x(fdivr, kInstFdivr, Mem) + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) //! Reverse divide `o0` by fp0 (FPU). - INST_1x(fdivrp, kInstFdivrp, FpReg) + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) //! \overload - INST_0x(fdivrp, kInstFdivrp) + INST_0x(fdivrp, kX86InstIdFdivrp) //! Free FP register (FPU). - //! - //! Sets the tag in the FPU tag register associated with register `o0` - //! to empty (11B). The contents of `o0` and the FPU stack-top pointer - //! (TOP) are not affected. - INST_1x(ffree, kInstFfree, FpReg) + INST_1x(ffree, kX86InstIdFfree, X86FpReg) //! Add 16-bit or 32-bit integer to fp0 (FPU). - INST_1x_(fiadd, kInstFiadd, Mem, o0.getSize() == 2 || o0.getSize() == 4) - + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Compare fp0 with 16-bit or 32-bit Integer (FPU). - INST_1x_(ficom, kInstFicom, Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Compare fp0 with 16-bit or 32-bit Integer and pop the stack (FPU). - INST_1x_(ficomp, kInstFicomp, Mem, o0.getSize() == 2 || o0.getSize() == 4) - + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). - INST_1x_(fidiv, kInstFidiv, Mem, o0.getSize() == 2 || o0.getSize() == 4) + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). - INST_1x_(fidivr, kInstFidivr, Mem, o0.getSize() == 2 || o0.getSize() == 4) - - //! Load 16-bit, 32-bit or 64-bit Integer and push it to the stack (FPU). - INST_1x_(fild, kInstFild, Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). - INST_1x_(fimul, kInstFimul, Mem, o0.getSize() == 2 || o0.getSize() == 4) - - //! Increment stack-top pointer (FPU). - INST_0x(fincstp, kInstFincstp) + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Increment FPU stack-top pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) //! Initialize FPU (FPU). - INST_0x(finit, kInstFinit) + INST_0x(finit, kX86InstIdFinit) //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). - INST_1x_(fisub, kInstFisub, Mem, o0.getSize() == 2 || o0.getSize() == 4) + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). - INST_1x_(fisubr, kInstFisubr, Mem, o0.getSize() == 2 || o0.getSize() == 4) + INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Initialize FPU without checking for pending unmasked exceptions (FPU). - INST_0x(fninit, kInstFninit) + INST_0x(fninit, kX86InstIdFninit) //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU). - INST_1x_(fist, kInstFist, Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop stack (FPU). - INST_1x_(fistp, kInstFistp, Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Push `o0` on the FPU stack (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) - //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU register stack (FPU). - INST_1x_(fld, kInstFld, Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) - //! Push `o0` on the FPU register stack (FPU). - INST_1x(fld, kInstFld, FpReg) - - //! Push +1.0 on the FPU register stack (FPU). - INST_0x(fld1, kInstFld1) - //! Push log2(10) on the FPU register stack (FPU). - INST_0x(fldl2t, kInstFldl2t) - //! Push log2(e) on the FPU register stack (FPU). - INST_0x(fldl2e, kInstFldl2e) - //! Push pi on the FPU register stack (FPU). - INST_0x(fldpi, kInstFldpi) - //! Push log10(2) on the FPU register stack (FPU). - INST_0x(fldlg2, kInstFldlg2) - //! Push ln(2) on the FPU register stack (FPU). - INST_0x(fldln2, kInstFldln2) - //! Push +0.0 on the FPU register stack (FPU). - INST_0x(fldz, kInstFldz) + //! Push +1.0 on the FPU stack (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! Push log2(10) on the FPU stack (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! Push log2(e) on the FPU stack (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! Push pi on the FPU stack (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! Push log10(2) on the FPU stack (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! Push ln(2) on the FPU stack (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! Push +0.0 on the FPU stack (FPU). + INST_0x(fldz, kX86InstIdFldz) //! Load x87 FPU control word (2 bytes) (FPU). - INST_1x(fldcw, kInstFldcw, Mem) + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) //! Load x87 FPU environment (14 or 28 bytes) (FPU). - INST_1x(fldenv, kInstFldenv, Mem) + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) - //! Multiply `o0` by `o1` and store result in `o0` (FPU). - //! - //! \note One of dst or src must be fp0. - INST_2x_(fmul, kInstFmul, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). - INST_1x(fmul, kInstFmul, Mem) - - //! Multiply fp0 by `o0` and POP register stack (FPU). - INST_1x(fmulp, kInstFmulp, FpReg) + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) //! \overload - INST_0x(fmulp, kInstFmulp) + INST_0x(fmulp, kX86InstIdFmulp) //! Clear exceptions (FPU). - INST_0x(fnclex, kInstFnclex) - + INST_0x(fnclex, kX86InstIdFnclex) //! No operation (FPU). - INST_0x(fnop, kInstFnop) - + INST_0x(fnop, kX86InstIdFnop) //! Save FPU state (FPU). - INST_1x(fnsave, kInstFnsave, Mem) - + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) //! Store x87 FPU environment (FPU). - INST_1x(fnstenv, kInstFnstenv, Mem) - + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) //! Store x87 FPU control word (FPU). - INST_1x(fnstcw, kInstFnstcw, Mem) + INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) //! Store x87 FPU status word to `o0` (AX) (FPU). - INST_1x_(fnstsw, kInstFnstsw, GpReg, o0.isRegCode(kRegTypeGpw, kRegIndexAx)) + INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) //! Store x87 FPU status word to `o0` (2 bytes) (FPU). - INST_1x(fnstsw, kInstFnstsw, Mem) + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) - //! Calculate arctan(fp1 / fp0) and pop the register stack (FPU). - INST_0x(fpatan, kInstFpatan) - - //! Calculate fprem(fp0, fp1) and pop the register stack (FPU). - INST_0x(fprem, kInstFprem) - //! Calculate IEEE fprem(fp0, fp1) and pop the register stack (FPU). - INST_0x(fprem1, kInstFprem1) - - //! Calculate arctan(fp0) and pop the register stack (FPU). - INST_0x(fptan, kInstFptan) - //! Round fp0 to Integer (FPU). - INST_0x(frndint, kInstFrndint) + //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Arctan(`fp0`) and pop the FPU stack (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0` to Integer (FPU). + INST_0x(frndint, kX86InstIdFrndint) //! Restore FPU state from `o0` (94 or 108 bytes) (FPU). - INST_1x(frstor, kInstFrstor, Mem) + INST_1x(frstor, kX86InstIdFrstor, X86Mem) + //! Save FPU state to `o0` (94 or 108 bytes) (FPU). + INST_1x(fsave, kX86InstIdFsave, X86Mem) - //! Save FPU state to `o0` (FPU). - //! - //! Store FPU state to 94 or 108-bytes after checking for - //! pending unmasked FP exceptions. Then reinitialize - //! the FPU. - INST_1x(fsave, kInstFsave, Mem) - - //! Scale (FPU). - //! - //! Scale fp0 by fp1. - INST_0x(fscale, kInstFscale) - - //! Calculate sine of fp0 and store result in fp0 (FPU). - INST_0x(fsin, kInstFsin) - - //! Sine and cosine (FPU). - //! - //! Compute the sine and cosine of fp0; replace fp0 with the sine - //! and push the cosine on the register stack. - INST_0x(fsincos, kInstFsincos) - - //! Square root (FPU). - //! - //! Calculates square root of fp0 and stores the result in fp0. - INST_0x(fsqrt, kInstFsqrt) - - //! Store floating point value (FPU). - //! - //! Store fp0 as 32-bit or 64-bit floating point value to `o0`. - INST_1x_(fst, kInstFst, Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Scale `fp0` by `fp1` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sine of `fp0` and store result in `fp0` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root of `fp0` and store it in `fp0` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + //! Store floating point value to 32-bit or 64-bit memory location (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) //! Store floating point value to `o0` (FPU). - INST_1x(fst, kInstFst, FpReg) + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Store floating point value to `o0` and pop the FPU stack (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) - //! Store floating point value and pop register stack (FPU). - //! - //! Store fp0 as 32-bit or 64-bit floating point value to `o0` - //! and pop register stack. - INST_1x_(fstp, kInstFstp, Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Store x87 FPU control word to `o0` (2 bytes) (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 AX (FPU). + INST_1x_(fstsw, kX86InstIdFstsw, X86GpReg, o0.getRegIndex() == kX86RegIndexAx) + //! Store x87 FPU status word (2 bytes) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) - //! Store floating point value and pop register stack (FPU). - //! - //! Store fp0 to `o0` and pop register stack. - INST_1x(fstp, kInstFstp, FpReg) - - //! Store x87 FPU control word (FPU). - //! - //! Store FPU control word to `o0` (2 bytes) after checking for pending - //! unmasked floating-point exceptions. - INST_1x(fstcw, kInstFstcw, Mem) - - //! Store x87 FPU environment (FPU). - //! - //! Store FPU environment to `o0` (14 or 28 bytes) after checking for - //! pending unmasked floating-point exceptions. Then mask all floating - //! point exceptions. - INST_1x(fstenv, kInstFstenv, Mem) - - //! Store x87 FPU status word (AX) (FPU). - INST_1x_(fstsw, kInstFstsw, GpReg, o0.isRegCode(kRegTypeGpw, kRegIndexAx)) - //! Store x87 FPU status sord (2 bytes) (FPU). - INST_1x(fstsw, kInstFstsw, Mem) - - //! Subtract `o0` from `o0` and store result in `o0` (FPU). - //! - //! \note One of dst or src must be fp0. - INST_2x_(fsub, kInstFsub, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). - INST_1x_(fsub, kInstFsub, Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Subtract fp0 from `o0` and POP register stack (FPU). - INST_1x(fsubp, kInstFsubp, FpReg) + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract fp0 from `o0` and pop FPU stack (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) //! \overload - INST_0x(fsubp, kInstFsubp) + INST_0x(fsubp, kX86InstIdFsubp) - //! Reverse subtract `o1` from `o0` and store result in `o0` (FPU). - //! - //! \note One of dst or src must be fp0. - INST_2x_(fsubr, kInstFsubr, FpReg, FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Reverse subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). - INST_1x_(fsubr, kInstFsubr, Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Reverse subtract fp0 from `o0` and POP register stack (FPU). - INST_1x(fsubrp, kInstFsubrp, FpReg) + //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) //! \overload - INST_0x(fsubrp, kInstFsubrp) + INST_0x(fsubrp, kX86InstIdFsubrp) - //! Floating point test - Compare fp0 with 0.0. (FPU). - INST_0x(ftst, kInstFtst) + //! Floating point test - Compare `fp0` with 0.0. (FPU). + INST_0x(ftst, kX86InstIdFtst) - //! Unordered compare fp0 with `o0` (FPU). - INST_1x(fucom, kInstFucom, FpReg) - //! Unordered compare fp0 with fp1 (FPU). - INST_0x(fucom, kInstFucom) - //! Unordered compare fp0 and `o0`, check for ordered values and Set EFLAGS (FPU). - INST_1x(fucomi, kInstFucomi, FpReg) - //! Unordered compare fp0 and `o0`, Check for ordered values and Set EFLAGS and pop the stack (FPU). - INST_1x(fucomip, kInstFucomip, FpReg) - //! Unordered compare fp0 with `o0` and pop register stack (FPU). - INST_1x(fucomp, kInstFucomp, FpReg) - //! Unordered compare fp0 with fp1 and pop register stack (FPU). - INST_0x(fucomp, kInstFucomp) - //! Unordered compare fp0 with fp1 and pop register stack twice (FPU). - INST_0x(fucompp, kInstFucompp) + //! Unordered compare `fp0` with `o0` (FPU). + INST_1x(fucom, kX86InstIdFucom, X86FpReg) + //! Unordered compare `fp0` with `fp1` (FPU). + INST_0x(fucom, kX86InstIdFucom) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) - INST_0x(fwait, kInstFwait) + INST_0x(fwait, kX86InstIdFwait) //! Examine fp0 (FPU). - INST_0x(fxam, kInstFxam) + INST_0x(fxam, kX86InstIdFxam) + //! Exchange content of fp0 with `o0` (FPU). + INST_1x(fxch, kX86InstIdFxch, X86FpReg) - //! Exchange register contents (FPU). - //! - //! Exchange content of fp0 with `o0`. - INST_1x(fxch, kInstFxch, FpReg) + //! 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 exponent and store to `fp0` and push significand on the FPU stack (FPU). + INST_0x(fxtract, kX86InstIdFxtract) - //! Restore FP, MMX and streaming SIMD extension states (FPU, MMX, SSE). - //! - //! Load FP and MMX technology and Streaming SIMD Extension state from - //! src (512 bytes). - INST_1x(fxrstor, kInstFxrstor, Mem) - - //! Store FP, MMX and streaming SIMD extension states (FPU, MMX, SSE). - //! - //! Store FP and MMX technology state and Streaming SIMD Extension state - //! to dst (512 bytes). - INST_1x(fxsave, kInstFxsave, Mem) - - //! Extract exponent and significand (FPU). - //! - //! Separate value in fp0 into exponent and significand, store exponent - //! in fp0 and push the significand on the register stack. - INST_0x(fxtract, kInstFxtract) - - //! Compute y * log2(x). - //! - //! Replace fp1 with (fp1 * log2(fp0)) and pop the register stack. - INST_0x(fyl2x, kInstFyl2x) - //! Compute y * log_2(x+1). - //! - //! Replace fp1 with (fp1 * (log2(fp0)+1)) and pop the register stack. - INST_0x(fyl2xp1, kInstFyl2xp1) + //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) // -------------------------------------------------------------------------- // [MMX] // -------------------------------------------------------------------------- //! Move DWORD (MMX). - INST_2x(movd, kInstMovd, Mem, MmReg) + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmReg) //! \overload - INST_2x(movd, kInstMovd, GpReg, MmReg) + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86MmReg) //! \overload - INST_2x(movd, kInstMovd, MmReg, Mem) + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86Mem) //! \overload - INST_2x(movd, kInstMovd, MmReg, GpReg) + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86GpReg) //! Move QWORD (MMX). - INST_2x(movq, kInstMovq, MmReg, MmReg) + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86MmReg) //! \overload - INST_2x(movq, kInstMovq, Mem, MmReg) + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmReg) //! \overload - INST_2x(movq, kInstMovq, MmReg, Mem) + 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, kInstPackssdw, MmReg, MmReg) + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86MmReg) //! \overload - INST_2x(packssdw, kInstPackssdw, MmReg, Mem) + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86Mem) //! Pack WORDs to BYTEs with signed saturation (MMX). - INST_2x(packsswb, kInstPacksswb, MmReg, MmReg) + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86MmReg) //! \overload - INST_2x(packsswb, kInstPacksswb, MmReg, Mem) + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (MMX). - INST_2x(packuswb, kInstPackuswb, MmReg, MmReg) + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86MmReg) //! \overload - INST_2x(packuswb, kInstPackuswb, MmReg, Mem) + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86Mem) //! Packed BYTE add (MMX). - INST_2x(paddb, kInstPaddb, MmReg, MmReg) + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86MmReg) //! \overload - INST_2x(paddb, kInstPaddb, MmReg, Mem) + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86Mem) //! Packed DWORD add (MMX). - INST_2x(paddd, kInstPaddd, MmReg, MmReg) + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86MmReg) //! \overload - INST_2x(paddd, kInstPaddd, MmReg, Mem) + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86Mem) //! Packed BYTE add with saturation (MMX). - INST_2x(paddsb, kInstPaddsb, MmReg, MmReg) + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86MmReg) //! \overload - INST_2x(paddsb, kInstPaddsb, MmReg, Mem) + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86Mem) //! Packed WORD add with saturation (MMX). - INST_2x(paddsw, kInstPaddsw, MmReg, MmReg) + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86MmReg) //! \overload - INST_2x(paddsw, kInstPaddsw, MmReg, Mem) + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86Mem) //! Packed BYTE add with unsigned saturation (MMX). - INST_2x(paddusb, kInstPaddusb, MmReg, MmReg) + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86MmReg) //! \overload - INST_2x(paddusb, kInstPaddusb, MmReg, Mem) + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86Mem) //! Packed WORD add with unsigned saturation (MMX). - INST_2x(paddusw, kInstPaddusw, MmReg, MmReg) + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86MmReg) //! \overload - INST_2x(paddusw, kInstPaddusw, MmReg, Mem) + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86Mem) //! Packed WORD add (MMX). - INST_2x(paddw, kInstPaddw, MmReg, MmReg) + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86MmReg) //! \overload - INST_2x(paddw, kInstPaddw, MmReg, Mem) + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86Mem) //! Packed bitwise and (MMX). - INST_2x(pand, kInstPand, MmReg, MmReg) + INST_2x(pand, kX86InstIdPand, X86MmReg, X86MmReg) //! \overload - INST_2x(pand, kInstPand, MmReg, Mem) + INST_2x(pand, kX86InstIdPand, X86MmReg, X86Mem) //! Packed bitwise and-not (MMX). - INST_2x(pandn, kInstPandn, MmReg, MmReg) + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86MmReg) //! \overload - INST_2x(pandn, kInstPandn, MmReg, Mem) + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86Mem) //! Packed BYTEs compare for equality (MMX). - INST_2x(pcmpeqb, kInstPcmpeqb, MmReg, MmReg) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpeqb, kInstPcmpeqb, MmReg, Mem) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86Mem) //! Packed DWORDs compare for equality (MMX). - INST_2x(pcmpeqd, kInstPcmpeqd, MmReg, MmReg) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpeqd, kInstPcmpeqd, MmReg, Mem) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86Mem) //! Packed WORDs compare for equality (MMX). - INST_2x(pcmpeqw, kInstPcmpeqw, MmReg, MmReg) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpeqw, kInstPcmpeqw, MmReg, Mem) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86Mem) //! Packed BYTEs compare if greater than (MMX). - INST_2x(pcmpgtb, kInstPcmpgtb, MmReg, MmReg) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpgtb, kInstPcmpgtb, MmReg, Mem) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86Mem) //! Packed DWORDs compare if greater than (MMX). - INST_2x(pcmpgtd, kInstPcmpgtd, MmReg, MmReg) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpgtd, kInstPcmpgtd, MmReg, Mem) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86Mem) //! Packed WORDs compare if greater than (MMX). - INST_2x(pcmpgtw, kInstPcmpgtw, MmReg, MmReg) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86MmReg) //! \overload - INST_2x(pcmpgtw, kInstPcmpgtw, MmReg, Mem) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86Mem) //! Packed WORDs multiply high (MMX). - INST_2x(pmulhw, kInstPmulhw, MmReg, MmReg) + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmulhw, kInstPmulhw, MmReg, Mem) + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86Mem) //! Packed WORDs multiply low (MMX). - INST_2x(pmullw, kInstPmullw, MmReg, MmReg) + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmullw, kInstPmullw, MmReg, Mem) + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86Mem) //! Pakced bitwise or (MMX). - INST_2x(por, kInstPor, MmReg, MmReg) + INST_2x(por, kX86InstIdPor, X86MmReg, X86MmReg) //! \overload - INST_2x(por, kInstPor, MmReg, Mem) + INST_2x(por, kX86InstIdPor, X86MmReg, X86Mem) //! Packed WORD multiply and add to packed DWORD (MMX). - INST_2x(pmaddwd, kInstPmaddwd, MmReg, MmReg) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86MmReg) //! \overload - INST_2x(pmaddwd, kInstPmaddwd, MmReg, Mem) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86Mem) //! Packed DWORD shift left logical (MMX). - INST_2x(pslld, kInstPslld, MmReg, MmReg) + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86MmReg) //! \overload - INST_2x(pslld, kInstPslld, MmReg, Mem) + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86Mem) //! \overload - INST_2i(pslld, kInstPslld, MmReg, Imm) + INST_2i(pslld, kX86InstIdPslld, X86MmReg, Imm) //! Packed QWORD shift left logical (MMX). - INST_2x(psllq, kInstPsllq, MmReg, MmReg) + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86MmReg) //! \overload - INST_2x(psllq, kInstPsllq, MmReg, Mem) + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86Mem) //! \overload - INST_2i(psllq, kInstPsllq, MmReg, Imm) + INST_2i(psllq, kX86InstIdPsllq, X86MmReg, Imm) //! Packed WORD shift left logical (MMX). - INST_2x(psllw, kInstPsllw, MmReg, MmReg) + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86MmReg) //! \overload - INST_2x(psllw, kInstPsllw, MmReg, Mem) + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86Mem) //! \overload - INST_2i(psllw, kInstPsllw, MmReg, Imm) + INST_2i(psllw, kX86InstIdPsllw, X86MmReg, Imm) //! Packed DWORD shift right arithmetic (MMX). - INST_2x(psrad, kInstPsrad, MmReg, MmReg) + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86MmReg) //! \overload - INST_2x(psrad, kInstPsrad, MmReg, Mem) + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86Mem) //! \overload - INST_2i(psrad, kInstPsrad, MmReg, Imm) + INST_2i(psrad, kX86InstIdPsrad, X86MmReg, Imm) //! Packed WORD shift right arithmetic (MMX). - INST_2x(psraw, kInstPsraw, MmReg, MmReg) + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86MmReg) //! \overload - INST_2x(psraw, kInstPsraw, MmReg, Mem) + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86Mem) //! \overload - INST_2i(psraw, kInstPsraw, MmReg, Imm) + INST_2i(psraw, kX86InstIdPsraw, X86MmReg, Imm) //! Packed DWORD shift right logical (MMX). - INST_2x(psrld, kInstPsrld, MmReg, MmReg) + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86MmReg) //! \overload - INST_2x(psrld, kInstPsrld, MmReg, Mem) + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86Mem) //! \overload - INST_2i(psrld, kInstPsrld, MmReg, Imm) + INST_2i(psrld, kX86InstIdPsrld, X86MmReg, Imm) //! Packed QWORD shift right logical (MMX). - INST_2x(psrlq, kInstPsrlq, MmReg, MmReg) + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86MmReg) //! \overload - INST_2x(psrlq, kInstPsrlq, MmReg, Mem) + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86Mem) //! \overload - INST_2i(psrlq, kInstPsrlq, MmReg, Imm) + INST_2i(psrlq, kX86InstIdPsrlq, X86MmReg, Imm) //! Packed WORD shift right logical (MMX). - INST_2x(psrlw, kInstPsrlw, MmReg, MmReg) + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86MmReg) //! \overload - INST_2x(psrlw, kInstPsrlw, MmReg, Mem) + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86Mem) //! \overload - INST_2i(psrlw, kInstPsrlw, MmReg, Imm) + INST_2i(psrlw, kX86InstIdPsrlw, X86MmReg, Imm) //! Packed BYTE subtract (MMX). - INST_2x(psubb, kInstPsubb, MmReg, MmReg) + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86MmReg) //! \overload - INST_2x(psubb, kInstPsubb, MmReg, Mem) + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86Mem) //! Packed DWORD subtract (MMX). - INST_2x(psubd, kInstPsubd, MmReg, MmReg) + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86MmReg) //! \overload - INST_2x(psubd, kInstPsubd, MmReg, Mem) + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86Mem) //! Packed BYTE subtract with saturation (MMX). - INST_2x(psubsb, kInstPsubsb, MmReg, MmReg) + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86MmReg) //! \overload - INST_2x(psubsb, kInstPsubsb, MmReg, Mem) + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86Mem) //! Packed WORD subtract with saturation (MMX). - INST_2x(psubsw, kInstPsubsw, MmReg, MmReg) + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86MmReg) //! \overload - INST_2x(psubsw, kInstPsubsw, MmReg, Mem) + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86Mem) //! Packed BYTE subtract with unsigned saturation (MMX). - INST_2x(psubusb, kInstPsubusb, MmReg, MmReg) + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86MmReg) //! \overload - INST_2x(psubusb, kInstPsubusb, MmReg, Mem) + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86Mem) //! Packed WORD subtract with unsigned saturation (MMX). - INST_2x(psubusw, kInstPsubusw, MmReg, MmReg) + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86MmReg) //! \overload - INST_2x(psubusw, kInstPsubusw, MmReg, Mem) + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86Mem) //! Packed WORD subtract (MMX). - INST_2x(psubw, kInstPsubw, MmReg, MmReg) + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86MmReg) //! \overload - INST_2x(psubw, kInstPsubw, MmReg, Mem) + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86Mem) //! Unpack high packed BYTEs to WORDs (MMX). - INST_2x(punpckhbw, kInstPunpckhbw, MmReg, MmReg) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86MmReg) //! \overload - INST_2x(punpckhbw, kInstPunpckhbw, MmReg, Mem) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86Mem) //! Unpack high packed DWORDs to QWORDs (MMX). - INST_2x(punpckhdq, kInstPunpckhdq, MmReg, MmReg) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86MmReg) //! \overload - INST_2x(punpckhdq, kInstPunpckhdq, MmReg, Mem) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86Mem) //! Unpack high packed WORDs to DWORDs (MMX). - INST_2x(punpckhwd, kInstPunpckhwd, MmReg, MmReg) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86MmReg) //! \overload - INST_2x(punpckhwd, kInstPunpckhwd, MmReg, Mem) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86Mem) //! Unpack low packed BYTEs to WORDs (MMX). - INST_2x(punpcklbw, kInstPunpcklbw, MmReg, MmReg) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86MmReg) //! \overload - INST_2x(punpcklbw, kInstPunpcklbw, MmReg, Mem) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86Mem) //! Unpack low packed DWORDs to QWORDs (MMX). - INST_2x(punpckldq, kInstPunpckldq, MmReg, MmReg) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86MmReg) //! \overload - INST_2x(punpckldq, kInstPunpckldq, MmReg, Mem) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86Mem) //! Unpack low packed WORDs to DWORDs (MMX). - INST_2x(punpcklwd, kInstPunpcklwd, MmReg, MmReg) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86MmReg) //! \overload - INST_2x(punpcklwd, kInstPunpcklwd, MmReg, Mem) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86Mem) //! Packed bitwise xor (MMX). - INST_2x(pxor, kInstPxor, MmReg, MmReg) + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86MmReg) //! \overload - INST_2x(pxor, kInstPxor, MmReg, Mem) + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86Mem) //! Empty MMX state. - INST_0x(emms, kInstEmms) + INST_0x(emms, kX86InstIdEmms) // ------------------------------------------------------------------------- // [3dNow] // ------------------------------------------------------------------------- //! Packed SP-FP to DWORD convert (3dNow!). - INST_2x(pf2id, kInstPf2id, MmReg, MmReg) + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86MmReg) //! \overload - INST_2x(pf2id, kInstPf2id, MmReg, Mem) + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86Mem) //! Packed SP-FP to WORD convert (3dNow!). - INST_2x(pf2iw, kInstPf2iw, MmReg, MmReg) + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86MmReg) //! \overload - INST_2x(pf2iw, kInstPf2iw, MmReg, Mem) + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86Mem) //! Packed SP-FP accumulate (3dNow!). - INST_2x(pfacc, kInstPfacc, MmReg, MmReg) + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86MmReg) //! \overload - INST_2x(pfacc, kInstPfacc, MmReg, Mem) + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86Mem) //! Packed SP-FP addition (3dNow!). - INST_2x(pfadd, kInstPfadd, MmReg, MmReg) + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86MmReg) //! \overload - INST_2x(pfadd, kInstPfadd, MmReg, Mem) + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86Mem) //! Packed SP-FP compare - dst == src (3dNow!). - INST_2x(pfcmpeq, kInstPfcmpeq, MmReg, MmReg) + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86MmReg) //! \overload - INST_2x(pfcmpeq, kInstPfcmpeq, MmReg, Mem) + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86Mem) //! Packed SP-FP compare - dst >= src (3dNow!). - INST_2x(pfcmpge, kInstPfcmpge, MmReg, MmReg) + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86MmReg) //! \overload - INST_2x(pfcmpge, kInstPfcmpge, MmReg, Mem) + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86Mem) //! Packed SP-FP compare - dst > src (3dNow!). - INST_2x(pfcmpgt, kInstPfcmpgt, MmReg, MmReg) + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86MmReg) //! \overload - INST_2x(pfcmpgt, kInstPfcmpgt, MmReg, Mem) + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86Mem) //! Packed SP-FP maximum (3dNow!). - INST_2x(pfmax, kInstPfmax, MmReg, MmReg) + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86MmReg) //! \overload - INST_2x(pfmax, kInstPfmax, MmReg, Mem) + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86Mem) //! Packed SP-FP minimum (3dNow!). - INST_2x(pfmin, kInstPfmin, MmReg, MmReg) + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86MmReg) //! \overload - INST_2x(pfmin, kInstPfmin, MmReg, Mem) + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86Mem) //! Packed SP-FP multiply (3dNow!). - INST_2x(pfmul, kInstPfmul, MmReg, MmReg) + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86MmReg) //! \overload - INST_2x(pfmul, kInstPfmul, MmReg, Mem) + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86Mem) //! Packed SP-FP negative accumulate (3dNow!). - INST_2x(pfnacc, kInstPfnacc, MmReg, MmReg) + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86MmReg) //! \overload - INST_2x(pfnacc, kInstPfnacc, MmReg, Mem) + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86Mem) //! Packed SP-FP mixed accumulate (3dNow!). - INST_2x(pfpnacc, kInstPfpnacc, MmReg, MmReg) + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86MmReg) //! \overload - INST_2x(pfpnacc, kInstPfpnacc, MmReg, Mem) + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86Mem) //! Packed SP-FP reciprocal Approximation (3dNow!). - INST_2x(pfrcp, kInstPfrcp, MmReg, MmReg) + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86MmReg) //! \overload - INST_2x(pfrcp, kInstPfrcp, MmReg, Mem) + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86Mem) //! Packed SP-FP reciprocal, first iteration step (3dNow!). - INST_2x(pfrcpit1, kInstPfrcpit1, MmReg, MmReg) + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86MmReg) //! \overload - INST_2x(pfrcpit1, kInstPfrcpit1, MmReg, Mem) + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86Mem) //! Packed SP-FP reciprocal, second iteration step (3dNow!). - INST_2x(pfrcpit2, kInstPfrcpit2, MmReg, MmReg) + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86MmReg) //! \overload - INST_2x(pfrcpit2, kInstPfrcpit2, MmReg, Mem) + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86Mem) //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). - INST_2x(pfrsqit1, kInstPfrsqit1, MmReg, MmReg) + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86MmReg) //! \overload - INST_2x(pfrsqit1, kInstPfrsqit1, MmReg, Mem) + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86Mem) //! Packed SP-FP reciprocal square root approximation (3dNow!). - INST_2x(pfrsqrt, kInstPfrsqrt, MmReg, MmReg) + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86MmReg) //! \overload - INST_2x(pfrsqrt, kInstPfrsqrt, MmReg, Mem) + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86Mem) //! Packed SP-FP subtract (3dNow!). - INST_2x(pfsub, kInstPfsub, MmReg, MmReg) + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86MmReg) //! \overload - INST_2x(pfsub, kInstPfsub, MmReg, Mem) + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86Mem) //! Packed SP-FP reverse subtract (3dNow!). - INST_2x(pfsubr, kInstPfsubr, MmReg, MmReg) + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86MmReg) //! \overload - INST_2x(pfsubr, kInstPfsubr, MmReg, Mem) + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86Mem) //! Packed DWORDs to SP-FP (3dNow!). - INST_2x(pi2fd, kInstPi2fd, MmReg, MmReg) + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86MmReg) //! \overload - INST_2x(pi2fd, kInstPi2fd, MmReg, Mem) + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86Mem) //! Packed WORDs to SP-FP (3dNow!). - INST_2x(pi2fw, kInstPi2fw, MmReg, MmReg) + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86MmReg) //! \overload - INST_2x(pi2fw, kInstPi2fw, MmReg, Mem) + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86Mem) //! Packed swap DWORDs (3dNow!) - INST_2x(pswapd, kInstPswapd, MmReg, MmReg) + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86MmReg) //! \overload - INST_2x(pswapd, kInstPswapd, MmReg, Mem) + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86Mem) //! Prefetch (3dNow!). - INST_1x(prefetch3dnow, kInstPrefetch3dNow, Mem) + INST_1x(prefetch3dnow, kX86InstIdPrefetch3dNow, X86Mem) //! Prefetch and set cache to modified (3dNow!). - INST_1x(prefetchw3dnow, kInstPrefetchw3dNow, Mem) + INST_1x(prefetchw3dnow, kX86InstIdPrefetchw3dNow, X86Mem) //! Faster EMMS (3dNow!). - INST_0x(femms, kInstFemms) + INST_0x(femms, kX86InstIdFemms) // -------------------------------------------------------------------------- // [SSE] // -------------------------------------------------------------------------- //! Packed SP-FP add (SSE). - INST_2x(addps, kInstAddps, XmmReg, XmmReg) + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addps, kInstAddps, XmmReg, Mem) + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86Mem) //! Scalar SP-FP add (SSE). - INST_2x(addss, kInstAddss, XmmReg, XmmReg) + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addss, kInstAddss, XmmReg, Mem) + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86Mem) //! Packed SP-FP bitwise and-not (SSE). - INST_2x(andnps, kInstAndnps, XmmReg, XmmReg) + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(andnps, kInstAndnps, XmmReg, Mem) + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86Mem) //! Packed SP-FP bitwise and (SSE). - INST_2x(andps, kInstAndps, XmmReg, XmmReg) + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(andps, kInstAndps, XmmReg, Mem) + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86Mem) //! Packed SP-FP compare (SSE). - INST_3i(cmpps, kInstCmpps, XmmReg, XmmReg, Imm) + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(cmpps, kInstCmpps, XmmReg, Mem, Imm) + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86Mem, Imm) //! Compare scalar SP-FP (SSE). - INST_3i(cmpss, kInstCmpss, XmmReg, XmmReg, Imm) + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(cmpss, kInstCmpss, XmmReg, Mem, Imm) + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86Mem, Imm) //! Scalar ordered SP-FP compare and set EFLAGS (SSE). - INST_2x(comiss, kInstComiss, XmmReg, XmmReg) + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(comiss, kInstComiss, XmmReg, Mem) + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86Mem) //! Packed signed INT32 to packed SP-FP conversion (SSE). - INST_2x(cvtpi2ps, kInstCvtpi2ps, XmmReg, MmReg) + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86MmReg) //! \overload - INST_2x(cvtpi2ps, kInstCvtpi2ps, XmmReg, Mem) + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86Mem) //! Packed SP-FP to packed INT32 conversion (SSE). - INST_2x(cvtps2pi, kInstCvtps2pi, MmReg, XmmReg) + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86XmmReg) //! \overload - INST_2x(cvtps2pi, kInstCvtps2pi, MmReg, Mem) + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86Mem) //! Convert scalar INT32 to SP-FP (SSE). - INST_2x(cvtsi2ss, kInstCvtsi2ss, XmmReg, GpReg) + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86GpReg) //! \overload - INST_2x(cvtsi2ss, kInstCvtsi2ss, XmmReg, Mem) + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86Mem) //! Convert scalar SP-FP to INT32 (SSE). - INST_2x(cvtss2si, kInstCvtss2si, GpReg, XmmReg) + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(cvtss2si, kInstCvtss2si, GpReg, Mem) + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86Mem) //! Convert with truncation packed SP-FP to packed INT32 (SSE). - INST_2x(cvttps2pi, kInstCvttps2pi, MmReg, XmmReg) + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86XmmReg) //! \overload - INST_2x(cvttps2pi, kInstCvttps2pi, MmReg, Mem) + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86Mem) //! Convert with truncation scalar SP-FP to INT32 (SSE). - INST_2x(cvttss2si, kInstCvttss2si, GpReg, XmmReg) + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(cvttss2si, kInstCvttss2si, GpReg, Mem) + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86Mem) //! Packed SP-FP divide (SSE). - INST_2x(divps, kInstDivps, XmmReg, XmmReg) + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(divps, kInstDivps, XmmReg, Mem) + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86Mem) //! Scalar SP-FP divide (SSE). - INST_2x(divss, kInstDivss, XmmReg, XmmReg) + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(divss, kInstDivss, XmmReg, Mem) + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86Mem) //! Load streaming SIMD extension control/status (SSE). - INST_1x(ldmxcsr, kInstLdmxcsr, Mem) + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) //! Byte mask write to DS:EDI/RDI (SSE). - INST_2x(maskmovq, kInstMaskmovq, MmReg, MmReg) + INST_2x(maskmovq, kX86InstIdMaskmovq, X86MmReg, X86MmReg) //! Packed SP-FP maximum (SSE). - INST_2x(maxps, kInstMaxps, XmmReg, XmmReg) + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(maxps, kInstMaxps, XmmReg, Mem) + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86Mem) //! Scalar SP-FP maximum (SSE). - INST_2x(maxss, kInstMaxss, XmmReg, XmmReg) + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(maxss, kInstMaxss, XmmReg, Mem) + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86Mem) //! Packed SP-FP minimum (SSE). - INST_2x(minps, kInstMinps, XmmReg, XmmReg) + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(minps, kInstMinps, XmmReg, Mem) + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86Mem) //! Scalar SP-FP minimum (SSE). - INST_2x(minss, kInstMinss, XmmReg, XmmReg) + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(minss, kInstMinss, XmmReg, Mem) + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86Mem) //! Move aligned packed SP-FP (SSE). - INST_2x(movaps, kInstMovaps, XmmReg, XmmReg) + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movaps, kInstMovaps, XmmReg, Mem) + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86Mem) //! Move aligned packed SP-FP (SSE). - INST_2x(movaps, kInstMovaps, Mem, XmmReg) + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmReg) //! Move DWORD. - INST_2x(movd, kInstMovd, Mem, XmmReg) + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmReg) //! \overload - INST_2x(movd, kInstMovd, GpReg, XmmReg) + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86XmmReg) //! \overload - INST_2x(movd, kInstMovd, XmmReg, Mem) + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86Mem) //! \overload - INST_2x(movd, kInstMovd, XmmReg, GpReg) + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86GpReg) //! Move QWORD (SSE). - INST_2x(movq, kInstMovq, XmmReg, XmmReg) + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movq, kInstMovq, Mem, XmmReg) + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmReg) //! \overload - INST_2x(movq, kInstMovq, XmmReg, Mem) + 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, kInstMovntq, Mem, MmReg) + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmReg) //! Move high to low packed SP-FP (SSE). - INST_2x(movhlps, kInstMovhlps, XmmReg, XmmReg) + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmReg, X86XmmReg) //! Move high packed SP-FP (SSE). - INST_2x(movhps, kInstMovhps, XmmReg, Mem) + INST_2x(movhps, kX86InstIdMovhps, X86XmmReg, X86Mem) //! Move high packed SP-FP (SSE). - INST_2x(movhps, kInstMovhps, Mem, XmmReg) + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmReg) //! Move low to high packed SP-FP (SSE). - INST_2x(movlhps, kInstMovlhps, XmmReg, XmmReg) + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmReg, X86XmmReg) //! Move low packed SP-FP (SSE). - INST_2x(movlps, kInstMovlps, XmmReg, Mem) + INST_2x(movlps, kX86InstIdMovlps, X86XmmReg, X86Mem) //! Move low packed SP-FP (SSE). - INST_2x(movlps, kInstMovlps, Mem, XmmReg) + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmReg) //! Move aligned packed SP-FP using NT hint (SSE). - INST_2x(movntps, kInstMovntps, Mem, XmmReg) + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmReg) //! Move scalar SP-FP (SSE). - INST_2x(movss, kInstMovss, XmmReg, XmmReg) + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movss, kInstMovss, XmmReg, Mem) + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86Mem) //! \overload - INST_2x(movss, kInstMovss, Mem, XmmReg) + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmReg) //! Move unaligned packed SP-FP (SSE). - INST_2x(movups, kInstMovups, XmmReg, XmmReg) + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movups, kInstMovups, XmmReg, Mem) + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86Mem) //! \overload - INST_2x(movups, kInstMovups, Mem, XmmReg) + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmReg) //! Packed SP-FP multiply (SSE). - INST_2x(mulps, kInstMulps, XmmReg, XmmReg) + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(mulps, kInstMulps, XmmReg, Mem) + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86Mem) //! Scalar SP-FP multiply (SSE). - INST_2x(mulss, kInstMulss, XmmReg, XmmReg) + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(mulss, kInstMulss, XmmReg, Mem) + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86Mem) //! Packed SP-FP bitwise or (SSE). - INST_2x(orps, kInstOrps, XmmReg, XmmReg) + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(orps, kInstOrps, XmmReg, Mem) + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86Mem) //! Packed BYTE average (SSE). - INST_2x(pavgb, kInstPavgb, MmReg, MmReg) + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86MmReg) //! \overload - INST_2x(pavgb, kInstPavgb, MmReg, Mem) + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86Mem) //! Packed WORD average (SSE). - INST_2x(pavgw, kInstPavgw, MmReg, MmReg) + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86MmReg) //! \overload - INST_2x(pavgw, kInstPavgw, MmReg, Mem) + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86Mem) //! Extract WORD based on selector (SSE). - INST_3i(pextrw, kInstPextrw, GpReg, MmReg, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86MmReg, Imm) //! Insert WORD based on selector (SSE). - INST_3i(pinsrw, kInstPinsrw, MmReg, GpReg, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86GpReg, Imm) //! \overload - INST_3i(pinsrw, kInstPinsrw, MmReg, Mem, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86Mem, Imm) //! Packed WORD maximum (SSE). - INST_2x(pmaxsw, kInstPmaxsw, MmReg, MmReg) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmaxsw, kInstPmaxsw, MmReg, Mem) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86Mem) //! Packed BYTE unsigned maximum (SSE). - INST_2x(pmaxub, kInstPmaxub, MmReg, MmReg) + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86MmReg) //! \overload - INST_2x(pmaxub, kInstPmaxub, MmReg, Mem) + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86Mem) //! Packed WORD minimum (SSE). - INST_2x(pminsw, kInstPminsw, MmReg, MmReg) + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86MmReg) //! \overload - INST_2x(pminsw, kInstPminsw, MmReg, Mem) + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86Mem) //! Packed BYTE unsigned minimum (SSE). - INST_2x(pminub, kInstPminub, MmReg, MmReg) + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86MmReg) //! \overload - INST_2x(pminub, kInstPminub, MmReg, Mem) + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86Mem) //! Move Byte mask to integer (SSE). - INST_2x(pmovmskb, kInstPmovmskb, GpReg, MmReg) + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86MmReg) //! Packed WORD unsigned multiply high (SSE). - INST_2x(pmulhuw, kInstPmulhuw, MmReg, MmReg) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmulhuw, kInstPmulhuw, MmReg, Mem) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86Mem) //! Packed WORD sum of absolute differences (SSE). - INST_2x(psadbw, kInstPsadbw, MmReg, MmReg) + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86MmReg) //! \overload - INST_2x(psadbw, kInstPsadbw, MmReg, Mem) + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86Mem) //! Packed WORD shuffle (SSE). - INST_3i(pshufw, kInstPshufw, MmReg, MmReg, Imm) + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86MmReg, Imm) //! \overload - INST_3i(pshufw, kInstPshufw, MmReg, Mem, Imm) + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86Mem, Imm) //! Packed SP-FP reciprocal (SSE). - INST_2x(rcpps, kInstRcpps, XmmReg, XmmReg) + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(rcpps, kInstRcpps, XmmReg, Mem) + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86Mem) //! Scalar SP-FP reciprocal (SSE). - INST_2x(rcpss, kInstRcpss, XmmReg, XmmReg) + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(rcpss, kInstRcpss, XmmReg, Mem) + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86Mem) //! Prefetch (SSE). - INST_2i(prefetch, kInstPrefetch, Mem, Imm) + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) //! Packed WORD sum of absolute differences (SSE). - INST_2x(psadbw, kInstPsadbw, XmmReg, XmmReg) + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psadbw, kInstPsadbw, XmmReg, Mem) + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86Mem) //! Packed SP-FP square root reciprocal (SSE). - INST_2x(rsqrtps, kInstRsqrtps, XmmReg, XmmReg) + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(rsqrtps, kInstRsqrtps, XmmReg, Mem) + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86Mem) //! Scalar SP-FP square root reciprocal (SSE). - INST_2x(rsqrtss, kInstRsqrtss, XmmReg, XmmReg) + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(rsqrtss, kInstRsqrtss, XmmReg, Mem) + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86Mem) //! Store fence (SSE). - INST_0x(sfence, kInstSfence) + INST_0x(sfence, kX86InstIdSfence) //! Shuffle SP-FP (SSE). - INST_3i(shufps, kInstShufps, XmmReg, XmmReg, Imm) + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(shufps, kInstShufps, XmmReg, Mem, Imm) + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86Mem, Imm) //! Packed SP-FP square root (SSE). - INST_2x(sqrtps, kInstSqrtps, XmmReg, XmmReg) + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(sqrtps, kInstSqrtps, XmmReg, Mem) + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86Mem) //! Scalar SP-FP square root (SSE). - INST_2x(sqrtss, kInstSqrtss, XmmReg, XmmReg) + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(sqrtss, kInstSqrtss, XmmReg, Mem) + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86Mem) //! Store streaming SIMD extension control/status (SSE). - INST_1x(stmxcsr, kInstStmxcsr, Mem) + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) //! Packed SP-FP subtract (SSE). - INST_2x(subps, kInstSubps, XmmReg, XmmReg) + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(subps, kInstSubps, XmmReg, Mem) + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86Mem) //! Scalar SP-FP subtract (SSE). - INST_2x(subss, kInstSubss, XmmReg, XmmReg) + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(subss, kInstSubss, XmmReg, Mem) + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86Mem) //! Unordered scalar SP-FP compare and set EFLAGS (SSE). - INST_2x(ucomiss, kInstUcomiss, XmmReg, XmmReg) + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(ucomiss, kInstUcomiss, XmmReg, Mem) + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86Mem) //! Unpack high packed SP-FP data (SSE). - INST_2x(unpckhps, kInstUnpckhps, XmmReg, XmmReg) + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(unpckhps, kInstUnpckhps, XmmReg, Mem) + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86Mem) //! Unpack low packed SP-FP data (SSE). - INST_2x(unpcklps, kInstUnpcklps, XmmReg, XmmReg) + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(unpcklps, kInstUnpcklps, XmmReg, Mem) + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86Mem) //! Packed SP-FP bitwise xor (SSE). - INST_2x(xorps, kInstXorps, XmmReg, XmmReg) + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(xorps, kInstXorps, XmmReg, Mem) + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86Mem) // -------------------------------------------------------------------------- // [SSE2] // -------------------------------------------------------------------------- //! Packed DP-FP add (SSE2). - INST_2x(addpd, kInstAddpd, XmmReg, XmmReg) + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addpd, kInstAddpd, XmmReg, Mem) + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86Mem) //! Scalar DP-FP add (SSE2). - INST_2x(addsd, kInstAddsd, XmmReg, XmmReg) + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addsd, kInstAddsd, XmmReg, Mem) + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86Mem) //! Packed DP-FP bitwise and-not (SSE2). - INST_2x(andnpd, kInstAndnpd, XmmReg, XmmReg) + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(andnpd, kInstAndnpd, XmmReg, Mem) + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86Mem) //! Packed DP-FP bitwise and (SSE2). - INST_2x(andpd, kInstAndpd, XmmReg, XmmReg) + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(andpd, kInstAndpd, XmmReg, Mem) + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86Mem) //! Flush cache line (SSE2). - INST_1x(clflush, kInstClflush, Mem) + INST_1x(clflush, kX86InstIdClflush, X86Mem) //! Packed DP-FP compare (SSE2). - INST_3i(cmppd, kInstCmppd, XmmReg, XmmReg, Imm) + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(cmppd, kInstCmppd, XmmReg, Mem, Imm) + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86Mem, Imm) //! Scalar SP-FP compare (SSE2). - INST_3i(cmpsd, kInstCmpsd, XmmReg, XmmReg, Imm) + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(cmpsd, kInstCmpsd, XmmReg, Mem, Imm) + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86Mem, Imm) //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). - INST_2x(comisd, kInstComisd, XmmReg, XmmReg) + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(comisd, kInstComisd, XmmReg, Mem) + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86Mem) //! Convert packed QWORDs to packed DP-FP (SSE2). - INST_2x(cvtdq2pd, kInstCvtdq2pd, XmmReg, XmmReg) + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtdq2pd, kInstCvtdq2pd, XmmReg, Mem) + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86Mem) //! Convert packed QWORDs to packed SP-FP (SSE2). - INST_2x(cvtdq2ps, kInstCvtdq2ps, XmmReg, XmmReg) + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtdq2ps, kInstCvtdq2ps, XmmReg, Mem) + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86Mem) //! Convert packed DP-FP to packed QWORDs (SSE2). - INST_2x(cvtpd2dq, kInstCvtpd2dq, XmmReg, XmmReg) + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtpd2dq, kInstCvtpd2dq, XmmReg, Mem) + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86Mem) //! Convert packed DP-FP to packed QRODSs (SSE2). - INST_2x(cvtpd2pi, kInstCvtpd2pi, MmReg, XmmReg) + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86XmmReg) //! \overload - INST_2x(cvtpd2pi, kInstCvtpd2pi, MmReg, Mem) + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86Mem) //! Convert packed DP-FP to packed SP-FP (SSE2). - INST_2x(cvtpd2ps, kInstCvtpd2ps, XmmReg, XmmReg) + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtpd2ps, kInstCvtpd2ps, XmmReg, Mem) + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86Mem) //! Convert packed DWORDs integers to packed DP-FP (SSE2). - INST_2x(cvtpi2pd, kInstCvtpi2pd, XmmReg, MmReg) + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86MmReg) //! \overload - INST_2x(cvtpi2pd, kInstCvtpi2pd, XmmReg, Mem) + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86Mem) //! Convert packed SP-FP to packed QWORDs (SSE2). - INST_2x(cvtps2dq, kInstCvtps2dq, XmmReg, XmmReg) + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtps2dq, kInstCvtps2dq, XmmReg, Mem) + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86Mem) //! Convert packed SP-FP to packed DP-FP (SSE2). - INST_2x(cvtps2pd, kInstCvtps2pd, XmmReg, XmmReg) + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtps2pd, kInstCvtps2pd, XmmReg, Mem) + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86Mem) //! Convert scalar DP-FP to DWORD integer (SSE2). - INST_2x(cvtsd2si, kInstCvtsd2si, GpReg, XmmReg) + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(cvtsd2si, kInstCvtsd2si, GpReg, Mem) + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86Mem) //! Convert scalar DP-FP to scalar SP-FP (SSE2). - INST_2x(cvtsd2ss, kInstCvtsd2ss, XmmReg, XmmReg) + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtsd2ss, kInstCvtsd2ss, XmmReg, Mem) + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86Mem) //! Convert DWORD integer to scalar DP-FP (SSE2). - INST_2x(cvtsi2sd, kInstCvtsi2sd, XmmReg, GpReg) + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86GpReg) //! \overload - INST_2x(cvtsi2sd, kInstCvtsi2sd, XmmReg, Mem) + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86Mem) //! Convert scalar SP-FP to DP-FP (SSE2). - INST_2x(cvtss2sd, kInstCvtss2sd, XmmReg, XmmReg) + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvtss2sd, kInstCvtss2sd, XmmReg, Mem) + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86Mem) //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). - INST_2x(cvttpd2pi, kInstCvttpd2pi, MmReg, XmmReg) + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86XmmReg) //! \overload - INST_2x(cvttpd2pi, kInstCvttpd2pi, MmReg, Mem) + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86Mem) //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). - INST_2x(cvttpd2dq, kInstCvttpd2dq, XmmReg, XmmReg) + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvttpd2dq, kInstCvttpd2dq, XmmReg, Mem) + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86Mem) //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). - INST_2x(cvttps2dq, kInstCvttps2dq, XmmReg, XmmReg) + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(cvttps2dq, kInstCvttps2dq, XmmReg, Mem) + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86Mem) //! Convert with truncation scalar DP-FP to signed DWORDs (SSE2). - INST_2x(cvttsd2si, kInstCvttsd2si, GpReg, XmmReg) + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(cvttsd2si, kInstCvttsd2si, GpReg, Mem) + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86Mem) //! Packed DP-FP divide (SSE2). - INST_2x(divpd, kInstDivpd, XmmReg, XmmReg) + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(divpd, kInstDivpd, XmmReg, Mem) + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86Mem) //! Scalar DP-FP divide (SSE2). - INST_2x(divsd, kInstDivsd, XmmReg, XmmReg) + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(divsd, kInstDivsd, XmmReg, Mem) + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86Mem) //! Load fence (SSE2). - INST_0x(lfence, kInstLfence) + INST_0x(lfence, kX86InstIdLfence) //! Store selected bytes of OWORD to DS:EDI/RDI (SSE2). - INST_2x(maskmovdqu, kInstMaskmovdqu, XmmReg, XmmReg) + INST_2x(maskmovdqu, kX86InstIdMaskmovdqu, X86XmmReg, X86XmmReg) //! Packed DP-FP maximum (SSE2). - INST_2x(maxpd, kInstMaxpd, XmmReg, XmmReg) + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(maxpd, kInstMaxpd, XmmReg, Mem) + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86Mem) //! Scalar DP-FP maximum (SSE2). - INST_2x(maxsd, kInstMaxsd, XmmReg, XmmReg) + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(maxsd, kInstMaxsd, XmmReg, Mem) + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86Mem) //! Memory fence (SSE2). - INST_0x(mfence, kInstMfence) + INST_0x(mfence, kX86InstIdMfence) //! Packed DP-FP minimum (SSE2). - INST_2x(minpd, kInstMinpd, XmmReg, XmmReg) + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(minpd, kInstMinpd, XmmReg, Mem) + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86Mem) //! Scalar DP-FP minimum (SSE2). - INST_2x(minsd, kInstMinsd, XmmReg, XmmReg) + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(minsd, kInstMinsd, XmmReg, Mem) + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86Mem) //! Move aligned OWORD (SSE2). - INST_2x(movdqa, kInstMovdqa, XmmReg, XmmReg) + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movdqa, kInstMovdqa, XmmReg, Mem) + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86Mem) //! \overload - INST_2x(movdqa, kInstMovdqa, Mem, XmmReg) + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmReg) //! Move unaligned OWORD (SSE2). - INST_2x(movdqu, kInstMovdqu, XmmReg, XmmReg) + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movdqu, kInstMovdqu, XmmReg, Mem) + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86Mem) //! \overload - INST_2x(movdqu, kInstMovdqu, Mem, XmmReg) + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmReg) //! Extract packed SP-FP sign mask (SSE2). - INST_2x(movmskps, kInstMovmskps, GpReg, XmmReg) + INST_2x(movmskps, kX86InstIdMovmskps, X86GpReg, X86XmmReg) //! Extract packed DP-FP sign mask (SSE2). - INST_2x(movmskpd, kInstMovmskpd, GpReg, XmmReg) + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpReg, X86XmmReg) //! Move scalar DP-FP (SSE2). - INST_2x(movsd, kInstMovsd, XmmReg, XmmReg) + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movsd, kInstMovsd, XmmReg, Mem) + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86Mem) //! \overload - INST_2x(movsd, kInstMovsd, Mem, XmmReg) + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmReg) //! Move aligned packed DP-FP (SSE2). - INST_2x(movapd, kInstMovapd, XmmReg, XmmReg) + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movapd, kInstMovapd, XmmReg, Mem) + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86Mem) //! \overload - INST_2x(movapd, kInstMovapd, Mem, XmmReg) + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmReg) //! Move QWORD from Xmm to Mm register (SSE2). - INST_2x(movdq2q, kInstMovdq2q, MmReg, XmmReg) + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmReg, X86XmmReg) //! Move QWORD from Mm to Xmm register (SSE2). - INST_2x(movq2dq, kInstMovq2dq, XmmReg, MmReg) + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmReg, X86MmReg) //! Move high packed DP-FP (SSE2). - INST_2x(movhpd, kInstMovhpd, XmmReg, Mem) + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmReg, X86Mem) //! \overload - INST_2x(movhpd, kInstMovhpd, Mem, XmmReg) + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmReg) //! Move low packed DP-FP (SSE2). - INST_2x(movlpd, kInstMovlpd, XmmReg, Mem) + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmReg, X86Mem) //! \overload - INST_2x(movlpd, kInstMovlpd, Mem, XmmReg) + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmReg) //! Store OWORD using NT hint (SSE2). - INST_2x(movntdq, kInstMovntdq, Mem, XmmReg) + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmReg) //! Store DWORD using NT hint (SSE2). - INST_2x(movnti, kInstMovnti, Mem, GpReg) + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpReg) //! Store packed DP-FP using NT hint (SSE2). - INST_2x(movntpd, kInstMovntpd, Mem, XmmReg) + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmReg) //! Move unaligned packed DP-FP (SSE2). - INST_2x(movupd, kInstMovupd, XmmReg, XmmReg) + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movupd, kInstMovupd, XmmReg, Mem) + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86Mem) //! \overload - INST_2x(movupd, kInstMovupd, Mem, XmmReg) + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmReg) //! Packed DP-FP multiply (SSE2). - INST_2x(mulpd, kInstMulpd, XmmReg, XmmReg) + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(mulpd, kInstMulpd, XmmReg, Mem) + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86Mem) //! Scalar DP-FP multiply (SSE2). - INST_2x(mulsd, kInstMulsd, XmmReg, XmmReg) + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(mulsd, kInstMulsd, XmmReg, Mem) + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86Mem) //! Packed DP-FP bitwise or (SSE2). - INST_2x(orpd, kInstOrpd, XmmReg, XmmReg) + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(orpd, kInstOrpd, XmmReg, Mem) + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86Mem) //! Pack WORDs to BYTEs with signed saturation (SSE2). - INST_2x(packsswb, kInstPacksswb, XmmReg, XmmReg) + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(packsswb, kInstPacksswb, XmmReg, Mem) + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86Mem) //! Pack DWORDs to WORDs with signed saturation (SSE2). - INST_2x(packssdw, kInstPackssdw, XmmReg, XmmReg) + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(packssdw, kInstPackssdw, XmmReg, Mem) + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (SSE2). - INST_2x(packuswb, kInstPackuswb, XmmReg, XmmReg) + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(packuswb, kInstPackuswb, XmmReg, Mem) + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86Mem) //! Packed BYTE Add (SSE2). - INST_2x(paddb, kInstPaddb, XmmReg, XmmReg) + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddb, kInstPaddb, XmmReg, Mem) + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86Mem) //! Packed WORD add (SSE2). - INST_2x(paddw, kInstPaddw, XmmReg, XmmReg) + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddw, kInstPaddw, XmmReg, Mem) + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86Mem) //! Packed DWORD add (SSE2). - INST_2x(paddd, kInstPaddd, XmmReg, XmmReg) + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddd, kInstPaddd, XmmReg, Mem) + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86Mem) //! Packed QWORD add (SSE2). - INST_2x(paddq, kInstPaddq, MmReg, MmReg) + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86MmReg) //! \overload - INST_2x(paddq, kInstPaddq, MmReg, Mem) + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86Mem) //! Packed QWORD add (SSE2). - INST_2x(paddq, kInstPaddq, XmmReg, XmmReg) + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddq, kInstPaddq, XmmReg, Mem) + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86Mem) //! Packed BYTE add with saturation (SSE2). - INST_2x(paddsb, kInstPaddsb, XmmReg, XmmReg) + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddsb, kInstPaddsb, XmmReg, Mem) + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86Mem) //! Packed WORD add with saturation (SSE2). - INST_2x(paddsw, kInstPaddsw, XmmReg, XmmReg) + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddsw, kInstPaddsw, XmmReg, Mem) + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86Mem) //! Packed BYTE add with unsigned saturation (SSE2). - INST_2x(paddusb, kInstPaddusb, XmmReg, XmmReg) + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddusb, kInstPaddusb, XmmReg, Mem) + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86Mem) //! Packed WORD add with unsigned saturation (SSE2). - INST_2x(paddusw, kInstPaddusw, XmmReg, XmmReg) + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(paddusw, kInstPaddusw, XmmReg, Mem) + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86Mem) //! Packed bitwise and (SSE2). - INST_2x(pand, kInstPand, XmmReg, XmmReg) + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pand, kInstPand, XmmReg, Mem) + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86Mem) //! Packed bitwise and-not (SSE2). - INST_2x(pandn, kInstPandn, XmmReg, XmmReg) + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pandn, kInstPandn, XmmReg, Mem) + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86Mem) //! Spin loop hint (SSE2). - INST_0x(pause, kInstPause) + INST_0x(pause, kX86InstIdPause) //! Packed BYTE average (SSE2). - INST_2x(pavgb, kInstPavgb, XmmReg, XmmReg) + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pavgb, kInstPavgb, XmmReg, Mem) + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86Mem) //! Packed WORD average (SSE2). - INST_2x(pavgw, kInstPavgw, XmmReg, XmmReg) + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pavgw, kInstPavgw, XmmReg, Mem) + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86Mem) //! Packed BYTE compare for equality (SSE2). - INST_2x(pcmpeqb, kInstPcmpeqb, XmmReg, XmmReg) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpeqb, kInstPcmpeqb, XmmReg, Mem) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86Mem) //! Packed WORD compare for equality (SSE2). - INST_2x(pcmpeqw, kInstPcmpeqw, XmmReg, XmmReg) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpeqw, kInstPcmpeqw, XmmReg, Mem) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86Mem) //! Packed DWORD compare for equality (SSE2). - INST_2x(pcmpeqd, kInstPcmpeqd, XmmReg, XmmReg) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpeqd, kInstPcmpeqd, XmmReg, Mem) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86Mem) //! Packed BYTE compare if greater than (SSE2). - INST_2x(pcmpgtb, kInstPcmpgtb, XmmReg, XmmReg) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpgtb, kInstPcmpgtb, XmmReg, Mem) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86Mem) //! Packed WORD compare if greater than (SSE2). - INST_2x(pcmpgtw, kInstPcmpgtw, XmmReg, XmmReg) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpgtw, kInstPcmpgtw, XmmReg, Mem) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86Mem) //! Packed DWORD compare if greater than (SSE2). - INST_2x(pcmpgtd, kInstPcmpgtd, XmmReg, XmmReg) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpgtd, kInstPcmpgtd, XmmReg, Mem) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86Mem) //! Extract WORD based on selector (SSE2). - INST_3i(pextrw, kInstPextrw, GpReg, XmmReg, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86XmmReg, Imm) //! Insert WORD based on selector (SSE2). - INST_3i(pinsrw, kInstPinsrw, XmmReg, GpReg, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86GpReg, Imm) //! \overload - INST_3i(pinsrw, kInstPinsrw, XmmReg, Mem, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86Mem, Imm) //! Packed WORD maximum (SSE2). - INST_2x(pmaxsw, kInstPmaxsw, XmmReg, XmmReg) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxsw, kInstPmaxsw, XmmReg, Mem) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86Mem) //! Packed BYTE unsigned maximum (SSE2). - INST_2x(pmaxub, kInstPmaxub, XmmReg, XmmReg) + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxub, kInstPmaxub, XmmReg, Mem) + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86Mem) //! Packed WORD minimum (SSE2). - INST_2x(pminsw, kInstPminsw, XmmReg, XmmReg) + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminsw, kInstPminsw, XmmReg, Mem) + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86Mem) //! Packed BYTE unsigned minimum (SSE2). - INST_2x(pminub, kInstPminub, XmmReg, XmmReg) + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminub, kInstPminub, XmmReg, Mem) + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86Mem) //! Move byte mask (SSE2). - INST_2x(pmovmskb, kInstPmovmskb, GpReg, XmmReg) + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86XmmReg) //! Packed WORD multiply high (SSE2). - INST_2x(pmulhw, kInstPmulhw, XmmReg, XmmReg) + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmulhw, kInstPmulhw, XmmReg, Mem) + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86Mem) //! Packed WORD unsigned multiply high (SSE2). - INST_2x(pmulhuw, kInstPmulhuw, XmmReg, XmmReg) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmulhuw, kInstPmulhuw, XmmReg, Mem) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86Mem) //! Packed WORD multiply low (SSE2). - INST_2x(pmullw, kInstPmullw, XmmReg, XmmReg) + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmullw, kInstPmullw, XmmReg, Mem) + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86Mem) //! Packed DWORD multiply to QWORD (SSE2). - INST_2x(pmuludq, kInstPmuludq, MmReg, MmReg) + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86MmReg) //! \overload - INST_2x(pmuludq, kInstPmuludq, MmReg, Mem) + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86Mem) //! Packed DWORD multiply to QWORD (SSE2). - INST_2x(pmuludq, kInstPmuludq, XmmReg, XmmReg) + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmuludq, kInstPmuludq, XmmReg, Mem) + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86Mem) //! Packed bitwise or (SSE2). - INST_2x(por, kInstPor, XmmReg, XmmReg) + INST_2x(por, kX86InstIdPor, X86XmmReg, X86XmmReg) //! \overload - INST_2x(por, kInstPor, XmmReg, Mem) + INST_2x(por, kX86InstIdPor, X86XmmReg, X86Mem) //! Packed DWORD shift left logical (SSE2). - INST_2x(pslld, kInstPslld, XmmReg, XmmReg) + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pslld, kInstPslld, XmmReg, Mem) + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86Mem) //! \overload - INST_2i(pslld, kInstPslld, XmmReg, Imm) + INST_2i(pslld, kX86InstIdPslld, X86XmmReg, Imm) //! Packed QWORD shift left logical (SSE2). - INST_2x(psllq, kInstPsllq, XmmReg, XmmReg) + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psllq, kInstPsllq, XmmReg, Mem) + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86Mem) //! \overload - INST_2i(psllq, kInstPsllq, XmmReg, Imm) + INST_2i(psllq, kX86InstIdPsllq, X86XmmReg, Imm) //! Packed WORD shift left logical (SSE2). - INST_2x(psllw, kInstPsllw, XmmReg, XmmReg) + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psllw, kInstPsllw, XmmReg, Mem) + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86Mem) //! \overload - INST_2i(psllw, kInstPsllw, XmmReg, Imm) + INST_2i(psllw, kX86InstIdPsllw, X86XmmReg, Imm) //! Packed OWORD shift left logical (SSE2). - INST_2i(pslldq, kInstPslldq, XmmReg, Imm) + INST_2i(pslldq, kX86InstIdPslldq, X86XmmReg, Imm) //! Packed DWORD shift right arithmetic (SSE2). - INST_2x(psrad, kInstPsrad, XmmReg, XmmReg) + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psrad, kInstPsrad, XmmReg, Mem) + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86Mem) //! \overload - INST_2i(psrad, kInstPsrad, XmmReg, Imm) + INST_2i(psrad, kX86InstIdPsrad, X86XmmReg, Imm) //! Packed WORD shift right arithmetic (SSE2). - INST_2x(psraw, kInstPsraw, XmmReg, XmmReg) + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psraw, kInstPsraw, XmmReg, Mem) + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86Mem) //! \overload - INST_2i(psraw, kInstPsraw, XmmReg, Imm) + INST_2i(psraw, kX86InstIdPsraw, X86XmmReg, Imm) //! Packed BYTE subtract (SSE2). - INST_2x(psubb, kInstPsubb, XmmReg, XmmReg) + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubb, kInstPsubb, XmmReg, Mem) + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86Mem) //! Packed DWORD subtract (SSE2). - INST_2x(psubd, kInstPsubd, XmmReg, XmmReg) + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubd, kInstPsubd, XmmReg, Mem) + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86Mem) //! Packed QWORD subtract (SSE2). - INST_2x(psubq, kInstPsubq, MmReg, MmReg) + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86MmReg) //! \overload - INST_2x(psubq, kInstPsubq, MmReg, Mem) + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86Mem) //! Packed QWORD subtract (SSE2). - INST_2x(psubq, kInstPsubq, XmmReg, XmmReg) + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubq, kInstPsubq, XmmReg, Mem) + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86Mem) //! Packed WORD subtract (SSE2). - INST_2x(psubw, kInstPsubw, XmmReg, XmmReg) + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubw, kInstPsubw, XmmReg, Mem) + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86Mem) //! Packed WORD to DWORD multiply and add (SSE2). - INST_2x(pmaddwd, kInstPmaddwd, XmmReg, XmmReg) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaddwd, kInstPmaddwd, XmmReg, Mem) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86Mem) //! Packed DWORD shuffle (SSE2). - INST_3i(pshufd, kInstPshufd, XmmReg, XmmReg, Imm) + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pshufd, kInstPshufd, XmmReg, Mem, Imm) + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86Mem, Imm) //! Packed WORD shuffle high (SSE2). - INST_3i(pshufhw, kInstPshufhw, XmmReg, XmmReg, Imm) + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pshufhw, kInstPshufhw, XmmReg, Mem, Imm) + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86Mem, Imm) //! Packed WORD shuffle low (SSE2). - INST_3i(pshuflw, kInstPshuflw, XmmReg, XmmReg, Imm) + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pshuflw, kInstPshuflw, XmmReg, Mem, Imm) + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86Mem, Imm) //! Packed DWORD shift right logical (SSE2). - INST_2x(psrld, kInstPsrld, XmmReg, XmmReg) + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psrld, kInstPsrld, XmmReg, Mem) + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86Mem) //! \overload - INST_2i(psrld, kInstPsrld, XmmReg, Imm) + INST_2i(psrld, kX86InstIdPsrld, X86XmmReg, Imm) //! Packed QWORD shift right logical (SSE2). - INST_2x(psrlq, kInstPsrlq, XmmReg, XmmReg) + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psrlq, kInstPsrlq, XmmReg, Mem) + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86Mem) //! \overload - INST_2i(psrlq, kInstPsrlq, XmmReg, Imm) + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmReg, Imm) //! Scalar OWORD shift right logical (SSE2). - INST_2i(psrldq, kInstPsrldq, XmmReg, Imm) + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmReg, Imm) //! Packed WORD shift right logical (SSE2). - INST_2x(psrlw, kInstPsrlw, XmmReg, XmmReg) + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psrlw, kInstPsrlw, XmmReg, Mem) + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86Mem) //! \overload - INST_2i(psrlw, kInstPsrlw, XmmReg, Imm) + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmReg, Imm) //! Packed BYTE subtract with saturation (SSE2). - INST_2x(psubsb, kInstPsubsb, XmmReg, XmmReg) + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubsb, kInstPsubsb, XmmReg, Mem) + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86Mem) //! Packed WORD subtract with saturation (SSE2). - INST_2x(psubsw, kInstPsubsw, XmmReg, XmmReg) + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubsw, kInstPsubsw, XmmReg, Mem) + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86Mem) //! Packed BYTE subtract with unsigned saturation (SSE2). - INST_2x(psubusb, kInstPsubusb, XmmReg, XmmReg) + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubusb, kInstPsubusb, XmmReg, Mem) + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86Mem) //! Packed WORD subtract with unsigned saturation (SSE2). - INST_2x(psubusw, kInstPsubusw, XmmReg, XmmReg) + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psubusw, kInstPsubusw, XmmReg, Mem) + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86Mem) //! Unpack high packed BYTEs to WORDs (SSE2). - INST_2x(punpckhbw, kInstPunpckhbw, XmmReg, XmmReg) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpckhbw, kInstPunpckhbw, XmmReg, Mem) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86Mem) //! Unpack high packed DWORDs to QWORDs (SSE2). - INST_2x(punpckhdq, kInstPunpckhdq, XmmReg, XmmReg) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpckhdq, kInstPunpckhdq, XmmReg, Mem) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86Mem) //! Unpack high packed QWORDs to OWORD (SSE2). - INST_2x(punpckhqdq, kInstPunpckhqdq, XmmReg, XmmReg) + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpckhqdq, kInstPunpckhqdq, XmmReg, Mem) + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86Mem) //! Unpack high packed WORDs to DWORDs (SSE2). - INST_2x(punpckhwd, kInstPunpckhwd, XmmReg, XmmReg) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpckhwd, kInstPunpckhwd, XmmReg, Mem) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86Mem) //! Unpack low packed BYTEs to WORDs (SSE2). - INST_2x(punpcklbw, kInstPunpcklbw, XmmReg, XmmReg) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpcklbw, kInstPunpcklbw, XmmReg, Mem) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86Mem) //! Unpack low packed DWORDs to QWORDs (SSE2). - INST_2x(punpckldq, kInstPunpckldq, XmmReg, XmmReg) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpckldq, kInstPunpckldq, XmmReg, Mem) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86Mem) //! Unpack low packed QWORDs to OWORD (SSE2). - INST_2x(punpcklqdq, kInstPunpcklqdq, XmmReg, XmmReg) + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpcklqdq, kInstPunpcklqdq, XmmReg, Mem) + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86Mem) //! Unpack low packed WORDs to DWORDs (SSE2). - INST_2x(punpcklwd, kInstPunpcklwd, XmmReg, XmmReg) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(punpcklwd, kInstPunpcklwd, XmmReg, Mem) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86Mem) //! Packed bitwise xor (SSE2). - INST_2x(pxor, kInstPxor, XmmReg, XmmReg) + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pxor, kInstPxor, XmmReg, Mem) + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86Mem) //! Shuffle DP-FP (SSE2). - INST_3i(shufpd, kInstShufpd, XmmReg, XmmReg, Imm) + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(shufpd, kInstShufpd, XmmReg, Mem, Imm) + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86Mem, Imm) //! Packed DP-FP square root (SSE2). - INST_2x(sqrtpd, kInstSqrtpd, XmmReg, XmmReg) + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(sqrtpd, kInstSqrtpd, XmmReg, Mem) + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86Mem) //! Scalar DP-FP square root (SSE2). - INST_2x(sqrtsd, kInstSqrtsd, XmmReg, XmmReg) + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(sqrtsd, kInstSqrtsd, XmmReg, Mem) + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86Mem) //! Packed DP-FP subtract (SSE2). - INST_2x(subpd, kInstSubpd, XmmReg, XmmReg) + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(subpd, kInstSubpd, XmmReg, Mem) + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86Mem) //! Scalar DP-FP subtract (SSE2). - INST_2x(subsd, kInstSubsd, XmmReg, XmmReg) + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(subsd, kInstSubsd, XmmReg, Mem) + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86Mem) //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). - INST_2x(ucomisd, kInstUcomisd, XmmReg, XmmReg) + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(ucomisd, kInstUcomisd, XmmReg, Mem) + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86Mem) //! Unpack and interleave high packed DP-FP (SSE2). - INST_2x(unpckhpd, kInstUnpckhpd, XmmReg, XmmReg) + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(unpckhpd, kInstUnpckhpd, XmmReg, Mem) + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86Mem) //! Unpack and interleave low packed DP-FP (SSE2). - INST_2x(unpcklpd, kInstUnpcklpd, XmmReg, XmmReg) + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(unpcklpd, kInstUnpcklpd, XmmReg, Mem) + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86Mem) //! Packed DP-FP bitwise xor (SSE2). - INST_2x(xorpd, kInstXorpd, XmmReg, XmmReg) + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(xorpd, kInstXorpd, XmmReg, Mem) + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86Mem) // -------------------------------------------------------------------------- // [SSE3] // -------------------------------------------------------------------------- //! Packed DP-FP add/subtract (SSE3). - INST_2x(addsubpd, kInstAddsubpd, XmmReg, XmmReg) + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addsubpd, kInstAddsubpd, XmmReg, Mem) + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86Mem) //! Packed SP-FP add/subtract (SSE3). - INST_2x(addsubps, kInstAddsubps, XmmReg, XmmReg) + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(addsubps, kInstAddsubps, XmmReg, Mem) + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86Mem) - //! Store integer with truncation (SSE3). - INST_1x(fisttp, kInstFisttp, Mem) + //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop + //! the FPU stack (FPU / SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) //! Packed DP-FP horizontal add (SSE3). - INST_2x(haddpd, kInstHaddpd, XmmReg, XmmReg) + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(haddpd, kInstHaddpd, XmmReg, Mem) + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86Mem) //! Packed SP-FP horizontal add (SSE3). - INST_2x(haddps, kInstHaddps, XmmReg, XmmReg) + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(haddps, kInstHaddps, XmmReg, Mem) + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86Mem) //! Packed DP-FP horizontal subtract (SSE3). - INST_2x(hsubpd, kInstHsubpd, XmmReg, XmmReg) + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(hsubpd, kInstHsubpd, XmmReg, Mem) + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86Mem) //! Packed SP-FP horizontal subtract (SSE3). - INST_2x(hsubps, kInstHsubps, XmmReg, XmmReg) + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(hsubps, kInstHsubps, XmmReg, Mem) + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86Mem) //! Load 128-bits unaligned (SSE3). - INST_2x(lddqu, kInstLddqu, XmmReg, Mem) + INST_2x(lddqu, kX86InstIdLddqu, X86XmmReg, X86Mem) //! Setup monitor address (SSE3). - INST_0x(monitor, kInstMonitor) + INST_0x(monitor, kX86InstIdMonitor) //! Move one DP-FP and duplicate (SSE3). - INST_2x(movddup, kInstMovddup, XmmReg, XmmReg) + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movddup, kInstMovddup, XmmReg, Mem) + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86Mem) //! Move packed SP-FP high and duplicate (SSE3). - INST_2x(movshdup, kInstMovshdup, XmmReg, XmmReg) + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movshdup, kInstMovshdup, XmmReg, Mem) + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86Mem) //! Move packed SP-FP low and duplicate (SSE3). - INST_2x(movsldup, kInstMovsldup, XmmReg, XmmReg) + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(movsldup, kInstMovsldup, XmmReg, Mem) + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86Mem) //! Monitor wait (SSE3). - INST_0x(mwait, kInstMwait) + INST_0x(mwait, kX86InstIdMwait) // -------------------------------------------------------------------------- // [SSSE3] // -------------------------------------------------------------------------- //! Packed BYTE sign (SSSE3). - INST_2x(psignb, kInstPsignb, MmReg, MmReg) + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86MmReg) //! \overload - INST_2x(psignb, kInstPsignb, MmReg, Mem) + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86Mem) //! Packed BYTE sign (SSSE3). - INST_2x(psignb, kInstPsignb, XmmReg, XmmReg) + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psignb, kInstPsignb, XmmReg, Mem) + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86Mem) //! Packed DWORD sign (SSSE3). - INST_2x(psignd, kInstPsignd, MmReg, MmReg) + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86MmReg) //! \overload - INST_2x(psignd, kInstPsignd, MmReg, Mem) + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86Mem) //! Packed DWORD sign (SSSE3). - INST_2x(psignd, kInstPsignd, XmmReg, XmmReg) + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psignd, kInstPsignd, XmmReg, Mem) + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86Mem) //! Packed WORD sign (SSSE3). - INST_2x(psignw, kInstPsignw, MmReg, MmReg) + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86MmReg) //! \overload - INST_2x(psignw, kInstPsignw, MmReg, Mem) + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86Mem) //! Packed WORD sign (SSSE3). - INST_2x(psignw, kInstPsignw, XmmReg, XmmReg) + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(psignw, kInstPsignw, XmmReg, Mem) + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86Mem) //! Packed DWORD horizontal add (SSSE3). - INST_2x(phaddd, kInstPhaddd, MmReg, MmReg) + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86MmReg) //! \overload - INST_2x(phaddd, kInstPhaddd, MmReg, Mem) + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86Mem) //! Packed DWORD horizontal add (SSSE3). - INST_2x(phaddd, kInstPhaddd, XmmReg, XmmReg) + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phaddd, kInstPhaddd, XmmReg, Mem) + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86Mem) //! Packed WORD horizontal add with saturation (SSSE3). - INST_2x(phaddsw, kInstPhaddsw, MmReg, MmReg) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86MmReg) //! \overload - INST_2x(phaddsw, kInstPhaddsw, MmReg, Mem) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86Mem) //! Packed WORD horizontal add with saturation (SSSE3). - INST_2x(phaddsw, kInstPhaddsw, XmmReg, XmmReg) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phaddsw, kInstPhaddsw, XmmReg, Mem) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86Mem) //! Packed WORD horizontal add (SSSE3). - INST_2x(phaddw, kInstPhaddw, MmReg, MmReg) + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86MmReg) //! \overload - INST_2x(phaddw, kInstPhaddw, MmReg, Mem) + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86Mem) //! Packed WORD horizontal add (SSSE3). - INST_2x(phaddw, kInstPhaddw, XmmReg, XmmReg) + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phaddw, kInstPhaddw, XmmReg, Mem) + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86Mem) //! Packed DWORD horizontal subtract (SSSE3). - INST_2x(phsubd, kInstPhsubd, MmReg, MmReg) + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86MmReg) //! \overload - INST_2x(phsubd, kInstPhsubd, MmReg, Mem) + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86Mem) //! Packed DWORD horizontal subtract (SSSE3). - INST_2x(phsubd, kInstPhsubd, XmmReg, XmmReg) + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phsubd, kInstPhsubd, XmmReg, Mem) + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86Mem) //! Packed WORD horizontal subtract with saturation (SSSE3). - INST_2x(phsubsw, kInstPhsubsw, MmReg, MmReg) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86MmReg) //! \overload - INST_2x(phsubsw, kInstPhsubsw, MmReg, Mem) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86Mem) //! Packed WORD horizontal subtract with saturation (SSSE3). - INST_2x(phsubsw, kInstPhsubsw, XmmReg, XmmReg) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phsubsw, kInstPhsubsw, XmmReg, Mem) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86Mem) //! Packed WORD horizontal subtract (SSSE3). - INST_2x(phsubw, kInstPhsubw, MmReg, MmReg) + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86MmReg) //! \overload - INST_2x(phsubw, kInstPhsubw, MmReg, Mem) + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86Mem) //! Packed WORD horizontal subtract (SSSE3). - INST_2x(phsubw, kInstPhsubw, XmmReg, XmmReg) + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phsubw, kInstPhsubw, XmmReg, Mem) + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86Mem) //! Packed multiply and add signed and unsigned bytes (SSSE3). - INST_2x(pmaddubsw, kInstPmaddubsw, MmReg, MmReg) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmaddubsw, kInstPmaddubsw, MmReg, Mem) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86Mem) //! Packed multiply and add signed and unsigned bytes (SSSE3). - INST_2x(pmaddubsw, kInstPmaddubsw, XmmReg, XmmReg) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaddubsw, kInstPmaddubsw, XmmReg, Mem) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86Mem) //! Packed BYTE absolute value (SSSE3). - INST_2x(pabsb, kInstPabsb, MmReg, MmReg) + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86MmReg) //! \overload - INST_2x(pabsb, kInstPabsb, MmReg, Mem) + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86Mem) //! Packed BYTE absolute value (SSSE3). - INST_2x(pabsb, kInstPabsb, XmmReg, XmmReg) + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pabsb, kInstPabsb, XmmReg, Mem) + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86Mem) //! Packed DWORD absolute value (SSSE3). - INST_2x(pabsd, kInstPabsd, MmReg, MmReg) + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86MmReg) //! \overload - INST_2x(pabsd, kInstPabsd, MmReg, Mem) + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86Mem) //! Packed DWORD absolute value (SSSE3). - INST_2x(pabsd, kInstPabsd, XmmReg, XmmReg) + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pabsd, kInstPabsd, XmmReg, Mem) + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86Mem) //! Packed WORD absolute value (SSSE3). - INST_2x(pabsw, kInstPabsw, MmReg, MmReg) + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86MmReg) //! \overload - INST_2x(pabsw, kInstPabsw, MmReg, Mem) + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86Mem) //! Packed WORD absolute value (SSSE3). - INST_2x(pabsw, kInstPabsw, XmmReg, XmmReg) + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pabsw, kInstPabsw, XmmReg, Mem) + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86Mem) //! Packed WORD multiply high, round and scale (SSSE3). - INST_2x(pmulhrsw, kInstPmulhrsw, MmReg, MmReg) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86MmReg) //! \overload - INST_2x(pmulhrsw, kInstPmulhrsw, MmReg, Mem) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86Mem) //! Packed WORD multiply high, round and scale (SSSE3). - INST_2x(pmulhrsw, kInstPmulhrsw, XmmReg, XmmReg) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmulhrsw, kInstPmulhrsw, XmmReg, Mem) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86Mem) //! Packed BYTE shuffle (SSSE3). - INST_2x(pshufb, kInstPshufb, MmReg, MmReg) + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86MmReg) //! \overload - INST_2x(pshufb, kInstPshufb, MmReg, Mem) + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86Mem) //! Packed BYTE shuffle (SSSE3). - INST_2x(pshufb, kInstPshufb, XmmReg, XmmReg) + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pshufb, kInstPshufb, XmmReg, Mem) + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86Mem) //! Packed align right (SSSE3). - INST_3i(palignr, kInstPalignr, MmReg, MmReg, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86MmReg, Imm) //! \overload - INST_3i(palignr, kInstPalignr, MmReg, Mem, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86Mem, Imm) //! Packed align right (SSSE3). - INST_3i(palignr, kInstPalignr, XmmReg, XmmReg, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(palignr, kInstPalignr, XmmReg, Mem, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [SSE4.1] // -------------------------------------------------------------------------- //! Packed DP-FP blend (SSE4.1). - INST_3i(blendpd, kInstBlendpd, XmmReg, XmmReg, Imm) + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(blendpd, kInstBlendpd, XmmReg, Mem, Imm) + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86Mem, Imm) //! Packed SP-FP blend (SSE4.1). - INST_3i(blendps, kInstBlendps, XmmReg, XmmReg, Imm) + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(blendps, kInstBlendps, XmmReg, Mem, Imm) + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86Mem, Imm) //! Packed DP-FP variable blend (SSE4.1). - INST_2x(blendvpd, kInstBlendvpd, XmmReg, XmmReg) + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(blendvpd, kInstBlendvpd, XmmReg, Mem) + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86Mem) //! Packed SP-FP variable blend (SSE4.1). - INST_2x(blendvps, kInstBlendvps, XmmReg, XmmReg) + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(blendvps, kInstBlendvps, XmmReg, Mem) + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86Mem) //! Packed DP-FP dot product (SSE4.1). - INST_3i(dppd, kInstDppd, XmmReg, XmmReg, Imm) + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(dppd, kInstDppd, XmmReg, Mem, Imm) + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86Mem, Imm) //! Packed SP-FP dot product (SSE4.1). - INST_3i(dpps, kInstDpps, XmmReg, XmmReg, Imm) + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(dpps, kInstDpps, XmmReg, Mem, Imm) + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86Mem, Imm) //! Extract SP-FP based on selector (SSE4.1). - INST_3i(extractps, kInstExtractps, GpReg, XmmReg, Imm) + INST_3i(extractps, kX86InstIdExtractps, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(extractps, kInstExtractps, Mem, XmmReg, Imm) + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmReg, Imm) //! Insert SP-FP based on selector (SSE4.1). - INST_3i(insertps, kInstInsertps, XmmReg, XmmReg, Imm) + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(insertps, kInstInsertps, XmmReg, Mem, Imm) + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86Mem, Imm) //! Load OWORD aligned using NT hint (SSE4.1). - INST_2x(movntdqa, kInstMovntdqa, XmmReg, Mem) + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmReg, X86Mem) //! Packed WORD sums of absolute difference (SSE4.1). - INST_3i(mpsadbw, kInstMpsadbw, XmmReg, XmmReg, Imm) + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(mpsadbw, kInstMpsadbw, XmmReg, Mem, Imm) + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86Mem, Imm) //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). - INST_2x(packusdw, kInstPackusdw, XmmReg, XmmReg) + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(packusdw, kInstPackusdw, XmmReg, Mem) + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86Mem) //! Packed BYTE variable blend (SSE4.1). - INST_2x(pblendvb, kInstPblendvb, XmmReg, XmmReg) + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pblendvb, kInstPblendvb, XmmReg, Mem) + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86Mem) //! Packed WORD blend (SSE4.1). - INST_3i(pblendw, kInstPblendw, XmmReg, XmmReg, Imm) + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pblendw, kInstPblendw, XmmReg, Mem, Imm) + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86Mem, Imm) //! Packed QWORD compare for equality (SSE4.1). - INST_2x(pcmpeqq, kInstPcmpeqq, XmmReg, XmmReg) + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpeqq, kInstPcmpeqq, XmmReg, Mem) + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86Mem) //! Extract BYTE based on selector (SSE4.1). - INST_3i(pextrb, kInstPextrb, GpReg, XmmReg, Imm) + INST_3i(pextrb, kX86InstIdPextrb, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(pextrb, kInstPextrb, Mem, XmmReg, Imm) + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmReg, Imm) //! Extract DWORD based on selector (SSE4.1). - INST_3i(pextrd, kInstPextrd, GpReg, XmmReg, Imm) + INST_3i(pextrd, kX86InstIdPextrd, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(pextrd, kInstPextrd, Mem, XmmReg, Imm) + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmReg, Imm) //! Extract QWORD based on selector (SSE4.1). - INST_3i(pextrq, kInstPextrq, GpReg, XmmReg, Imm) + INST_3i(pextrq, kX86InstIdPextrq, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(pextrq, kInstPextrq, Mem, XmmReg, Imm) + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmReg, Imm) //! Extract WORD based on selector (SSE4.1). - INST_3i(pextrw, kInstPextrw, Mem, XmmReg, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmReg, Imm) //! Packed WORD horizontal minimum (SSE4.1). - INST_2x(phminposuw, kInstPhminposuw, XmmReg, XmmReg) + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(phminposuw, kInstPhminposuw, XmmReg, Mem) + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86Mem) //! Insert BYTE based on selector (SSE4.1). - INST_3i(pinsrb, kInstPinsrb, XmmReg, GpReg, Imm) + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86GpReg, Imm) //! \overload - INST_3i(pinsrb, kInstPinsrb, XmmReg, Mem, Imm) + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86Mem, Imm) //! Insert DWORD based on selector (SSE4.1). - INST_3i(pinsrd, kInstPinsrd, XmmReg, GpReg, Imm) + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86GpReg, Imm) //! \overload - INST_3i(pinsrd, kInstPinsrd, XmmReg, Mem, Imm) + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86Mem, Imm) //! Insert QWORD based on selector (SSE4.1). - INST_3i(pinsrq, kInstPinsrq, XmmReg, GpReg, Imm) + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86GpReg, Imm) //! \overload - INST_3i(pinsrq, kInstPinsrq, XmmReg, Mem, Imm) + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86Mem, Imm) //! Packed BYTE maximum (SSE4.1). - INST_2x(pmaxsb, kInstPmaxsb, XmmReg, XmmReg) + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxsb, kInstPmaxsb, XmmReg, Mem) + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86Mem) //! Packed DWORD maximum (SSE4.1). - INST_2x(pmaxsd, kInstPmaxsd, XmmReg, XmmReg) + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxsd, kInstPmaxsd, XmmReg, Mem) + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86Mem) //! Packed DWORD unsigned maximum (SSE4.1). - INST_2x(pmaxud, kInstPmaxud, XmmReg, XmmReg) + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxud,kInstPmaxud , XmmReg, Mem) + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmReg, X86Mem) //! Packed WORD unsigned maximum (SSE4.1). - INST_2x(pmaxuw, kInstPmaxuw, XmmReg, XmmReg) + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmaxuw, kInstPmaxuw, XmmReg, Mem) + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86Mem) //! Packed BYTE minimum (SSE4.1). - INST_2x(pminsb, kInstPminsb, XmmReg, XmmReg) + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminsb, kInstPminsb, XmmReg, Mem) + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86Mem) //! Packed DWORD minimum (SSE4.1). - INST_2x(pminsd, kInstPminsd, XmmReg, XmmReg) + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminsd, kInstPminsd, XmmReg, Mem) + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86Mem) //! Packed WORD unsigned minimum (SSE4.1). - INST_2x(pminuw, kInstPminuw, XmmReg, XmmReg) + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminuw, kInstPminuw, XmmReg, Mem) + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86Mem) //! Packed DWORD unsigned minimum (SSE4.1). - INST_2x(pminud, kInstPminud, XmmReg, XmmReg) + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pminud, kInstPminud, XmmReg, Mem) + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86Mem) //! BYTE to DWORD with sign extend (SSE4.1). - INST_2x(pmovsxbd, kInstPmovsxbd, XmmReg, XmmReg) + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxbd, kInstPmovsxbd, XmmReg, Mem) + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86Mem) //! Packed BYTE to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxbq, kInstPmovsxbq, XmmReg, XmmReg) + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxbq, kInstPmovsxbq, XmmReg, Mem) + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86Mem) //! Packed BYTE to WORD with sign extend (SSE4.1). - INST_2x(pmovsxbw, kInstPmovsxbw, XmmReg, XmmReg) + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxbw, kInstPmovsxbw, XmmReg, Mem) + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86Mem) //! Packed DWORD to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxdq, kInstPmovsxdq, XmmReg, XmmReg) + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxdq, kInstPmovsxdq, XmmReg, Mem) + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86Mem) //! Packed WORD to DWORD with sign extend (SSE4.1). - INST_2x(pmovsxwd, kInstPmovsxwd, XmmReg, XmmReg) + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxwd, kInstPmovsxwd, XmmReg, Mem) + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86Mem) //! Packed WORD to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxwq, kInstPmovsxwq, XmmReg, XmmReg) + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovsxwq, kInstPmovsxwq, XmmReg, Mem) + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86Mem) //! BYTE to DWORD with zero extend (SSE4.1). - INST_2x(pmovzxbd, kInstPmovzxbd, XmmReg, XmmReg) + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxbd, kInstPmovzxbd, XmmReg, Mem) + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86Mem) //! Packed BYTE to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxbq, kInstPmovzxbq, XmmReg, XmmReg) + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxbq, kInstPmovzxbq, XmmReg, Mem) + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86Mem) //! BYTE to WORD with zero extend (SSE4.1). - INST_2x(pmovzxbw, kInstPmovzxbw, XmmReg, XmmReg) + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxbw, kInstPmovzxbw, XmmReg, Mem) + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86Mem) //! Packed DWORD to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxdq, kInstPmovzxdq, XmmReg, XmmReg) + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxdq, kInstPmovzxdq, XmmReg, Mem) + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86Mem) //! Packed WORD to DWORD with zero extend (SSE4.1). - INST_2x(pmovzxwd, kInstPmovzxwd, XmmReg, XmmReg) + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxwd, kInstPmovzxwd, XmmReg, Mem) + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86Mem) //! Packed WORD to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxwq, kInstPmovzxwq, XmmReg, XmmReg) + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmovzxwq, kInstPmovzxwq, XmmReg, Mem) + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86Mem) //! Packed DWORD to QWORD multiply (SSE4.1). - INST_2x(pmuldq, kInstPmuldq, XmmReg, XmmReg) + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmuldq, kInstPmuldq, XmmReg, Mem) + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86Mem) //! Packed DWORD multiply low (SSE4.1). - INST_2x(pmulld, kInstPmulld, XmmReg, XmmReg) + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pmulld, kInstPmulld, XmmReg, Mem) + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86Mem) //! Logical compare (SSE4.1). - INST_2x(ptest, kInstPtest, XmmReg, XmmReg) + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86XmmReg) //! \overload - INST_2x(ptest, kInstPtest, XmmReg, Mem) + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86Mem) //! Packed DP-FP round (SSE4.1). - INST_3i(roundpd, kInstRoundpd, XmmReg, XmmReg, Imm) + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(roundpd, kInstRoundpd, XmmReg, Mem, Imm) + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86Mem, Imm) //! Packed SP-FP round (SSE4.1). - INST_3i(roundps, kInstRoundps, XmmReg, XmmReg, Imm) + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(roundps, kInstRoundps, XmmReg, Mem, Imm) + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86Mem, Imm) //! Scalar DP-FP round (SSE4.1). - INST_3i(roundsd, kInstRoundsd, XmmReg, XmmReg, Imm) + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(roundsd, kInstRoundsd, XmmReg, Mem, Imm) + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86Mem, Imm) //! Scalar SP-FP round (SSE4.1). - INST_3i(roundss, kInstRoundss, XmmReg, XmmReg, Imm) + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(roundss, kInstRoundss, XmmReg, Mem, Imm) + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [SSE4.2] // -------------------------------------------------------------------------- //! Packed compare explicit length strings, return index (SSE4.2). - INST_3i(pcmpestri, kInstPcmpestri, XmmReg, XmmReg, Imm) + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pcmpestri, kInstPcmpestri, XmmReg, Mem, Imm) + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86Mem, Imm) //! Packed compare explicit length strings, return mask (SSE4.2). - INST_3i(pcmpestrm, kInstPcmpestrm, XmmReg, XmmReg, Imm) + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pcmpestrm, kInstPcmpestrm, XmmReg, Mem, Imm) + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86Mem, Imm) //! Packed compare implicit length strings, return index (SSE4.2). - INST_3i(pcmpistri, kInstPcmpistri, XmmReg, XmmReg, Imm) + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pcmpistri, kInstPcmpistri, XmmReg, Mem, Imm) + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86Mem, Imm) //! Packed compare implicit length strings, return mask (SSE4.2). - INST_3i(pcmpistrm, kInstPcmpistrm, XmmReg, XmmReg, Imm) + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pcmpistrm, kInstPcmpistrm, XmmReg, Mem, Imm) + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86Mem, Imm) //! Packed QWORD compare if greater than (SSE4.2). - INST_2x(pcmpgtq, kInstPcmpgtq, XmmReg, XmmReg) + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(pcmpgtq, kInstPcmpgtq, XmmReg, Mem) + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86Mem) // -------------------------------------------------------------------------- // [AESNI] // -------------------------------------------------------------------------- //! Perform a single round of the AES decryption flow (AESNI). - INST_2x(aesdec, kInstAesdec, XmmReg, XmmReg) + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86XmmReg) //! \overload - INST_2x(aesdec, kInstAesdec, XmmReg, Mem) + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86Mem) //! Perform the last round of the AES decryption flow (AESNI). - INST_2x(aesdeclast, kInstAesdeclast, XmmReg, XmmReg) + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86XmmReg) //! \overload - INST_2x(aesdeclast, kInstAesdeclast, XmmReg, Mem) + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86Mem) //! Perform a single round of the AES encryption flow (AESNI). - INST_2x(aesenc, kInstAesenc, XmmReg, XmmReg) + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86XmmReg) //! \overload - INST_2x(aesenc, kInstAesenc, XmmReg, Mem) + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86Mem) //! Perform the last round of the AES encryption flow (AESNI). - INST_2x(aesenclast, kInstAesenclast, XmmReg, XmmReg) + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86XmmReg) //! \overload - INST_2x(aesenclast, kInstAesenclast, XmmReg, Mem) + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86Mem) //! Perform the InvMixColumns transformation (AESNI). - INST_2x(aesimc, kInstAesimc, XmmReg, XmmReg) + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86XmmReg) //! \overload - INST_2x(aesimc, kInstAesimc, XmmReg, Mem) + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86Mem) //! Assist in expanding the AES cipher key (AESNI). - INST_3i(aeskeygenassist, kInstAeskeygenassist, XmmReg, XmmReg, Imm) + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(aeskeygenassist, kInstAeskeygenassist, XmmReg, Mem, Imm) + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [PCLMULQDQ] // -------------------------------------------------------------------------- //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). - INST_3i(pclmulqdq, kInstPclmulqdq, XmmReg, XmmReg, Imm) + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(pclmulqdq, kInstPclmulqdq, XmmReg, Mem, Imm) + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [AVX] // -------------------------------------------------------------------------- //! Packed DP-FP add (AVX). - INST_3x(vaddpd, kInstVaddpd, XmmReg, XmmReg, XmmReg) + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddpd, kInstVaddpd, XmmReg, XmmReg, Mem) + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vaddpd, kInstVaddpd, YmmReg, YmmReg, YmmReg) + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vaddpd, kInstVaddpd, YmmReg, YmmReg, Mem) + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP add (AVX). - INST_3x(vaddps, kInstVaddps, XmmReg, XmmReg, XmmReg) + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddps, kInstVaddps, XmmReg, XmmReg, Mem) + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vaddps, kInstVaddps, YmmReg, YmmReg, YmmReg) + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vaddps, kInstVaddps, YmmReg, YmmReg, Mem) + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86Mem) //! Scalar DP-FP add (AVX) - INST_3x(vaddsd, kInstVaddsd, XmmReg, XmmReg, XmmReg) + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddsd, kInstVaddsd, XmmReg, XmmReg, Mem) + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP add (AVX) - INST_3x(vaddss, kInstVaddss, XmmReg, XmmReg, XmmReg) + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddss, kInstVaddss, XmmReg, XmmReg, Mem) + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86Mem) //! Packed DP-FP add/subtract (AVX). - INST_3x(vaddsubpd, kInstVaddsubpd, XmmReg, XmmReg, XmmReg) + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddsubpd, kInstVaddsubpd, XmmReg, XmmReg, Mem) + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vaddsubpd, kInstVaddsubpd, YmmReg, YmmReg, YmmReg) + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vaddsubpd, kInstVaddsubpd, YmmReg, YmmReg, Mem) + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP add/subtract (AVX). - INST_3x(vaddsubps, kInstVaddsubps, XmmReg, XmmReg, XmmReg) + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaddsubps, kInstVaddsubps, XmmReg, XmmReg, Mem) + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vaddsubps, kInstVaddsubps, YmmReg, YmmReg, YmmReg) + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vaddsubps, kInstVaddsubps, YmmReg, YmmReg, Mem) + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP bitwise and (AVX). - INST_3x(vandpd, kInstVandpd, XmmReg, XmmReg, XmmReg) + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vandpd, kInstVandpd, XmmReg, XmmReg, Mem) + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vandpd, kInstVandpd, YmmReg, YmmReg, YmmReg) + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vandpd, kInstVandpd, YmmReg, YmmReg, Mem) + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP bitwise and (AVX). - INST_3x(vandps, kInstVandps, XmmReg, XmmReg, XmmReg) + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vandps, kInstVandps, XmmReg, XmmReg, Mem) + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vandps, kInstVandps, YmmReg, YmmReg, YmmReg) + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vandps, kInstVandps, YmmReg, YmmReg, Mem) + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP bitwise and-not (AVX). - INST_3x(vandnpd, kInstVandnpd, XmmReg, XmmReg, XmmReg) + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vandnpd, kInstVandnpd, XmmReg, XmmReg, Mem) + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vandnpd, kInstVandnpd, YmmReg, YmmReg, YmmReg) + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vandnpd, kInstVandnpd, YmmReg, YmmReg, Mem) + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP bitwise and-not (AVX). - INST_3x(vandnps, kInstVandnps, XmmReg, XmmReg, XmmReg) + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vandnps, kInstVandnps, XmmReg, XmmReg, Mem) + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vandnps, kInstVandnps, YmmReg, YmmReg, YmmReg) + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vandnps, kInstVandnps, YmmReg, YmmReg, Mem) + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP blend (AVX). - INST_4i(vblendpd, kInstVblendpd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vblendpd, kInstVblendpd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vblendpd, kInstVblendpd, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vblendpd, kInstVblendpd, YmmReg, YmmReg, Mem, Imm) + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed SP-FP blend (AVX). - INST_4i(vblendps, kInstVblendps, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vblendps, kInstVblendps, XmmReg, XmmReg, Mem, Imm) + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vblendps, kInstVblendps, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vblendps, kInstVblendps, YmmReg, YmmReg, Mem, Imm) + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed DP-FP variable blend (AVX). - INST_4x(vblendvpd, kInstVblendvpd, XmmReg, XmmReg, XmmReg, XmmReg) + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_4x(vblendvpd, kInstVblendvpd, XmmReg, XmmReg, Mem, XmmReg) + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) //! \overload - INST_4x(vblendvpd, kInstVblendvpd, YmmReg, YmmReg, YmmReg, YmmReg) + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_4x(vblendvpd, kInstVblendvpd, YmmReg, YmmReg, Mem, YmmReg) + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) //! Packed SP-FP variable blend (AVX). - INST_4x(vblendvps, kInstVblendvps, XmmReg, XmmReg, XmmReg, XmmReg) + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_4x(vblendvps, kInstVblendvps, XmmReg, XmmReg, Mem, XmmReg) + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) //! \overload - INST_4x(vblendvps, kInstVblendvps, YmmReg, YmmReg, YmmReg, YmmReg) + INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_4x(vblendvps, kInstVblendvps, YmmReg, YmmReg, Mem, YmmReg) + 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, kInstVbroadcastf128, YmmReg, Mem) + INST_2x(vbroadcastf128, kX86InstIdVbroadcastf128, X86YmmReg, X86Mem) //! Broadcast DP-FP element in `o1` to four locations in `o0` (AVX). - INST_2x(vbroadcastsd, kInstVbroadcastsd, YmmReg, Mem) + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86Mem) //! Broadcast SP-FP element in `o1` to four locations in `o0` (AVX). - INST_2x(vbroadcastss, kInstVbroadcastss, XmmReg, Mem) + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86Mem) //! Broadcast SP-FP element in `o1` to eight locations in `o0` (AVX). - INST_2x(vbroadcastss, kInstVbroadcastss, YmmReg, Mem) + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86Mem) //! Packed DP-FP compare (AVX). - INST_4i(vcmppd, kInstVcmppd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vcmppd, kInstVcmppd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vcmppd, kInstVcmppd, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vcmppd, kInstVcmppd, YmmReg, YmmReg, Mem, Imm) + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed SP-FP compare (AVX). - INST_4i(vcmpps, kInstVcmpps, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vcmpps, kInstVcmpps, XmmReg, XmmReg, Mem, Imm) + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vcmpps, kInstVcmpps, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vcmpps, kInstVcmpps, YmmReg, YmmReg, Mem, Imm) + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Scalar DP-FP compare (AVX). - INST_4i(vcmpsd, kInstVcmpsd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vcmpsd, kInstVcmpsd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Scalar SP-FP compare (AVX). - INST_4i(vcmpss, kInstVcmpss, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vcmpss, kInstVcmpss, XmmReg, XmmReg, Mem, Imm) + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Scalar DP-FP ordered compare and set EFLAGS (AVX). - INST_2x(vcomisd, kInstVcomisd, XmmReg, XmmReg) + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcomisd, kInstVcomisd, XmmReg, Mem) + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86Mem) //! Scalar SP-FP ordered compare and set EFLAGS (AVX). - INST_2x(vcomiss, kInstVcomiss, XmmReg, XmmReg) + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcomiss, kInstVcomiss, XmmReg, Mem) + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86Mem) //! Convert packed QWORDs to packed DP-FP (AVX). - INST_2x(vcvtdq2pd, kInstVcvtdq2pd, XmmReg, XmmReg) + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtdq2pd, kInstVcvtdq2pd, XmmReg, Mem) + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvtdq2pd, kInstVcvtdq2pd, YmmReg, XmmReg) + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vcvtdq2pd, kInstVcvtdq2pd, YmmReg, Mem) + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86Mem) //! Convert packed QWORDs to packed SP-FP (AVX). - INST_2x(vcvtdq2ps, kInstVcvtdq2ps, XmmReg, XmmReg) + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtdq2ps, kInstVcvtdq2ps, XmmReg, Mem) + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvtdq2ps, kInstVcvtdq2ps, YmmReg, YmmReg) + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vcvtdq2ps, kInstVcvtdq2ps, YmmReg, Mem) + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86Mem) //! Convert packed DP-FP to packed QWORDs (AVX). - INST_2x(vcvtpd2dq, kInstVcvtpd2dq, XmmReg, XmmReg) + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtpd2dq, kInstVcvtpd2dq, XmmReg, YmmReg) + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86YmmReg) //! \overload - INST_2x(vcvtpd2dq, kInstVcvtpd2dq, XmmReg, Mem) + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86Mem) //! Convert packed DP-FP to packed SP-FP (AVX). - INST_2x(vcvtpd2ps, kInstVcvtpd2ps, XmmReg, XmmReg) + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtpd2ps, kInstVcvtpd2ps, XmmReg, YmmReg) + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86YmmReg) //! \overload - INST_2x(vcvtpd2ps, kInstVcvtpd2ps, XmmReg, Mem) + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86Mem) //! Convert packed SP-FP to packed QWORDs (AVX). - INST_2x(vcvtps2dq, kInstVcvtps2dq, XmmReg, XmmReg) + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtps2dq, kInstVcvtps2dq, XmmReg, Mem) + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvtps2dq, kInstVcvtps2dq, YmmReg, YmmReg) + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vcvtps2dq, kInstVcvtps2dq, YmmReg, Mem) + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86Mem) //! Convert packed SP-FP to packed DP-FP (AVX). - INST_2x(vcvtps2pd, kInstVcvtps2pd, XmmReg, XmmReg) + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtps2pd, kInstVcvtps2pd, XmmReg, Mem) + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvtps2pd, kInstVcvtps2pd, YmmReg, XmmReg) + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vcvtps2pd, kInstVcvtps2pd, YmmReg, Mem) + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86Mem) //! Convert scalar DP-FP to DWORD (AVX). - INST_2x(vcvtsd2si, kInstVcvtsd2si, GpReg, XmmReg) + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(vcvtsd2si, kInstVcvtsd2si, GpReg, Mem) + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86Mem) //! Convert scalar DP-FP to scalar SP-FP (AVX). - INST_3x(vcvtsd2ss, kInstVcvtsd2ss, XmmReg, XmmReg, XmmReg) + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vcvtsd2ss, kInstVcvtsd2ss, XmmReg, XmmReg, Mem) + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86Mem) //! Convert DWORD integer to scalar DP-FP (AVX). - INST_3x(vcvtsi2sd, kInstVcvtsi2sd, XmmReg, XmmReg, GpReg) + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86GpReg) //! \overload - INST_3x(vcvtsi2sd, kInstVcvtsi2sd, XmmReg, XmmReg, Mem) + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86Mem) //! Convert scalar INT32 to SP-FP (AVX). - INST_3x(vcvtsi2ss, kInstVcvtsi2ss, XmmReg, XmmReg, GpReg) + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86GpReg) //! \overload - INST_3x(vcvtsi2ss, kInstVcvtsi2ss, XmmReg, XmmReg, Mem) + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86Mem) //! Convert scalar SP-FP to DP-FP (AVX). - INST_3x(vcvtss2sd, kInstVcvtss2sd, XmmReg, XmmReg, XmmReg) + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vcvtss2sd, kInstVcvtss2sd, XmmReg, XmmReg, Mem) + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86Mem) //! Convert scalar SP-FP to INT32 (AVX). - INST_2x(vcvtss2si, kInstVcvtss2si, GpReg, XmmReg) + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(vcvtss2si, kInstVcvtss2si, GpReg, Mem) + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86Mem) //! Convert with truncation packed DP-FP to packed QWORDs (AVX). - INST_2x(vcvttpd2dq, kInstVcvttpd2dq, XmmReg, XmmReg) + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvttpd2dq, kInstVcvttpd2dq, XmmReg, YmmReg) + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86YmmReg) //! \overload - INST_2x(vcvttpd2dq, kInstVcvttpd2dq, XmmReg, Mem) + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86Mem) //! Convert with truncation packed SP-FP to packed QWORDs (AVX). - INST_2x(vcvttps2dq, kInstVcvttps2dq, XmmReg, XmmReg) + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvttps2dq, kInstVcvttps2dq, XmmReg, Mem) + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvttps2dq, kInstVcvttps2dq, YmmReg, YmmReg) + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vcvttps2dq, kInstVcvttps2dq, YmmReg, Mem) + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86Mem) //! Convert with truncation scalar DP-FP to DWORD (AVX). - INST_2x(vcvttsd2si, kInstVcvttsd2si, GpReg, XmmReg) + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(vcvttsd2si, kInstVcvttsd2si, GpReg, Mem) + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86Mem) //! Convert with truncation scalar SP-FP to INT32 (AVX). - INST_2x(vcvttss2si, kInstVcvttss2si, GpReg, XmmReg) + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86XmmReg) //! \overload - INST_2x(vcvttss2si, kInstVcvttss2si, GpReg, Mem) + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86Mem) //! Packed DP-FP divide (AVX). - INST_3x(vdivpd, kInstVdivpd, XmmReg, XmmReg, XmmReg) + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vdivpd, kInstVdivpd, XmmReg, XmmReg, Mem) + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vdivpd, kInstVdivpd, YmmReg, YmmReg, YmmReg) + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vdivpd, kInstVdivpd, YmmReg, YmmReg, Mem) + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP divide (AVX). - INST_3x(vdivps, kInstVdivps, XmmReg, XmmReg, XmmReg) + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vdivps, kInstVdivps, XmmReg, XmmReg, Mem) + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vdivps, kInstVdivps, YmmReg, YmmReg, YmmReg) + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vdivps, kInstVdivps, YmmReg, YmmReg, Mem) + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86Mem) //! Scalar DP-FP divide (AVX). - INST_3x(vdivsd, kInstVdivsd, XmmReg, XmmReg, XmmReg) + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vdivsd, kInstVdivsd, XmmReg, XmmReg, Mem) + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP divide (AVX). - INST_3x(vdivss, kInstVdivss, XmmReg, XmmReg, XmmReg) + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vdivss, kInstVdivss, XmmReg, XmmReg, Mem) + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86Mem) //! Packed DP-FP dot product (AVX). - INST_4i(vdppd, kInstVdppd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vdppd, kInstVdppd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Packed SP-FP dot product (AVX). - INST_4i(vdpps, kInstVdpps, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vdpps, kInstVdpps, XmmReg, XmmReg, Mem, Imm) + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vdpps, kInstVdpps, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vdpps, kInstVdpps, YmmReg, YmmReg, Mem, Imm) + 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, kInstVextractf128, XmmReg, YmmReg, Imm) + INST_3i(vextractf128, kX86InstIdVextractf128, X86XmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vextractf128, kInstVextractf128, Mem, YmmReg, Imm) + INST_3i(vextractf128, kX86InstIdVextractf128, X86Mem, X86YmmReg, Imm) //! Extract SP-FP based on selector (AVX). - INST_3i(vextractps, kInstVextractps, GpReg, XmmReg, Imm) + INST_3i(vextractps, kX86InstIdVextractps, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(vextractps, kInstVextractps, Mem, XmmReg, Imm) + INST_3i(vextractps, kX86InstIdVextractps, X86Mem, X86XmmReg, Imm) //! Packed DP-FP horizontal add (AVX). - INST_3x(vhaddpd, kInstVhaddpd, XmmReg, XmmReg, XmmReg) + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vhaddpd, kInstVhaddpd, XmmReg, XmmReg, Mem) + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vhaddpd, kInstVhaddpd, YmmReg, YmmReg, YmmReg) + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vhaddpd, kInstVhaddpd, YmmReg, YmmReg, Mem) + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP horizontal add (AVX). - INST_3x(vhaddps, kInstVhaddps, XmmReg, XmmReg, XmmReg) + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vhaddps, kInstVhaddps, XmmReg, XmmReg, Mem) + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vhaddps, kInstVhaddps, YmmReg, YmmReg, YmmReg) + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vhaddps, kInstVhaddps, YmmReg, YmmReg, Mem) + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP horizontal subtract (AVX). - INST_3x(vhsubpd, kInstVhsubpd, XmmReg, XmmReg, XmmReg) + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vhsubpd, kInstVhsubpd, XmmReg, XmmReg, Mem) + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vhsubpd, kInstVhsubpd, YmmReg, YmmReg, YmmReg) + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vhsubpd, kInstVhsubpd, YmmReg, YmmReg, Mem) + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP horizontal subtract (AVX). - INST_3x(vhsubps, kInstVhsubps, XmmReg, XmmReg, XmmReg) + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vhsubps, kInstVhsubps, XmmReg, XmmReg, Mem) + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vhsubps, kInstVhsubps, YmmReg, YmmReg, YmmReg) + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vhsubps, kInstVhsubps, YmmReg, YmmReg, Mem) + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86Mem) //! Insert 128-bit of packed FP data based on selector (AVX). - INST_4i(vinsertf128, kInstVinsertf128, YmmReg, YmmReg, XmmReg, Imm) + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vinsertf128, kInstVinsertf128, YmmReg, YmmReg, Mem, Imm) + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Insert SP-FP based on selector (AVX). - INST_4i(vinsertps, kInstVinsertps, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vinsertps, kInstVinsertps, XmmReg, XmmReg, Mem, Imm) + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Load 128-bits unaligned (AVX). - INST_2x(vlddqu, kInstVlddqu, XmmReg, Mem) + INST_2x(vlddqu, kX86InstIdVlddqu, X86XmmReg, X86Mem) //! Load 256-bits unaligned (AVX). - INST_2x(vlddqu, kInstVlddqu, YmmReg, Mem) + INST_2x(vlddqu, kX86InstIdVlddqu, X86YmmReg, X86Mem) //! Load streaming SIMD extension control/status (AVX). - INST_1x(vldmxcsr, kInstVldmxcsr, Mem) + INST_1x(vldmxcsr, kX86InstIdVldmxcsr, X86Mem) //! Store selected bytes of OWORD to DS:EDI/RDI (AVX). - INST_2x(vmaskmovdqu, kInstVmaskmovdqu, XmmReg, XmmReg) + 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, kInstVmaskmovpd, XmmReg, XmmReg, Mem) + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmaskmovpd, kInstVmaskmovpd, YmmReg, YmmReg, Mem) + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vmaskmovpd, kInstVmaskmovpd, Mem, XmmReg, XmmReg) + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaskmovpd, kInstVmaskmovpd, Mem, YmmReg, YmmReg) + 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, kInstVmaskmovps, XmmReg, XmmReg, Mem) + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmaskmovps, kInstVmaskmovps, YmmReg, YmmReg, Mem) + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vmaskmovps, kInstVmaskmovps, Mem, XmmReg, XmmReg) + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaskmovps, kInstVmaskmovps, Mem, YmmReg, YmmReg) + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86YmmReg, X86YmmReg) //! Packed DP-FP maximum (AVX). - INST_3x(vmaxpd, kInstVmaxpd, XmmReg, XmmReg, XmmReg) + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaxpd, kInstVmaxpd, XmmReg, XmmReg, Mem) + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmaxpd, kInstVmaxpd, YmmReg, YmmReg, YmmReg) + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vmaxpd, kInstVmaxpd, YmmReg, YmmReg, Mem) + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP maximum (AVX). - INST_3x(vmaxps, kInstVmaxps, XmmReg, XmmReg, XmmReg) + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaxps, kInstVmaxps, XmmReg, XmmReg, Mem) + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmaxps, kInstVmaxps, YmmReg, YmmReg, YmmReg) + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vmaxps, kInstVmaxps, YmmReg, YmmReg, Mem) + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86Mem) //! Scalar DP-FP maximum (AVX). - INST_3x(vmaxsd, kInstVmaxsd, XmmReg, XmmReg, XmmReg) + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaxsd, kInstVmaxsd, XmmReg, XmmReg, Mem) + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP maximum (AVX). - INST_3x(vmaxss, kInstVmaxss, XmmReg, XmmReg, XmmReg) + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmaxss, kInstVmaxss, XmmReg, XmmReg, Mem) + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86Mem) //! Packed DP-FP minimum (AVX). - INST_3x(vminpd, kInstVminpd, XmmReg, XmmReg, XmmReg) + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vminpd, kInstVminpd, XmmReg, XmmReg, Mem) + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vminpd, kInstVminpd, YmmReg, YmmReg, YmmReg) + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vminpd, kInstVminpd, YmmReg, YmmReg, Mem) + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP minimum (AVX). - INST_3x(vminps, kInstVminps, XmmReg, XmmReg, XmmReg) + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vminps, kInstVminps, XmmReg, XmmReg, Mem) + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vminps, kInstVminps, YmmReg, YmmReg, YmmReg) + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vminps, kInstVminps, YmmReg, YmmReg, Mem) + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86Mem) //! Scalar DP-FP minimum (AVX). - INST_3x(vminsd, kInstVminsd, XmmReg, XmmReg, XmmReg) + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vminsd, kInstVminsd, XmmReg, XmmReg, Mem) + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP minimum (AVX). - INST_3x(vminss, kInstVminss, XmmReg, XmmReg, XmmReg) + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vminss, kInstVminss, XmmReg, XmmReg, Mem) + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86Mem) //! Move 128-bits of aligned packed DP-FP (AVX). - INST_2x(vmovapd, kInstVmovapd, XmmReg, XmmReg) + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovapd, kInstVmovapd, XmmReg, Mem) + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovapd, kInstVmovapd, Mem, XmmReg) + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86XmmReg) //! Move 256-bits of aligned packed DP-FP (AVX). - INST_2x(vmovapd, kInstVmovapd, YmmReg, YmmReg) + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovapd, kInstVmovapd, YmmReg, Mem) + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovapd, kInstVmovapd, Mem, YmmReg) + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86YmmReg) //! Move 128-bits of aligned packed SP-FP (AVX). - INST_2x(vmovaps, kInstVmovaps, XmmReg, XmmReg) + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovaps, kInstVmovaps, XmmReg, Mem) + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovaps, kInstVmovaps, Mem, XmmReg) + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86XmmReg) //! Move 256-bits of aligned packed SP-FP (AVX). - INST_2x(vmovaps, kInstVmovaps, YmmReg, YmmReg) + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovaps, kInstVmovaps, YmmReg, Mem) + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovaps, kInstVmovaps, Mem, YmmReg) + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86YmmReg) //! Move DWORD (AVX). - INST_2x(vmovd, kInstVmovd, XmmReg, GpReg) + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86GpReg) //! \overload - INST_2x(vmovd, kInstVmovd, XmmReg, Mem) + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovd, kInstVmovd, GpReg, XmmReg) + INST_2x(vmovd, kX86InstIdVmovd, X86GpReg, X86XmmReg) //! \overload - INST_2x(vmovd, kInstVmovd, Mem, XmmReg) + INST_2x(vmovd, kX86InstIdVmovd, X86Mem, X86XmmReg) //! Move QWORD (AVX). - INST_2x(vmovq, kInstVmovq, XmmReg, XmmReg) + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovq, kInstVmovq, XmmReg, Mem) + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovq, kInstVmovq, Mem, XmmReg) + 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, kInstVmovddup, XmmReg, XmmReg) + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovddup, kInstVmovddup, XmmReg, Mem) + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovddup, kInstVmovddup, YmmReg, YmmReg) + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovddup, kInstVmovddup, YmmReg, Mem) + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86Mem) //! Move 128-bits aligned (AVX). - INST_2x(vmovdqa, kInstVmovdqa, XmmReg, XmmReg) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovdqa, kInstVmovdqa, XmmReg, Mem) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovdqa, kInstVmovdqa, Mem, XmmReg) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86XmmReg) //! Move 256-bits aligned (AVX). - INST_2x(vmovdqa, kInstVmovdqa, YmmReg, YmmReg) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovdqa, kInstVmovdqa, YmmReg, Mem) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovdqa, kInstVmovdqa, Mem, YmmReg) + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86YmmReg) //! Move 128-bits unaligned (AVX). - INST_2x(vmovdqu, kInstVmovdqu, XmmReg, XmmReg) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovdqu, kInstVmovdqu, XmmReg, Mem) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovdqu, kInstVmovdqu, Mem, XmmReg) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86XmmReg) //! Move 256-bits unaligned (AVX). - INST_2x(vmovdqu, kInstVmovdqu, YmmReg, YmmReg) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovdqu, kInstVmovdqu, YmmReg, Mem) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovdqu, kInstVmovdqu, Mem, YmmReg) + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86YmmReg) //! High to low packed SP-FP (AVX). - INST_3x(vmovhlps, kInstVmovhlps, XmmReg, XmmReg, XmmReg) + INST_3x(vmovhlps, kX86InstIdVmovhlps, X86XmmReg, X86XmmReg, X86XmmReg) //! Move high packed DP-FP (AVX). - INST_3x(vmovhpd, kInstVmovhpd, XmmReg, XmmReg, Mem) + INST_3x(vmovhpd, kX86InstIdVmovhpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovhpd, kInstVmovhpd, Mem, XmmReg) + INST_2x(vmovhpd, kX86InstIdVmovhpd, X86Mem, X86XmmReg) //! Move high packed SP-FP (AVX). - INST_3x(vmovhps, kInstVmovhps, XmmReg, XmmReg, Mem) + INST_3x(vmovhps, kX86InstIdVmovhps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovhps, kInstVmovhps, Mem, XmmReg) + INST_2x(vmovhps, kX86InstIdVmovhps, X86Mem, X86XmmReg) //! Move low to high packed SP-FP (AVX). - INST_3x(vmovlhps, kInstVmovlhps, XmmReg, XmmReg, XmmReg) + INST_3x(vmovlhps, kX86InstIdVmovlhps, X86XmmReg, X86XmmReg, X86XmmReg) //! Move low packed DP-FP (AVX). - INST_3x(vmovlpd, kInstVmovlpd, XmmReg, XmmReg, Mem) + INST_3x(vmovlpd, kX86InstIdVmovlpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovlpd, kInstVmovlpd, Mem, XmmReg) + INST_2x(vmovlpd, kX86InstIdVmovlpd, X86Mem, X86XmmReg) //! Move low packed SP-FP (AVX). - INST_3x(vmovlps, kInstVmovlps, XmmReg, XmmReg, Mem) + INST_3x(vmovlps, kX86InstIdVmovlps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovlps, kInstVmovlps, Mem, XmmReg) + INST_2x(vmovlps, kX86InstIdVmovlps, X86Mem, X86XmmReg) //! Extract packed DP-FP sign mask (AVX). - INST_2x(vmovmskpd, kInstVmovmskpd, GpReg, XmmReg) + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86XmmReg) //! \overload - INST_2x(vmovmskpd, kInstVmovmskpd, GpReg, YmmReg) + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86YmmReg) //! Extract packed SP-FP sign mask (AVX). - INST_2x(vmovmskps, kInstVmovmskps, GpReg, XmmReg) + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86XmmReg) //! \overload - INST_2x(vmovmskps, kInstVmovmskps, GpReg, YmmReg) + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86YmmReg) //! Store 128-bits using NT hint (AVX). - INST_2x(vmovntdq, kInstVmovntdq, Mem, XmmReg) + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86XmmReg) //! Store 256-bits using NT hint (AVX). - INST_2x(vmovntdq, kInstVmovntdq, Mem, YmmReg) + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86YmmReg) //! Store 128-bits aligned using NT hint (AVX). - INST_2x(vmovntdqa, kInstVmovntdqa, XmmReg, Mem) + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86XmmReg, X86Mem) //! Store packed DP-FP (128-bits) using NT hint (AVX). - INST_2x(vmovntpd, kInstVmovntpd, Mem, XmmReg) + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86XmmReg) //! Store packed DP-FP (256-bits) using NT hint (AVX). - INST_2x(vmovntpd, kInstVmovntpd, Mem, YmmReg) + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86YmmReg) //! Store packed SP-FP (128-bits) using NT hint (AVX). - INST_2x(vmovntps, kInstVmovntps, Mem, XmmReg) + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86XmmReg) //! Store packed SP-FP (256-bits) using NT hint (AVX). - INST_2x(vmovntps, kInstVmovntps, Mem, YmmReg) + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86YmmReg) //! Move scalar DP-FP (AVX). - INST_3x(vmovsd, kInstVmovsd, XmmReg, XmmReg, XmmReg) + INST_3x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovsd, kInstVmovsd, XmmReg, Mem) + INST_2x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovsd, kInstVmovsd, Mem, XmmReg) + INST_2x(vmovsd, kX86InstIdVmovsd, X86Mem, X86XmmReg) //! Move packed SP-FP high and duplicate (AVX). - INST_2x(vmovshdup, kInstVmovshdup, XmmReg, XmmReg) + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovshdup, kInstVmovshdup, XmmReg, Mem) + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovshdup, kInstVmovshdup, YmmReg, YmmReg) + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovshdup, kInstVmovshdup, YmmReg, Mem) + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86Mem) //! Move packed SP-FP low and duplicate (AVX). - INST_2x(vmovsldup, kInstVmovsldup, XmmReg, XmmReg) + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovsldup, kInstVmovsldup, XmmReg, Mem) + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovsldup, kInstVmovsldup, YmmReg, YmmReg) + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovsldup, kInstVmovsldup, YmmReg, Mem) + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86Mem) //! Move scalar SP-FP (AVX). - INST_3x(vmovss, kInstVmovss, XmmReg, XmmReg, XmmReg) + INST_3x(vmovss, kX86InstIdVmovss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovss, kInstVmovss, XmmReg, Mem) + INST_2x(vmovss, kX86InstIdVmovss, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovss, kInstVmovss, Mem, XmmReg) + INST_2x(vmovss, kX86InstIdVmovss, X86Mem, X86XmmReg) //! Move 128-bits of unaligned packed DP-FP (AVX). - INST_2x(vmovupd, kInstVmovupd, XmmReg, XmmReg) + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovupd, kInstVmovupd, XmmReg, Mem) + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovupd, kInstVmovupd, Mem, XmmReg) + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86XmmReg) //! Move 256-bits of unaligned packed DP-FP (AVX). - INST_2x(vmovupd, kInstVmovupd, YmmReg, YmmReg) + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovupd, kInstVmovupd, YmmReg, Mem) + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovupd, kInstVmovupd, Mem, YmmReg) + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86YmmReg) //! Move 128-bits of unaligned packed SP-FP (AVX). - INST_2x(vmovups, kInstVmovups, XmmReg, XmmReg) + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vmovups, kInstVmovups, XmmReg, Mem) + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86Mem) //! \overload - INST_2x(vmovups, kInstVmovups, Mem, XmmReg) + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86XmmReg) //! Move 256-bits of unaligned packed SP-FP (AVX). - INST_2x(vmovups, kInstVmovups, YmmReg, YmmReg) + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vmovups, kInstVmovups, YmmReg, Mem) + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86Mem) //! \overload - INST_2x(vmovups, kInstVmovups, Mem, YmmReg) + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86YmmReg) //! Packed WORD sums of absolute difference (AVX). - INST_4i(vmpsadbw, kInstVmpsadbw, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vmpsadbw, kInstVmpsadbw, XmmReg, XmmReg, Mem, Imm) + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Packed DP-FP multiply (AVX). - INST_3x(vmulpd, kInstVmulpd, XmmReg, XmmReg, XmmReg) + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmulpd, kInstVmulpd, XmmReg, XmmReg, Mem) + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmulpd, kInstVmulpd, YmmReg, YmmReg, YmmReg) + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vmulpd, kInstVmulpd, YmmReg, YmmReg, Mem) + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP multiply (AVX). - INST_3x(vmulps, kInstVmulps, XmmReg, XmmReg, XmmReg) + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmulps, kInstVmulps, XmmReg, XmmReg, Mem) + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vmulps, kInstVmulps, YmmReg, YmmReg, YmmReg) + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vmulps, kInstVmulps, YmmReg, YmmReg, Mem) + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP multiply (AVX). - INST_3x(vmulsd, kInstVmulsd, XmmReg, XmmReg, XmmReg) + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmulsd, kInstVmulsd, XmmReg, XmmReg, Mem) + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP multiply (AVX). - INST_3x(vmulss, kInstVmulss, XmmReg, XmmReg, XmmReg) + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vmulss, kInstVmulss, XmmReg, XmmReg, Mem) + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86Mem) //! Packed DP-FP bitwise or (AVX). - INST_3x(vorpd, kInstVorpd, XmmReg, XmmReg, XmmReg) + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vorpd, kInstVorpd, XmmReg, XmmReg, Mem) + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vorpd, kInstVorpd, YmmReg, YmmReg, YmmReg) + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vorpd, kInstVorpd, YmmReg, YmmReg, Mem) + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP bitwise or (AVX). - INST_3x(vorps, kInstVorps, XmmReg, XmmReg, XmmReg) + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vorps, kInstVorps, XmmReg, XmmReg, Mem) + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vorps, kInstVorps, YmmReg, YmmReg, YmmReg) + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vorps, kInstVorps, YmmReg, YmmReg, Mem) + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTE absolute value (AVX). - INST_2x(vpabsb, kInstVpabsb, XmmReg, XmmReg) + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpabsb, kInstVpabsb, XmmReg, Mem) + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86Mem) //! Packed DWORD absolute value (AVX). - INST_2x(vpabsd, kInstVpabsd, XmmReg, XmmReg) + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpabsd, kInstVpabsd, XmmReg, Mem) + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86Mem) //! Packed WORD absolute value (AVX). - INST_2x(vpabsw, kInstVpabsw, XmmReg, XmmReg) + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpabsw, kInstVpabsw, XmmReg, Mem) + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86Mem) //! Pack DWORDs to WORDs with signed saturation (AVX). - INST_3x(vpackssdw, kInstVpackssdw, XmmReg, XmmReg, XmmReg) + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpackssdw, kInstVpackssdw, XmmReg, XmmReg, Mem) + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86Mem) //! Pack WORDs to BYTEs with signed saturation (AVX). - INST_3x(vpacksswb, kInstVpacksswb, XmmReg, XmmReg, XmmReg) + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpacksswb, kInstVpacksswb, XmmReg, XmmReg, Mem) + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86Mem) //! Pack DWORDs to WORDs with unsigned saturation (AVX). - INST_3x(vpackusdw, kInstVpackusdw, XmmReg, XmmReg, XmmReg) + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpackusdw, kInstVpackusdw, XmmReg, XmmReg, Mem) + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (AVX). - INST_3x(vpackuswb, kInstVpackuswb, XmmReg, XmmReg, XmmReg) + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpackuswb, kInstVpackuswb, XmmReg, XmmReg, Mem) + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE add (AVX). - INST_3x(vpaddb, kInstVpaddb, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddb, kInstVpaddb, XmmReg, XmmReg, Mem) + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD add (AVX). - INST_3x(vpaddd, kInstVpaddd, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddd, kInstVpaddd, XmmReg, XmmReg, Mem) + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86Mem) //! Packed QWORD add (AVX). - INST_3x(vpaddq, kInstVpaddq, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddq, kInstVpaddq, XmmReg, XmmReg, Mem) + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD add (AVX). - INST_3x(vpaddw, kInstVpaddw, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddw, kInstVpaddw, XmmReg, XmmReg, Mem) + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE add with saturation (AVX). - INST_3x(vpaddsb, kInstVpaddsb, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddsb, kInstVpaddsb, XmmReg, XmmReg, Mem) + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD add with saturation (AVX). - INST_3x(vpaddsw, kInstVpaddsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddsw, kInstVpaddsw, XmmReg, XmmReg, Mem) + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE add with unsigned saturation (AVX). - INST_3x(vpaddusb, kInstVpaddusb, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddusb, kInstVpaddusb, XmmReg, XmmReg, Mem) + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD add with unsigned saturation (AVX). - INST_3x(vpaddusw, kInstVpaddusw, XmmReg, XmmReg, XmmReg) + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpaddusw, kInstVpaddusw, XmmReg, XmmReg, Mem) + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86Mem) //! Packed align right (AVX). - INST_4i(vpalignr, kInstVpalignr, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vpalignr, kInstVpalignr, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Packed bitwise and (AVX). - INST_3x(vpand, kInstVpand, XmmReg, XmmReg, XmmReg) + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpand, kInstVpand, XmmReg, XmmReg, Mem) + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86Mem) //! Packed bitwise and-not (AVX). - INST_3x(vpandn, kInstVpandn, XmmReg, XmmReg, XmmReg) + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpandn, kInstVpandn, XmmReg, XmmReg, Mem) + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE average (AVX). - INST_3x(vpavgb, kInstVpavgb, XmmReg, XmmReg, XmmReg) + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpavgb, kInstVpavgb, XmmReg, XmmReg, Mem) + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD average (AVX). - INST_3x(vpavgw, kInstVpavgw, XmmReg, XmmReg, XmmReg) + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpavgw, kInstVpavgw, XmmReg, XmmReg, Mem) + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE variable blend (AVX). - INST_4x(vpblendvb, kInstVpblendvb, XmmReg, XmmReg, XmmReg, XmmReg) + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_4x(vpblendvb, kInstVpblendvb, XmmReg, XmmReg, Mem, XmmReg) + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) //! Packed WORD blend (AVX). - INST_4i(vpblendw, kInstVpblendw, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vpblendw, kInstVpblendw, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Packed BYTEs compare for equality (AVX). - INST_3x(vpcmpeqb, kInstVpcmpeqb, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpeqb, kInstVpcmpeqb, XmmReg, XmmReg, Mem) + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORDs compare for equality (AVX). - INST_3x(vpcmpeqd, kInstVpcmpeqd, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpeqd, kInstVpcmpeqd, XmmReg, XmmReg, Mem) + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86Mem) //! Packed QWORDs compare for equality (AVX). - INST_3x(vpcmpeqq, kInstVpcmpeqq, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpeqq, kInstVpcmpeqq, XmmReg, XmmReg, Mem) + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORDs compare for equality (AVX). - INST_3x(vpcmpeqw, kInstVpcmpeqw, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpeqw, kInstVpcmpeqw, XmmReg, XmmReg, Mem) + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTEs compare if greater than (AVX). - INST_3x(vpcmpgtb, kInstVpcmpgtb, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpgtb, kInstVpcmpgtb, XmmReg, XmmReg, Mem) + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORDs compare if greater than (AVX). - INST_3x(vpcmpgtd, kInstVpcmpgtd, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpgtd, kInstVpcmpgtd, XmmReg, XmmReg, Mem) + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86Mem) //! Packed QWORDs compare if greater than (AVX). - INST_3x(vpcmpgtq, kInstVpcmpgtq, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpgtq, kInstVpcmpgtq, XmmReg, XmmReg, Mem) + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORDs compare if greater than (AVX). - INST_3x(vpcmpgtw, kInstVpcmpgtw, XmmReg, XmmReg, XmmReg) + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpcmpgtw, kInstVpcmpgtw, XmmReg, XmmReg, Mem) + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86Mem) //! Packed compare explicit length strings, return index (AVX). - INST_3i(vpcmpestri, kInstVpcmpestri, XmmReg, XmmReg, Imm) + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpcmpestri, kInstVpcmpestri, XmmReg, Mem, Imm) + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86Mem, Imm) //! Packed compare explicit length strings, return mask (AVX). - INST_3i(vpcmpestrm, kInstVpcmpestrm, XmmReg, XmmReg, Imm) + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpcmpestrm, kInstVpcmpestrm, XmmReg, Mem, Imm) + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86Mem, Imm) //! Packed compare implicit length strings, return index (AVX). - INST_3i(vpcmpistri, kInstVpcmpistri, XmmReg, XmmReg, Imm) + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpcmpistri, kInstVpcmpistri, XmmReg, Mem, Imm) + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86Mem, Imm) //! Packed compare implicit length strings, return mask (AVX). - INST_3i(vpcmpistrm, kInstVpcmpistrm, XmmReg, XmmReg, Imm) + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpcmpistrm, kInstVpcmpistrm, XmmReg, Mem, Imm) + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86Mem, Imm) //! Packed DP-FP permute (AVX). - INST_3x(vpermilpd, kInstVpermilpd, XmmReg, XmmReg, XmmReg) + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpermilpd, kInstVpermilpd, XmmReg, XmmReg, Mem) + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vpermilpd, kInstVpermilpd, YmmReg, YmmReg, YmmReg) + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpermilpd, kInstVpermilpd, YmmReg, YmmReg, Mem) + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3i(vpermilpd, kInstVpermilpd, XmmReg, XmmReg, Imm) + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpermilpd, kInstVpermilpd, XmmReg, Mem, Imm) + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86Mem, Imm) //! \overload - INST_3i(vpermilpd, kInstVpermilpd, YmmReg, YmmReg, Imm) + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vpermilpd, kInstVpermilpd, YmmReg, Mem, Imm) + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86Mem, Imm) //! Packed SP-FP permute (AVX). - INST_3x(vpermilps, kInstVpermilps, XmmReg, XmmReg, XmmReg) + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpermilps, kInstVpermilps, XmmReg, XmmReg, Mem) + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vpermilps, kInstVpermilps, YmmReg, YmmReg, YmmReg) + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpermilps, kInstVpermilps, YmmReg, YmmReg, Mem) + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3i(vpermilps, kInstVpermilps, XmmReg, XmmReg, Imm) + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpermilps, kInstVpermilps, XmmReg, Mem, Imm) + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86Mem, Imm) //! \overload - INST_3i(vpermilps, kInstVpermilps, YmmReg, YmmReg, Imm) + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vpermilps, kInstVpermilps, YmmReg, Mem, Imm) + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86Mem, Imm) //! Packed 128-bit FP permute (AVX). - INST_4i(vperm2f128, kInstVperm2f128, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vperm2f128, kInstVperm2f128, YmmReg, YmmReg, Mem, Imm) + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Extract BYTE (AVX). - INST_3i(vpextrb, kInstVpextrb, GpReg, XmmReg, Imm) + INST_3i(vpextrb, kX86InstIdVpextrb, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(vpextrb, kInstVpextrb, Mem, XmmReg, Imm) + INST_3i(vpextrb, kX86InstIdVpextrb, X86Mem, X86XmmReg, Imm) //! Extract DWORD (AVX). - INST_3i(vpextrd, kInstVpextrd, GpReg, XmmReg, Imm) + INST_3i(vpextrd, kX86InstIdVpextrd, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(vpextrd, kInstVpextrd, Mem, XmmReg, Imm) + 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, kInstVpextrw, GpReg, XmmReg, Imm) + INST_3i(vpextrw, kX86InstIdVpextrw, X86GpReg, X86XmmReg, Imm) //! \overload - INST_3i(vpextrw, kInstVpextrw, Mem, XmmReg, Imm) + INST_3i(vpextrw, kX86InstIdVpextrw, X86Mem, X86XmmReg, Imm) //! Packed DWORD horizontal add (AVX). - INST_3x(vphaddd, kInstVphaddd, XmmReg, XmmReg, XmmReg) + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphaddd, kInstVphaddd, XmmReg, XmmReg, Mem) + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD horizontal add with saturation (AVX). - INST_3x(vphaddsw, kInstVphaddsw, XmmReg, XmmReg, XmmReg) + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphaddsw, kInstVphaddsw, XmmReg, XmmReg, Mem) + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD horizontal add (AVX). - INST_3x(vphaddw, kInstVphaddw, XmmReg, XmmReg, XmmReg) + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphaddw, kInstVphaddw, XmmReg, XmmReg, Mem) + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD horizontal minimum (AVX). - INST_2x(vphminposuw, kInstVphminposuw, XmmReg, XmmReg) + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vphminposuw, kInstVphminposuw, XmmReg, Mem) + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86Mem) //! Packed DWORD horizontal subtract (AVX). - INST_3x(vphsubd, kInstVphsubd, XmmReg, XmmReg, XmmReg) + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphsubd, kInstVphsubd, XmmReg, XmmReg, Mem) + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD horizontal subtract with saturation (AVX). - INST_3x(vphsubsw, kInstVphsubsw, XmmReg, XmmReg, XmmReg) + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphsubsw, kInstVphsubsw, XmmReg, XmmReg, Mem) + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD horizontal subtract (AVX). - INST_3x(vphsubw, kInstVphsubw, XmmReg, XmmReg, XmmReg) + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vphsubw, kInstVphsubw, XmmReg, XmmReg, Mem) + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86Mem) //! Insert BYTE based on selector (AVX). - INST_4i(vpinsrb, kInstVpinsrb, XmmReg, XmmReg, GpReg, Imm) + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86GpReg, Imm) //! \overload - INST_4i(vpinsrb, kInstVpinsrb, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Insert DWORD based on selector (AVX). - INST_4i(vpinsrd, kInstVpinsrd, XmmReg, XmmReg, GpReg, Imm) + INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86GpReg, Imm) //! \overload - INST_4i(vpinsrd, kInstVpinsrd, XmmReg, XmmReg, Mem, Imm) + 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, kInstVpinsrw, XmmReg, XmmReg, GpReg, Imm) + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86GpReg, Imm) //! \overload - INST_4i(vpinsrw, kInstVpinsrw, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Packed multiply and add signed and unsigned bytes (AVX). - INST_3x(vpmaddubsw, kInstVpmaddubsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaddubsw, kInstVpmaddubsw, XmmReg, XmmReg, Mem) + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD multiply and add to packed DWORD (AVX). - INST_3x(vpmaddwd, kInstVpmaddwd, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaddwd, kInstVpmaddwd, XmmReg, XmmReg, Mem) + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE maximum (AVX). - INST_3x(vpmaxsb, kInstVpmaxsb, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxsb, kInstVpmaxsb, XmmReg, XmmReg, Mem) + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD maximum (AVX). - INST_3x(vpmaxsd, kInstVpmaxsd, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxsd, kInstVpmaxsd, XmmReg, XmmReg, Mem) + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD maximum (AVX). - INST_3x(vpmaxsw, kInstVpmaxsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxsw, kInstVpmaxsw, XmmReg, XmmReg, Mem) + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE unsigned maximum (AVX). - INST_3x(vpmaxub, kInstVpmaxub, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxub, kInstVpmaxub, XmmReg, XmmReg, Mem) + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD unsigned maximum (AVX). - INST_3x(vpmaxud, kInstVpmaxud, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxud, kInstVpmaxud, XmmReg, XmmReg, Mem) + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD unsigned maximum (AVX). - INST_3x(vpmaxuw, kInstVpmaxuw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmaxuw, kInstVpmaxuw, XmmReg, XmmReg, Mem) + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE minimum (AVX). - INST_3x(vpminsb, kInstVpminsb, XmmReg, XmmReg, XmmReg) + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminsb, kInstVpminsb, XmmReg, XmmReg, Mem) + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD minimum (AVX). - INST_3x(vpminsd, kInstVpminsd, XmmReg, XmmReg, XmmReg) + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminsd, kInstVpminsd, XmmReg, XmmReg, Mem) + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD minimum (AVX). - INST_3x(vpminsw, kInstVpminsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminsw, kInstVpminsw, XmmReg, XmmReg, Mem) + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE unsigned minimum (AVX). - INST_3x(vpminub, kInstVpminub, XmmReg, XmmReg, XmmReg) + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminub, kInstVpminub, XmmReg, XmmReg, Mem) + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD unsigned minimum (AVX). - INST_3x(vpminud, kInstVpminud, XmmReg, XmmReg, XmmReg) + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminud, kInstVpminud, XmmReg, XmmReg, Mem) + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD unsigned minimum (AVX). - INST_3x(vpminuw, kInstVpminuw, XmmReg, XmmReg, XmmReg) + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpminuw, kInstVpminuw, XmmReg, XmmReg, Mem) + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86Mem) //! Move Byte mask to integer (AVX). - INST_2x(vpmovmskb, kInstVpmovmskb, GpReg, XmmReg) + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86XmmReg) //! BYTE to DWORD with sign extend (AVX). - INST_2x(vpmovsxbd, kInstVpmovsxbd, XmmReg, XmmReg) + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxbd, kInstVpmovsxbd, XmmReg, Mem) + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86Mem) //! Packed BYTE to QWORD with sign extend (AVX). - INST_2x(vpmovsxbq, kInstVpmovsxbq, XmmReg, XmmReg) + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxbq, kInstVpmovsxbq, XmmReg, Mem) + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86Mem) //! Packed BYTE to WORD with sign extend (AVX). - INST_2x(vpmovsxbw, kInstVpmovsxbw, XmmReg, XmmReg) + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxbw, kInstVpmovsxbw, XmmReg, Mem) + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86Mem) //! Packed DWORD to QWORD with sign extend (AVX). - INST_2x(vpmovsxdq, kInstVpmovsxdq, XmmReg, XmmReg) + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxdq, kInstVpmovsxdq, XmmReg, Mem) + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86Mem) //! Packed WORD to DWORD with sign extend (AVX). - INST_2x(vpmovsxwd, kInstVpmovsxwd, XmmReg, XmmReg) + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxwd, kInstVpmovsxwd, XmmReg, Mem) + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86Mem) //! Packed WORD to QWORD with sign extend (AVX). - INST_2x(vpmovsxwq, kInstVpmovsxwq, XmmReg, XmmReg) + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovsxwq, kInstVpmovsxwq, XmmReg, Mem) + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86Mem) //! BYTE to DWORD with zero extend (AVX). - INST_2x(vpmovzxbd, kInstVpmovzxbd, XmmReg, XmmReg) + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxbd, kInstVpmovzxbd, XmmReg, Mem) + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86Mem) //! Packed BYTE to QWORD with zero extend (AVX). - INST_2x(vpmovzxbq, kInstVpmovzxbq, XmmReg, XmmReg) + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxbq, kInstVpmovzxbq, XmmReg, Mem) + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86Mem) //! BYTE to WORD with zero extend (AVX). - INST_2x(vpmovzxbw, kInstVpmovzxbw, XmmReg, XmmReg) + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxbw, kInstVpmovzxbw, XmmReg, Mem) + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86Mem) //! Packed DWORD to QWORD with zero extend (AVX). - INST_2x(vpmovzxdq, kInstVpmovzxdq, XmmReg, XmmReg) + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxdq, kInstVpmovzxdq, XmmReg, Mem) + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86Mem) //! Packed WORD to DWORD with zero extend (AVX). - INST_2x(vpmovzxwd, kInstVpmovzxwd, XmmReg, XmmReg) + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxwd, kInstVpmovzxwd, XmmReg, Mem) + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86Mem) //! Packed WORD to QWORD with zero extend (AVX). - INST_2x(vpmovzxwq, kInstVpmovzxwq, XmmReg, XmmReg) + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpmovzxwq, kInstVpmovzxwq, XmmReg, Mem) + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86Mem) //! Packed DWORD to QWORD multiply (AVX). - INST_3x(vpmuldq, kInstVpmuldq, XmmReg, XmmReg, XmmReg) + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmuldq, kInstVpmuldq, XmmReg, XmmReg, Mem) + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD multiply high, round and scale (AVX). - INST_3x(vpmulhrsw, kInstVpmulhrsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmulhrsw, kInstVpmulhrsw, XmmReg, XmmReg, Mem) + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD unsigned multiply high (AVX). - INST_3x(vpmulhuw, kInstVpmulhuw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmulhuw, kInstVpmulhuw, XmmReg, XmmReg, Mem) + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD multiply high (AVX). - INST_3x(vpmulhw, kInstVpmulhw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmulhw, kInstVpmulhw, XmmReg, XmmReg, Mem) + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD multiply low (AVX). - INST_3x(vpmulld, kInstVpmulld, XmmReg, XmmReg, XmmReg) + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmulld, kInstVpmulld, XmmReg, XmmReg, Mem) + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORDs multiply low (AVX). - INST_3x(vpmullw, kInstVpmullw, XmmReg, XmmReg, XmmReg) + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmullw, kInstVpmullw, XmmReg, XmmReg, Mem) + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD multiply to QWORD (AVX). - INST_3x(vpmuludq, kInstVpmuludq, XmmReg, XmmReg, XmmReg) + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpmuludq, kInstVpmuludq, XmmReg, XmmReg, Mem) + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86Mem) //! Packed bitwise or (AVX). - INST_3x(vpor, kInstVpor, XmmReg, XmmReg, XmmReg) + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpor, kInstVpor, XmmReg, XmmReg, Mem) + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD sum of absolute differences (AVX). - INST_3x(vpsadbw, kInstVpsadbw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsadbw, kInstVpsadbw, XmmReg, XmmReg, Mem) + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE shuffle (AVX). - INST_3x(vpshufb, kInstVpshufb, XmmReg, XmmReg, XmmReg) + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpshufb, kInstVpshufb, XmmReg, XmmReg, Mem) + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD shuffle (AVX). - INST_3i(vpshufd, kInstVpshufd, XmmReg, XmmReg, Imm) + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpshufd, kInstVpshufd, XmmReg, Mem, Imm) + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86Mem, Imm) //! Packed WORD shuffle high (AVX). - INST_3i(vpshufhw, kInstVpshufhw, XmmReg, XmmReg, Imm) + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpshufhw, kInstVpshufhw, XmmReg, Mem, Imm) + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86Mem, Imm) //! Packed WORD shuffle low (AVX). - INST_3i(vpshuflw, kInstVpshuflw, XmmReg, XmmReg, Imm) + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vpshuflw, kInstVpshuflw, XmmReg, Mem, Imm) + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86Mem, Imm) //! Packed BYTE sign (AVX). - INST_3x(vpsignb, kInstVpsignb, XmmReg, XmmReg, XmmReg) + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsignb, kInstVpsignb, XmmReg, XmmReg, Mem) + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD sign (AVX). - INST_3x(vpsignd, kInstVpsignd, XmmReg, XmmReg, XmmReg) + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsignd, kInstVpsignd, XmmReg, XmmReg, Mem) + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD sign (AVX). - INST_3x(vpsignw, kInstVpsignw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsignw, kInstVpsignw, XmmReg, XmmReg, Mem) + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD shift left logical (AVX). - INST_3x(vpslld, kInstVpslld, XmmReg, XmmReg, XmmReg) + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpslld, kInstVpslld, XmmReg, XmmReg, Mem) + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpslld, kInstVpslld, XmmReg, XmmReg, Imm) + INST_3i(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, Imm) //! Packed OWORD shift left logical (AVX). - INST_3i(vpslldq, kInstVpslldq, XmmReg, XmmReg, Imm) + INST_3i(vpslldq, kX86InstIdVpslldq, X86XmmReg, X86XmmReg, Imm) //! Packed QWORD shift left logical (AVX). - INST_3x(vpsllq, kInstVpsllq, XmmReg, XmmReg, XmmReg) + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsllq, kInstVpsllq, XmmReg, XmmReg, Mem) + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsllq, kInstVpsllq, XmmReg, XmmReg, Imm) + INST_3i(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, Imm) //! Packed WORD shift left logical (AVX). - INST_3x(vpsllw, kInstVpsllw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsllw, kInstVpsllw, XmmReg, XmmReg, Mem) + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsllw, kInstVpsllw, XmmReg, XmmReg, Imm) + INST_3i(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, Imm) //! Packed DWORD shift right arithmetic (AVX). - INST_3x(vpsrad, kInstVpsrad, XmmReg, XmmReg, XmmReg) + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsrad, kInstVpsrad, XmmReg, XmmReg, Mem) + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsrad, kInstVpsrad, XmmReg, XmmReg, Imm) + INST_3i(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, Imm) //! Packed WORD shift right arithmetic (AVX). - INST_3x(vpsraw, kInstVpsraw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsraw, kInstVpsraw, XmmReg, XmmReg, Mem) + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsraw, kInstVpsraw, XmmReg, XmmReg, Imm) + INST_3i(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, Imm) //! Packed DWORD shift right logical (AVX). - INST_3x(vpsrld, kInstVpsrld, XmmReg, XmmReg, XmmReg) + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsrld, kInstVpsrld, XmmReg, XmmReg, Mem) + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsrld, kInstVpsrld, XmmReg, XmmReg, Imm) + INST_3i(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, Imm) //! Scalar OWORD shift right logical (AVX). - INST_3i(vpsrldq, kInstVpsrldq, XmmReg, XmmReg, Imm) + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86XmmReg, X86XmmReg, Imm) //! Packed QWORD shift right logical (AVX). - INST_3x(vpsrlq, kInstVpsrlq, XmmReg, XmmReg, XmmReg) + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsrlq, kInstVpsrlq, XmmReg, XmmReg, Mem) + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsrlq, kInstVpsrlq, XmmReg, XmmReg, Imm) + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, Imm) //! Packed WORD shift right logical (AVX). - INST_3x(vpsrlw, kInstVpsrlw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsrlw, kInstVpsrlw, XmmReg, XmmReg, Mem) + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3i(vpsrlw, kInstVpsrlw, XmmReg, XmmReg, Imm) + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, Imm) //! Packed BYTE subtract (AVX). - INST_3x(vpsubb, kInstVpsubb, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubb, kInstVpsubb, XmmReg, XmmReg, Mem) + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86Mem) //! Packed DWORD subtract (AVX). - INST_3x(vpsubd, kInstVpsubd, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubd, kInstVpsubd, XmmReg, XmmReg, Mem) + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86Mem) //! Packed QWORD subtract (AVX). - INST_3x(vpsubq, kInstVpsubq, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubq, kInstVpsubq, XmmReg, XmmReg, Mem) + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD subtract (AVX). - INST_3x(vpsubw, kInstVpsubw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubw, kInstVpsubw, XmmReg, XmmReg, Mem) + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE subtract with saturation (AVX). - INST_3x(vpsubsb, kInstVpsubsb, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubsb, kInstVpsubsb, XmmReg, XmmReg, Mem) + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD subtract with saturation (AVX). - INST_3x(vpsubsw, kInstVpsubsw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubsw, kInstVpsubsw, XmmReg, XmmReg, Mem) + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86Mem) //! Packed BYTE subtract with unsigned saturation (AVX). - INST_3x(vpsubusb, kInstVpsubusb, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubusb, kInstVpsubusb, XmmReg, XmmReg, Mem) + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86Mem) //! Packed WORD subtract with unsigned saturation (AVX). - INST_3x(vpsubusw, kInstVpsubusw, XmmReg, XmmReg, XmmReg) + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpsubusw, kInstVpsubusw, XmmReg, XmmReg, Mem) + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86Mem) //! Logical compare (AVX). - INST_2x(vptest, kInstVptest, XmmReg, XmmReg) + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vptest, kInstVptest, XmmReg, Mem) + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86Mem) //! \overload - INST_2x(vptest, kInstVptest, YmmReg, YmmReg) + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vptest, kInstVptest, YmmReg, Mem) + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86Mem) //! Unpack high packed BYTEs to WORDs (AVX). - INST_3x(vpunpckhbw, kInstVpunpckhbw, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpckhbw, kInstVpunpckhbw, XmmReg, XmmReg, Mem) + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86Mem) //! Unpack high packed DWORDs to QWORDs (AVX). - INST_3x(vpunpckhdq, kInstVpunpckhdq, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpckhdq, kInstVpunpckhdq, XmmReg, XmmReg, Mem) + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86Mem) //! Unpack high packed QWORDs to OWORD (AVX). - INST_3x(vpunpckhqdq, kInstVpunpckhqdq, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpckhqdq, kInstVpunpckhqdq, XmmReg, XmmReg, Mem) + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86Mem) //! Unpack high packed WORDs to DWORDs (AVX). - INST_3x(vpunpckhwd, kInstVpunpckhwd, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpckhwd, kInstVpunpckhwd, XmmReg, XmmReg, Mem) + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86Mem) //! Unpack low packed BYTEs to WORDs (AVX). - INST_3x(vpunpcklbw, kInstVpunpcklbw, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpcklbw, kInstVpunpcklbw, XmmReg, XmmReg, Mem) + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86Mem) //! Unpack low packed DWORDs to QWORDs (AVX). - INST_3x(vpunpckldq, kInstVpunpckldq, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpckldq, kInstVpunpckldq, XmmReg, XmmReg, Mem) + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86Mem) //! Unpack low packed QWORDs to OWORD (AVX). - INST_3x(vpunpcklqdq, kInstVpunpcklqdq, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpcklqdq, kInstVpunpcklqdq, XmmReg, XmmReg, Mem) + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86Mem) //! Unpack low packed WORDs to DWORDs (AVX). - INST_3x(vpunpcklwd, kInstVpunpcklwd, XmmReg, XmmReg, XmmReg) + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpunpcklwd, kInstVpunpcklwd, XmmReg, XmmReg, Mem) + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86Mem) //! Packed bitwise xor (AVX). - INST_3x(vpxor, kInstVpxor, XmmReg, XmmReg, XmmReg) + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vpxor, kInstVpxor, XmmReg, XmmReg, Mem) + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86Mem) //! Packed SP-FP reciprocal (AVX). - INST_2x(vrcpps, kInstVrcpps, XmmReg, XmmReg) + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vrcpps, kInstVrcpps, XmmReg, Mem) + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86Mem) //! \overload - INST_2x(vrcpps, kInstVrcpps, YmmReg, YmmReg) + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vrcpps, kInstVrcpps, YmmReg, Mem) + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86Mem) //! Scalar SP-FP reciprocal (AVX). - INST_3x(vrcpss, kInstVrcpss, XmmReg, XmmReg, XmmReg) + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vrcpss, kInstVrcpss, XmmReg, XmmReg, Mem) + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86Mem) //! Packed SP-FP square root reciprocal (AVX). - INST_2x(vrsqrtps, kInstVrsqrtps, XmmReg, XmmReg) + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vrsqrtps, kInstVrsqrtps, XmmReg, Mem) + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86Mem) //! \overload - INST_2x(vrsqrtps, kInstVrsqrtps, YmmReg, YmmReg) + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vrsqrtps, kInstVrsqrtps, YmmReg, Mem) + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86Mem) //! Scalar SP-FP square root reciprocal (AVX). - INST_3x(vrsqrtss, kInstVrsqrtss, XmmReg, XmmReg, XmmReg) + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vrsqrtss, kInstVrsqrtss, XmmReg, XmmReg, Mem) + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86Mem) //! Packed DP-FP round (AVX). - INST_3i(vroundpd, kInstVroundpd, XmmReg, XmmReg, Imm) + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vroundpd, kInstVroundpd, XmmReg, Mem, Imm) + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86Mem, Imm) //! \overload - INST_3i(vroundpd, kInstVroundpd, YmmReg, YmmReg, Imm) + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vroundpd, kInstVroundpd, YmmReg, Mem, Imm) + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86Mem, Imm) //! Packed SP-FP round (AVX). - INST_3i(vroundps, kInstVroundps, XmmReg, XmmReg, Imm) + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vroundps, kInstVroundps, XmmReg, Mem, Imm) + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86Mem, Imm) //! \overload - INST_3i(vroundps, kInstVroundps, YmmReg, YmmReg, Imm) + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vroundps, kInstVroundps, YmmReg, Mem, Imm) + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86Mem, Imm) //! Scalar DP-FP round (AVX). - INST_4i(vroundsd, kInstVroundsd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vroundsd, kInstVroundsd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Scalar SP-FP round (AVX). - INST_4i(vroundss, kInstVroundss, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vroundss, kInstVroundss, XmmReg, XmmReg, Mem, Imm) + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86Mem, Imm) //! Shuffle DP-FP (AVX). - INST_4i(vshufpd, kInstVshufpd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vshufpd, kInstVshufpd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vshufpd, kInstVshufpd, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vshufpd, kInstVshufpd, YmmReg, YmmReg, Mem, Imm) + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Shuffle SP-FP (AVX). - INST_4i(vshufps, kInstVshufps, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vshufps, kInstVshufps, XmmReg, XmmReg, Mem, Imm) + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vshufps, kInstVshufps, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vshufps, kInstVshufps, YmmReg, YmmReg, Mem, Imm) + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed DP-FP square root (AVX). - INST_2x(vsqrtpd, kInstVsqrtpd, XmmReg, XmmReg) + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vsqrtpd, kInstVsqrtpd, XmmReg, Mem) + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86Mem) //! \overload - INST_2x(vsqrtpd, kInstVsqrtpd, YmmReg, YmmReg) + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vsqrtpd, kInstVsqrtpd, YmmReg, Mem) + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86Mem) //! Packed SP-FP square root (AVX). - INST_2x(vsqrtps, kInstVsqrtps, XmmReg, XmmReg) + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vsqrtps, kInstVsqrtps, XmmReg, Mem) + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86Mem) //! \overload - INST_2x(vsqrtps, kInstVsqrtps, YmmReg, YmmReg) + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vsqrtps, kInstVsqrtps, YmmReg, Mem) + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86Mem) //! Scalar DP-FP square root (AVX). - INST_3x(vsqrtsd, kInstVsqrtsd, XmmReg, XmmReg, XmmReg) + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsqrtsd, kInstVsqrtsd, XmmReg, XmmReg, Mem) + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP square root (AVX). - INST_3x(vsqrtss, kInstVsqrtss, XmmReg, XmmReg, XmmReg) + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsqrtss, kInstVsqrtss, XmmReg, XmmReg, Mem) + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86Mem) //! Store streaming SIMD extension control/status (AVX). - INST_1x(vstmxcsr, kInstVstmxcsr, Mem) + INST_1x(vstmxcsr, kX86InstIdVstmxcsr, X86Mem) //! Packed DP-FP subtract (AVX). - INST_3x(vsubpd, kInstVsubpd, XmmReg, XmmReg, XmmReg) + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsubpd, kInstVsubpd, XmmReg, XmmReg, Mem) + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vsubpd, kInstVsubpd, YmmReg, YmmReg, YmmReg) + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vsubpd, kInstVsubpd, YmmReg, YmmReg, Mem) + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP subtract (AVX). - INST_3x(vsubps, kInstVsubps, XmmReg, XmmReg, XmmReg) + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsubps, kInstVsubps, XmmReg, XmmReg, Mem) + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vsubps, kInstVsubps, YmmReg, YmmReg, YmmReg) + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vsubps, kInstVsubps, YmmReg, YmmReg, Mem) + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86Mem) //! Scalar DP-FP subtract (AVX). - INST_3x(vsubsd, kInstVsubsd, XmmReg, XmmReg, XmmReg) + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsubsd, kInstVsubsd, XmmReg, XmmReg, Mem) + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86Mem) //! Scalar SP-FP subtract (AVX). - INST_3x(vsubss, kInstVsubss, XmmReg, XmmReg, XmmReg) + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vsubss, kInstVsubss, XmmReg, XmmReg, Mem) + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86Mem) //! Logical compare DP-FP (AVX). - INST_2x(vtestpd, kInstVtestpd, XmmReg, XmmReg) + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vtestpd, kInstVtestpd, XmmReg, Mem) + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86Mem) //! \overload - INST_2x(vtestpd, kInstVtestpd, YmmReg, YmmReg) + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vtestpd, kInstVtestpd, YmmReg, Mem) + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86Mem) //! Logical compare SP-FP (AVX). - INST_2x(vtestps, kInstVtestps, XmmReg, XmmReg) + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vtestps, kInstVtestps, XmmReg, Mem) + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86Mem) //! \overload - INST_2x(vtestps, kInstVtestps, YmmReg, YmmReg) + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vtestps, kInstVtestps, YmmReg, Mem) + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86Mem) //! Scalar DP-FP unordered compare and set EFLAGS (AVX). - INST_2x(vucomisd, kInstVucomisd, XmmReg, XmmReg) + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vucomisd, kInstVucomisd, XmmReg, Mem) + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86Mem) //! Unordered scalar SP-FP compare and set EFLAGS (AVX). - INST_2x(vucomiss, kInstVucomiss, XmmReg, XmmReg) + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vucomiss, kInstVucomiss, XmmReg, Mem) + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86Mem) //! Unpack and interleave high packed DP-FP (AVX). - INST_3x(vunpckhpd, kInstVunpckhpd, XmmReg, XmmReg, XmmReg) + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vunpckhpd, kInstVunpckhpd, XmmReg, XmmReg, Mem) + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vunpckhpd, kInstVunpckhpd, YmmReg, YmmReg, YmmReg) + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vunpckhpd, kInstVunpckhpd, YmmReg, YmmReg, Mem) + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86Mem) //! Unpack high packed SP-FP data (AVX). - INST_3x(vunpckhps, kInstVunpckhps, XmmReg, XmmReg, XmmReg) + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vunpckhps, kInstVunpckhps, XmmReg, XmmReg, Mem) + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vunpckhps, kInstVunpckhps, YmmReg, YmmReg, YmmReg) + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vunpckhps, kInstVunpckhps, YmmReg, YmmReg, Mem) + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86Mem) //! Unpack and interleave low packed DP-FP (AVX). - INST_3x(vunpcklpd, kInstVunpcklpd, XmmReg, XmmReg, XmmReg) + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vunpcklpd, kInstVunpcklpd, XmmReg, XmmReg, Mem) + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vunpcklpd, kInstVunpcklpd, YmmReg, YmmReg, YmmReg) + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vunpcklpd, kInstVunpcklpd, YmmReg, YmmReg, Mem) + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86Mem) //! Unpack low packed SP-FP data (AVX). - INST_3x(vunpcklps, kInstVunpcklps, XmmReg, XmmReg, XmmReg) + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vunpcklps, kInstVunpcklps, XmmReg, XmmReg, Mem) + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vunpcklps, kInstVunpcklps, YmmReg, YmmReg, YmmReg) + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vunpcklps, kInstVunpcklps, YmmReg, YmmReg, Mem) + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP bitwise xor (AVX). - INST_3x(vxorpd, kInstVxorpd, XmmReg, XmmReg, XmmReg) + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vxorpd, kInstVxorpd, XmmReg, XmmReg, Mem) + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vxorpd, kInstVxorpd, YmmReg, YmmReg, YmmReg) + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vxorpd, kInstVxorpd, YmmReg, YmmReg, Mem) + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86Mem) //! Packed SP-FP bitwise xor (AVX). - INST_3x(vxorps, kInstVxorps, XmmReg, XmmReg, XmmReg) + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vxorps, kInstVxorps, XmmReg, XmmReg, Mem) + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86Mem) //! \overload - INST_3x(vxorps, kInstVxorps, YmmReg, YmmReg, YmmReg) + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vxorps, kInstVxorps, YmmReg, YmmReg, Mem) + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86Mem) //! Zero all Ymm registers. - INST_0x(vzeroall, kInstVzeroall) + INST_0x(vzeroall, kX86InstIdVzeroall) //! Zero upper 128-bits of all Ymm registers. - INST_0x(vzeroupper, kInstVzeroupper) + INST_0x(vzeroupper, kX86InstIdVzeroupper) // -------------------------------------------------------------------------- // [AVX+AESNI] // -------------------------------------------------------------------------- //! Perform a single round of the AES decryption flow (AVX+AESNI). - INST_3x(vaesdec, kInstVaesdec, XmmReg, XmmReg, XmmReg) + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaesdec, kInstVaesdec, XmmReg, XmmReg, Mem) + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86Mem) //! Perform the last round of the AES decryption flow (AVX+AESNI). - INST_3x(vaesdeclast, kInstVaesdeclast, XmmReg, XmmReg, XmmReg) + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaesdeclast, kInstVaesdeclast, XmmReg, XmmReg, Mem) + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86Mem) //! Perform a single round of the AES encryption flow (AVX+AESNI). - INST_3x(vaesenc, kInstVaesenc, XmmReg, XmmReg, XmmReg) + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaesenc, kInstVaesenc, XmmReg, XmmReg, Mem) + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86Mem) //! Perform the last round of the AES encryption flow (AVX+AESNI). - INST_3x(vaesenclast, kInstVaesenclast, XmmReg, XmmReg, XmmReg) + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86XmmReg) //! \overload - INST_3x(vaesenclast, kInstVaesenclast, XmmReg, XmmReg, Mem) + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86Mem) //! Perform the InvMixColumns transformation (AVX+AESNI). - INST_2x(vaesimc, kInstVaesimc, XmmReg, XmmReg) + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vaesimc, kInstVaesimc, XmmReg, Mem) + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86Mem) //! Assist in expanding the AES cipher key (AVX+AESNI). - INST_3i(vaeskeygenassist, kInstVaeskeygenassist, XmmReg, XmmReg, Imm) + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vaeskeygenassist, kInstVaeskeygenassist, XmmReg, Mem, Imm) + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [AVX+PCLMULQDQ] // -------------------------------------------------------------------------- //! Carry-less multiplication QWORD (AVX+PCLMULQDQ). - INST_4i(vpclmulqdq, kInstVpclmulqdq, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vpclmulqdq, kInstVpclmulqdq, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86Mem, Imm) // -------------------------------------------------------------------------- // [AVX2] // -------------------------------------------------------------------------- //! Broadcast low 128-bit element in `o1` to `o0` (AVX2). - INST_2x(vbroadcasti128, kInstVbroadcasti128, YmmReg, Mem) + INST_2x(vbroadcasti128, kX86InstIdVbroadcasti128, X86YmmReg, X86Mem) //! Broadcast low DP-FP element in `o1` to `o0` (AVX2). - INST_2x(vbroadcastsd, kInstVbroadcastsd, YmmReg, XmmReg) + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86XmmReg) //! Broadcast low SP-FP element in `o1` to `o0` (AVX2). - INST_2x(vbroadcastss, kInstVbroadcastss, XmmReg, XmmReg) + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vbroadcastss, kInstVbroadcastss, YmmReg, XmmReg) + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86XmmReg) //! Extract 128-bit element from `o1` to `o0` based on selector (AVX2). - INST_3i(vextracti128, kInstVextracti128, XmmReg, YmmReg, Imm) + INST_3i(vextracti128, kX86InstIdVextracti128, X86XmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vextracti128, kInstVextracti128, Mem, YmmReg, Imm) + INST_3i(vextracti128, kX86InstIdVextracti128, X86Mem, X86YmmReg, Imm) //! Gather DP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). - INST_3x(vgatherdpd, kInstVgatherdpd, XmmReg, Mem, XmmReg) + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86XmmReg, X86Mem, X86XmmReg) //! \overload - INST_3x(vgatherdpd, kInstVgatherdpd, YmmReg, Mem, YmmReg) + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86YmmReg, X86Mem, X86YmmReg) //! Gather SP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). - INST_3x(vgatherdps, kInstVgatherdps, XmmReg, Mem, XmmReg) + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86XmmReg, X86Mem, X86XmmReg) //! \overload - INST_3x(vgatherdps, kInstVgatherdps, YmmReg, Mem, YmmReg) + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86YmmReg, X86Mem, X86YmmReg) //! Gather DP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). - INST_3x(vgatherqpd, kInstVgatherqpd, XmmReg, Mem, XmmReg) + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86XmmReg, X86Mem, X86XmmReg) //! \overload - INST_3x(vgatherqpd, kInstVgatherqpd, YmmReg, Mem, YmmReg) + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86YmmReg, X86Mem, X86YmmReg) //! Gather SP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). - INST_3x(vgatherqps, kInstVgatherqps, XmmReg, Mem, XmmReg) + INST_3x(vgatherqps, kX86InstIdVgatherqps, X86XmmReg, X86Mem, X86XmmReg) //! Insert 128-bit of packed data based on selector (AVX2). - INST_4i(vinserti128, kInstVinserti128, YmmReg, YmmReg, XmmReg, Imm) + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vinserti128, kInstVinserti128, YmmReg, YmmReg, Mem, Imm) + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Load 256-bits aligned using NT hint (AVX2). - INST_2x(vmovntdqa, kInstVmovntdqa, YmmReg, Mem) + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86YmmReg, X86Mem) //! Packed WORD sums of absolute difference (AVX2). - INST_4i(vmpsadbw, kInstVmpsadbw, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vmpsadbw, kInstVmpsadbw, YmmReg, YmmReg, Mem, Imm) + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed BYTE absolute value (AVX2). - INST_2x(vpabsb, kInstVpabsb, YmmReg, YmmReg) + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vpabsb, kInstVpabsb, YmmReg, Mem) + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86Mem) //! Packed DWORD absolute value (AVX2). - INST_2x(vpabsd, kInstVpabsd, YmmReg, YmmReg) + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vpabsd, kInstVpabsd, YmmReg, Mem) + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86Mem) //! Packed WORD absolute value (AVX2). - INST_2x(vpabsw, kInstVpabsw, YmmReg, YmmReg) + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86YmmReg) //! \overload - INST_2x(vpabsw, kInstVpabsw, YmmReg, Mem) + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86Mem) //! Pack DWORDs to WORDs with signed saturation (AVX2). - INST_3x(vpackssdw, kInstVpackssdw, YmmReg, YmmReg, YmmReg) + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpackssdw, kInstVpackssdw, YmmReg, YmmReg, Mem) + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86Mem) //! Pack WORDs to BYTEs with signed saturation (AVX2). - INST_3x(vpacksswb, kInstVpacksswb, YmmReg, YmmReg, YmmReg) + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpacksswb, kInstVpacksswb, YmmReg, YmmReg, Mem) + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86Mem) //! Pack DWORDs to WORDs with unsigned saturation (AVX2). - INST_3x(vpackusdw, kInstVpackusdw, YmmReg, YmmReg, YmmReg) + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpackusdw, kInstVpackusdw, YmmReg, YmmReg, Mem) + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (AVX2). - INST_3x(vpackuswb, kInstVpackuswb, YmmReg, YmmReg, YmmReg) + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpackuswb, kInstVpackuswb, YmmReg, YmmReg, Mem) + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTE add (AVX2). - INST_3x(vpaddb, kInstVpaddb, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddb, kInstVpaddb, YmmReg, YmmReg, Mem) + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86Mem) //! Packed DWORD add (AVX2). - INST_3x(vpaddd, kInstVpaddd, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddd, kInstVpaddd, YmmReg, YmmReg, Mem) + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86Mem) //! Packed QDWORD add (AVX2). - INST_3x(vpaddq, kInstVpaddq, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddq, kInstVpaddq, YmmReg, YmmReg, Mem) + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORD add (AVX2). - INST_3x(vpaddw, kInstVpaddw, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddw, kInstVpaddw, YmmReg, YmmReg, Mem) + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTE add with saturation (AVX2). - INST_3x(vpaddsb, kInstVpaddsb, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddsb, kInstVpaddsb, YmmReg, YmmReg, Mem) + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORD add with saturation (AVX2). - INST_3x(vpaddsw, kInstVpaddsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddsw, kInstVpaddsw, YmmReg, YmmReg, Mem) + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTE add with unsigned saturation (AVX2). - INST_3x(vpaddusb, kInstVpaddusb, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddusb, kInstVpaddusb, YmmReg, YmmReg, Mem) + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORD add with unsigned saturation (AVX2). - INST_3x(vpaddusw, kInstVpaddusw, YmmReg, YmmReg, YmmReg) + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpaddusw, kInstVpaddusw, YmmReg, YmmReg, Mem) + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86Mem) //! Packed align right (AVX2). - INST_4i(vpalignr, kInstVpalignr, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vpalignr, kInstVpalignr, YmmReg, YmmReg, Mem, Imm) + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed bitwise and (AVX2). - INST_3x(vpand, kInstVpand, YmmReg, YmmReg, YmmReg) + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpand, kInstVpand, YmmReg, YmmReg, Mem) + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86Mem) //! Packed bitwise and-not (AVX2). - INST_3x(vpandn, kInstVpandn, YmmReg, YmmReg, YmmReg) + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpandn, kInstVpandn, YmmReg, YmmReg, Mem) + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTE average (AVX2). - INST_3x(vpavgb, kInstVpavgb, YmmReg, YmmReg, YmmReg) + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpavgb, kInstVpavgb, YmmReg, YmmReg, Mem) + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORD average (AVX2). - INST_3x(vpavgw, kInstVpavgw, YmmReg, YmmReg, YmmReg) + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpavgw, kInstVpavgw, YmmReg, YmmReg, Mem) + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86Mem) //! Packed DWORD blend (AVX2). - INST_4i(vpblendd, kInstVpblendd, XmmReg, XmmReg, XmmReg, Imm) + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_4i(vpblendd, kInstVpblendd, XmmReg, XmmReg, Mem, Imm) + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86Mem, Imm) //! \overload - INST_4i(vpblendd, kInstVpblendd, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vpblendd, kInstVpblendd, YmmReg, YmmReg, Mem, Imm) + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed DWORD variable blend (AVX2). - INST_4x(vpblendvb, kInstVpblendvb, YmmReg, YmmReg, YmmReg, YmmReg) + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_4x(vpblendvb, kInstVpblendvb, YmmReg, YmmReg, Mem, YmmReg) + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) //! Packed WORD blend (AVX2). - INST_4i(vpblendw, kInstVpblendw, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vpblendw, kInstVpblendw, YmmReg, YmmReg, Mem, Imm) + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Broadcast BYTE from `o1` to 128-bits in `o0` (AVX2). - INST_2x(vpbroadcastb, kInstVpbroadcastb, XmmReg, XmmReg) + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastb, kInstVpbroadcastb, XmmReg, Mem) + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86Mem) //! Broadcast BYTE from `o1` to 256-bits in `o0` (AVX2). - INST_2x(vpbroadcastb, kInstVpbroadcastb, YmmReg, XmmReg) + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastb, kInstVpbroadcastb, YmmReg, Mem) + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86Mem) //! Broadcast DWORD from `o1` to 128-bits in `o0` (AVX2). - INST_2x(vpbroadcastd, kInstVpbroadcastd, XmmReg, XmmReg) + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastd, kInstVpbroadcastd, XmmReg, Mem) + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86Mem) //! Broadcast DWORD from `o1` to 256-bits in `o0` (AVX2). - INST_2x(vpbroadcastd, kInstVpbroadcastd, YmmReg, XmmReg) + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastd, kInstVpbroadcastd, YmmReg, Mem) + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86Mem) //! Broadcast QWORD from `o1` to 128-bits in `o0` (AVX2). - INST_2x(vpbroadcastq, kInstVpbroadcastq, XmmReg, XmmReg) + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastq, kInstVpbroadcastq, XmmReg, Mem) + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86Mem) //! Broadcast QWORD from `o1` to 256-bits in `o0` (AVX2). - INST_2x(vpbroadcastq, kInstVpbroadcastq, YmmReg, XmmReg) + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastq, kInstVpbroadcastq, YmmReg, Mem) + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86Mem) //! Broadcast WORD from `o1` to 128-bits in `o0` (AVX2). - INST_2x(vpbroadcastw, kInstVpbroadcastw, XmmReg, XmmReg) + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastw, kInstVpbroadcastw, XmmReg, Mem) + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86Mem) //! Broadcast WORD from `o1` to 256-bits in `o0` (AVX2). - INST_2x(vpbroadcastw, kInstVpbroadcastw, YmmReg, XmmReg) + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vpbroadcastw, kInstVpbroadcastw, YmmReg, Mem) + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86Mem) //! Packed BYTEs compare for equality (AVX2). - INST_3x(vpcmpeqb, kInstVpcmpeqb, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpeqb, kInstVpcmpeqb, YmmReg, YmmReg, Mem) + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86Mem) //! Packed DWORDs compare for equality (AVX2). - INST_3x(vpcmpeqd, kInstVpcmpeqd, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpeqd, kInstVpcmpeqd, YmmReg, YmmReg, Mem) + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86Mem) //! Packed QWORDs compare for equality (AVX2). - INST_3x(vpcmpeqq, kInstVpcmpeqq, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpeqq, kInstVpcmpeqq, YmmReg, YmmReg, Mem) + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORDs compare for equality (AVX2). - INST_3x(vpcmpeqw, kInstVpcmpeqw, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpeqw, kInstVpcmpeqw, YmmReg, YmmReg, Mem) + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86Mem) //! Packed BYTEs compare if greater than (AVX2). - INST_3x(vpcmpgtb, kInstVpcmpgtb, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpgtb, kInstVpcmpgtb, YmmReg, YmmReg, Mem) + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86Mem) //! Packed DWORDs compare if greater than (AVX2). - INST_3x(vpcmpgtd, kInstVpcmpgtd, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpgtd, kInstVpcmpgtd, YmmReg, YmmReg, Mem) + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86Mem) //! Packed QWORDs compare if greater than (AVX2). - INST_3x(vpcmpgtq, kInstVpcmpgtq, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpgtq, kInstVpcmpgtq, YmmReg, YmmReg, Mem) + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86Mem) //! Packed WORDs compare if greater than (AVX2). - INST_3x(vpcmpgtw, kInstVpcmpgtw, YmmReg, YmmReg, YmmReg) + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpcmpgtw, kInstVpcmpgtw, YmmReg, YmmReg, Mem) + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86Mem) //! Packed OWORD permute (AVX2). - INST_4i(vperm2i128, kInstVperm2i128, YmmReg, YmmReg, YmmReg, Imm) + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_4i(vperm2i128, kInstVperm2i128, YmmReg, YmmReg, Mem, Imm) + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86Mem, Imm) //! Packed DWORD permute (AVX2). - INST_3x(vpermd, kInstVpermd, YmmReg, YmmReg, YmmReg) + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpermd, kInstVpermd, YmmReg, YmmReg, Mem) + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86Mem) //! Packed DP-FP permute (AVX2). - INST_3i(vpermpd, kInstVpermpd, YmmReg, YmmReg, Imm) + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vpermpd, kInstVpermpd, YmmReg, Mem, Imm) + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86Mem, Imm) //! Packed SP-FP permute (AVX2). - INST_3x(vpermps, kInstVpermps, YmmReg, YmmReg, YmmReg) + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86YmmReg) //! \overload - INST_3x(vpermps, kInstVpermps, YmmReg, YmmReg, Mem) + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86Mem) //! Packed QWORD permute (AVX2). - INST_3i(vpermq, kInstVpermq, YmmReg, YmmReg, Imm) + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vpermq, kInstVpermq, YmmReg, Mem, Imm) + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86Mem, Imm) - INST_3x(vpgatherdd, kInstVpgatherdd, XmmReg, Mem, XmmReg) - INST_3x(vpgatherdd, kInstVpgatherdd, YmmReg, Mem, YmmReg) + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86YmmReg, X86Mem, X86YmmReg) - INST_3x(vpgatherdq, kInstVpgatherdq, XmmReg, Mem, XmmReg) - INST_3x(vpgatherdq, kInstVpgatherdq, YmmReg, Mem, YmmReg) + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86YmmReg, X86Mem, X86YmmReg) - INST_3x(vpgatherqd, kInstVpgatherqd, XmmReg, Mem, XmmReg) + INST_3x(vpgatherqd, kX86InstIdVpgatherqd, X86XmmReg, X86Mem, X86XmmReg) - INST_3x(vpgatherqq, kInstVpgatherqq, XmmReg, Mem, XmmReg) - INST_3x(vpgatherqq, kInstVpgatherqq, YmmReg, Mem, YmmReg) + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86YmmReg, X86Mem, X86YmmReg) //! Packed DWORD horizontal add (AVX2). - INST_3x(vphaddd, kInstVphaddd, YmmReg, YmmReg, Mem) + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphaddd, kInstVphaddd, YmmReg, YmmReg, YmmReg) + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD horizontal add with saturation (AVX2). - INST_3x(vphaddsw, kInstVphaddsw, YmmReg, YmmReg, Mem) + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphaddsw, kInstVphaddsw, YmmReg, YmmReg, YmmReg) + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD horizontal add (AVX2). - INST_3x(vphaddw, kInstVphaddw, YmmReg, YmmReg, Mem) + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphaddw, kInstVphaddw, YmmReg, YmmReg, YmmReg) + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD horizontal subtract (AVX2). - INST_3x(vphsubd, kInstVphsubd, YmmReg, YmmReg, Mem) + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphsubd, kInstVphsubd, YmmReg, YmmReg, YmmReg) + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD horizontal subtract with saturation (AVX2). - INST_3x(vphsubsw, kInstVphsubsw, YmmReg, YmmReg, Mem) + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphsubsw, kInstVphsubsw, YmmReg, YmmReg, YmmReg) + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD horizontal subtract (AVX2). - INST_3x(vphsubw, kInstVphsubw, YmmReg, YmmReg, Mem) + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vphsubw, kInstVphsubw, YmmReg, YmmReg, YmmReg) + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86YmmReg) //! Move Byte mask to integer (AVX2). - INST_2x(vpmovmskb, kInstVpmovmskb, GpReg, YmmReg) + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86YmmReg) //! BYTE to DWORD with sign extend (AVX). - INST_2x(vpmovsxbd, kInstVpmovsxbd, YmmReg, Mem) + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxbd, kInstVpmovsxbd, YmmReg, XmmReg) + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86XmmReg) //! Packed BYTE to QWORD with sign extend (AVX2). - INST_2x(vpmovsxbq, kInstVpmovsxbq, YmmReg, Mem) + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxbq, kInstVpmovsxbq, YmmReg, XmmReg) + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86XmmReg) //! Packed BYTE to WORD with sign extend (AVX2). - INST_2x(vpmovsxbw, kInstVpmovsxbw, YmmReg, Mem) + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxbw, kInstVpmovsxbw, YmmReg, XmmReg) + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86XmmReg) //! Packed DWORD to QWORD with sign extend (AVX2). - INST_2x(vpmovsxdq, kInstVpmovsxdq, YmmReg, Mem) + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxdq, kInstVpmovsxdq, YmmReg, XmmReg) + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86XmmReg) //! Packed WORD to DWORD with sign extend (AVX2). - INST_2x(vpmovsxwd, kInstVpmovsxwd, YmmReg, Mem) + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxwd, kInstVpmovsxwd, YmmReg, XmmReg) + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86XmmReg) //! Packed WORD to QWORD with sign extend (AVX2). - INST_2x(vpmovsxwq, kInstVpmovsxwq, YmmReg, Mem) + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovsxwq, kInstVpmovsxwq, YmmReg, XmmReg) + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86XmmReg) //! BYTE to DWORD with zero extend (AVX2). - INST_2x(vpmovzxbd, kInstVpmovzxbd, YmmReg, Mem) + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxbd, kInstVpmovzxbd, YmmReg, XmmReg) + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86XmmReg) //! Packed BYTE to QWORD with zero extend (AVX2). - INST_2x(vpmovzxbq, kInstVpmovzxbq, YmmReg, Mem) + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxbq, kInstVpmovzxbq, YmmReg, XmmReg) + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86XmmReg) //! BYTE to WORD with zero extend (AVX2). - INST_2x(vpmovzxbw, kInstVpmovzxbw, YmmReg, Mem) + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxbw, kInstVpmovzxbw, YmmReg, XmmReg) + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86XmmReg) //! Packed DWORD to QWORD with zero extend (AVX2). - INST_2x(vpmovzxdq, kInstVpmovzxdq, YmmReg, Mem) + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxdq, kInstVpmovzxdq, YmmReg, XmmReg) + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86XmmReg) //! Packed WORD to DWORD with zero extend (AVX2). - INST_2x(vpmovzxwd, kInstVpmovzxwd, YmmReg, Mem) + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxwd, kInstVpmovzxwd, YmmReg, XmmReg) + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86XmmReg) //! Packed WORD to QWORD with zero extend (AVX2). - INST_2x(vpmovzxwq, kInstVpmovzxwq, YmmReg, Mem) + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86Mem) //! \overload - INST_2x(vpmovzxwq, kInstVpmovzxwq, YmmReg, XmmReg) + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86XmmReg) //! Packed multiply and add signed and unsigned bytes (AVX2). - INST_3x(vpmaddubsw, kInstVpmaddubsw, YmmReg, YmmReg, Mem) + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaddubsw, kInstVpmaddubsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD multiply and add to packed DWORD (AVX2). - INST_3x(vpmaddwd, kInstVpmaddwd, YmmReg, YmmReg, Mem) + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaddwd, kInstVpmaddwd, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86YmmReg) - INST_3x(vpmaskmovd, kInstVpmaskmovd, Mem, XmmReg, XmmReg) - INST_3x(vpmaskmovd, kInstVpmaskmovd, Mem, YmmReg, YmmReg) - INST_3x(vpmaskmovd, kInstVpmaskmovd, XmmReg, XmmReg, Mem) - INST_3x(vpmaskmovd, kInstVpmaskmovd, YmmReg, YmmReg, Mem) + 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, kInstVpmaskmovq, Mem, XmmReg, XmmReg) - INST_3x(vpmaskmovq, kInstVpmaskmovq, Mem, YmmReg, YmmReg) - INST_3x(vpmaskmovq, kInstVpmaskmovq, XmmReg, XmmReg, Mem) - INST_3x(vpmaskmovq, kInstVpmaskmovq, YmmReg, YmmReg, Mem) + 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, kInstVpmaxsb, YmmReg, YmmReg, Mem) + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxsb, kInstVpmaxsb, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD maximum (AVX2). - INST_3x(vpmaxsd, kInstVpmaxsd, YmmReg, YmmReg, Mem) + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxsd, kInstVpmaxsd, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD maximum (AVX2). - INST_3x(vpmaxsw, kInstVpmaxsw, YmmReg, YmmReg, Mem) + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxsw, kInstVpmaxsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE unsigned maximum (AVX2). - INST_3x(vpmaxub, kInstVpmaxub, YmmReg, YmmReg, Mem) + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxub, kInstVpmaxub, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD unsigned maximum (AVX2). - INST_3x(vpmaxud, kInstVpmaxud, YmmReg, YmmReg, Mem) + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxud, kInstVpmaxud, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD unsigned maximum (AVX2). - INST_3x(vpmaxuw, kInstVpmaxuw, YmmReg, YmmReg, Mem) + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmaxuw, kInstVpmaxuw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE minimum (AVX2). - INST_3x(vpminsb, kInstVpminsb, YmmReg, YmmReg, Mem) + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminsb, kInstVpminsb, YmmReg, YmmReg, YmmReg) + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD minimum (AVX2). - INST_3x(vpminsd, kInstVpminsd, YmmReg, YmmReg, Mem) + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminsd, kInstVpminsd, YmmReg, YmmReg, YmmReg) + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD minimum (AVX2). - INST_3x(vpminsw, kInstVpminsw, YmmReg, YmmReg, Mem) + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminsw, kInstVpminsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE unsigned minimum (AVX2). - INST_3x(vpminub, kInstVpminub, YmmReg, YmmReg, Mem) + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminub, kInstVpminub, YmmReg, YmmReg, YmmReg) + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD unsigned minimum (AVX2). - INST_3x(vpminud, kInstVpminud, YmmReg, YmmReg, Mem) + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminud, kInstVpminud, YmmReg, YmmReg, YmmReg) + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD unsigned minimum (AVX2). - INST_3x(vpminuw, kInstVpminuw, YmmReg, YmmReg, Mem) + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpminuw, kInstVpminuw, YmmReg, YmmReg, YmmReg) + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD to QWORD multiply (AVX2). - INST_3x(vpmuldq, kInstVpmuldq, YmmReg, YmmReg, Mem) + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmuldq, kInstVpmuldq, YmmReg, YmmReg, YmmReg) + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD multiply high, round and scale (AVX2). - INST_3x(vpmulhrsw, kInstVpmulhrsw, YmmReg, YmmReg, Mem) + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmulhrsw, kInstVpmulhrsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD unsigned multiply high (AVX2). - INST_3x(vpmulhuw, kInstVpmulhuw, YmmReg, YmmReg, Mem) + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmulhuw, kInstVpmulhuw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD multiply high (AVX2). - INST_3x(vpmulhw, kInstVpmulhw, YmmReg, YmmReg, Mem) + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmulhw, kInstVpmulhw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD multiply low (AVX2). - INST_3x(vpmulld, kInstVpmulld, YmmReg, YmmReg, Mem) + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmulld, kInstVpmulld, YmmReg, YmmReg, YmmReg) + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORDs multiply low (AVX2). - INST_3x(vpmullw, kInstVpmullw, YmmReg, YmmReg, Mem) + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmullw, kInstVpmullw, YmmReg, YmmReg, YmmReg) + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD multiply to QWORD (AVX2). - INST_3x(vpmuludq, kInstVpmuludq, YmmReg, YmmReg, Mem) + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpmuludq, kInstVpmuludq, YmmReg, YmmReg, YmmReg) + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed bitwise or (AVX2). - INST_3x(vpor, kInstVpor, YmmReg, YmmReg, Mem) + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpor, kInstVpor, YmmReg, YmmReg, YmmReg) + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD sum of absolute differences (AVX2). - INST_3x(vpsadbw, kInstVpsadbw, YmmReg, YmmReg, Mem) + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsadbw, kInstVpsadbw, YmmReg, YmmReg, YmmReg) + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE shuffle (AVX2). - INST_3x(vpshufb, kInstVpshufb, YmmReg, YmmReg, Mem) + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpshufb, kInstVpshufb, YmmReg, YmmReg, YmmReg) + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD shuffle (AVX2). - INST_3i(vpshufd, kInstVpshufd, YmmReg, Mem, Imm) + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86Mem, Imm) //! \overload - INST_3i(vpshufd, kInstVpshufd, YmmReg, YmmReg, Imm) + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86YmmReg, Imm) //! Packed WORD shuffle high (AVX2). - INST_3i(vpshufhw, kInstVpshufhw, YmmReg, Mem, Imm) + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86Mem, Imm) //! \overload - INST_3i(vpshufhw, kInstVpshufhw, YmmReg, YmmReg, Imm) + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86YmmReg, Imm) //! Packed WORD shuffle low (AVX2). - INST_3i(vpshuflw, kInstVpshuflw, YmmReg, Mem, Imm) + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86Mem, Imm) //! \overload - INST_3i(vpshuflw, kInstVpshuflw, YmmReg, YmmReg, Imm) + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86YmmReg, Imm) //! Packed BYTE sign (AVX2). - INST_3x(vpsignb, kInstVpsignb, YmmReg, YmmReg, Mem) + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsignb, kInstVpsignb, YmmReg, YmmReg, YmmReg) + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD sign (AVX2). - INST_3x(vpsignd, kInstVpsignd, YmmReg, YmmReg, Mem) + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsignd, kInstVpsignd, YmmReg, YmmReg, YmmReg) + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD sign (AVX2). - INST_3x(vpsignw, kInstVpsignw, YmmReg, YmmReg, Mem) + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsignw, kInstVpsignw, YmmReg, YmmReg, YmmReg) + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD shift left logical (AVX2). - INST_3x(vpslld, kInstVpslld, YmmReg, YmmReg, Mem) + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpslld, kInstVpslld, YmmReg, YmmReg, XmmReg) + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpslld, kInstVpslld, YmmReg, YmmReg, Imm) + INST_3i(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, Imm) //! Packed OWORD shift left logical (AVX2). - INST_3i(vpslldq, kInstVpslldq, YmmReg, YmmReg, Imm) + INST_3i(vpslldq, kX86InstIdVpslldq, X86YmmReg, X86YmmReg, Imm) //! Packed QWORD shift left logical (AVX2). - INST_3x(vpsllq, kInstVpsllq, YmmReg, YmmReg, Mem) + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsllq, kInstVpsllq, YmmReg, YmmReg, XmmReg) + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsllq, kInstVpsllq, YmmReg, YmmReg, Imm) + INST_3i(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, Imm) - INST_3x(vpsllvd, kInstVpsllvd, XmmReg, XmmReg, Mem) - INST_3x(vpsllvd, kInstVpsllvd, XmmReg, XmmReg, XmmReg) - INST_3x(vpsllvd, kInstVpsllvd, YmmReg, YmmReg, Mem) - INST_3x(vpsllvd, kInstVpsllvd, YmmReg, YmmReg, YmmReg) + 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, kInstVpsllvq, XmmReg, XmmReg, Mem) - INST_3x(vpsllvq, kInstVpsllvq, XmmReg, XmmReg, XmmReg) - INST_3x(vpsllvq, kInstVpsllvq, YmmReg, YmmReg, Mem) - INST_3x(vpsllvq, kInstVpsllvq, YmmReg, YmmReg, YmmReg) + 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, kInstVpsllw, YmmReg, YmmReg, Mem) + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsllw, kInstVpsllw, YmmReg, YmmReg, XmmReg) + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86XmmReg) //! Packed WORD shift left logical (AVX2). - INST_3i(vpsllw, kInstVpsllw, YmmReg, YmmReg, Imm) + INST_3i(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, Imm) //! Packed DWORD shift right arithmetic (AVX2). - INST_3x(vpsrad, kInstVpsrad, YmmReg, YmmReg, Mem) + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsrad, kInstVpsrad, YmmReg, YmmReg, XmmReg) + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsrad, kInstVpsrad, YmmReg, YmmReg, Imm) + INST_3i(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, Imm) - INST_3x(vpsravd, kInstVpsravd, XmmReg, XmmReg, Mem) - INST_3x(vpsravd, kInstVpsravd, XmmReg, XmmReg, XmmReg) - INST_3x(vpsravd, kInstVpsravd, YmmReg, YmmReg, Mem) - INST_3x(vpsravd, kInstVpsravd, YmmReg, YmmReg, YmmReg) + 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, kInstVpsraw, YmmReg, YmmReg, Mem) + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsraw, kInstVpsraw, YmmReg, YmmReg, XmmReg) + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsraw, kInstVpsraw, YmmReg, YmmReg, Imm) + INST_3i(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, Imm) //! Packed DWORD shift right logical (AVX2). - INST_3x(vpsrld, kInstVpsrld, YmmReg, YmmReg, Mem) + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsrld, kInstVpsrld, YmmReg, YmmReg, XmmReg) + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsrld, kInstVpsrld, YmmReg, YmmReg, Imm) + INST_3i(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, Imm) //! Scalar OWORD shift right logical (AVX2). - INST_3i(vpsrldq, kInstVpsrldq, YmmReg, YmmReg, Imm) + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86YmmReg, X86YmmReg, Imm) //! Packed QWORD shift right logical (AVX2). - INST_3x(vpsrlq, kInstVpsrlq, YmmReg, YmmReg, Mem) + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsrlq, kInstVpsrlq, YmmReg, YmmReg, XmmReg) + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsrlq, kInstVpsrlq, YmmReg, YmmReg, Imm) + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, Imm) - INST_3x(vpsrlvd, kInstVpsrlvd, XmmReg, XmmReg, Mem) - INST_3x(vpsrlvd, kInstVpsrlvd, XmmReg, XmmReg, XmmReg) - INST_3x(vpsrlvd, kInstVpsrlvd, YmmReg, YmmReg, Mem) - INST_3x(vpsrlvd, kInstVpsrlvd, YmmReg, YmmReg, YmmReg) + 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, kInstVpsrlvq, XmmReg, XmmReg, Mem) - INST_3x(vpsrlvq, kInstVpsrlvq, XmmReg, XmmReg, XmmReg) - INST_3x(vpsrlvq, kInstVpsrlvq, YmmReg, YmmReg, Mem) - INST_3x(vpsrlvq, kInstVpsrlvq, YmmReg, YmmReg, YmmReg) + 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, kInstVpsrlw, YmmReg, YmmReg, Mem) + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsrlw, kInstVpsrlw, YmmReg, YmmReg, XmmReg) + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86XmmReg) //! \overload - INST_3i(vpsrlw, kInstVpsrlw, YmmReg, YmmReg, Imm) + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, Imm) //! Packed BYTE subtract (AVX2). - INST_3x(vpsubb, kInstVpsubb, YmmReg, YmmReg, Mem) - INST_3x(vpsubb, kInstVpsubb, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed DWORD subtract (AVX2). - INST_3x(vpsubd, kInstVpsubd, YmmReg, YmmReg, Mem) + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubd, kInstVpsubd, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed QWORD subtract (AVX2). - INST_3x(vpsubq, kInstVpsubq, YmmReg, YmmReg, Mem) + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubq, kInstVpsubq, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE subtract with saturation (AVX2). - INST_3x(vpsubsb, kInstVpsubsb, YmmReg, YmmReg, Mem) + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubsb, kInstVpsubsb, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD subtract with saturation (AVX2). - INST_3x(vpsubsw, kInstVpsubsw, YmmReg, YmmReg, Mem) + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubsw, kInstVpsubsw, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed BYTE subtract with unsigned saturation (AVX2). - INST_3x(vpsubusb, kInstVpsubusb, YmmReg, YmmReg, Mem) + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubusb, kInstVpsubusb, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD subtract with unsigned saturation (AVX2). - INST_3x(vpsubusw, kInstVpsubusw, YmmReg, YmmReg, Mem) + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubusw, kInstVpsubusw, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed WORD subtract (AVX2). - INST_3x(vpsubw, kInstVpsubw, YmmReg, YmmReg, Mem) + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpsubw, kInstVpsubw, YmmReg, YmmReg, YmmReg) + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack high packed BYTEs to WORDs (AVX2). - INST_3x(vpunpckhbw, kInstVpunpckhbw, YmmReg, YmmReg, Mem) + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpckhbw, kInstVpunpckhbw, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack high packed DWORDs to QWORDs (AVX2). - INST_3x(vpunpckhdq, kInstVpunpckhdq, YmmReg, YmmReg, Mem) + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpckhdq, kInstVpunpckhdq, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack high packed QWORDs to OWORD (AVX2). - INST_3x(vpunpckhqdq, kInstVpunpckhqdq, YmmReg, YmmReg, Mem) + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpckhqdq, kInstVpunpckhqdq, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack high packed WORDs to DWORDs (AVX2). - INST_3x(vpunpckhwd, kInstVpunpckhwd, YmmReg, YmmReg, Mem) + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpckhwd, kInstVpunpckhwd, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack low packed BYTEs to WORDs (AVX2). - INST_3x(vpunpcklbw, kInstVpunpcklbw, YmmReg, YmmReg, Mem) + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpcklbw, kInstVpunpcklbw, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack low packed DWORDs to QWORDs (AVX2). - INST_3x(vpunpckldq, kInstVpunpckldq, YmmReg, YmmReg, Mem) + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpckldq, kInstVpunpckldq, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack low packed QWORDs to OWORD (AVX2). - INST_3x(vpunpcklqdq, kInstVpunpcklqdq, YmmReg, YmmReg, Mem) + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpcklqdq, kInstVpunpcklqdq, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86YmmReg) //! Unpack low packed WORDs to DWORDs (AVX2). - INST_3x(vpunpcklwd, kInstVpunpcklwd, YmmReg, YmmReg, Mem) + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpunpcklwd, kInstVpunpcklwd, YmmReg, YmmReg, YmmReg) + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86YmmReg) //! Packed bitwise xor (AVX2). - INST_3x(vpxor, kInstVpxor, YmmReg, YmmReg, Mem) + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86Mem) //! \overload - INST_3x(vpxor, kInstVpxor, YmmReg, YmmReg, YmmReg) + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86YmmReg) // -------------------------------------------------------------------------- // [FMA3] // -------------------------------------------------------------------------- - INST_3x(vfmadd132pd, kInstVfmadd132pd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd132pd, kInstVfmadd132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd132pd, kInstVfmadd132pd, YmmReg, YmmReg, Mem) - INST_3x(vfmadd132pd, kInstVfmadd132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd132ps, XmmReg, XmmReg, Mem) - INST_3x(vfmadd132ps, kInstVfmadd132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd132ps, kInstVfmadd132ps, YmmReg, YmmReg, Mem) - INST_3x(vfmadd132ps, kInstVfmadd132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd132sd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd132sd, kInstVfmadd132sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmadd132ss, kInstVfmadd132ss, XmmReg, XmmReg, Mem) - INST_3x(vfmadd132ss, kInstVfmadd132ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmadd213pd, kInstVfmadd213pd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd213pd, kInstVfmadd213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd213pd, kInstVfmadd213pd, YmmReg, YmmReg, Mem) - INST_3x(vfmadd213pd, kInstVfmadd213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd213ps, XmmReg, XmmReg, Mem) - INST_3x(vfmadd213ps, kInstVfmadd213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd213ps, kInstVfmadd213ps, YmmReg, YmmReg, Mem) - INST_3x(vfmadd213ps, kInstVfmadd213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd213sd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd213sd, kInstVfmadd213sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmadd213ss, kInstVfmadd213ss, XmmReg, XmmReg, Mem) - INST_3x(vfmadd213ss, kInstVfmadd213ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmadd231pd, kInstVfmadd231pd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd231pd, kInstVfmadd231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd231pd, kInstVfmadd231pd, YmmReg, YmmReg, Mem) - INST_3x(vfmadd231pd, kInstVfmadd231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd231ps, XmmReg, XmmReg, Mem) - INST_3x(vfmadd231ps, kInstVfmadd231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmadd231ps, kInstVfmadd231ps, YmmReg, YmmReg, Mem) - INST_3x(vfmadd231ps, kInstVfmadd231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmadd231sd, XmmReg, XmmReg, Mem) - INST_3x(vfmadd231sd, kInstVfmadd231sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmadd231ss, kInstVfmadd231ss, XmmReg, XmmReg, Mem) - INST_3x(vfmadd231ss, kInstVfmadd231ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmaddsub132pd, kInstVfmaddsub132pd, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub132pd, kInstVfmaddsub132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub132pd, kInstVfmaddsub132pd, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub132pd, kInstVfmaddsub132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmaddsub132ps, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub132ps, kInstVfmaddsub132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub132ps, kInstVfmaddsub132ps, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub132ps, kInstVfmaddsub132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmaddsub213pd, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub213pd, kInstVfmaddsub213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub213pd, kInstVfmaddsub213pd, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub213pd, kInstVfmaddsub213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmaddsub213ps, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub213ps, kInstVfmaddsub213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub213ps, kInstVfmaddsub213ps, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub213ps, kInstVfmaddsub213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmaddsub231pd, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub231pd, kInstVfmaddsub231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub231pd, kInstVfmaddsub231pd, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub231pd, kInstVfmaddsub231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmaddsub231ps, XmmReg, XmmReg, Mem) - INST_3x(vfmaddsub231ps, kInstVfmaddsub231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmaddsub231ps, kInstVfmaddsub231ps, YmmReg, YmmReg, Mem) - INST_3x(vfmaddsub231ps, kInstVfmaddsub231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub132pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub132pd, kInstVfmsub132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub132pd, kInstVfmsub132pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsub132pd, kInstVfmsub132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub132ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsub132ps, kInstVfmsub132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub132ps, kInstVfmsub132ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsub132ps, kInstVfmsub132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub132sd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub132sd, kInstVfmsub132sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsub132ss, kInstVfmsub132ss, XmmReg, XmmReg, Mem) - INST_3x(vfmsub132ss, kInstVfmsub132ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsub213pd, kInstVfmsub213pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub213pd, kInstVfmsub213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub213pd, kInstVfmsub213pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsub213pd, kInstVfmsub213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub213ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsub213ps, kInstVfmsub213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub213ps, kInstVfmsub213ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsub213ps, kInstVfmsub213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub213sd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub213sd, kInstVfmsub213sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsub213ss, kInstVfmsub213ss, XmmReg, XmmReg, Mem) - INST_3x(vfmsub213ss, kInstVfmsub213ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsub231pd, kInstVfmsub231pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub231pd, kInstVfmsub231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub231pd, kInstVfmsub231pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsub231pd, kInstVfmsub231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub231ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsub231ps, kInstVfmsub231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsub231ps, kInstVfmsub231ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsub231ps, kInstVfmsub231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsub231sd, XmmReg, XmmReg, Mem) - INST_3x(vfmsub231sd, kInstVfmsub231sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsub231ss, kInstVfmsub231ss, XmmReg, XmmReg, Mem) - INST_3x(vfmsub231ss, kInstVfmsub231ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfmsubadd132pd, kInstVfmsubadd132pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd132pd, kInstVfmsubadd132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd132pd, kInstVfmsubadd132pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd132pd, kInstVfmsubadd132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsubadd132ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd132ps, kInstVfmsubadd132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd132ps, kInstVfmsubadd132ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd132ps, kInstVfmsubadd132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsubadd213pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd213pd, kInstVfmsubadd213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd213pd, kInstVfmsubadd213pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd213pd, kInstVfmsubadd213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsubadd213ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd213ps, kInstVfmsubadd213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd213ps, kInstVfmsubadd213ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd213ps, kInstVfmsubadd213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsubadd231pd, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd231pd, kInstVfmsubadd231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd231pd, kInstVfmsubadd231pd, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd231pd, kInstVfmsubadd231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfmsubadd231ps, XmmReg, XmmReg, Mem) - INST_3x(vfmsubadd231ps, kInstVfmsubadd231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfmsubadd231ps, kInstVfmsubadd231ps, YmmReg, YmmReg, Mem) - INST_3x(vfmsubadd231ps, kInstVfmsubadd231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd132pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd132pd, kInstVfnmadd132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd132pd, kInstVfnmadd132pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd132pd, kInstVfnmadd132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd132ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd132ps, kInstVfnmadd132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd132ps, kInstVfnmadd132ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd132ps, kInstVfnmadd132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd132sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd132sd, kInstVfnmadd132sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmadd132ss, kInstVfnmadd132ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd132ss, kInstVfnmadd132ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmadd213pd, kInstVfnmadd213pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd213pd, kInstVfnmadd213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd213pd, kInstVfnmadd213pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd213pd, kInstVfnmadd213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd213ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd213ps, kInstVfnmadd213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd213ps, kInstVfnmadd213ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd213ps, kInstVfnmadd213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd213sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd213sd, kInstVfnmadd213sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmadd213ss, kInstVfnmadd213ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd213ss, kInstVfnmadd213ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmadd231pd, kInstVfnmadd231pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd231pd, kInstVfnmadd231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd231pd, kInstVfnmadd231pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd231pd, kInstVfnmadd231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd231ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd231ps, kInstVfnmadd231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmadd231ps, kInstVfnmadd231ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmadd231ps, kInstVfnmadd231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmadd231sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd231sd, kInstVfnmadd231sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmadd231ss, kInstVfnmadd231ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmadd231ss, kInstVfnmadd231ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub132pd, kInstVfnmsub132pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub132pd, kInstVfnmsub132pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub132pd, kInstVfnmsub132pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub132pd, kInstVfnmsub132pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub132ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub132ps, kInstVfnmsub132ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub132ps, kInstVfnmsub132ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub132ps, kInstVfnmsub132ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub132sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub132sd, kInstVfnmsub132sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub132ss, kInstVfnmsub132ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub132ss, kInstVfnmsub132ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub213pd, kInstVfnmsub213pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub213pd, kInstVfnmsub213pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub213pd, kInstVfnmsub213pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub213pd, kInstVfnmsub213pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub213ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub213ps, kInstVfnmsub213ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub213ps, kInstVfnmsub213ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub213ps, kInstVfnmsub213ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub213sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub213sd, kInstVfnmsub213sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub213ss, kInstVfnmsub213ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub213ss, kInstVfnmsub213ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub231pd, kInstVfnmsub231pd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub231pd, kInstVfnmsub231pd, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub231pd, kInstVfnmsub231pd, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub231pd, kInstVfnmsub231pd, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub231ps, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub231ps, kInstVfnmsub231ps, XmmReg, XmmReg, XmmReg) - INST_3x(vfnmsub231ps, kInstVfnmsub231ps, YmmReg, YmmReg, Mem) - INST_3x(vfnmsub231ps, kInstVfnmsub231ps, YmmReg, YmmReg, YmmReg) + 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, kInstVfnmsub231sd, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub231sd, kInstVfnmsub231sd, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) - INST_3x(vfnmsub231ss, kInstVfnmsub231ss, XmmReg, XmmReg, Mem) - INST_3x(vfnmsub231ss, kInstVfnmsub231ss, XmmReg, XmmReg, XmmReg) + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) // -------------------------------------------------------------------------- // [FMA4] // -------------------------------------------------------------------------- - INST_4x(vfmaddpd, kInstVfmaddpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddpd, kInstVfmaddpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddpd, kInstVfmaddpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmaddpd, kInstVfmaddpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmaddpd, kInstVfmaddpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmaddpd, kInstVfmaddpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmaddps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddps, kInstVfmaddps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddps, kInstVfmaddps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmaddps, kInstVfmaddps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmaddps, kInstVfmaddps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmaddps, kInstVfmaddps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmaddsd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddsd, kInstVfmaddsd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddsd, kInstVfmaddsd, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfmaddss, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddss, kInstVfmaddss, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddss, kInstVfmaddss, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfmaddsubpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddsubpd, kInstVfmaddsubpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddsubpd, kInstVfmaddsubpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmaddsubpd, kInstVfmaddsubpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmaddsubpd, kInstVfmaddsubpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmaddsubpd, kInstVfmaddsubpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmaddsubps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmaddsubps, kInstVfmaddsubps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmaddsubps, kInstVfmaddsubps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmaddsubps, kInstVfmaddsubps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmaddsubps, kInstVfmaddsubps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmaddsubps, kInstVfmaddsubps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmsubaddpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubaddpd, kInstVfmsubaddpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubaddpd, kInstVfmsubaddpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmsubaddpd, kInstVfmsubaddpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmsubaddpd, kInstVfmsubaddpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmsubaddpd, kInstVfmsubaddpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmsubaddps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubaddps, kInstVfmsubaddps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubaddps, kInstVfmsubaddps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmsubaddps, kInstVfmsubaddps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmsubaddps, kInstVfmsubaddps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmsubaddps, kInstVfmsubaddps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmsubpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubpd, kInstVfmsubpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubpd, kInstVfmsubpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmsubpd, kInstVfmsubpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmsubpd, kInstVfmsubpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmsubpd, kInstVfmsubpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmsubps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubps, kInstVfmsubps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubps, kInstVfmsubps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfmsubps, kInstVfmsubps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfmsubps, kInstVfmsubps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfmsubps, kInstVfmsubps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfmsubsd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubsd, kInstVfmsubsd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubsd, kInstVfmsubsd, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfmsubss, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfmsubss, kInstVfmsubss, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfmsubss, kInstVfmsubss, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfnmaddpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmaddpd, kInstVfnmaddpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmaddpd, kInstVfnmaddpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfnmaddpd, kInstVfnmaddpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfnmaddpd, kInstVfnmaddpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfnmaddpd, kInstVfnmaddpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfnmaddps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmaddps, kInstVfnmaddps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmaddps, kInstVfnmaddps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfnmaddps, kInstVfnmaddps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfnmaddps, kInstVfnmaddps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfnmaddps, kInstVfnmaddps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfnmaddsd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmaddsd, kInstVfnmaddsd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmaddsd, kInstVfnmaddsd, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfnmaddss, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmaddss, kInstVfnmaddss, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmaddss, kInstVfnmaddss, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfnmsubpd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmsubpd, kInstVfnmsubpd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmsubpd, kInstVfnmsubpd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfnmsubpd, kInstVfnmsubpd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfnmsubpd, kInstVfnmsubpd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfnmsubpd, kInstVfnmsubpd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfnmsubps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmsubps, kInstVfnmsubps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmsubps, kInstVfnmsubps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vfnmsubps, kInstVfnmsubps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vfnmsubps, kInstVfnmsubps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vfnmsubps, kInstVfnmsubps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVfnmsubsd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmsubsd, kInstVfnmsubsd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmsubsd, kInstVfnmsubsd, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfnmsubss, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vfnmsubss, kInstVfnmsubss, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vfnmsubss, kInstVfnmsubss, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVfrczpd, XmmReg, XmmReg) - INST_2x(vfrczpd, kInstVfrczpd, XmmReg, Mem) - INST_2x(vfrczpd, kInstVfrczpd, YmmReg, YmmReg) - INST_2x(vfrczpd, kInstVfrczpd, YmmReg, Mem) + 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, kInstVfrczps, XmmReg, XmmReg) - INST_2x(vfrczps, kInstVfrczps, XmmReg, Mem) - INST_2x(vfrczps, kInstVfrczps, YmmReg, YmmReg) - INST_2x(vfrczps, kInstVfrczps, YmmReg, Mem) + 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, kInstVfrczsd, XmmReg, XmmReg) - INST_2x(vfrczsd, kInstVfrczsd, XmmReg, Mem) + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86XmmReg) + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86Mem) - INST_2x(vfrczss, kInstVfrczss, XmmReg, XmmReg) - INST_2x(vfrczss, kInstVfrczss, XmmReg, Mem) + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86XmmReg) + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86Mem) - INST_4x(vpcmov, kInstVpcmov, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpcmov, kInstVpcmov, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpcmov, kInstVpcmov, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vpcmov, kInstVpcmov, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vpcmov, kInstVpcmov, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vpcmov, kInstVpcmov, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVpcomb, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomb, kInstVpcomb, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomd, kInstVpcomd, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomd, kInstVpcomd, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomq, kInstVpcomq, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomq, kInstVpcomq, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomw, kInstVpcomw, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomw, kInstVpcomw, XmmReg, XmmReg, Mem, Imm) + 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, kInstVpcomub, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomub, kInstVpcomub, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomud, kInstVpcomud, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomud, kInstVpcomud, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomuq, kInstVpcomuq, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomuq, kInstVpcomuq, XmmReg, XmmReg, Mem, Imm) - INST_4i(vpcomuw, kInstVpcomuw, XmmReg, XmmReg, XmmReg, Imm) - INST_4i(vpcomuw, kInstVpcomuw, XmmReg, XmmReg, Mem, 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, kInstVpermil2pd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpermil2pd, kInstVpermil2pd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpermil2pd, kInstVpermil2pd, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vpermil2pd, kInstVpermil2pd, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vpermil2pd, kInstVpermil2pd, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vpermil2pd, kInstVpermil2pd, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVpermil2ps, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpermil2ps, kInstVpermil2ps, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpermil2ps, kInstVpermil2ps, XmmReg, XmmReg, XmmReg, Mem) - INST_4x(vpermil2ps, kInstVpermil2ps, YmmReg, YmmReg, YmmReg, YmmReg) - INST_4x(vpermil2ps, kInstVpermil2ps, YmmReg, YmmReg, Mem, YmmReg) - INST_4x(vpermil2ps, kInstVpermil2ps, YmmReg, YmmReg, YmmReg, Mem) + 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, kInstVphaddbd, XmmReg, XmmReg) - INST_2x(vphaddbd, kInstVphaddbd, XmmReg, Mem) - INST_2x(vphaddbq, kInstVphaddbq, XmmReg, XmmReg) - INST_2x(vphaddbq, kInstVphaddbq, XmmReg, Mem) - INST_2x(vphaddbw, kInstVphaddbw, XmmReg, XmmReg) - INST_2x(vphaddbw, kInstVphaddbw, XmmReg, Mem) - INST_2x(vphadddq, kInstVphadddq, XmmReg, XmmReg) - INST_2x(vphadddq, kInstVphadddq, XmmReg, Mem) - INST_2x(vphaddwd, kInstVphaddwd, XmmReg, XmmReg) - INST_2x(vphaddwd, kInstVphaddwd, XmmReg, Mem) - INST_2x(vphaddwq, kInstVphaddwq, XmmReg, XmmReg) - INST_2x(vphaddwq, kInstVphaddwq, XmmReg, Mem) + 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, kInstVphaddubd, XmmReg, XmmReg) - INST_2x(vphaddubd, kInstVphaddubd, XmmReg, Mem) - INST_2x(vphaddubq, kInstVphaddubq, XmmReg, XmmReg) - INST_2x(vphaddubq, kInstVphaddubq, XmmReg, Mem) - INST_2x(vphaddubw, kInstVphaddubw, XmmReg, XmmReg) - INST_2x(vphaddubw, kInstVphaddubw, XmmReg, Mem) - INST_2x(vphaddudq, kInstVphaddudq, XmmReg, XmmReg) - INST_2x(vphaddudq, kInstVphaddudq, XmmReg, Mem) - INST_2x(vphadduwd, kInstVphadduwd, XmmReg, XmmReg) - INST_2x(vphadduwd, kInstVphadduwd, XmmReg, Mem) - INST_2x(vphadduwq, kInstVphadduwq, XmmReg, XmmReg) - INST_2x(vphadduwq, kInstVphadduwq, XmmReg, Mem) + 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, kInstVphsubbw, XmmReg, XmmReg) - INST_2x(vphsubbw, kInstVphsubbw, XmmReg, Mem) - INST_2x(vphsubdq, kInstVphsubdq, XmmReg, XmmReg) - INST_2x(vphsubdq, kInstVphsubdq, XmmReg, Mem) - INST_2x(vphsubwd, kInstVphsubwd, XmmReg, XmmReg) - INST_2x(vphsubwd, kInstVphsubwd, XmmReg, Mem) + 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, kInstVpmacsdd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacsdd, kInstVpmacsdd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacsdqh, kInstVpmacsdqh, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacsdqh, kInstVpmacsdqh, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacsdql, kInstVpmacsdql, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacsdql, kInstVpmacsdql, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacswd, kInstVpmacswd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacswd, kInstVpmacswd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacsww, kInstVpmacsww, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacsww, kInstVpmacsww, XmmReg, XmmReg, Mem, XmmReg) + 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, kInstVpmacssdd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacssdd, kInstVpmacssdd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacssdqh, kInstVpmacssdqh, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacssdqh, kInstVpmacssdqh, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacssdql, kInstVpmacssdql, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacssdql, kInstVpmacssdql, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacsswd, kInstVpmacsswd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacsswd, kInstVpmacsswd, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpmacssww, kInstVpmacssww, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmacssww, kInstVpmacssww, XmmReg, XmmReg, Mem, XmmReg) + 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, kInstVpmadcsswd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmadcsswd, kInstVpmadcsswd, XmmReg, XmmReg, Mem, XmmReg) + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) - INST_4x(vpmadcswd, kInstVpmadcswd, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpmadcswd, kInstVpmadcswd, XmmReg, XmmReg, Mem, XmmReg) + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) - INST_4x(vpperm, kInstVpperm, XmmReg, XmmReg, XmmReg, XmmReg) - INST_4x(vpperm, kInstVpperm, XmmReg, XmmReg, Mem, XmmReg) - INST_4x(vpperm, kInstVpperm, XmmReg, XmmReg, XmmReg, Mem) + 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, kInstVprotb, XmmReg, XmmReg, XmmReg) - INST_3x(vprotb, kInstVprotb, XmmReg, Mem, XmmReg) - INST_3x(vprotb, kInstVprotb, XmmReg, XmmReg, Mem) - INST_3i(vprotb, kInstVprotb, XmmReg, XmmReg, Imm) - INST_3i(vprotb, kInstVprotb, XmmReg, Mem, Imm) + 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, kInstVprotd, XmmReg, XmmReg, XmmReg) - INST_3x(vprotd, kInstVprotd, XmmReg, Mem, XmmReg) - INST_3x(vprotd, kInstVprotd, XmmReg, XmmReg, Mem) - INST_3i(vprotd, kInstVprotd, XmmReg, XmmReg, Imm) - INST_3i(vprotd, kInstVprotd, XmmReg, Mem, 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, kInstVprotq, XmmReg, XmmReg, XmmReg) - INST_3x(vprotq, kInstVprotq, XmmReg, Mem, XmmReg) - INST_3x(vprotq, kInstVprotq, XmmReg, XmmReg, Mem) - INST_3i(vprotq, kInstVprotq, XmmReg, XmmReg, Imm) - INST_3i(vprotq, kInstVprotq, XmmReg, Mem, 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, kInstVprotw, XmmReg, XmmReg, XmmReg) - INST_3x(vprotw, kInstVprotw, XmmReg, Mem, XmmReg) - INST_3x(vprotw, kInstVprotw, XmmReg, XmmReg, Mem) - INST_3i(vprotw, kInstVprotw, XmmReg, XmmReg, Imm) - INST_3i(vprotw, kInstVprotw, XmmReg, Mem, 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, kInstVpshab, XmmReg, XmmReg, XmmReg) - INST_3x(vpshab, kInstVpshab, XmmReg, Mem, XmmReg) - INST_3x(vpshab, kInstVpshab, XmmReg, XmmReg, Mem) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshad, kInstVpshad, XmmReg, XmmReg, XmmReg) - INST_3x(vpshad, kInstVpshad, XmmReg, Mem, XmmReg) - INST_3x(vpshad, kInstVpshad, XmmReg, XmmReg, Mem) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshaq, kInstVpshaq, XmmReg, XmmReg, XmmReg) - INST_3x(vpshaq, kInstVpshaq, XmmReg, Mem, XmmReg) - INST_3x(vpshaq, kInstVpshaq, XmmReg, XmmReg, Mem) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshaw, kInstVpshaw, XmmReg, XmmReg, XmmReg) - INST_3x(vpshaw, kInstVpshaw, XmmReg, Mem, XmmReg) - INST_3x(vpshaw, kInstVpshaw, XmmReg, XmmReg, Mem) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshlb, kInstVpshlb, XmmReg, XmmReg, XmmReg) - INST_3x(vpshlb, kInstVpshlb, XmmReg, Mem, XmmReg) - INST_3x(vpshlb, kInstVpshlb, XmmReg, XmmReg, Mem) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshld, kInstVpshld, XmmReg, XmmReg, XmmReg) - INST_3x(vpshld, kInstVpshld, XmmReg, Mem, XmmReg) - INST_3x(vpshld, kInstVpshld, XmmReg, XmmReg, Mem) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshlq, kInstVpshlq, XmmReg, XmmReg, XmmReg) - INST_3x(vpshlq, kInstVpshlq, XmmReg, Mem, XmmReg) - INST_3x(vpshlq, kInstVpshlq, XmmReg, XmmReg, Mem) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86Mem) - INST_3x(vpshlw, kInstVpshlw, XmmReg, XmmReg, XmmReg) - INST_3x(vpshlw, kInstVpshlw, XmmReg, Mem, XmmReg) - INST_3x(vpshlw, kInstVpshlw, XmmReg, XmmReg, Mem) + 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, kInstAndn, GpReg, GpReg, GpReg) + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(andn, kInstAndn, GpReg, GpReg, Mem) + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86Mem) //! Bit field extract (BMI). - INST_3x(bextr, kInstBextr, GpReg, GpReg, GpReg) + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(bextr, kInstBextr, GpReg, Mem, GpReg) + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86Mem, X86GpReg) //! Extract lower set isolated bit (BMI). - INST_2x(blsi, kInstBlsi, GpReg, GpReg) + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86GpReg) //! \overload - INST_2x(blsi, kInstBlsi, GpReg, Mem) + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86Mem) //! Get mask up to lowest set bit (BMI). - INST_2x(blsmsk, kInstBlsmsk, GpReg, GpReg) + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86GpReg) //! \overload - INST_2x(blsmsk, kInstBlsmsk, GpReg, Mem) + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86Mem) //! Reset lowest set bit (BMI). - INST_2x(blsr, kInstBlsr, GpReg, GpReg) + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86GpReg) //! \overload - INST_2x(blsr, kInstBlsr, GpReg, Mem) + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86Mem) //! Count the number of trailing zero bits (BMI). - INST_2x(tzcnt, kInstTzcnt, GpReg, GpReg) + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86GpReg) //! \overload - INST_2x(tzcnt, kInstTzcnt, GpReg, Mem) + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86Mem) // -------------------------------------------------------------------------- // [LZCNT] // -------------------------------------------------------------------------- //! Count the number of leading zero bits (LZCNT). - INST_2x(lzcnt, kInstLzcnt, GpReg, GpReg) + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg) //! \overload - INST_2x(lzcnt, kInstLzcnt, GpReg, Mem) + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem) // -------------------------------------------------------------------------- // [BMI2] // -------------------------------------------------------------------------- //! Zero high bits starting with specified bit position (BMI2). - INST_3x(bzhi, kInstBzhi, GpReg, GpReg, GpReg) + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(bzhi, kInstBzhi, GpReg, Mem, GpReg) + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86Mem, X86GpReg) //! Unsigned multiply without affecting flags (BMI2). - INST_3x(mulx, kInstMulx, GpReg, GpReg, GpReg) + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(mulx, kInstMulx, GpReg, GpReg, Mem) + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86Mem) //! Parallel bits deposit (BMI2). - INST_3x(pdep, kInstPdep, GpReg, GpReg, GpReg) + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(pdep, kInstPdep, GpReg, GpReg, Mem) + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86Mem) //! Parallel bits extract (BMI2). - INST_3x(pext, kInstPext, GpReg, GpReg, GpReg) + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(pext, kInstPext, GpReg, GpReg, Mem) + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86Mem) //! Rotate right without affecting flags (BMI2). - INST_3i(rorx, kInstRorx, GpReg, GpReg, Imm) + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86GpReg, Imm) //! \overload - INST_3i(rorx, kInstRorx, GpReg, Mem, Imm) + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86Mem, Imm) //! Shift arithmetic right without affecting flags (BMI2). - INST_3x(sarx, kInstSarx, GpReg, GpReg, GpReg) + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(sarx, kInstSarx, GpReg, Mem, GpReg) + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86Mem, X86GpReg) //! Shift logical left without affecting flags (BMI2). - INST_3x(shlx, kInstShlx, GpReg, GpReg, GpReg) + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(shlx, kInstShlx, GpReg, Mem, GpReg) + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86Mem, X86GpReg) //! Shift logical right without affecting flags (BMI2). - INST_3x(shrx, kInstShrx, GpReg, GpReg, GpReg) + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86GpReg, X86GpReg) //! \overload - INST_3x(shrx, kInstShrx, GpReg, Mem, GpReg) + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86Mem, X86GpReg) // -------------------------------------------------------------------------- // [RDRAND] @@ -6377,219 +6461,38 @@ struct X86X64Assembler : public BaseAssembler { //! Please do not use this instruction in cryptographic software. The result //! doesn't necessarily have to be random which may cause a major security //! issue in the software that relies on it. - INST_1x(rdrand, kInstRdrand, GpReg) + INST_1x(rdrand, kX86InstIdRdrand, X86GpReg) // -------------------------------------------------------------------------- // [F16C] // -------------------------------------------------------------------------- //! Convert packed HP-FP to SP-FP. - INST_2x(vcvtph2ps, kInstVcvtph2ps, XmmReg, XmmReg) + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86XmmReg) //! \overload - INST_2x(vcvtph2ps, kInstVcvtph2ps, XmmReg, Mem) + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86Mem) //! \overload - INST_2x(vcvtph2ps, kInstVcvtph2ps, YmmReg, XmmReg) + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86XmmReg) //! \overload - INST_2x(vcvtph2ps, kInstVcvtph2ps, YmmReg, Mem) + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86Mem) //! Convert packed SP-FP to HP-FP. - INST_3i(vcvtps2ph, kInstVcvtps2ph, XmmReg, XmmReg, Imm) + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86XmmReg, Imm) //! \overload - INST_3i(vcvtps2ph, kInstVcvtps2ph, Mem, XmmReg, Imm) + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86XmmReg, Imm) //! \overload - INST_3i(vcvtps2ph, kInstVcvtps2ph, XmmReg, YmmReg, Imm) + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86YmmReg, Imm) //! \overload - INST_3i(vcvtps2ph, kInstVcvtps2ph, Mem, YmmReg, Imm) -}; - -//! \} - -} // x86x64 namespace -} // asmjit namespace - -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -//! \addtogroup asmjit_x86x64_general -//! \{ - -//! X86-only assembler. -struct Assembler : public X86X64Assembler { - ASMJIT_NO_COPY(Assembler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_API Assembler(Runtime* runtime); - ASMJIT_API virtual ~Assembler(); - - // -------------------------------------------------------------------------- - // [Reloc] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual size_t _relocCode(void* dst, Ptr base) const; - - // -------------------------------------------------------------------------- - // [Emit] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); - - // ------------------------------------------------------------------------- - // [Options] - // ------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(Assembler) - - // -------------------------------------------------------------------------- - // [X86-Only Instructions] - // -------------------------------------------------------------------------- - - //! Decimal adjust AL after addition (32-bit). - INST_0x(daa, kInstDaa) - //! Decimal adjust AL after subtraction (32-bit). - INST_0x(das, kInstDas) - - //! Pop all Gp registers - EDI|ESI|EBP|Ign|EBX|EDX|ECX|EAX. - INST_0x(popa, kInstPopa) - //! Push all Gp registers - EAX|ECX|EDX|EBX|ESP|EBP|ESI|EDI. - INST_0x(pusha, kInstPusha) -}; - -//! \} - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -//! \addtogroup asmjit_x86x64_general -//! \{ - -//! X64-only assembler. -struct Assembler : public X86X64Assembler { - ASMJIT_NO_COPY(Assembler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_API Assembler(Runtime* runtime); - ASMJIT_API virtual ~Assembler(); - - // -------------------------------------------------------------------------- - // [Reloc] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual size_t _relocCode(void* dst, Ptr base) const; - - // -------------------------------------------------------------------------- - // [Emit] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); - - // -------------------------------------------------------------------------- - // [Options] - // -------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(Assembler) - - // -------------------------------------------------------------------------- - // [X64-Only Instructions] - // -------------------------------------------------------------------------- - - //! Convert DWORD to QWORD (RAX <- Sign Extend EAX). - INST_0x(cdqe, kInstCdqe) - //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX). - INST_0x(cqo, kInstCqo) - - //! Compares the 128-bit value in RDX:RAX with the memory operand (64-bit). - INST_1x(cmpxchg16b, kInstCmpxchg16b, Mem) - - //! Move DWORD to QWORD with sign-extension. - INST_2x(movsxd, kInstMovsxd, GpReg, GpReg) - //! \overload - INST_2x(movsxd, kInstMovsxd, GpReg, Mem) - - //! Load Ecx/Rcx QWORDs from ds:[Esi/Rri] to Rax. - INST_0x(rep_lodsq, kInstRepLodsq) - //! Move Ecx/Rcx QWORDs from ds:[Esi/Rsi] to es:[Edi/Rdi]. - INST_0x(rep_movsq, kInstRepMovsq) - //! Fill Ecx/Rcx QWORDs at es:[Edi/Rdi] with Rax. - INST_0x(rep_stosq, kInstRepStosq) - - //! Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repe_cmpsq, kInstRepeCmpsq) - //! Find non-rax QWORD starting at ES:[EDI/RDI]. - INST_0x(repe_scasq, kInstRepeScasq) - - //! Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_0x(repne_cmpsq, kInstRepneCmpsq) - //! Find RAX, starting at ES:[EDI/RDI]. - INST_0x(repne_scasq, kInstRepneScasq) - - using X86X64Assembler::movq; - - //! \overload - INST_2x(movq, kInstMovq, GpReg, MmReg) - //! \overload - INST_2x(movq, kInstMovq, MmReg, GpReg) - - //! \overload - INST_2x(movq, kInstMovq, GpReg, XmmReg) - //! \overload - INST_2x(movq, kInstMovq, XmmReg, GpReg) - - // -------------------------------------------------------------------------- - // [AVX] - // -------------------------------------------------------------------------- - - INST_2x(vmovq, kInstVmovq, XmmReg, GpReg) - INST_2x(vmovq, kInstVmovq, GpReg, XmmReg) - - INST_3i(vpextrq, kInstVpextrq, GpReg, XmmReg, Imm) - INST_3i(vpextrq, kInstVpextrq, Mem, XmmReg, Imm) - - INST_4i(vpinsrq, kInstVpinsrq, XmmReg, XmmReg, GpReg, Imm) - INST_4i(vpinsrq, kInstVpinsrq, XmmReg, XmmReg, Mem, Imm) + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86YmmReg, Imm) // -------------------------------------------------------------------------- // [FSGSBASE] // -------------------------------------------------------------------------- - INST_1x(rdfsbase, kInstRdfsbase, GpReg) - INST_1x(rdgsbase, kInstRdgsbase, GpReg) - INST_1x(wrfsbase, kInstWrfsbase, GpReg) - INST_1x(wrgsbase, kInstWrgsbase, GpReg) -}; - -//! \} - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - -// ============================================================================ -// [CodeGen-End] -// ============================================================================ + INST_1x(rdfsbase, kX86InstIdRdfsbase, X86GpReg) + INST_1x(rdgsbase, kX86InstIdRdgsbase, X86GpReg) + INST_1x(wrfsbase, kX86InstIdWrfsbase, X86GpReg) + INST_1x(wrgsbase, kX86InstIdWrgsbase, X86GpReg) #undef INST_0x @@ -6610,6 +6513,11 @@ struct Assembler : public X86X64Assembler { #undef INST_4x #undef INST_4x_ #undef INST_4i +}; + +//! \} + +} // asmjit namespace // [Api-End] #include "../apiend.h" diff --git a/src/asmjit/x86/x86compiler.cpp b/src/asmjit/x86/x86compiler.cpp index c6a1ca4..a078d06 100644 --- a/src/asmjit/x86/x86compiler.cpp +++ b/src/asmjit/x86/x86compiler.cpp @@ -22,17 +22,16 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ // [Debug] // ============================================================================ #if !defined(ASMJIT_DEBUG) -#define ASMJIT_DETECT_UNINITIALIZED(op) \ +#define ASMJIT_ASSERT_UNINITIALIZED(op) \ do {} while(0) #else -#define ASMJIT_DETECT_UNINITIALIZED(op) \ +#define ASMJIT_ASSERT_UNINITIALIZED(op) \ do { \ if (op.isVar() || op.isLabel()) { \ ASMJIT_ASSERT(op.getId() != kInvalidValue); \ @@ -41,18 +40,618 @@ namespace x86x64 { #endif // ============================================================================ -// [asmjit::x86x64::X86X64CallNode - Prototype] +// [asmjit::X86VarInfo] // ============================================================================ -Error X86X64CallNode::setPrototype(uint32_t conv, const FuncPrototype& p) { +#define C(_Class_) kX86RegClass##_Class_ +#define D(_Desc_) kVarFlag##_Desc_ + +const X86VarInfo _x86VarInfo[] = { + /* 00: kVarTypeInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, + /* 01: kVarTypeUInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, + /* 02: kVarTypeInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, + /* 03: kVarTypeUInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, + /* 04: kVarTypeInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, + /* 05: kVarTypeUInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, + /* 06: kVarTypeInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, + /* 07: kVarTypeUInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, + /* 08: kVarTypeIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. + /* 09: kVarTypeUIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. + /* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" }, + /* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" }, + /* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" }, + /* 13: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" }, + /* 14: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, + /* 15: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, + /* 16: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, + /* 17: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, + /* 18: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" }, + /* 19: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, + /* 20: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" } +}; + +#undef D +#undef C + +#if defined(ASMJIT_BUILD_X86) +const uint8_t _x86VarMapping[kX86VarTypeCount] = { + /* 00: kVarTypeInt8 */ kVarTypeInt8, + /* 01: kVarTypeUInt8 */ kVarTypeUInt8, + /* 02: kVarTypeInt16 */ kVarTypeInt16, + /* 03: kVarTypeUInt16 */ kVarTypeUInt16, + /* 04: kVarTypeInt32 */ kVarTypeInt32, + /* 05: kVarTypeUInt32 */ kVarTypeUInt32, + /* 06: kVarTypeInt64 */ kInvalidVar, // Invalid in 32-bit mode. + /* 07: kVarTypeUInt64 */ kInvalidVar, // Invalid in 32-bit mode. + /* 08: kVarTypeIntPtr */ kVarTypeInt32, // Remapped to Int32. + /* 09: kVarTypeUIntPtr */ kVarTypeUInt32, // Remapped to UInt32. + /* 10: kVarTypeFp32 */ kVarTypeFp32, + /* 11: kVarTypeFp64 */ kVarTypeFp64, + /* 12: kX86VarTypeMm */ kX86VarTypeMm, + /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd +}; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) +const uint8_t _x64VarMapping[kX86VarTypeCount] = { + /* 00: kVarTypeInt8 */ kVarTypeInt8, + /* 01: kVarTypeUInt8 */ kVarTypeUInt8, + /* 02: kVarTypeInt16 */ kVarTypeInt16, + /* 03: kVarTypeUInt16 */ kVarTypeUInt16, + /* 04: kVarTypeInt32 */ kVarTypeInt32, + /* 05: kVarTypeUInt32 */ kVarTypeUInt32, + /* 06: kVarTypeInt64 */ kVarTypeInt64, + /* 07: kVarTypeUInt64 */ kVarTypeUInt64, + /* 08: kVarTypeIntPtr */ kVarTypeInt64, // Remapped to Int64. + /* 09: kVarTypeUIntPtr */ kVarTypeUInt64, // Remapped to UInt64. + /* 10: kVarTypeFp32 */ kVarTypeFp32, + /* 11: kVarTypeFp64 */ kVarTypeFp64, + /* 12: kX86VarTypeMm */ kX86VarTypeMm, + /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd +}; +#endif // ASMJIT_BUILD_X64 + + +// ============================================================================ +// [asmjit::X86FuncDecl - Helpers] +// ============================================================================ + +static ASMJIT_INLINE bool x86ArgIsInt(uint32_t aType) { + ASMJIT_ASSERT(aType < kX86VarTypeCount); + return IntUtil::inInterval(aType, _kVarTypeIntStart, _kVarTypeIntEnd); +} + +static ASMJIT_INLINE bool x86ArgIsFp(uint32_t aType) { + ASMJIT_ASSERT(aType < kX86VarTypeCount); + return IntUtil::inInterval(aType, _kVarTypeFpStart, _kVarTypeFpEnd); +} + +static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) { + if (aType == kVarTypeFp32) + return kX86VarTypeXmmSs; + if (aType == kVarTypeFp64) + return kX86VarTypeXmmSd; + return aType; +} + +//! Get an architecture from calling convention. +//! +//! Returns `kArchX86` or `kArchX64` depending on `conv`. +static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) { + return IntUtil::inInterval(conv, kX86FuncConvW64, kX86FuncConvU64) ? kArchX64 : kArchX86; +} + +// ============================================================================ +// [asmjit::X86FuncDecl - SetPrototype] +// ============================================================================ + +#define R(_Index_) kX86RegIndex##_Index_ +static uint32_t X86FuncDecl_initConv(X86FuncDecl* self, uint32_t arch, uint32_t conv) { + // Setup defaults. + self->_argStackSize = 0; + self->_redZoneSize = 0; + self->_spillZoneSize = 0; + + self->_convention = static_cast(conv); + self->_calleePopsStack = false; + self->_direction = kFuncDirRtl; + + self->_passed.reset(); + self->_preserved.reset(); + + ::memset(self->_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderGp)); + ::memset(self->_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)); + + // -------------------------------------------------------------------------- + // [X86 Support] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di))); + + switch (conv) { + case kX86FuncConvCDecl: + break; + + case kX86FuncConvStdCall: + self->_calleePopsStack = true; + break; + + case kX86FuncConvMsThisCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx))); + self->_passedOrderGp[0] = R(Cx); + break; + + case kX86FuncConvMsFastCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Cx))); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvBorlandFastCall: + self->_calleePopsStack = true; + self->_direction = kFuncDirLtr; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = R(Cx); + break; + + case kX86FuncConvGccFastCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx))); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvGccRegParm1: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax))); + self->_passedOrderGp[0] = R(Ax); + break; + + case kX86FuncConvGccRegParm2: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvGccRegParm3: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = R(Cx); + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + + // -------------------------------------------------------------------------- + // [X64 Support] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_BUILD_X64) + switch (conv) { + case kX86FuncConvW64: + self->_spillZoneSize = 32; + + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx), 8, 9)); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = 8; + self->_passedOrderGp[3] = 9; + + self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3)); + self->_passedOrderXmm[0] = 0; + self->_passedOrderXmm[1] = 1; + self->_passedOrderXmm[2] = 2; + self->_passedOrderXmm[3] = 3; + + self->_preserved.set(kX86RegClassGp , IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), 12, 13, 14, 15)); + self->_preserved.set(kX86RegClassXyz, IntUtil::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); + break; + + case kX86FuncConvU64: + self->_redZoneSize = 128; + + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), 8, 9)); + self->_passedOrderGp[0] = R(Di); + self->_passedOrderGp[1] = R(Si); + self->_passedOrderGp[2] = R(Dx); + self->_passedOrderGp[3] = R(Cx); + self->_passedOrderGp[4] = 8; + self->_passedOrderGp[5] = 9; + + self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3, 4, 5, 6, 7)); + self->_passedOrderXmm[0] = 0; + self->_passedOrderXmm[1] = 1; + self->_passedOrderXmm[2] = 2; + self->_passedOrderXmm[3] = 3; + self->_passedOrderXmm[4] = 4; + self->_passedOrderXmm[5] = 5; + self->_passedOrderXmm[6] = 6; + self->_passedOrderXmm[7] = 7; + + self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), 12, 13, 14, 15)); + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } +#endif // ASMJIT_BUILD_X64 + + return kErrorOk; +} +#undef R + +static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, + uint32_t ret, const uint32_t* argList, uint32_t argCount) { + + ASMJIT_ASSERT(argCount <= kFuncArgCount); + + uint32_t conv = self->_convention; + uint32_t regSize = (arch == kArchX86) ? 4 : 8; + + int32_t i = 0; + int32_t gpPos = 0; + int32_t xmmPos = 0; + int32_t stackOffset = 0; + + const uint8_t* varMapping; + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) + varMapping = _x86VarMapping; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) + varMapping = _x64VarMapping; +#endif // ASMJIT_BUILD_X64 + + self->_argCount = static_cast(argCount); + self->_retCount = 0; + + for (i = 0; i < static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + arg._varType = static_cast(argList[i]); + arg._regIndex = kInvalidReg; + arg._stackOffset = kFuncStackInvalid; + } + + for (; i < kFuncArgCount; i++) { + self->_argList[i].reset(); + } + + self->_retList[0].reset(); + self->_retList[1].reset(); + self->_argStackSize = 0; + self->_used.reset(); + + if (ret != kInvalidVar) { + ret = varMapping[ret]; + switch (ret) { + case kVarTypeInt64: + case kVarTypeUInt64: + // 64-bit value is returned in EDX:EAX on x86. +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + self->_retCount = 2; + self->_retList[0]._varType = kVarTypeUInt32; + self->_retList[0]._regIndex = kX86RegIndexAx; + self->_retList[1]._varType = static_cast(ret - 2); + self->_retList[1]._regIndex = kX86RegIndexDx; + } +#endif // ASMJIT_BUILD_X86 + // ... Fall through ... + + case kVarTypeInt8: + case kVarTypeUInt8: + case kVarTypeInt16: + case kVarTypeUInt16: + case kVarTypeInt32: + case kVarTypeUInt32: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = kX86RegIndexAx; + break; + + case kX86VarTypeMm: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = 0; + break; + + case kVarTypeFp32: + self->_retCount = 1; + if (arch == kArchX86) { + self->_retList[0]._varType = kVarTypeFp32; + self->_retList[0]._regIndex = 0; + } + else { + self->_retList[0]._varType = kX86VarTypeXmmSs; + self->_retList[0]._regIndex = 0; + } + break; + + case kVarTypeFp64: + self->_retCount = 1; + if (arch == kArchX86) { + self->_retList[0]._varType = kVarTypeFp64; + self->_retList[0]._regIndex = 0; + } + else { + self->_retList[0]._varType = kX86VarTypeXmmSd; + self->_retList[0]._regIndex = 0; + break; + } + break; + + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = 0; + break; + } + } + + if (self->_argCount == 0) + return kErrorOk; + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + // Register arguments (Integer), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) + continue; + + if (self->_passedOrderGp[gpPos] == kInvalidReg) + continue; + + arg._regIndex = self->_passedOrderGp[gpPos++]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + } + + // Stack arguments. + int32_t iStart = static_cast(argCount - 1); + int32_t iEnd = -1; + int32_t iStep = -1; + + if (self->_direction == kFuncDirLtr) { + iStart = 0; + iEnd = static_cast(argCount); + iStep = 1; + } + + for (i = iStart; i != iEnd; i += iStep) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 4; + arg._stackOffset = static_cast(stackOffset); + } + else if (x86ArgIsFp(varType)) { + int32_t size = static_cast(_x86VarInfo[varType].getSize()); + stackOffset -= size; + arg._stackOffset = static_cast(stackOffset); + } + } + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + if (conv == kX86FuncConvW64) { + int32_t argMax = IntUtil::iMin(argCount, 4); + + // Register arguments (Gp/Xmm), always left-to-right. + for (i = 0; i != argMax; i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) { + arg._regIndex = self->_passedOrderGp[i]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + continue; + } + + if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { + arg._varType = static_cast(x86ArgTypeToXmmType(varType)); + arg._regIndex = self->_passedOrderXmm[i]; + self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + } + } + + // Stack arguments (always right-to-left). + for (i = argCount - 1; i != -1; i--) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 8; // Always 8 bytes. + arg._stackOffset = stackOffset; + } + else if (x86ArgIsFp(varType)) { + stackOffset -= 8; // Always 8 bytes (float/double). + arg._stackOffset = stackOffset; + } + } + + // 32 bytes shadow space (X64W calling convention specific). + stackOffset -= 4 * 8; + } + else { + // Register arguments (Gp), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) + continue; + + if (self->_passedOrderGp[gpPos] == kInvalidReg) + continue; + + arg._regIndex = self->_passedOrderGp[gpPos++]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + } + + // Register arguments (Xmm), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (x86ArgIsFp(varType)) { + arg._varType = static_cast(x86ArgTypeToXmmType(varType)); + arg._regIndex = self->_passedOrderXmm[xmmPos++]; + self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + } + } + + // Stack arguments. + for (i = argCount - 1; i != -1; i--) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 8; + arg._stackOffset = static_cast(stackOffset); + } + else if (x86ArgIsFp(varType)) { + int32_t size = static_cast(_x86VarInfo[varType].getSize()); + + stackOffset -= size; + arg._stackOffset = static_cast(stackOffset); + } + } + } + } +#endif // ASMJIT_BUILD_X64 + + // Modify the stack offset, thus in result all parameters would have positive + // non-zero stack offset. + for (i = 0; i < static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + if (!arg.hasRegIndex()) { + arg._stackOffset += static_cast(static_cast(regSize) - stackOffset); + } + } + + self->_argStackSize = static_cast(-stackOffset); + return kErrorOk; +} + +Error X86FuncDecl::setPrototype(uint32_t conv, const FuncPrototype& p) { + if (conv == kFuncConvNone || conv >= _kX86FuncConvCount) + return kErrorInvalidArgument; + + if (p.getArgCount() > kFuncArgCount) + return kErrorInvalidArgument; + + // Validate that the required convention is supported by the current asmjit + // configuration, if only one target is compiled. + uint32_t arch = x86GetArchFromCConv(conv); +#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) + return kErrorInvalidState; +#endif // ASMJIT_BUILD_X86 && !ASMJIT_BUILD_X64 + +#if !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) + if (arch == kArchX86) + return kErrorInvalidState; +#endif // !ASMJIT_BUILD_X86 && ASMJIT_BUILD_X64 + + ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initConv(this, arch, conv)); + ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initFunc(this, arch, p.getRet(), p.getArgList(), p.getArgCount())); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86FuncDecl - Reset] +// ============================================================================ + +void X86FuncDecl::reset() { + uint32_t i; + + _convention = kFuncConvNone; + _calleePopsStack = false; + _direction = kFuncDirRtl; + _reserved0 = 0; + + _argCount = 0; + _retCount = 0; + + _argStackSize = 0; + _redZoneSize = 0; + _spillZoneSize = 0; + + for (i = 0; i < ASMJIT_ARRAY_SIZE(_argList); i++) { + _argList[i].reset(); + } + + _retList[0].reset(); + _retList[1].reset(); + + _used.reset(); + _passed.reset(); + _preserved.reset(); + + ::memset(_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderGp)); + ::memset(_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderXmm)); +} + +// ============================================================================ +// [asmjit::X86CallNode - Prototype] +// ============================================================================ + +Error X86CallNode::setPrototype(uint32_t conv, const FuncPrototype& p) { return _x86Decl.setPrototype(conv, p); } // ============================================================================ -// [asmjit::x86x64::X86X64CallNode - Arg / Ret] +// [asmjit::X86CallNode - Arg / Ret] // ============================================================================ -bool X86X64CallNode::_setArg(uint32_t i, const Operand& op) { +bool X86CallNode::_setArg(uint32_t i, const Operand& op) { if ((i & ~kFuncArgHi) >= _x86Decl.getArgCount()) return false; @@ -60,7 +659,7 @@ bool X86X64CallNode::_setArg(uint32_t i, const Operand& op) { return true; } -bool X86X64CallNode::_setRet(uint32_t i, const Operand& op) { +bool X86CallNode::_setRet(uint32_t i, const Operand& op) { if (i >= 2) return false; @@ -69,10 +668,10 @@ bool X86X64CallNode::_setRet(uint32_t i, const Operand& op) { } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Helpers (Private)] +// [asmjit::X86Compiler - Helpers (Private)] // ============================================================================ -static Error X86X64Compiler_emitConstPool(X86X64Compiler* self, +static Error X86Compiler_emitConstPool(X86Compiler* self, Label& label, ConstPool& pool) { if (label.getId() == kInvalidValue) @@ -93,27 +692,99 @@ static Error X86X64Compiler_emitConstPool(X86X64Compiler* self, } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Construction / Destruction] +// [asmjit::X86Compiler - Construction / Destruction] // ============================================================================ -X86X64Compiler::X86X64Compiler(Runtime* runtime) : BaseCompiler(runtime) {} -X86X64Compiler::~X86X64Compiler() {} +X86Compiler::X86Compiler(Runtime* runtime, uint32_t arch) : + Compiler(runtime), + zax(NoInit), + zcx(NoInit), + zdx(NoInit), + zbx(NoInit), + zsp(NoInit), + zbp(NoInit), + zsi(NoInit), + zdi(NoInit) { + + setArch(arch); +} + +X86Compiler::~X86Compiler() {} // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Inst] +// [asmjit::X86Compiler - Arch] +// ============================================================================ + +Error X86Compiler::setArch(uint32_t arch) { +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + _arch = kArchX86; + _regSize = 4; + + _regCount.reset(); + _regCount._gp = 8; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 8; + + zax = x86::eax; + zcx = x86::ecx; + zdx = x86::edx; + zbx = x86::ebx; + zsp = x86::esp; + zbp = x86::ebp; + zsi = x86::esi; + zdi = x86::edi; + + _targetVarMapping = _x86VarMapping; + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + _arch = kArchX64; + _regSize = 8; + + _regCount.reset(); + _regCount._gp = 16; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 16; + + zax = x86::rax; + zcx = x86::rcx; + zdx = x86::rdx; + zbx = x86::rbx; + zsp = x86::rsp; + zbp = x86::rbp; + zsi = x86::rsi; + zdi = x86::rdi; + + _targetVarMapping = _x64VarMapping; + return kErrorOk; + } +#endif // ASMJIT_BUILD_X64 + + ASMJIT_ASSERT(!"Reached"); + return kErrorInvalidArgument; +} + +// ============================================================================ +// [asmjit::X86Compiler - Inst] // ============================================================================ //! Get compiler instruction item size without operands assigned. -static ASMJIT_INLINE size_t X86X64Compiler_getInstSize(uint32_t code) { - return (IntUtil::inInterval(code, _kInstJbegin, _kInstJend)) ? sizeof(JumpNode) : sizeof(InstNode); +static ASMJIT_INLINE size_t X86Compiler_getInstSize(uint32_t code) { + return IntUtil::inInterval(code, _kX86InstIdJbegin, _kX86InstIdJend) ? sizeof(JumpNode) : sizeof(InstNode); } -static InstNode* X86X64Compiler_newInst(X86X64Compiler* self, void* p, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) { - if (IntUtil::inInterval(code, _kInstJbegin, _kInstJend)) { +static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) { + if (IntUtil::inInterval(code, _kX86InstIdJbegin, _kX86InstIdJend)) { JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount); TargetNode* jTarget = self->getTargetById(opList[0].getId()); - node->addFlags(code == kInstJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); + node->addFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); node->_target = jTarget; node->_jumpNext = static_cast(jTarget->_from); @@ -121,7 +792,7 @@ static InstNode* X86X64Compiler_newInst(X86X64Compiler* self, void* p, uint32_t jTarget->addNumRefs(); // The 'jmp' is always taken, conditional jump can contain hint, we detect it. - if (code == kInstJmp) + if (code == kX86InstIdJmp) node->addFlags(kNodeFlagIsTaken); else if (options & kInstOptionTaken) node->addFlags(kNodeFlagIsTaken); @@ -136,22 +807,22 @@ static InstNode* X86X64Compiler_newInst(X86X64Compiler* self, void* p, uint32_t } } -InstNode* X86X64Compiler::newInst(uint32_t code) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size)); if (inst == NULL) goto _NoMemory; - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), NULL, 0); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), NULL, 0); _NoMemory: setError(kErrorNoHeapMemory); return NULL; } -InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size + 1 * sizeof(Operand))); if (inst == NULL) @@ -160,8 +831,8 @@ InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0) { { Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); opList[0] = o0; - ASMJIT_DETECT_UNINITIALIZED(o0); - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), opList, 1); + ASMJIT_ASSERT_UNINITIALIZED(o0); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), opList, 1); } _NoMemory: @@ -169,8 +840,8 @@ _NoMemory: return NULL; } -InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size + 2 * sizeof(Operand))); if (inst == NULL) @@ -180,9 +851,9 @@ InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operan Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); opList[0] = o0; opList[1] = o1; - ASMJIT_DETECT_UNINITIALIZED(o0); - ASMJIT_DETECT_UNINITIALIZED(o1); - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), opList, 2); + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), opList, 2); } _NoMemory: @@ -190,8 +861,8 @@ _NoMemory: return NULL; } -InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size + 3 * sizeof(Operand))); if (inst == NULL) @@ -202,10 +873,10 @@ InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operan opList[0] = o0; opList[1] = o1; opList[2] = o2; - ASMJIT_DETECT_UNINITIALIZED(o0); - ASMJIT_DETECT_UNINITIALIZED(o1); - ASMJIT_DETECT_UNINITIALIZED(o2); - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), opList, 3); + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), opList, 3); } _NoMemory: @@ -213,8 +884,8 @@ _NoMemory: return NULL; } -InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size + 4 * sizeof(Operand))); if (inst == NULL) @@ -226,11 +897,11 @@ InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operan opList[1] = o1; opList[2] = o2; opList[3] = o3; - ASMJIT_DETECT_UNINITIALIZED(o0); - ASMJIT_DETECT_UNINITIALIZED(o1); - ASMJIT_DETECT_UNINITIALIZED(o2); - ASMJIT_DETECT_UNINITIALIZED(o3); - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), opList, 4); + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + ASMJIT_ASSERT_UNINITIALIZED(o3); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), opList, 4); } _NoMemory: @@ -238,8 +909,8 @@ _NoMemory: return NULL; } -InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { - size_t size = X86X64Compiler_getInstSize(code); +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { + size_t size = X86Compiler_getInstSize(code); InstNode* inst = static_cast(_baseZone.alloc(size + 5 * sizeof(Operand))); if (inst == NULL) @@ -252,12 +923,12 @@ InstNode* X86X64Compiler::newInst(uint32_t code, const Operand& o0, const Operan opList[2] = o2; opList[3] = o3; opList[4] = o4; - ASMJIT_DETECT_UNINITIALIZED(o0); - ASMJIT_DETECT_UNINITIALIZED(o1); - ASMJIT_DETECT_UNINITIALIZED(o2); - ASMJIT_DETECT_UNINITIALIZED(o3); - ASMJIT_DETECT_UNINITIALIZED(o4); - return X86X64Compiler_newInst(this, inst, code, getOptionsAndClear(), opList, 5); + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + ASMJIT_ASSERT_UNINITIALIZED(o3); + ASMJIT_ASSERT_UNINITIALIZED(o4); + return X86Compiler_newInst(this, inst, code, getOptionsAndReset(), opList, 5); } _NoMemory: @@ -265,49 +936,49 @@ _NoMemory: return NULL; } -InstNode* X86X64Compiler::emit(uint32_t code) { +InstNode* X86Compiler::emit(uint32_t code) { InstNode* node = newInst(code); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0) { InstNode* node = newInst(code, o0); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1){ +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1){ InstNode* node = newInst(code, o0, o1); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { InstNode* node = newInst(code, o0, o1, o2); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3){ +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3){ InstNode* node = newInst(code, o0, o1, o2, o3); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { InstNode* node = newInst(code, o0, o1, o2, o3, o4); if (node == NULL) return NULL; return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, int o0_) { +InstNode* X86Compiler::emit(uint32_t code, int o0_) { Imm o0(o0_); InstNode* node = newInst(code, o0); if (node == NULL) @@ -315,7 +986,7 @@ InstNode* X86X64Compiler::emit(uint32_t code, int o0_) { return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, uint64_t o0_) { +InstNode* X86Compiler::emit(uint32_t code, uint64_t o0_) { Imm o0(o0_); InstNode* node = newInst(code, o0); if (node == NULL) @@ -323,7 +994,7 @@ InstNode* X86X64Compiler::emit(uint32_t code, uint64_t o0_) { return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, int o1_) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, int o1_) { Imm o1(o1_); InstNode* node = newInst(code, o0, o1); if (node == NULL) @@ -331,7 +1002,7 @@ InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, int o1_) { return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, uint64_t o1_) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, uint64_t o1_) { Imm o1(o1_); InstNode* node = newInst(code, o0, o1); if (node == NULL) @@ -339,7 +1010,7 @@ InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, uint64_t o1_) { return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2_) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2_) { Imm o2(o2_); InstNode* node = newInst(code, o0, o1, o2); if (node == NULL) @@ -347,7 +1018,7 @@ InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& return static_cast(addNode(node)); } -InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2_) { +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2_) { Imm o2(o2_); InstNode* node = newInst(code, o0, o1, o2); if (node == NULL) @@ -356,11 +1027,11 @@ InstNode* X86X64Compiler::emit(uint32_t code, const Operand& o0, const Operand& } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Func] +// [asmjit::X86Compiler - Func] // ============================================================================ -X86X64FuncNode* X86X64Compiler::newFunc(uint32_t conv, const FuncPrototype& p) { - X86X64FuncNode* func = newNode(); +X86FuncNode* X86Compiler::newFunc(uint32_t conv, const FuncPrototype& p) { + X86FuncNode* func = newNode(); Error error; if (func == NULL) @@ -375,7 +1046,7 @@ X86X64FuncNode* X86X64Compiler::newFunc(uint32_t conv, const FuncPrototype& p) { goto _NoMemory; // Emit push/pop sequence by default. - func->_funcHints |= IntUtil::mask(kFuncHintPushPop); + func->_funcHints |= IntUtil::mask(kX86FuncHintPushPop); // Function prototype. if ((error = func->_x86Decl.setPrototype(conv, p)) != kErrorOk) { @@ -384,7 +1055,7 @@ X86X64FuncNode* X86X64Compiler::newFunc(uint32_t conv, const FuncPrototype& p) { } // Function arguments stack size. Since function requires _argStackSize to be - // set, we have to copy it from X86X64FuncDecl. + // set, we have to copy it from X86FuncDecl. func->_argStackSize = func->_x86Decl.getArgStackSize(); func->_redZoneSize = static_cast(func->_x86Decl.getRedZoneSize()); func->_spillZoneSize = static_cast(func->_x86Decl.getSpillZoneSize()); @@ -409,8 +1080,8 @@ _NoMemory: return NULL; } -X86X64FuncNode* X86X64Compiler::addFunc(uint32_t conv, const FuncPrototype& p) { - X86X64FuncNode* func = newFunc(conv, p); +X86FuncNode* X86Compiler::addFunc(uint32_t conv, const FuncPrototype& p) { + X86FuncNode* func = newFunc(conv, p); if (func == NULL) { setError(kErrorNoHeapMemory); @@ -426,15 +1097,15 @@ X86X64FuncNode* X86X64Compiler::addFunc(uint32_t conv, const FuncPrototype& p) { return func; } -EndNode* X86X64Compiler::endFunc() { - X86X64FuncNode* func = getFunc(); +EndNode* X86Compiler::endFunc() { + X86FuncNode* func = getFunc(); ASMJIT_ASSERT(func != NULL); // App function exit / epilog marker. addNode(func->getExitNode()); // Add local constant pool at the end of the function (if exist). - X86X64Compiler_emitConstPool(this, _localConstPoolLabel, _localConstPool); + X86Compiler_emitConstPool(this, _localConstPoolLabel, _localConstPool); // Add function end marker. addNode(func->getEnd()); @@ -447,10 +1118,10 @@ EndNode* X86X64Compiler::endFunc() { } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Ret] +// [asmjit::X86Compiler - Ret] // ============================================================================ -RetNode* X86X64Compiler::newRet(const Operand& o0, const Operand& o1) { +RetNode* X86Compiler::newRet(const Operand& o0, const Operand& o1) { RetNode* node = newNode(o0, o1); if (node == NULL) goto _NoMemory; @@ -461,7 +1132,7 @@ _NoMemory: return NULL; } -RetNode* X86X64Compiler::addRet(const Operand& o0, const Operand& o1) { +RetNode* X86Compiler::addRet(const Operand& o0, const Operand& o1) { RetNode* node = newRet(o0, o1); if (node == NULL) return node; @@ -469,11 +1140,11 @@ RetNode* X86X64Compiler::addRet(const Operand& o0, const Operand& o1) { } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Call] +// [asmjit::X86Compiler - Call] // ============================================================================ -X86X64CallNode* X86X64Compiler::newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { - X86X64CallNode* node = newNode(o0); +X86CallNode* X86Compiler::newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { + X86CallNode* node = newNode(o0); Error error; uint32_t nArgs; @@ -501,19 +1172,19 @@ _NoMemory: return NULL; } -X86X64CallNode* X86X64Compiler::addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { - X86X64CallNode* node = newCall(o0, conv, p); +X86CallNode* X86Compiler::addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { + X86CallNode* node = newCall(o0, conv, p); if (node == NULL) return NULL; - return static_cast(addNode(node)); + return static_cast(addNode(node)); } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Vars] +// [asmjit::X86Compiler - Vars] // ============================================================================ -Error X86X64Compiler::setArg(uint32_t argIndex, BaseVar& var) { - X86X64FuncNode* func = getFunc(); +Error X86Compiler::setArg(uint32_t argIndex, Var& var) { + X86FuncNode* func = getFunc(); if (func == NULL) return kErrorInvalidArgument; @@ -527,19 +1198,19 @@ Error X86X64Compiler::setArg(uint32_t argIndex, BaseVar& var) { return kErrorOk; } -Error X86X64Compiler::_newVar(BaseVar* var, uint32_t vType, const char* name) { - ASMJIT_ASSERT(vType < kVarTypeCount); +Error X86Compiler::_newVar(Var* var, uint32_t vType, const char* name) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); vType = _targetVarMapping[vType]; - ASMJIT_ASSERT(vType != kVarTypeInvalid); + ASMJIT_ASSERT(vType != kInvalidVar); // There is not ASSERT in release mode and this should be checked. - if (vType == kVarTypeInvalid) { + if (vType == kInvalidVar) { static_cast(var)->reset(); return kErrorInvalidArgument; } - const VarInfo& vInfo = _varInfo[vType]; + const X86VarInfo& vInfo = _x86VarInfo[vType]; VarData* vd = _newVd(vType, vInfo.getSize(), vInfo.getClass(), name); if (vd == NULL) { @@ -553,34 +1224,34 @@ Error X86X64Compiler::_newVar(BaseVar* var, uint32_t vType, const char* name) { } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Stack] +// [asmjit::X86Compiler - Stack] // ============================================================================ -Error X86X64Compiler::_newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) { +Error X86Compiler::_newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) { if (size == 0) return kErrorInvalidArgument; if (alignment > 64) alignment = 64; - VarData* vd = _newVd(kVarTypeInvalid, size, kRegClassInvalid, name); + VarData* vd = _newVd(kInvalidVar, size, kInvalidReg, name); if (vd == NULL) { - static_cast(mem)->reset(); + static_cast(mem)->reset(); return getError(); } vd->_isStack = true; vd->_alignment = static_cast(alignment); - static_cast(mem)->_init(kMemTypeStackIndex, vd->getId(), 0, 0); + static_cast(mem)->_init(kMemTypeStackIndex, vd->getId(), 0, 0); return kErrorOk; } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Const] +// [asmjit::X86Compiler - Const] // ============================================================================ -Error X86X64Compiler::_newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) { +Error X86Compiler::_newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) { Error error = kErrorOk; size_t offset; @@ -610,7 +1281,7 @@ Error X86X64Compiler::_newConst(BaseMem* mem, uint32_t scope, const void* data, goto _OnError; } - *static_cast(mem) = ptr(*dstLabel, static_cast(offset), static_cast(size)); + *static_cast(mem) = x86::ptr(*dstLabel, static_cast(offset), static_cast(size)); return kErrorOk; _OnError: @@ -618,27 +1289,27 @@ _OnError: } // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Make] +// [asmjit::X86Compiler - Make] // ============================================================================ -template -static ASMJIT_INLINE void* X86X64Compiler_make(X86X64Compiler* self) { - Assembler assembler(self->_runtime); +void* X86Compiler::make() { + // Flush global constant pool + X86Compiler_emitConstPool(this, _globalConstPoolLabel, _globalConstPool); + + X86Assembler assembler(_runtime, _arch); #if !defined(ASMJIT_DISABLE_LOGGER) - Logger* logger = self->_logger; + Logger* logger = _logger; if (logger) assembler.setLogger(logger); #endif // !ASMJIT_DISABLE_LOGGER - assembler._features = self->_features; - - if (self->serialize(assembler) != kErrorOk) { + assembler._features = _features; + if (serialize(assembler) != kErrorOk) return NULL; - } if (assembler.getError() != kErrorOk) { - self->setError(assembler.getError()); + setError(assembler.getError()); return NULL; } @@ -656,31 +1327,15 @@ static ASMJIT_INLINE void* X86X64Compiler_make(X86X64Compiler* self) { return result; } -void* X86X64Compiler::make() { - // Flush global constant pool - X86X64Compiler_emitConstPool(this, _globalConstPoolLabel, _globalConstPool); - -#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) - return X86X64Compiler_make(this); -#elif !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) - return X86X64Compiler_make(this); -#else - if (_arch == kArchX86) - return X86X64Compiler_make(this); - else - return X86X64Compiler_make(this); -#endif // ASMJIT_BUILD_X86 && ASMJIT_BUILD_X64 -} - // ============================================================================ -// [asmjit::x86x64::X86X64Compiler - Assemble] +// [asmjit::X86Compiler - Assemble] // ============================================================================ -Error X86X64Compiler::serialize(BaseAssembler& assembler) { +Error X86Compiler::serialize(Assembler& assembler) { if (_firstNode == NULL) return kErrorOk; - X86X64Context context(this); + X86Context context(this); Error error = kErrorOk; Node* node = _firstNode; @@ -691,8 +1346,8 @@ Error X86X64Compiler::serialize(BaseAssembler& assembler) { start = node; if (node->getType() == kNodeTypeFunc) { - node = static_cast(start)->getEnd(); - error = context.compile(static_cast(start)); + node = static_cast(start)->getEnd(); + error = context.compile(static_cast(start)); if (error != kErrorOk) goto _Error; @@ -714,53 +1369,8 @@ _Error: return error; } -} // x86x64 namespace } // asmjit namespace -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -Compiler::Compiler(Runtime* runtime) : X86X64Compiler(runtime) { - _arch = kArchX86; - _regSize = 4; - _targetVarMapping = _varMapping; -} - -Compiler::~Compiler() {} - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -Compiler::Compiler(Runtime* runtime) : X86X64Compiler(runtime) { - _arch = kArchX64; - _regSize = 8; - _targetVarMapping = _varMapping; -} - -Compiler::~Compiler() {} - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - // [Api-End] #include "../apiend.h" diff --git a/src/asmjit/x86/x86compiler.h b/src/asmjit/x86/x86compiler.h index 7dd99fa..0d01efe 100644 --- a/src/asmjit/x86/x86compiler.h +++ b/src/asmjit/x86/x86compiler.h @@ -15,19 +15,2432 @@ #include "../base/compiler.h" #include "../base/vectypes.h" #include "../x86/x86assembler.h" -#include "../x86/x86func.h" -#include "../x86/x86util.h" // [Api-Begin] #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ -// [CodeGen-Begin] +// [Forward Declarations] // ============================================================================ +struct X86CallNode; +struct X86FuncNode; +struct X86VarState; + +//! \addtogroup asmjit_x86_compiler +//! \{ + +// ============================================================================ +// [asmjit::k86VarType] +// ============================================================================ + +//! X86/X64 variable type. +ASMJIT_ENUM(k86VarType) { + //! Variable is SP-FP (x87). + kX86VarTypeFp32 = kVarTypeFp32, + //! Variable is DP-FP (x87). + kX86VarTypeFp64 = kVarTypeFp64, + + //! Variable is Mm (MMX). + kX86VarTypeMm = 12, + + //! Variable is Xmm (SSE+). + kX86VarTypeXmm, + //! Variable is scalar Xmm SP-FP number. + kX86VarTypeXmmSs, + //! Variable is packed Xmm SP-FP number (4 floats). + kX86VarTypeXmmPs, + //! Variable is scalar Xmm DP-FP number. + kX86VarTypeXmmSd, + //! Variable is packed Xmm DP-FP number (2 doubles). + kX86VarTypeXmmPd, + + //! Variable is Ymm (AVX+). + kX86VarTypeYmm, + //! Variable is packed Ymm SP-FP number (8 floats). + kX86VarTypeYmmPs, + //! Variable is packed Ymm DP-FP number (4 doubles). + kX86VarTypeYmmPd, + + //! Count of variable types. + kX86VarTypeCount, + + //! \internal + //! \{ + _kX86VarTypeMmStart = kX86VarTypeMm, + _kX86VarTypeMmEnd = kX86VarTypeMm, + + _kX86VarTypeXmmStart = kX86VarTypeXmm, + _kX86VarTypeXmmEnd = kX86VarTypeXmmPd, + + _kX86VarTypeYmmStart = kX86VarTypeYmm, + _kX86VarTypeYmmEnd = kX86VarTypeYmmPd + //! \} +}; + +// ============================================================================ +// [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); + } + + //! Reset X86Var operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, kInvalidValue); + } + + // -------------------------------------------------------------------------- + // [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 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] + // -------------------------------------------------------------------------- + + //! Get count of registers of the current architecture. + 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); + } + + ASMJIT_API Error setArch(uint32_t arch); + + // -------------------------------------------------------------------------- + // [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); + + // -------------------------------------------------------------------------- + // [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(); + + // ------------------------------------------------------------------------- + // [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; + + // -------------------------------------------------------------------------- + // [X86 Instructions] + // -------------------------------------------------------------------------- + #define INST_0x(_Inst_, _Code_) \ ASMJIT_INLINE InstNode* _Inst_() { \ return emit(_Code_); \ @@ -233,3968 +2646,2809 @@ namespace x86x64 { return emit(_Code_, o0, o1, o2, o3); \ } -// ============================================================================ -// [Forward Declarations] -// ============================================================================ - -struct X86X64CallNode; -struct X86X64FuncNode; -struct VarState; - -//! \addtogroup asmjit_x86x64_tree -//! \{ - -// ============================================================================ -// [asmjit::x86x64::kVarAttr] -// ============================================================================ - -//! X86/X64 VarAttr flags. -ASMJIT_ENUM(kVarAttr) { - kVarAttrGpbLo = 0x10000000, - kVarAttrGpbHi = 0x20000000 -}; - -// ============================================================================ -// [asmjit::x86x64::VarInst] -// ============================================================================ - -struct VarInst : public BaseVarInst { - // -------------------------------------------------------------------------- - // [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 (all). - ASMJIT_INLINE uint32_t getVaCount() const { - return _vaCount; - } - - //! 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] - // -------------------------------------------------------------------------- - - //! Variables count. - uint32_t _vaCount; - - //! 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. - RegMask _inRegs; - - //! Special registers on output. - //! - //! Special register(s) used on output. Each variable can have only one - //! special register on the output, 'VarInst' contains all registers from - //! all 'VarAttr's. - RegMask _outRegs; - - //! Clobbered registers (by a function call). - RegMask _clobberedRegs; - - //! Start indexes of variables per register class. - RegCount _start; - //! Count of variables per register class. - RegCount _count; - - //! VarAttr list. - VarAttr _list[1]; -}; - -// ============================================================================ -// [asmjit::x86x64::StateCell] -// ============================================================================ - -//! X86/X64 state-cell. -union StateCell { - // -------------------------------------------------------------------------- - // [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::x86x64::VarState] -// ============================================================================ - -//! X86/X64 state. -struct VarState : BaseVarState { - 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 `VarState`. - kAllCount = kXmmIndex + kXmmCount - }; - - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE VarData** getList() { - return _list; - } - - ASMJIT_INLINE VarData** getListByClass(uint32_t c) { - switch (c) { - case kRegClassGp : return _listGp; - case kRegClassMm : return _listMm; - case kRegClassXyz: return _listXmm; - - default: - return NULL; - } - } - - // -------------------------------------------------------------------------- - // [Clear] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void reset(size_t numCells) { - ::memset(this, 0, kAllCount * sizeof(VarData* ) + - 2 * sizeof(RegMask ) + - numCells * sizeof(StateCell)); - } - - // -------------------------------------------------------------------------- - // [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). - RegMask _occupied; - //! Modified registers (mask). - RegMask _modified; - - //! Variables data, the length is stored in `X86X64Context`. - StateCell _cells[1]; -}; - -// ============================================================================ -// [asmjit::X86X64FuncNode] -// ============================================================================ - -//! X86/X64 function node. -struct X86X64FuncNode : public FuncNode { - ASMJIT_NO_COPY(X86X64FuncNode) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new `X86X64FuncNode` instance. - ASMJIT_INLINE X86X64FuncNode(BaseCompiler* 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 `X86X64FuncNode` instance. - ASMJIT_INLINE ~X86X64FuncNode() {} - - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Get function declaration as `X86X64FuncDecl`. - ASMJIT_INLINE X86X64FuncDecl* 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. - X86X64FuncDecl _x86Decl; - //! Registers which must be saved/restored in prolog/epilog. - RegMask _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::X86X64CallNode] -// ============================================================================ - -//! X86/X64 function-call node. -struct X86X64CallNode : public CallNode { - ASMJIT_NO_COPY(X86X64CallNode) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new `X86X64CallNode` instance. - ASMJIT_INLINE X86X64CallNode(BaseCompiler* compiler, const Operand& target) : CallNode(compiler, target) { - _decl = &_x86Decl; - _usedArgs.reset(); - } - - //! Destroy the `X86X64CallNode` instance. - ASMJIT_INLINE ~X86X64CallNode() {} - - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Get function prototype. - ASMJIT_INLINE X86X64FuncDecl* 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 BaseVar& var) { return _setArg(i, var); } - //! 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 BaseVar& var) { return _setRet(i, var); } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - //! X86 declaration. - X86X64FuncDecl _x86Decl; - //! Mask of all registers actually used to pass function arguments. - //! - //! \note This bit-mask is not the same as @c X86X64Func::_passed. It contains - //! only registers actually used to do the call while X86X64Func::_passed - //! mask contains all registers for all function prototype combinations. - RegMask _usedArgs; -}; - -//! \} - -// ============================================================================ -// [asmjit::x86x64::X86X64Compiler] -// ============================================================================ - -//! \addtogroup asmjit_x86x64_general -//! \{ - -//! X86/X64 compiler. -//! -//! This class is used to store instruction stream and allows to modify -//! it on the fly. It uses different concept than @c asmjit::Assembler class -//! and in fact @c asmjit::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. -//! -//! `X86X64Compiler` moves code generation to a higher level. Higher level -//! constructs allows to write more abstract and extensible code that is not -//! possible with pure `X86X64Assembler`. -//! -//! 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 @c 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 @c 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; -//! GpVar a0(c, kVarTypeIntPtr); -//! -//! c.addFunc(kFuncConvHost, FuncBuilder1()); -//! c.setArg(0, a0); -//! -//! // Create your variables. -//! GpVar x0(c, kVarTypeInt32); -//! GpVar 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 @c Compiler. Most useful variables can -//! be allocated using general purpose registers (@c GpVar), MMX registers -//! (@c MmVar) or SSE/SSE2 registers (@c XmmVar). -//! -//! 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, ...). -//! -//! - `kVarTypeMm` - 64-bit Mm register (mm0, mm1, ...). -//! -//! - `kVarTypeXmm` - 128-bit SSE register. -//! - `kVarTypeXmmSs` - 128-bit SSE register that contains a scalar 32-bit SP-FP value. -//! - `kVarTypeXmmSd` - 128-bit SSE register that contains a scalar 64-bit DP-FP value. -//! - `kVarTypeXmmPs` - 128-bit SSE register that contains 4 packed 32-bit SP-FP values. -//! - `kVarTypeXmmPd` - 128-bit SSE register that contains 2 packed 64-bit DP-FP values. -//! -//! - `kVarTypeYmm` - 256-bit AVX register. -//! - `kVarTypeYmmPs` - 256-bit AVX register that contains 4 packed 32-bit SP-FP values. -//! - `kVarTypeYmmPd` - 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 @c kVarStateUnused, -//! allocating it to register or spilling to memory changes this state to -//! @c kVarStateReg or @c 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: -//! -//! - `BaseCompiler::alloc()` - Explicit method to alloc variable into register. -//! It can be used to force allocation a variable before a loop for example. -//! -//! - `BaseCompiler::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. -//! -//! - `BaseCompiler::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 -//! ----------------- -//! -//! @c Compiler Memory management follows these rules: -//! - Everything created by @c Compiler is always freed by @c 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 @c Compiler object after destructing it, -//! it also means that each object like @c Label, @c BaseVar and others are -//! created and managed by @c BaseCompiler itself. These objects contain ID -//! which is used internally by Compiler to store additional information about -//! these objects. -//! -//! Control-Flow and State Management -//! --------------------------------- -//! -//! The @c 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 @c 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. -//! GpVar var0(c, kVarTypeInt32); -//! GpVar 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 @c 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. -//! GpVar var0(c, kVarTypeInt32); -//! GpVar 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 @c 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 -//! @c Compiler (but also to @c Assembler). When emitting code to instruction -//! stream the methods like @c mov(), @c add(), @c sub() can be called directly -//! (advantage is static-type control performed also by C++ compiler) or -//! indirectly using @c emit() method. The @c emit() method needs only -//! instruction code and operands. -//! -//! Example of code generating by standard type-safe API: -//! -//! ~~~ -//! Compiler c; -//! -//! GpVar var0(c, kVarTypeInt32); -//! GpVar var1(c, kVarTypeInt32); -//! -//! ... -//! -//! c.mov(var0, 0); -//! c.add(var0, var1); -//! c.sub(var0, var1); -//! ~~~ -//! -//! The code above can be rewritten as: -//! -//! ~~~ -//! Compiler c; -//! -//! GpVar var0(c, kVarTypeInt32); -//! GpVar var1(c, kVarTypeInt32); -//! -//! ... -//! -//! c.emit(kInstMov, var0, 0); -//! c.emit(kInstAdd, var0, var1); -//! c.emit(kInstSub, 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 @c emit() method can be used to generate -//! abstract code. -//! -//! Use case: -//! -//! ~~~ -//! bool emitArithmetic(Compiler& c, XmmVar& var0, XmmVar& var1, const char* op) { -//! uint32_t code = kInstNone; -//! -//! if (strcmp(op, "ADD") == 0) -//! code = kInstAddss; -//! else if (::strcmp(op, "SUBTRACT") == 0) -//! code = kInstSubss; -//! else if (::strcmp(op, "MULTIPLY") == 0) -//! code = kInstMulss; -//! else if (::strcmp(op, "DIVIDE") == 0) -//! code = kInstDivss; -//! 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 @c kErrorUnknownInst. -struct X86X64Compiler : public BaseCompiler { - ASMJIT_NO_COPY(X86X64Compiler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a `X86X64Compiler` instance. - ASMJIT_API X86X64Compiler(Runtime* runtime); - //! Destroy the `X86X64Compiler` instance. - ASMJIT_API ~X86X64Compiler(); - - // -------------------------------------------------------------------------- - // [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); - - // -------------------------------------------------------------------------- - // [Func] - // -------------------------------------------------------------------------- - - //! Create a new `X86X64FuncNode`. - ASMJIT_API X86X64FuncNode* 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 @c Compiler. First parameter `cconv` specifies function calling - //! convention to use. Second parameter `params` specifies function - //! arguments. To create function arguments are used templates - //! @c FuncBuilder0<...>, @c FuncBuilder1<...>, @c 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 @c 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 @c 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 @c asmjit::Function::argument() method. Arguments - //! are indexed from 0 (like everything in C). - //! - //! ~~~ - //! // Accessing function arguments through asmjit::Function example. - //! - //! // Compiler instance - //! Compiler c; - //! GpVar a0(c, kVarTypeInt32); - //! GpVar a1(c, kVarTypeInt32); - //! - //! // Begin of function (also emits function @c 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 @c asmjit::Compiler, variables section. - //! - //! \note To get current function use @c currentFunction() method or save - //! pointer to @c asmjit::Function returned by @c asmjit::Compiler::addFunc<> - //! method. Recommended is to save the pointer. - //! - //! @sa @c FuncBuilder0, @c FuncBuilder1, @c FuncBuilder2, ... - ASMJIT_API X86X64FuncNode* addFunc(uint32_t conv, const FuncPrototype& p); - - //! End of current function. - ASMJIT_API EndNode* endFunc(); - - //! Get current function as `X86X64FuncNode`. - //! - //! This method can be called within @c addFunc() and @c endFunc() - //! block to get current function you are working with. It's recommended - //! to store @c asmjit::Function pointer returned by @c addFunc<> method, - //! because this allows you in future implement function sections outside of - //! function itself (yeah, this is possible!). - ASMJIT_INLINE X86X64FuncNode* 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 `X86X64CallNode`. - ASMJIT_API X86X64CallNode* newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); - //! Add a new `X86X64CallNode`. - ASMJIT_API X86X64CallNode* addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); - - // -------------------------------------------------------------------------- - // [Vars] - // -------------------------------------------------------------------------- - - //! Set function argument to `var`. - ASMJIT_API Error setArg(uint32_t argIndex, BaseVar& var); - - ASMJIT_API virtual Error _newVar(BaseVar* var, uint32_t type, const char* name); - - //! Create a new Gp variable. - ASMJIT_INLINE GpVar newGpVar(uint32_t vType = kVarTypeIntPtr, const char* name = NULL) { - ASMJIT_ASSERT(vType < kVarTypeCount); - ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeIntStart, _kVarTypeIntEnd)); - - GpVar var(NoInit); - _newVar(&var, vType, name); - return var; - } - - //! Create a new Mm variable. - ASMJIT_INLINE MmVar newMmVar(uint32_t vType = kVarTypeMm, const char* name = NULL) { - ASMJIT_ASSERT(vType < kVarTypeCount); - ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeMmStart, _kVarTypeMmEnd)); - - MmVar var(NoInit); - _newVar(&var, vType, name); - return var; - } - - //! Create a new Xmm variable. - ASMJIT_INLINE XmmVar newXmmVar(uint32_t vType = kVarTypeXmm, const char* name = NULL) { - ASMJIT_ASSERT(vType < kVarTypeCount); - ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeXmmStart, _kVarTypeXmmEnd)); - - XmmVar var(NoInit); - _newVar(&var, vType, name); - return var; - } - - //! Create a new Ymm variable. - ASMJIT_INLINE YmmVar newYmmVar(uint32_t vType = kVarTypeYmm, const char* name = NULL) { - ASMJIT_ASSERT(vType < kVarTypeCount); - ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeYmmStart, _kVarTypeYmmEnd)); - - YmmVar var(NoInit); - _newVar(&var, vType, name); - return var; - } - - //! Get memory home of variable `var`. - ASMJIT_API void getMemoryHome(BaseVar& var, GpVar* home, int* displacement = NULL); - - //! Set memory home of variable `var`. - //! - //! Default memory home location is on stack (ESP/RSP), but when needed the - //! bebahior can be changed by this method. - //! - //! It is an error to chaining memory home locations. For example the given - //! code is invalid: - //! - //! ~~~ - //! Compiler c; - //! - //! ... - //! - //! GpVar v0(c, kVarTypeIntPtr); - //! GpVar v1(c, kVarTypeIntPtr); - //! GpVar v2(c, kVarTypeIntPtr); - //! GpVar v3(c, kVarTypeIntPtr); - //! - //! c.setMemoryHome(v1, v0, 0); // Allowed, [v0+0] is memory home for v1. - //! c.setMemoryHome(v2, v0, 4); // Allowed, [v0+4] is memory home for v2. - //! c.setMemoryHome(v3, v2); // CHAINING, NOT ALLOWED! - //! ~~~ - ASMJIT_API void setMemoryHome(BaseVar& var, const GpVar& home, int displacement = 0); - - // -------------------------------------------------------------------------- - // [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 Mem newStack(uint32_t size, uint32_t alignment, const char* name = NULL) { - Mem 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 Mem newConst(uint32_t scope, const void* data, size_t size) { - Mem m(NoInit); - _newConst(&m, scope, data, size); - return m; - } - - ASMJIT_INLINE Mem newByteConst(uint32_t scope, uint8_t val) { return newConst(scope, &val, 1); } - ASMJIT_INLINE Mem newWordConst(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } - ASMJIT_INLINE Mem newDWordConst(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } - ASMJIT_INLINE Mem newQWordConst(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } - - ASMJIT_INLINE Mem newInt16Const(uint32_t scope, int16_t val) { return newConst(scope, &val, 2); } - ASMJIT_INLINE Mem newUInt16Const(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } - ASMJIT_INLINE Mem newInt32Const(uint32_t scope, int32_t val) { return newConst(scope, &val, 4); } - ASMJIT_INLINE Mem newUInt32Const(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } - ASMJIT_INLINE Mem newInt64Const(uint32_t scope, int64_t val) { return newConst(scope, &val, 8); } - ASMJIT_INLINE Mem newUInt64Const(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } - - ASMJIT_INLINE Mem newFloatConst(uint32_t scope, float val) { return newConst(scope, &val, 4); } - ASMJIT_INLINE Mem newDoubleConst(uint32_t scope, double val) { return newConst(scope, &val, 8); } - - ASMJIT_INLINE Mem newMmConst(uint32_t scope, const Vec64Data& val) { return newConst(scope, &val, 8); } - ASMJIT_INLINE Mem newXmmConst(uint32_t scope, const Vec128Data& val) { return newConst(scope, &val, 16); } - ASMJIT_INLINE Mem newYmmConst(uint32_t scope, const Vec256Data& val) { return newConst(scope, &val, 32); } - - // -------------------------------------------------------------------------- - // [Embed] - // -------------------------------------------------------------------------- - - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* db(uint8_t x) { return embed(&x, 1); } - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dw(uint16_t x) { return embed(&x, 2); } - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dd(uint32_t x) { return embed(&x, 4); } - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dq(uint64_t x) { return embed(&x, 8); } - - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dint8(int8_t x) { return embed(&x, static_cast(sizeof(int8_t))); } - //! Add 8-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* duint8(uint8_t x) { return embed(&x, static_cast(sizeof(uint8_t))); } - - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dint16(int16_t x) { return embed(&x, static_cast(sizeof(int16_t))); } - //! Add 16-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* duint16(uint16_t x) { return embed(&x, static_cast(sizeof(uint16_t))); } - - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dint32(int32_t x) { return embed(&x, static_cast(sizeof(int32_t))); } - //! Add 32-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* duint32(uint32_t x) { return embed(&x, static_cast(sizeof(uint32_t))); } - - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dint64(int64_t x) { return embed(&x, static_cast(sizeof(int64_t))); } - //! Add 64-bit integer data to the instuction stream. - ASMJIT_INLINE EmbedNode* duint64(uint64_t x) { return embed(&x, static_cast(sizeof(uint64_t))); } - - //! Add float data to the instuction stream. - ASMJIT_INLINE EmbedNode* dfloat(float x) { return embed(&x, static_cast(sizeof(float))); } - //! Add double data to the instuction stream. - ASMJIT_INLINE EmbedNode* ddouble(double x) { return embed(&x, static_cast(sizeof(double))); } - - //! Add pointer data to the instuction stream. - ASMJIT_INLINE EmbedNode* dptr(void* x) { return embed(&x, static_cast(sizeof(void*))); } - - //! Add Mm data to the instuction stream. - ASMJIT_INLINE EmbedNode* dmm(const MmData& x) { return embed(&x, static_cast(sizeof(MmData))); } - //! Add Xmm data to the instuction stream. - ASMJIT_INLINE EmbedNode* dxmm(const XmmData& x) { return embed(&x, static_cast(sizeof(XmmData))); } - //! Add Ymm data to the instuction stream. - ASMJIT_INLINE EmbedNode* dymm(const YmmData& x) { return embed(&x, static_cast(sizeof(YmmData))); } - - //! Add data in a given structure instance to the instuction stream. - template - ASMJIT_INLINE EmbedNode* dstruct(const T& x) { return embed(&x, static_cast(sizeof(T))); } - - // -------------------------------------------------------------------------- - // [Make] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual void* make(); - - // ------------------------------------------------------------------------- - // [Serialize] - // ------------------------------------------------------------------------- - - ASMJIT_API virtual Error serialize(BaseAssembler& assembler); - - // ------------------------------------------------------------------------- - // [Options] - // ------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(X86X64Compiler) - - // -------------------------------------------------------------------------- - // [X86 Instructions] - // -------------------------------------------------------------------------- - //! Add with carry. - INST_2x(adc, kInstAdc, GpVar, GpVar) + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86GpVar) //! \overload - INST_2x(adc, kInstAdc, GpVar, Mem) + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86Mem) //! \overload - INST_2i(adc, kInstAdc, GpVar, Imm) + INST_2i(adc, kX86InstIdAdc, X86GpVar, Imm) //! \overload - INST_2x(adc, kInstAdc, Mem, GpVar) + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpVar) //! \overload - INST_2i(adc, kInstAdc, Mem, Imm) + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) //! Add. - INST_2x(add, kInstAdd, GpVar, GpVar) + INST_2x(add, kX86InstIdAdd, X86GpVar, X86GpVar) //! \overload - INST_2x(add, kInstAdd, GpVar, Mem) + INST_2x(add, kX86InstIdAdd, X86GpVar, X86Mem) //! \overload - INST_2i(add, kInstAdd, GpVar, Imm) + INST_2i(add, kX86InstIdAdd, X86GpVar, Imm) //! \overload - INST_2x(add, kInstAdd, Mem, GpVar) + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpVar) //! \overload - INST_2i(add, kInstAdd, Mem, Imm) + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) //! And. - INST_2x(and_, kInstAnd, GpVar, GpVar) + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86GpVar) //! \overload - INST_2x(and_, kInstAnd, GpVar, Mem) + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86Mem) //! \overload - INST_2i(and_, kInstAnd, GpVar, Imm) + INST_2i(and_, kX86InstIdAnd, X86GpVar, Imm) //! \overload - INST_2x(and_, kInstAnd, Mem, GpVar) + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpVar) //! \overload - INST_2i(and_, kInstAnd, Mem, Imm) + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) //! Bit scan forward. - INST_2x_(bsf, kInstBsf, GpVar, GpVar, !o0.isGpb()) + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86GpVar, !o0.isGpb()) //! \overload - INST_2x_(bsf, kInstBsf, GpVar, Mem, !o0.isGpb()) + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86Mem, !o0.isGpb()) //! Bit scan reverse. - INST_2x_(bsr, kInstBsr, GpVar, GpVar, !o0.isGpb()) + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86GpVar, !o0.isGpb()) //! \overload - INST_2x_(bsr, kInstBsr, GpVar, Mem, !o0.isGpb()) + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86Mem, !o0.isGpb()) //! Byte swap (32-bit or 64-bit registers only) (i486). - INST_1x_(bswap, kInstBswap, GpVar, o0.getSize() >= 4) + INST_1x_(bswap, kX86InstIdBswap, X86GpVar, o0.getSize() >= 4) //! Bit test. - INST_2x(bt, kInstBt, GpVar, GpVar) + INST_2x(bt, kX86InstIdBt, X86GpVar, X86GpVar) //! \overload - INST_2i(bt, kInstBt, GpVar, Imm) + INST_2i(bt, kX86InstIdBt, X86GpVar, Imm) //! \overload - INST_2x(bt, kInstBt, Mem, GpVar) + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpVar) //! \overload - INST_2i(bt, kInstBt, Mem, Imm) + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) //! Bit test and complement. - INST_2x(btc, kInstBtc, GpVar, GpVar) + INST_2x(btc, kX86InstIdBtc, X86GpVar, X86GpVar) //! \overload - INST_2i(btc, kInstBtc, GpVar, Imm) + INST_2i(btc, kX86InstIdBtc, X86GpVar, Imm) //! \overload - INST_2x(btc, kInstBtc, Mem, GpVar) + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpVar) //! \overload - INST_2i(btc, kInstBtc, Mem, Imm) + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) //! Bit test and reset. - INST_2x(btr, kInstBtr, GpVar, GpVar) + INST_2x(btr, kX86InstIdBtr, X86GpVar, X86GpVar) //! \overload - INST_2i(btr, kInstBtr, GpVar, Imm) + INST_2i(btr, kX86InstIdBtr, X86GpVar, Imm) //! \overload - INST_2x(btr, kInstBtr, Mem, GpVar) + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpVar) //! \overload - INST_2i(btr, kInstBtr, Mem, Imm) + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) //! Bit test and set. - INST_2x(bts, kInstBts, GpVar, GpVar) + INST_2x(bts, kX86InstIdBts, X86GpVar, X86GpVar) //! \overload - INST_2i(bts, kInstBts, GpVar, Imm) + INST_2i(bts, kX86InstIdBts, X86GpVar, Imm) //! \overload - INST_2x(bts, kInstBts, Mem, GpVar) + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpVar) //! \overload - INST_2i(bts, kInstBts, Mem, Imm) + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) - //! Call. - ASMJIT_INLINE X86X64CallNode* call(const GpVar& dst, uint32_t conv, const FuncPrototype& p) { + //! Call a function. + ASMJIT_INLINE X86CallNode* call(const X86GpVar& dst, uint32_t conv, const FuncPrototype& p) { return addCall(dst, conv, p); } //! \overload - ASMJIT_INLINE X86X64CallNode* call(const Mem& dst, uint32_t conv, const FuncPrototype& p) { + ASMJIT_INLINE X86CallNode* call(const X86Mem& dst, uint32_t conv, const FuncPrototype& p) { return addCall(dst, conv, p); } //! \overload - ASMJIT_INLINE X86X64CallNode* call(const Imm& dst, uint32_t conv, const FuncPrototype& p) { - return addCall(dst, conv, p); - } - //! \overload - ASMJIT_INLINE X86X64CallNode* call(void* dst, uint32_t conv, const FuncPrototype& p) { - Imm imm((intptr_t)dst); - return addCall(imm, conv, p); - } - //! \overload - ASMJIT_INLINE X86X64CallNode* call(const Label& label, uint32_t conv, const FuncPrototype& p) { + 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, kInstClc) + INST_0x(clc, kX86InstIdClc) //! Clear direction flag - INST_0x(cld, kInstCld) + INST_0x(cld, kX86InstIdCld) //! Complement carry Flag. - INST_0x(cmc, kInstCmc) + INST_0x(cmc, kX86InstIdCmc) //! Convert BYTE to WORD (AX <- Sign Extend AL). - INST_1x(cbw, kInstCbw, GpVar /* al */) - //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). - INST_2x(cwd, kInstCwd, GpVar /* dx */, GpVar /* ax */) - //! Convert WORD to DWORD (EAX <- Sign Extend AX). - INST_1x(cwde, kInstCwde, GpVar /* eax */) + INST_1x(cbw, kX86InstIdCbw, X86GpVar /* al */) //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). - INST_2x(cdq, kInstCdq, GpVar /* edx */, GpVar /* 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, kInstCmov, X86Util::condToCmovcc, GpVar, GpVar) + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86GpVar) //! Conditional move. - INST_2cc(cmov, kInstCmov, X86Util::condToCmovcc, GpVar, Mem) + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86Mem) //! Compare two operands. - INST_2x(cmp, kInstCmp, GpVar, GpVar) + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86GpVar) //! \overload - INST_2x(cmp, kInstCmp, GpVar, Mem) + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86Mem) //! \overload - INST_2i(cmp, kInstCmp, GpVar, Imm) + INST_2i(cmp, kX86InstIdCmp, X86GpVar, Imm) //! \overload - INST_2x(cmp, kInstCmp, Mem, GpVar) + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpVar) //! \overload - INST_2i(cmp, kInstCmp, Mem, Imm) + 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, kInstCmpxchg, GpVar /* eax */, GpVar, GpVar) + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86GpVar, X86GpVar) //! \overload - INST_3x(cmpxchg, kInstCmpxchg, GpVar /* eax */, Mem, GpVar) + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86Mem, X86GpVar) - //! Compares the 64-bit value in EDX:EAX with the memory operand (Pentium). + //! 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 GpVar& cmp_edx, const GpVar& cmp_eax, - const GpVar& cmp_ecx, const GpVar& cmp_ebx, - const Mem& dst) { + const X86GpVar& r_edx, const X86GpVar& r_eax, + const X86GpVar& r_ecx, const X86GpVar& r_ebx, + const X86Mem& x_mem) { - return emit(kInstCmpxchg8b, cmp_edx, cmp_eax, cmp_ecx, cmp_ebx, dst); + return emit(kX86InstIdCmpxchg8b, r_edx, r_eax, r_ecx, r_ebx, x_mem); } //! CPU identification (i486). ASMJIT_INLINE InstNode* cpuid( - const GpVar& inout_eax, - const GpVar& out_ebx, - const GpVar& out_ecx, - const GpVar& out_edx) { + const X86GpVar& x_eax, + const X86GpVar& w_ebx, + const X86GpVar& x_ecx, + const X86GpVar& w_edx) { // Destination variables must be different. - ASMJIT_ASSERT(inout_eax.getId() != out_ebx.getId() && - out_ebx.getId() != out_ecx.getId() && - out_ecx.getId() != out_edx.getId()); + ASMJIT_ASSERT(x_eax.getId() != w_ebx.getId() && + w_ebx.getId() != x_ecx.getId() && + x_ecx.getId() != w_edx.getId()); - return emit(kInstCpuid, inout_eax, out_ebx, out_ecx, out_edx); + return emit(kX86InstIdCpuid, x_eax, w_ebx, x_ecx, w_edx); } //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). - INST_2x_(crc32, kInstCrc32, GpVar, GpVar, o0.isRegType(kRegTypeGpd) || o0.isRegType(kRegTypeGpq)) + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) //! \overload - INST_2x_(crc32, kInstCrc32, GpVar, Mem, o0.isRegType(kRegTypeGpd) || o0.isRegType(kRegTypeGpq)) + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! 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, kInstDec, GpVar) + INST_1x(dec, kX86InstIdDec, X86GpVar) //! \overload - INST_1x(dec, kInstDec, Mem) + 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, kInstDiv, GpVar, GpVar, GpVar, o0.getId() != o1.getId()) + INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) //! \overload - INST_3x_(div, kInstDiv, GpVar, GpVar, Mem, o0.getId() != o1.getId()) + 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, kInstIdiv, GpVar, GpVar, GpVar, o0.getId() != o1.getId()) + INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) //! \overload - INST_3x_(idiv, kInstIdiv, GpVar, GpVar, Mem, o0.getId() != o1.getId()) + 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, kInstImul, GpVar, GpVar, GpVar, o0.getId() != o1.getId()) + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) //! \overload - INST_3x_(imul, kInstImul, GpVar, GpVar, Mem, o0.getId() != o1.getId()) + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) //! Signed multiply. - INST_2x(imul, kInstImul, GpVar, GpVar) + INST_2x(imul, kX86InstIdImul, X86GpVar, X86GpVar) //! \overload - INST_2x(imul, kInstImul, GpVar, Mem) + INST_2x(imul, kX86InstIdImul, X86GpVar, X86Mem) //! \overload - INST_2i(imul, kInstImul, GpVar, Imm) + INST_2i(imul, kX86InstIdImul, X86GpVar, Imm) //! Signed multiply. - INST_3i(imul, kInstImul, GpVar, GpVar, Imm) + INST_3i(imul, kX86InstIdImul, X86GpVar, X86GpVar, Imm) //! \overload - INST_3i(imul, kInstImul, GpVar, Mem, Imm) + INST_3i(imul, kX86InstIdImul, X86GpVar, X86Mem, Imm) //! Increment by 1. - INST_1x(inc, kInstInc, GpVar) + INST_1x(inc, kX86InstIdInc, X86GpVar) //! \overload - INST_1x(inc, kInstInc, Mem) + INST_1x(inc, kX86InstIdInc, X86Mem) //! Interrupt. - INST_1i(int_, kInstInt, Imm) + 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, kInstJ, X86Util::condToJcc, Label) + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) //! Short jump if CX/ECX/RCX is zero. - INST_2x(jecxz, kInstJecxz, GpVar, Label) + INST_2x(jecxz, kX86InstIdJecxz, X86GpVar, Label) //! Jump. - INST_1x(jmp, kInstJmp, GpVar) + INST_1x(jmp, kX86InstIdJmp, X86GpVar) //! \overload - INST_1x(jmp, kInstJmp, Mem) + INST_1x(jmp, kX86InstIdJmp, X86Mem) //! \overload - INST_1x(jmp, kInstJmp, Label) + INST_1x(jmp, kX86InstIdJmp, Label) //! \overload - INST_1x(jmp, kInstJmp, Imm) + INST_1x(jmp, kX86InstIdJmp, Imm) //! \overload - ASMJIT_INLINE InstNode* jmp(void* dst) { return jmp(Imm((intptr_t)dst)); } + ASMJIT_INLINE InstNode* jmp(Ptr dst) { return jmp(Imm(dst)); } //! Load AH from flags. - INST_1x(lahf, kInstLahf, GpVar) + INST_1x(lahf, kX86InstIdLahf, X86GpVar) //! Load effective address - INST_2x(lea, kInstLea, GpVar, Mem) + 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, kInstMov, GpVar, GpVar) + INST_2x(mov, kX86InstIdMov, X86GpVar, X86GpVar) //! \overload - INST_2x(mov, kInstMov, GpVar, Mem) + INST_2x(mov, kX86InstIdMov, X86GpVar, X86Mem) //! \overload - INST_2i(mov, kInstMov, GpVar, Imm) + INST_2i(mov, kX86InstIdMov, X86GpVar, Imm) //! \overload - INST_2x(mov, kInstMov, Mem, GpVar) + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpVar) //! \overload - INST_2i(mov, kInstMov, Mem, Imm) + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) //! Move from segment register. - INST_2x(mov, kInstMov, GpVar, SegReg) + INST_2x(mov, kX86InstIdMov, X86GpVar, X86SegReg) //! \overload - INST_2x(mov, kInstMov, Mem, SegReg) + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) //! Move to segment register. - INST_2x(mov, kInstMov, SegReg, GpVar) + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpVar) //! \overload - INST_2x(mov, kInstMov, SegReg, Mem) + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) //! Move (AL|AX|EAX|RAX <- absolute address in immediate). - ASMJIT_INLINE InstNode* mov_ptr(const GpVar& dst, void* src) { - Imm imm(static_cast((intptr_t)src)); - return emit(kInstMovPtr, dst, imm); + 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). - ASMJIT_INLINE InstNode* mov_ptr(void* dst, const GpVar& src) { - Imm imm(static_cast((intptr_t)dst)); - return emit(kInstMovPtr, imm, src); + 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, kInstMovbe, GpVar, Mem, !o0.isGpb()); + INST_2x_(movbe, kX86InstIdMovbe, X86GpVar, X86Mem, !o0.isGpb()); //! \overload - INST_2x_(movbe, kInstMovbe, Mem, GpVar, !o1.isGpb()); + 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, kInstMovsx, GpVar, GpVar) + INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86GpVar) //! \overload - INST_2x(movsx, kInstMovsx, GpVar, Mem) + 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, kInstMovzx, GpVar, GpVar) + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86GpVar) //! \overload - INST_2x(movzx, kInstMovzx, GpVar, Mem) + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86Mem) //! Unsigned multiply (o0:o1 <- o1 * o2). - INST_3x_(mul, kInstMul, GpVar, GpVar, GpVar, o0.getId() != o1.getId()) + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) //! \overload - INST_3x_(mul, kInstMul, GpVar, GpVar, Mem, o0.getId() != o1.getId()) + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) //! Two's complement negation. - INST_1x(neg, kInstNeg, GpVar) + INST_1x(neg, kX86InstIdNeg, X86GpVar) //! \overload - INST_1x(neg, kInstNeg, Mem) + INST_1x(neg, kX86InstIdNeg, X86Mem) //! No operation. - INST_0x(nop, kInstNop) + INST_0x(nop, kX86InstIdNop) //! One's complement negation. - INST_1x(not_, kInstNot, GpVar) + INST_1x(not_, kX86InstIdNot, X86GpVar) //! \overload - INST_1x(not_, kInstNot, Mem) + INST_1x(not_, kX86InstIdNot, X86Mem) //! Or. - INST_2x(or_, kInstOr, GpVar, GpVar) + INST_2x(or_, kX86InstIdOr, X86GpVar, X86GpVar) //! \overload - INST_2x(or_, kInstOr, GpVar, Mem) + INST_2x(or_, kX86InstIdOr, X86GpVar, X86Mem) //! \overload - INST_2i(or_, kInstOr, GpVar, Imm) + INST_2i(or_, kX86InstIdOr, X86GpVar, Imm) //! \overload - INST_2x(or_, kInstOr, Mem, GpVar) + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpVar) //! \overload - INST_2i(or_, kInstOr, Mem, Imm) + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) //! Pop a value from the stack. - INST_1x_(pop, kInstPop, GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(pop, kX86InstIdPop, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) //! \overload - INST_1x_(pop, kInstPop, Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) //! Pop stack into EFLAGS Register (32-bit or 64-bit). - INST_0x(popf, kInstPopf) + INST_0x(popf, kX86InstIdPopf) //! Return the count of number of bits set to 1 (SSE4.2). - INST_2x_(popcnt, kInstPopcnt, GpVar, GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) //! \overload - INST_2x_(popcnt, kInstPopcnt, GpVar, Mem, !o0.isGpb()) + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb()) //! Push WORD or DWORD/QWORD on the stack. - INST_1x_(push, kInstPush, GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(push, kX86InstIdPush, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) //! Push WORD or DWORD/QWORD on the stack. - INST_1x_(push, kInstPush, Mem,o0.getSize() == 2 || o0.getSize() == _regSize) + INST_1x_(push, kX86InstIdPush, X86Mem,o0.getSize() == 2 || o0.getSize() == _regSize) //! Push segment register on the stack. - INST_1x(push, kInstPush, SegReg) + INST_1x(push, kX86InstIdPush, X86SegReg) //! Push WORD or DWORD/QWORD on the stack. - INST_1i(push, kInstPush, Imm) + INST_1i(push, kX86InstIdPush, Imm) //! Push EFLAGS register (32-bit or 64-bit) on the stack. - INST_0x(pushf, kInstPushf) + INST_0x(pushf, kX86InstIdPushf) //! Rotate bits left. - INST_2x(rcl, kInstRcl, GpVar, GpVar) + INST_2x(rcl, kX86InstIdRcl, X86GpVar, X86GpVar) //! \overload - INST_2x(rcl, kInstRcl, Mem, GpVar) + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpVar) //! Rotate bits left. - INST_2i(rcl, kInstRcl, GpVar, Imm) + INST_2i(rcl, kX86InstIdRcl, X86GpVar, Imm) //! \overload - INST_2i(rcl, kInstRcl, Mem, Imm) + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) //! Rotate bits right. - INST_2x(rcr, kInstRcr, GpVar, GpVar) + INST_2x(rcr, kX86InstIdRcr, X86GpVar, X86GpVar) //! \overload - INST_2x(rcr, kInstRcr, Mem, GpVar) + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpVar) //! Rotate bits right. - INST_2i(rcr, kInstRcr, GpVar, Imm) + INST_2i(rcr, kX86InstIdRcr, X86GpVar, Imm) //! \overload - INST_2i(rcr, kInstRcr, Mem, Imm) + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) //! Read time-stamp counter (Pentium). - INST_2x_(rdtsc, kInstRdtsc, GpVar, GpVar, o0.getId() != o1.getId()) + INST_2x_(rdtsc, kX86InstIdRdtsc, X86GpVar, X86GpVar, o0.getId() != o1.getId()) //! Read time-stamp counter and processor id (Pentium). - INST_3x_(rdtscp, kInstRdtscp, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + INST_3x_(rdtscp, kX86InstIdRdtscp, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Load ECX/RCX bytes from DS:[ESI/RSI] to AL. - INST_3x_(rep_lodsb, kInstRepLodsb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Load ECX/RCX dwords from DS:[ESI/RSI] to AL. - INST_3x_(rep_lodsd, kInstRepLodsd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Load ECX/RCX words from DS:[ESI/RSI] to AX. - INST_3x_(rep_lodsw, kInstRepLodsw, GpVar, GpVar, GpVar, 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()) - //! Move ECX/RCX bytes from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_3x_(rep_movsb, kInstRepMovsb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Move ECX/RCX dwords from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_3x_(rep_movsd, kInstRepMovsd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Move ECX/RCX dwords from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_3x_(rep_movsw, kInstRepMovsw, GpVar, GpVar, GpVar, 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()) - //! Fill ECX/RCX bytes at ES:[EDI/RDI] with AL. - INST_3x_(rep_stosb, kInstRepStosb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Fill ECX/RCX dwords at ES:[EDI/RDI] with EAX. - INST_3x_(rep_stosd, kInstRepStosd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Fill ECX/RCX words at ES:[EDI/RDI] with AX. - INST_3x_(rep_stosw, kInstRepStosw, GpVar, GpVar, GpVar, 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 nonmatching bytes in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_3x_(repe_cmpsb, kInstRepeCmpsb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Repeated find nonmatching dwords in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_3x_(repe_cmpsd, kInstRepeCmpsd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Repeated find nonmatching words in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_3x_(repe_cmpsw, kInstRepeCmpsw, GpVar, GpVar, GpVar, 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()) - //! Find non-AL byte starting at ES:[EDI/RDI]. - INST_3x_(repe_scasb, kInstRepeScasb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find non-EAX dword starting at ES:[EDI/RDI]. - INST_3x_(repe_scasd, kInstRepeScasd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find non-AX word starting at ES:[EDI/RDI]. - INST_3x_(repe_scasw, kInstRepeScasw, GpVar, GpVar, GpVar, 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()) - //! Find matching bytes in [RDI] and [RSI]. - INST_3x_(repne_cmpsb, kInstRepneCmpsb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find matching dwords in [RDI] and [RSI]. - INST_3x_(repne_cmpsd, kInstRepneCmpsd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find matching words in [RDI] and [RSI]. - INST_3x_(repne_cmpsw, kInstRepneCmpsw, GpVar, GpVar, GpVar, 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()) - //! Find AL, starting at ES:[EDI/RDI]. - INST_3x_(repne_scasb, kInstRepneScasb, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find EAX, starting at ES:[EDI/RDI]. - INST_3x_(repne_scasd, kInstRepneScasd, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find AX, starting at ES:[EDI/RDI]. - INST_3x_(repne_scasw, kInstRepneScasw, GpVar, GpVar, GpVar, 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 GpVar& o0) { return addRet(o0, noOperand); } + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0) { return addRet(o0, noOperand); } //! \overload - ASMJIT_INLINE RetNode* ret(const GpVar& o0, const GpVar& o1) { return addRet(o0, o1); } + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0, const X86GpVar& o1) { return addRet(o0, o1); } //! \overload - ASMJIT_INLINE RetNode* ret(const XmmVar& o0) { return addRet(o0, noOperand); } + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0) { return addRet(o0, noOperand); } //! \overload - ASMJIT_INLINE RetNode* ret(const XmmVar& o0, const XmmVar& o1) { return addRet(o0, o1); } + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0, const X86XmmVar& o1) { return addRet(o0, o1); } //! Rotate bits left. - INST_2x(rol, kInstRol, GpVar, GpVar) + INST_2x(rol, kX86InstIdRol, X86GpVar, X86GpVar) //! \overload - INST_2x(rol, kInstRol, Mem, GpVar) + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpVar) //! Rotate bits left. - INST_2i(rol, kInstRol, GpVar, Imm) + INST_2i(rol, kX86InstIdRol, X86GpVar, Imm) //! \overload - INST_2i(rol, kInstRol, Mem, Imm) + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) //! Rotate bits right. - INST_2x(ror, kInstRor, GpVar, GpVar) + INST_2x(ror, kX86InstIdRor, X86GpVar, X86GpVar) //! \overload - INST_2x(ror, kInstRor, Mem, GpVar) + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpVar) //! Rotate bits right. - INST_2i(ror, kInstRor, GpVar, Imm) + INST_2i(ror, kX86InstIdRor, X86GpVar, Imm) //! \overload - INST_2i(ror, kInstRor, Mem, Imm) + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) //! Store `a` (allocated in AH/AX/EAX/RAX) into Flags. - INST_1x(sahf, kInstSahf, GpVar) + INST_1x(sahf, kX86InstIdSahf, X86GpVar) //! Integer subtraction with borrow. - INST_2x(sbb, kInstSbb, GpVar, GpVar) + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86GpVar) //! \overload - INST_2x(sbb, kInstSbb, GpVar, Mem) + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86Mem) //! \overload - INST_2i(sbb, kInstSbb, GpVar, Imm) + INST_2i(sbb, kX86InstIdSbb, X86GpVar, Imm) //! \overload - INST_2x(sbb, kInstSbb, Mem, GpVar) + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpVar) //! \overload - INST_2i(sbb, kInstSbb, Mem, Imm) + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) //! Shift bits left. - INST_2x(sal, kInstSal, GpVar, GpVar) + INST_2x(sal, kX86InstIdSal, X86GpVar, X86GpVar) //! \overload - INST_2x(sal, kInstSal, Mem, GpVar) + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpVar) //! Shift bits left. - INST_2i(sal, kInstSal, GpVar, Imm) + INST_2i(sal, kX86InstIdSal, X86GpVar, Imm) //! \overload - INST_2i(sal, kInstSal, Mem, Imm) + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) //! Shift bits right. - INST_2x(sar, kInstSar, GpVar, GpVar) + INST_2x(sar, kX86InstIdSar, X86GpVar, X86GpVar) //! \overload - INST_2x(sar, kInstSar, Mem, GpVar) + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpVar) //! Shift bits right. - INST_2i(sar, kInstSar, GpVar, Imm) + INST_2i(sar, kX86InstIdSar, X86GpVar, Imm) //! \overload - INST_2i(sar, kInstSar, Mem, Imm) + 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, kInstSet, X86Util::condToSetcc, GpVar) + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpVar) //! Set byte on condition. - INST_1cc(set, kInstSet, X86Util::condToSetcc, Mem) + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) //! Shift bits left. - INST_2x(shl, kInstShl, GpVar, GpVar) + INST_2x(shl, kX86InstIdShl, X86GpVar, X86GpVar) //! \overload - INST_2x(shl, kInstShl, Mem, GpVar) + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpVar) //! Shift bits left. - INST_2i(shl, kInstShl, GpVar, Imm) + INST_2i(shl, kX86InstIdShl, X86GpVar, Imm) //! \overload - INST_2i(shl, kInstShl, Mem, Imm) + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) //! Shift bits right. - INST_2x(shr, kInstShr, GpVar, GpVar) + INST_2x(shr, kX86InstIdShr, X86GpVar, X86GpVar) //! \overload - INST_2x(shr, kInstShr, Mem, GpVar) + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpVar) //! Shift bits right. - INST_2i(shr, kInstShr, GpVar, Imm) + INST_2i(shr, kX86InstIdShr, X86GpVar, Imm) //! \overload - INST_2i(shr, kInstShr, Mem, Imm) + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) //! Double precision shift left. - INST_3x(shld, kInstShld, GpVar, GpVar, GpVar) + INST_3x(shld, kX86InstIdShld, X86GpVar, X86GpVar, X86GpVar) //! \overload - INST_3x(shld, kInstShld, Mem, GpVar, GpVar) + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpVar, X86GpVar) //! Double precision shift left. - INST_3i(shld, kInstShld, GpVar, GpVar, Imm) + INST_3i(shld, kX86InstIdShld, X86GpVar, X86GpVar, Imm) //! \overload - INST_3i(shld, kInstShld, Mem, GpVar, Imm) + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpVar, Imm) //! Double precision shift right. - INST_3x(shrd, kInstShrd, GpVar, GpVar, GpVar) + INST_3x(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, X86GpVar) //! \overload - INST_3x(shrd, kInstShrd, Mem, GpVar, GpVar) + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpVar, X86GpVar) //! Double precision shift right. - INST_3i(shrd, kInstShrd, GpVar, GpVar, Imm) + INST_3i(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, Imm) //! \overload - INST_3i(shrd, kInstShrd, Mem, GpVar, Imm) + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpVar, Imm) //! Set carry flag to 1. - INST_0x(stc, kInstStc) + INST_0x(stc, kX86InstIdStc) //! Set direction flag to 1. - INST_0x(std, kInstStd) + 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, kInstSub, GpVar, GpVar) + INST_2x(sub, kX86InstIdSub, X86GpVar, X86GpVar) //! \overload - INST_2x(sub, kInstSub, GpVar, Mem) + INST_2x(sub, kX86InstIdSub, X86GpVar, X86Mem) //! \overload - INST_2i(sub, kInstSub, GpVar, Imm) + INST_2i(sub, kX86InstIdSub, X86GpVar, Imm) //! \overload - INST_2x(sub, kInstSub, Mem, GpVar) + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpVar) //! \overload - INST_2i(sub, kInstSub, Mem, Imm) + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) //! Logical compare. - INST_2x(test, kInstTest, GpVar, GpVar) + INST_2x(test, kX86InstIdTest, X86GpVar, X86GpVar) //! \overload - INST_2i(test, kInstTest, GpVar, Imm) + INST_2i(test, kX86InstIdTest, X86GpVar, Imm) //! \overload - INST_2x(test, kInstTest, Mem, GpVar) + INST_2x(test, kX86InstIdTest, X86Mem, X86GpVar) //! \overload - INST_2i(test, kInstTest, Mem, Imm) + INST_2i(test, kX86InstIdTest, X86Mem, Imm) //! Undefined instruction - Raise #UD exception. - INST_0x(ud2, kInstUd2) + INST_0x(ud2, kX86InstIdUd2) //! Exchange and add. - INST_2x(xadd, kInstXadd, GpVar, GpVar) + INST_2x(xadd, kX86InstIdXadd, X86GpVar, X86GpVar) //! \overload - INST_2x(xadd, kInstXadd, Mem, GpVar) + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpVar) //! Exchange register/memory with register. - INST_2x(xchg, kInstXchg, GpVar, GpVar) + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86GpVar) //! \overload - INST_2x(xchg, kInstXchg, Mem, GpVar) + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpVar) //! \overload - INST_2x(xchg, kInstXchg, GpVar, Mem) + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86Mem) //! Xor. - INST_2x(xor_, kInstXor, GpVar, GpVar) + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86GpVar) //! \overload - INST_2x(xor_, kInstXor, GpVar, Mem) + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86Mem) //! \overload - INST_2i(xor_, kInstXor, GpVar, Imm) + INST_2i(xor_, kX86InstIdXor, X86GpVar, Imm) //! \overload - INST_2x(xor_, kInstXor, Mem, GpVar) + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpVar) //! \overload - INST_2i(xor_, kInstXor, Mem, Imm) + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [Fpu] + // -------------------------------------------------------------------------- + + //! Compute 2^x - 1 (FPU). + INST_0x(f2xm1, kX86InstIdF2xm1) + //! Absolute value of fp0 (FPU). + INST_0x(fabs, kX86InstIdFabs) + + //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add fp0 to `o0` and pop the FPU stack (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) + //! \overload + INST_0x(faddp, kX86InstIdFaddp) + + //! Load binary coded decimal (FPU). + INST_1x(fbld, kX86InstIdFbld, X86Mem) + //! Store BCD integer and Pop (FPU). + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) + //! Change fp0 sign (FPU). + INST_0x(fchs, kX86InstIdFchs) + //! Clear exceptions (FPU). + INST_0x(fclex, kX86InstIdFclex) + + //! Conditional move (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move (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 4-byte or 8-byte FP at `src` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare fp0 with `o0` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare fp0 with fp1 and pop the FPU stack (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) + //! Compare fp0 and `o0` and Set EFLAGS (FPU). + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) + + //! Calculate cosine of fp0 and store result in fp0 (FPU). + INST_0x(fcos, kX86InstIdFcos) + //! Decrement FPU stack-top pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) + + //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) + //! Divide `o0` by fp0 (FPU). + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) + //! \overload + INST_0x(fdivp, kX86InstIdFdivp) + + //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) + //! Reverse divide `o0` by fp0 (FPU). + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) + //! \overload + INST_0x(fdivrp, kX86InstIdFdivrp) + + //! Free FP register (FPU). + INST_1x(ffree, kX86InstIdFfree, X86FpReg) + + //! Add 16-bit or 32-bit integer to fp0 (FPU). + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer (FPU). + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Increment FPU stack-top pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) + //! Initialize FPU (FPU). + INST_0x(finit, kX86InstIdFinit) + + //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to 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 16-bit or 32-bit Integer to `o0` (FPU). + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Push `o0` on the FPU stack (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) + + //! Push +1.0 on the FPU stack (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! Push log2(10) on the FPU stack (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! Push log2(e) on the FPU stack (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! Push pi on the FPU stack (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! Push log10(2) on the FPU stack (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! Push ln(2) on the FPU stack (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! Push +0.0 on the FPU stack (FPU). + INST_0x(fldz, kX86InstIdFldz) + + //! Load x87 FPU control word (2 bytes) (FPU). + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) + //! Load x87 FPU environment (14 or 28 bytes) (FPU). + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) + + //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) + //! \overload + INST_0x(fmulp, kX86InstIdFmulp) + + //! Clear exceptions (FPU). + INST_0x(fnclex, kX86InstIdFnclex) + //! No operation (FPU). + INST_0x(fnop, kX86InstIdFnop) + //! Save FPU state (FPU). + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) + //! Store x87 FPU environment (FPU). + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) + //! Store x87 FPU control word (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 `o0` (2 bytes) (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) + + //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Arctan(`fp0`) and pop the FPU stack (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0` to Integer (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` by `fp1` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sine of `fp0` and store result in `fp0` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root of `fp0` and store it in `fp0` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + + //! Store floating point value to 32-bit or 64-bit memory location (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Store floating point value to `o0` (FPU). + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Store floating point value to `o0` and pop the FPU stack (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) + + //! Store x87 FPU control word to `o0` (2 bytes) (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` (allocated in AX) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86GpVar) + //! Store x87 FPU status word (2 bytes) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) + + //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract fp0 from `o0` and pop FPU stack (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) + //! \overload + INST_0x(fsubp, kX86InstIdFsubp) + + //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) + //! \overload + INST_0x(fsubrp, kX86InstIdFsubrp) + + //! Floating point test - 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` and `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) + + INST_0x(fwait, kX86InstIdFwait) + + //! Examine fp0 (FPU). + INST_0x(fxam, kX86InstIdFxam) + //! Exchange content of 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 exponent and store to `fp0` and push significand on the FPU stack (FPU). + INST_0x(fxtract, kX86InstIdFxtract) + + //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) // -------------------------------------------------------------------------- // [MMX] // -------------------------------------------------------------------------- //! Move DWORD (MMX). - INST_2x(movd, kInstMovd, Mem, MmVar) + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmVar) //! \overload - INST_2x(movd, kInstMovd, GpVar, MmVar) + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86MmVar) //! \overload - INST_2x(movd, kInstMovd, MmVar, Mem) + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86Mem) //! \overload - INST_2x(movd, kInstMovd, MmVar, GpVar) + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86GpVar) //! Move QWORD (MMX). - INST_2x(movq, kInstMovq, MmVar, MmVar) + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86MmVar) //! \overload - INST_2x(movq, kInstMovq, Mem, MmVar) + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmVar) //! \overload - INST_2x(movq, kInstMovq, MmVar, Mem) + 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, kInstPackssdw, MmVar, MmVar) + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86MmVar) //! \overload - INST_2x(packssdw, kInstPackssdw, MmVar, Mem) + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86Mem) //! Pack WORDs to BYTEs with signed saturation (MMX). - INST_2x(packsswb, kInstPacksswb, MmVar, MmVar) + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86MmVar) //! \overload - INST_2x(packsswb, kInstPacksswb, MmVar, Mem) + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (MMX). - INST_2x(packuswb, kInstPackuswb, MmVar, MmVar) + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86MmVar) //! \overload - INST_2x(packuswb, kInstPackuswb, MmVar, Mem) + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86Mem) //! Packed BYTE add (MMX). - INST_2x(paddb, kInstPaddb, MmVar, MmVar) + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86MmVar) //! \overload - INST_2x(paddb, kInstPaddb, MmVar, Mem) + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86Mem) //! Packed DWORD add (MMX). - INST_2x(paddd, kInstPaddd, MmVar, MmVar) + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86MmVar) //! \overload - INST_2x(paddd, kInstPaddd, MmVar, Mem) + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86Mem) //! Packed BYTE add with saturation (MMX). - INST_2x(paddsb, kInstPaddsb, MmVar, MmVar) + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86MmVar) //! \overload - INST_2x(paddsb, kInstPaddsb, MmVar, Mem) + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86Mem) //! Packed WORD add with saturation (MMX). - INST_2x(paddsw, kInstPaddsw, MmVar, MmVar) + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86MmVar) //! \overload - INST_2x(paddsw, kInstPaddsw, MmVar, Mem) + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86Mem) //! Packed BYTE add with unsigned saturation (MMX). - INST_2x(paddusb, kInstPaddusb, MmVar, MmVar) + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86MmVar) //! \overload - INST_2x(paddusb, kInstPaddusb, MmVar, Mem) + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86Mem) //! Packed WORD add with unsigned saturation (MMX). - INST_2x(paddusw, kInstPaddusw, MmVar, MmVar) + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86MmVar) //! \overload - INST_2x(paddusw, kInstPaddusw, MmVar, Mem) + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86Mem) //! Packed WORD add (MMX). - INST_2x(paddw, kInstPaddw, MmVar, MmVar) + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86MmVar) //! \overload - INST_2x(paddw, kInstPaddw, MmVar, Mem) + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86Mem) //! Packed and (MMX). - INST_2x(pand, kInstPand, MmVar, MmVar) + INST_2x(pand, kX86InstIdPand, X86MmVar, X86MmVar) //! \overload - INST_2x(pand, kInstPand, MmVar, Mem) + INST_2x(pand, kX86InstIdPand, X86MmVar, X86Mem) //! Packed and-not (MMX). - INST_2x(pandn, kInstPandn, MmVar, MmVar) + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86MmVar) //! \overload - INST_2x(pandn, kInstPandn, MmVar, Mem) + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86Mem) //! Packed BYTEs compare for equality (MMX). - INST_2x(pcmpeqb, kInstPcmpeqb, MmVar, MmVar) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpeqb, kInstPcmpeqb, MmVar, Mem) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86Mem) //! Packed DWORDs compare for equality (MMX). - INST_2x(pcmpeqd, kInstPcmpeqd, MmVar, MmVar) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpeqd, kInstPcmpeqd, MmVar, Mem) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86Mem) //! Packed WORDs compare for equality (MMX). - INST_2x(pcmpeqw, kInstPcmpeqw, MmVar, MmVar) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpeqw, kInstPcmpeqw, MmVar, Mem) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86Mem) //! Packed BYTEs compare if greater than (MMX). - INST_2x(pcmpgtb, kInstPcmpgtb, MmVar, MmVar) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpgtb, kInstPcmpgtb, MmVar, Mem) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86Mem) //! Packed DWORDs compare if greater than (MMX). - INST_2x(pcmpgtd, kInstPcmpgtd, MmVar, MmVar) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpgtd, kInstPcmpgtd, MmVar, Mem) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86Mem) //! Packed WORDs compare if greater than (MMX). - INST_2x(pcmpgtw, kInstPcmpgtw, MmVar, MmVar) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86MmVar) //! \overload - INST_2x(pcmpgtw, kInstPcmpgtw, MmVar, Mem) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86Mem) //! Packed WORD multiply high (MMX). - INST_2x(pmulhw, kInstPmulhw, MmVar, MmVar) + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmulhw, kInstPmulhw, MmVar, Mem) + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86Mem) //! Packed WORD multiply low (MMX). - INST_2x(pmullw, kInstPmullw, MmVar, MmVar) + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmullw, kInstPmullw, MmVar, Mem) + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86Mem) //! Packed bitwise or (MMX). - INST_2x(por, kInstPor, MmVar, MmVar) + INST_2x(por, kX86InstIdPor, X86MmVar, X86MmVar) //! \overload - INST_2x(por, kInstPor, MmVar, Mem) + INST_2x(por, kX86InstIdPor, X86MmVar, X86Mem) //! Packed WORD multiply and add to packed DWORD (MMX). - INST_2x(pmaddwd, kInstPmaddwd, MmVar, MmVar) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86MmVar) //! \overload - INST_2x(pmaddwd, kInstPmaddwd, MmVar, Mem) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86Mem) //! Packed DWORD shift left logical (MMX). - INST_2x(pslld, kInstPslld, MmVar, MmVar) + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86MmVar) //! \overload - INST_2x(pslld, kInstPslld, MmVar, Mem) + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86Mem) //! \overload - INST_2i(pslld, kInstPslld, MmVar, Imm) + INST_2i(pslld, kX86InstIdPslld, X86MmVar, Imm) //! Packed QWORD shift left logical (MMX). - INST_2x(psllq, kInstPsllq, MmVar, MmVar) + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86MmVar) //! \overload - INST_2x(psllq, kInstPsllq, MmVar, Mem) + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86Mem) //! \overload - INST_2i(psllq, kInstPsllq, MmVar, Imm) + INST_2i(psllq, kX86InstIdPsllq, X86MmVar, Imm) //! Packed WORD shift left logical (MMX). - INST_2x(psllw, kInstPsllw, MmVar, MmVar) + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86MmVar) //! \overload - INST_2x(psllw, kInstPsllw, MmVar, Mem) + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86Mem) //! \overload - INST_2i(psllw, kInstPsllw, MmVar, Imm) + INST_2i(psllw, kX86InstIdPsllw, X86MmVar, Imm) //! Packed DWORD shift right arithmetic (MMX). - INST_2x(psrad, kInstPsrad, MmVar, MmVar) + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86MmVar) //! \overload - INST_2x(psrad, kInstPsrad, MmVar, Mem) + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86Mem) //! \overload - INST_2i(psrad, kInstPsrad, MmVar, Imm) + INST_2i(psrad, kX86InstIdPsrad, X86MmVar, Imm) //! Packed WORD shift right arithmetic (MMX). - INST_2x(psraw, kInstPsraw, MmVar, MmVar) + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86MmVar) //! \overload - INST_2x(psraw, kInstPsraw, MmVar, Mem) + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86Mem) //! \overload - INST_2i(psraw, kInstPsraw, MmVar, Imm) + INST_2i(psraw, kX86InstIdPsraw, X86MmVar, Imm) //! Packed DWORD shift right logical (MMX). - INST_2x(psrld, kInstPsrld, MmVar, MmVar) + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86MmVar) //! \overload - INST_2x(psrld, kInstPsrld, MmVar, Mem) + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86Mem) //! \overload - INST_2i(psrld, kInstPsrld, MmVar, Imm) + INST_2i(psrld, kX86InstIdPsrld, X86MmVar, Imm) //! Packed QWORD shift right logical (MMX). - INST_2x(psrlq, kInstPsrlq, MmVar, MmVar) + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86MmVar) //! \overload - INST_2x(psrlq, kInstPsrlq, MmVar, Mem) + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86Mem) //! \overload - INST_2i(psrlq, kInstPsrlq, MmVar, Imm) + INST_2i(psrlq, kX86InstIdPsrlq, X86MmVar, Imm) //! Packed WORD shift right logical (MMX). - INST_2x(psrlw, kInstPsrlw, MmVar, MmVar) + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86MmVar) //! \overload - INST_2x(psrlw, kInstPsrlw, MmVar, Mem) + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86Mem) //! \overload - INST_2i(psrlw, kInstPsrlw, MmVar, Imm) + INST_2i(psrlw, kX86InstIdPsrlw, X86MmVar, Imm) //! Packed BYTE subtract (MMX). - INST_2x(psubb, kInstPsubb, MmVar, MmVar) + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86MmVar) //! \overload - INST_2x(psubb, kInstPsubb, MmVar, Mem) + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86Mem) //! Packed DWORD subtract (MMX). - INST_2x(psubd, kInstPsubd, MmVar, MmVar) + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86MmVar) //! \overload - INST_2x(psubd, kInstPsubd, MmVar, Mem) + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86Mem) //! Packed BYTE subtract with saturation (MMX). - INST_2x(psubsb, kInstPsubsb, MmVar, MmVar) + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86MmVar) //! \overload - INST_2x(psubsb, kInstPsubsb, MmVar, Mem) + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86Mem) //! Packed WORD subtract with saturation (MMX). - INST_2x(psubsw, kInstPsubsw, MmVar, MmVar) + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86MmVar) //! \overload - INST_2x(psubsw, kInstPsubsw, MmVar, Mem) + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86Mem) //! Packed BYTE subtract with unsigned saturation (MMX). - INST_2x(psubusb, kInstPsubusb, MmVar, MmVar) + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86MmVar) //! \overload - INST_2x(psubusb, kInstPsubusb, MmVar, Mem) + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86Mem) //! Packed WORD subtract with unsigned saturation (MMX). - INST_2x(psubusw, kInstPsubusw, MmVar, MmVar) + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86MmVar) //! \overload - INST_2x(psubusw, kInstPsubusw, MmVar, Mem) + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86Mem) //! Packed WORD subtract (MMX). - INST_2x(psubw, kInstPsubw, MmVar, MmVar) + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86MmVar) //! \overload - INST_2x(psubw, kInstPsubw, MmVar, Mem) + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86Mem) //! Unpack high packed BYTEs to WORDs (MMX). - INST_2x(punpckhbw, kInstPunpckhbw, MmVar, MmVar) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86MmVar) //! \overload - INST_2x(punpckhbw, kInstPunpckhbw, MmVar, Mem) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86Mem) //! Unpack high packed DWORDs to QWORDs (MMX). - INST_2x(punpckhdq, kInstPunpckhdq, MmVar, MmVar) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86MmVar) //! \overload - INST_2x(punpckhdq, kInstPunpckhdq, MmVar, Mem) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86Mem) //! Unpack high packed WORDs to DWORDs (MMX). - INST_2x(punpckhwd, kInstPunpckhwd, MmVar, MmVar) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86MmVar) //! \overload - INST_2x(punpckhwd, kInstPunpckhwd, MmVar, Mem) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86Mem) //! Unpack low packed BYTEs to WORDs (MMX). - INST_2x(punpcklbw, kInstPunpcklbw, MmVar, MmVar) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86MmVar) //! \overload - INST_2x(punpcklbw, kInstPunpcklbw, MmVar, Mem) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86Mem) //! Unpack low packed DWORDs to QWORDs (MMX). - INST_2x(punpckldq, kInstPunpckldq, MmVar, MmVar) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86MmVar) //! \overload - INST_2x(punpckldq, kInstPunpckldq, MmVar, Mem) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86Mem) //! Unpack low packed WORDs to DWORDs (MMX). - INST_2x(punpcklwd, kInstPunpcklwd, MmVar, MmVar) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86MmVar) //! \overload - INST_2x(punpcklwd, kInstPunpcklwd, MmVar, Mem) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86Mem) //! Packed bitwise xor (MMX). - INST_2x(pxor, kInstPxor, MmVar, MmVar) + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86MmVar) //! \overload - INST_2x(pxor, kInstPxor, MmVar, Mem) + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86Mem) //! Empty MMX state. - INST_0x(emms, kInstEmms) + INST_0x(emms, kX86InstIdEmms) // -------------------------------------------------------------------------- // [3dNow] // -------------------------------------------------------------------------- //! Packed SP-FP to DWORD convert (3dNow!). - INST_2x(pf2id, kInstPf2id, MmVar, MmVar) + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86MmVar) //! \overload - INST_2x(pf2id, kInstPf2id, MmVar, Mem) + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86Mem) //! Packed SP-FP to WORD convert (3dNow!). - INST_2x(pf2iw, kInstPf2iw, MmVar, MmVar) + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86MmVar) //! \overload - INST_2x(pf2iw, kInstPf2iw, MmVar, Mem) + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86Mem) //! Packed SP-FP accumulate (3dNow!). - INST_2x(pfacc, kInstPfacc, MmVar, MmVar) + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86MmVar) //! \overload - INST_2x(pfacc, kInstPfacc, MmVar, Mem) + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86Mem) //! Packed SP-FP addition (3dNow!). - INST_2x(pfadd, kInstPfadd, MmVar, MmVar) + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86MmVar) //! \overload - INST_2x(pfadd, kInstPfadd, MmVar, Mem) + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86Mem) //! Packed SP-FP compare - dst == src (3dNow!). - INST_2x(pfcmpeq, kInstPfcmpeq, MmVar, MmVar) + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86MmVar) //! \overload - INST_2x(pfcmpeq, kInstPfcmpeq, MmVar, Mem) + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86Mem) //! Packed SP-FP compare - dst >= src (3dNow!). - INST_2x(pfcmpge, kInstPfcmpge, MmVar, MmVar) + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86MmVar) //! \overload - INST_2x(pfcmpge, kInstPfcmpge, MmVar, Mem) + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86Mem) //! Packed SP-FP compare - dst > src (3dNow!). - INST_2x(pfcmpgt, kInstPfcmpgt, MmVar, MmVar) + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86MmVar) //! \overload - INST_2x(pfcmpgt, kInstPfcmpgt, MmVar, Mem) + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86Mem) //! Packed SP-FP maximum (3dNow!). - INST_2x(pfmax, kInstPfmax, MmVar, MmVar) + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86MmVar) //! \overload - INST_2x(pfmax, kInstPfmax, MmVar, Mem) + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86Mem) //! Packed SP-FP minimum (3dNow!). - INST_2x(pfmin, kInstPfmin, MmVar, MmVar) + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86MmVar) //! \overload - INST_2x(pfmin, kInstPfmin, MmVar, Mem) + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86Mem) //! Packed SP-FP multiply (3dNow!). - INST_2x(pfmul, kInstPfmul, MmVar, MmVar) + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86MmVar) //! \overload - INST_2x(pfmul, kInstPfmul, MmVar, Mem) + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86Mem) //! Packed SP-FP negative accumulate (3dNow!). - INST_2x(pfnacc, kInstPfnacc, MmVar, MmVar) + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86MmVar) //! \overload - INST_2x(pfnacc, kInstPfnacc, MmVar, Mem) + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86Mem) //! Packed SP-FP mixed accumulate (3dNow!). - INST_2x(pfpnacc, kInstPfpnacc, MmVar, MmVar) + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86MmVar) //! \overload - INST_2x(pfpnacc, kInstPfpnacc, MmVar, Mem) + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86Mem) //! Packed SP-FP reciprocal approximation (3dNow!). - INST_2x(pfrcp, kInstPfrcp, MmVar, MmVar) + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86MmVar) //! \overload - INST_2x(pfrcp, kInstPfrcp, MmVar, Mem) + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86Mem) //! Packed SP-FP reciprocal, first iteration step (3dNow!). - INST_2x(pfrcpit1, kInstPfrcpit1, MmVar, MmVar) + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86MmVar) //! \overload - INST_2x(pfrcpit1, kInstPfrcpit1, MmVar, Mem) + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86Mem) //! Packed SP-FP reciprocal, second iteration step (3dNow!). - INST_2x(pfrcpit2, kInstPfrcpit2, MmVar, MmVar) + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86MmVar) //! \overload - INST_2x(pfrcpit2, kInstPfrcpit2, MmVar, Mem) + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86Mem) //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). - INST_2x(pfrsqit1, kInstPfrsqit1, MmVar, MmVar) + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86MmVar) //! \overload - INST_2x(pfrsqit1, kInstPfrsqit1, MmVar, Mem) + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86Mem) //! Packed SP-FP reciprocal square root approximation (3dNow!). - INST_2x(pfrsqrt, kInstPfrsqrt, MmVar, MmVar) + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86MmVar) //! \overload - INST_2x(pfrsqrt, kInstPfrsqrt, MmVar, Mem) + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86Mem) //! Packed SP-FP subtract (3dNow!). - INST_2x(pfsub, kInstPfsub, MmVar, MmVar) + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86MmVar) //! \overload - INST_2x(pfsub, kInstPfsub, MmVar, Mem) + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86Mem) //! Packed SP-FP reverse subtract (3dNow!). - INST_2x(pfsubr, kInstPfsubr, MmVar, MmVar) + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86MmVar) //! \overload - INST_2x(pfsubr, kInstPfsubr, MmVar, Mem) + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86Mem) //! Packed DWORDs to SP-FP (3dNow!). - INST_2x(pi2fd, kInstPi2fd, MmVar, MmVar) + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86MmVar) //! \overload - INST_2x(pi2fd, kInstPi2fd, MmVar, Mem) + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86Mem) //! Packed WORDs to SP-FP (3dNow!). - INST_2x(pi2fw, kInstPi2fw, MmVar, MmVar) + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86MmVar) //! \overload - INST_2x(pi2fw, kInstPi2fw, MmVar, Mem) + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86Mem) //! Packed swap DWORDs (3dNow!) - INST_2x(pswapd, kInstPswapd, MmVar, MmVar) + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86MmVar) //! \overload - INST_2x(pswapd, kInstPswapd, MmVar, Mem) + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86Mem) //! Prefetch (3dNow!). - INST_1x(prefetch_3dnow, kInstPrefetch3dNow, Mem) + INST_1x(prefetch_3dnow, kX86InstIdPrefetch3dNow, X86Mem) //! Prefetch and set cache to modified (3dNow!). - INST_1x(prefetchw_3dnow, kInstPrefetchw3dNow, Mem) + INST_1x(prefetchw_3dnow, kX86InstIdPrefetchw3dNow, X86Mem) //! Faster EMMS (3dNow!). - INST_0x(femms, kInstFemms) + INST_0x(femms, kX86InstIdFemms) // -------------------------------------------------------------------------- // [SSE] // -------------------------------------------------------------------------- //! Packed SP-FP add (SSE). - INST_2x(addps, kInstAddps, XmmVar, XmmVar) + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addps, kInstAddps, XmmVar, Mem) + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86Mem) //! Scalar SP-FP add (SSE). - INST_2x(addss, kInstAddss, XmmVar, XmmVar) + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addss, kInstAddss, XmmVar, Mem) + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86Mem) //! Packed SP-FP bitwise and-not (SSE). - INST_2x(andnps, kInstAndnps, XmmVar, XmmVar) + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(andnps, kInstAndnps, XmmVar, Mem) + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86Mem) //! Packed SP-FP bitwise and (SSE). - INST_2x(andps, kInstAndps, XmmVar, XmmVar) + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(andps, kInstAndps, XmmVar, Mem) + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86Mem) //! Packed SP-FP compare (SSE). - INST_3i(cmpps, kInstCmpps, XmmVar, XmmVar, Imm) + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(cmpps, kInstCmpps, XmmVar, Mem, Imm) + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86Mem, Imm) //! Compare scalar SP-FP Values (SSE). - INST_3i(cmpss, kInstCmpss, XmmVar, XmmVar, Imm) + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(cmpss, kInstCmpss, XmmVar, Mem, Imm) + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86Mem, Imm) //! Scalar ordered SP-FP compare and set EFLAGS (SSE). - INST_2x(comiss, kInstComiss, XmmVar, XmmVar) + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(comiss, kInstComiss, XmmVar, Mem) + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86Mem) //! Packed signed INT32 to packed SP-FP conversion (SSE). - INST_2x(cvtpi2ps, kInstCvtpi2ps, XmmVar, MmVar) + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86MmVar) //! \overload - INST_2x(cvtpi2ps, kInstCvtpi2ps, XmmVar, Mem) + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86Mem) //! Packed SP-FP to packed INT32 conversion (SSE). - INST_2x(cvtps2pi, kInstCvtps2pi, MmVar, XmmVar) + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86XmmVar) //! \overload - INST_2x(cvtps2pi, kInstCvtps2pi, MmVar, Mem) + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86Mem) //! Convert scalar INT32 to SP-FP (SSE). - INST_2x(cvtsi2ss, kInstCvtsi2ss, XmmVar, GpVar) + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86GpVar) //! \overload - INST_2x(cvtsi2ss, kInstCvtsi2ss, XmmVar, Mem) + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86Mem) //! Convert scalar SP-FP to INT32 (SSE). - INST_2x(cvtss2si, kInstCvtss2si, GpVar, XmmVar) + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86XmmVar) //! \overload - INST_2x(cvtss2si, kInstCvtss2si, GpVar, Mem) + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86Mem) //! Convert with truncation packed SP-FP to packed INT32 (SSE). - INST_2x(cvttps2pi, kInstCvttps2pi, MmVar, XmmVar) + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86XmmVar) //! \overload - INST_2x(cvttps2pi, kInstCvttps2pi, MmVar, Mem) + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86Mem) //! Convert with truncation scalar SP-FP to INT32 (SSE). - INST_2x(cvttss2si, kInstCvttss2si, GpVar, XmmVar) + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86XmmVar) //! \overload - INST_2x(cvttss2si, kInstCvttss2si, GpVar, Mem) + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86Mem) //! Packed SP-FP divide (SSE). - INST_2x(divps, kInstDivps, XmmVar, XmmVar) + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(divps, kInstDivps, XmmVar, Mem) + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86Mem) //! Scalar SP-FP divide (SSE). - INST_2x(divss, kInstDivss, XmmVar, XmmVar) + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(divss, kInstDivss, XmmVar, Mem) + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86Mem) //! Load streaming SIMD extension control/status (SSE). - INST_1x(ldmxcsr, kInstLdmxcsr, Mem) + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) //! Byte mask write (SSE). - INST_3x(maskmovq, kInstMaskmovq, GpVar /* zdi */, MmVar, MmVar) + INST_3x(maskmovq, kX86InstIdMaskmovq, X86GpVar /* zdi */, X86MmVar, X86MmVar) //! Packed SP-FP maximum (SSE). - INST_2x(maxps, kInstMaxps, XmmVar, XmmVar) + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(maxps, kInstMaxps, XmmVar, Mem) + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86Mem) //! Scalar SP-FP maximum (SSE). - INST_2x(maxss, kInstMaxss, XmmVar, XmmVar) + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(maxss, kInstMaxss, XmmVar, Mem) + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86Mem) //! Packed SP-FP minimum (SSE). - INST_2x(minps, kInstMinps, XmmVar, XmmVar) + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(minps, kInstMinps, XmmVar, Mem) + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86Mem) //! Scalar SP-FP minimum (SSE). - INST_2x(minss, kInstMinss, XmmVar, XmmVar) + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(minss, kInstMinss, XmmVar, Mem) + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86Mem) //! Move aligned packed SP-FP (SSE). - INST_2x(movaps, kInstMovaps, XmmVar, XmmVar) + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movaps, kInstMovaps, XmmVar, Mem) + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86Mem) //! Move aligned packed SP-FP (SSE). - INST_2x(movaps, kInstMovaps, Mem, XmmVar) + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmVar) //! Move DWORD. - INST_2x(movd, kInstMovd, Mem, XmmVar) + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmVar) //! \overload - INST_2x(movd, kInstMovd, GpVar, XmmVar) + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86XmmVar) //! \overload - INST_2x(movd, kInstMovd, XmmVar, Mem) + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86Mem) //! \overload - INST_2x(movd, kInstMovd, XmmVar, GpVar) + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86GpVar) //! Move QWORD (SSE). - INST_2x(movq, kInstMovq, XmmVar, XmmVar) + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movq, kInstMovq, Mem, XmmVar) + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmVar) //! \overload - INST_2x(movq, kInstMovq, XmmVar, Mem) + 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, kInstMovntq, Mem, MmVar) + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmVar) //! Move high to low packed SP-FP (SSE). - INST_2x(movhlps, kInstMovhlps, XmmVar, XmmVar) + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmVar, X86XmmVar) //! Move high packed SP-FP (SSE). - INST_2x(movhps, kInstMovhps, XmmVar, Mem) + INST_2x(movhps, kX86InstIdMovhps, X86XmmVar, X86Mem) //! Move high packed SP-FP (SSE). - INST_2x(movhps, kInstMovhps, Mem, XmmVar) + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmVar) //! Move low to high packed SP-FP (SSE). - INST_2x(movlhps, kInstMovlhps, XmmVar, XmmVar) + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmVar, X86XmmVar) //! Move low packed SP-FP (SSE). - INST_2x(movlps, kInstMovlps, XmmVar, Mem) + INST_2x(movlps, kX86InstIdMovlps, X86XmmVar, X86Mem) //! Move low packed SP-FP (SSE). - INST_2x(movlps, kInstMovlps, Mem, XmmVar) + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmVar) //! Move aligned packed SP-FP using NT hint (SSE). - INST_2x(movntps, kInstMovntps, Mem, XmmVar) + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmVar) //! Move scalar SP-FP (SSE). - INST_2x(movss, kInstMovss, XmmVar, XmmVar) + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movss, kInstMovss, XmmVar, Mem) + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86Mem) //! \overload - INST_2x(movss, kInstMovss, Mem, XmmVar) + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmVar) //! Move unaligned packed SP-FP (SSE). - INST_2x(movups, kInstMovups, XmmVar, XmmVar) + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movups, kInstMovups, XmmVar, Mem) + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86Mem) //! \overload - INST_2x(movups, kInstMovups, Mem, XmmVar) + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmVar) //! Packed SP-FP multiply (SSE). - INST_2x(mulps, kInstMulps, XmmVar, XmmVar) + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(mulps, kInstMulps, XmmVar, Mem) + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86Mem) //! Scalar SP-FP multiply (SSE). - INST_2x(mulss, kInstMulss, XmmVar, XmmVar) + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(mulss, kInstMulss, XmmVar, Mem) + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86Mem) //! Packed SP-FP bitwise or (SSE). - INST_2x(orps, kInstOrps, XmmVar, XmmVar) + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(orps, kInstOrps, XmmVar, Mem) + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86Mem) //! Packed BYTE average (SSE). - INST_2x(pavgb, kInstPavgb, MmVar, MmVar) + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86MmVar) //! \overload - INST_2x(pavgb, kInstPavgb, MmVar, Mem) + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86Mem) //! Packed WORD average (SSE). - INST_2x(pavgw, kInstPavgw, MmVar, MmVar) + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86MmVar) //! \overload - INST_2x(pavgw, kInstPavgw, MmVar, Mem) + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86Mem) //! Extract WORD based on selector (SSE). - INST_3i(pextrw, kInstPextrw, GpVar, MmVar, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86MmVar, Imm) //! Insert WORD based on selector (SSE). - INST_3i(pinsrw, kInstPinsrw, MmVar, GpVar, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86GpVar, Imm) //! \overload - INST_3i(pinsrw, kInstPinsrw, MmVar, Mem, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86Mem, Imm) //! Packed WORD maximum (SSE). - INST_2x(pmaxsw, kInstPmaxsw, MmVar, MmVar) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmaxsw, kInstPmaxsw, MmVar, Mem) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86Mem) //! Packed BYTE unsigned maximum (SSE). - INST_2x(pmaxub, kInstPmaxub, MmVar, MmVar) + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86MmVar) //! \overload - INST_2x(pmaxub, kInstPmaxub, MmVar, Mem) + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86Mem) //! Packed WORD minimum (SSE). - INST_2x(pminsw, kInstPminsw, MmVar, MmVar) + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86MmVar) //! \overload - INST_2x(pminsw, kInstPminsw, MmVar, Mem) + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86Mem) //! Packed BYTE unsigned minimum (SSE). - INST_2x(pminub, kInstPminub, MmVar, MmVar) + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86MmVar) //! \overload - INST_2x(pminub, kInstPminub, MmVar, Mem) + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86Mem) //! Move byte mask to integer (SSE). - INST_2x(pmovmskb, kInstPmovmskb, GpVar, MmVar) + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86MmVar) //! Packed WORD unsigned multiply high (SSE). - INST_2x(pmulhuw, kInstPmulhuw, MmVar, MmVar) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmulhuw, kInstPmulhuw, MmVar, Mem) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86Mem) //! Packed WORD sum of absolute differences (SSE). - INST_2x(psadbw, kInstPsadbw, MmVar, MmVar) + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86MmVar) //! \overload - INST_2x(psadbw, kInstPsadbw, MmVar, Mem) + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86Mem) //! Packed WORD shuffle (SSE). - INST_3i(pshufw, kInstPshufw, MmVar, MmVar, Imm) + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86MmVar, Imm) //! \overload - INST_3i(pshufw, kInstPshufw, MmVar, Mem, Imm) + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86Mem, Imm) //! Packed SP-FP reciprocal (SSE). - INST_2x(rcpps, kInstRcpps, XmmVar, XmmVar) + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(rcpps, kInstRcpps, XmmVar, Mem) + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86Mem) //! Scalar SP-FP reciprocal (SSE). - INST_2x(rcpss, kInstRcpss, XmmVar, XmmVar) + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(rcpss, kInstRcpss, XmmVar, Mem) + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86Mem) //! Prefetch (SSE). - INST_2i(prefetch, kInstPrefetch, Mem, Imm) + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) //! Packed WORD sum of absolute differences (SSE). - INST_2x(psadbw, kInstPsadbw, XmmVar, XmmVar) + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psadbw, kInstPsadbw, XmmVar, Mem) + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86Mem) //! Packed SP-FP Square root reciprocal (SSE). - INST_2x(rsqrtps, kInstRsqrtps, XmmVar, XmmVar) + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(rsqrtps, kInstRsqrtps, XmmVar, Mem) + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86Mem) //! Scalar SP-FP Square root reciprocal (SSE). - INST_2x(rsqrtss, kInstRsqrtss, XmmVar, XmmVar) + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(rsqrtss, kInstRsqrtss, XmmVar, Mem) + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86Mem) //! Store fence (SSE). - INST_0x(sfence, kInstSfence) + INST_0x(sfence, kX86InstIdSfence) //! Shuffle SP-FP (SSE). - INST_3i(shufps, kInstShufps, XmmVar, XmmVar, Imm) + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(shufps, kInstShufps, XmmVar, Mem, Imm) + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86Mem, Imm) //! Packed SP-FP square root (SSE). - INST_2x(sqrtps, kInstSqrtps, XmmVar, XmmVar) + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(sqrtps, kInstSqrtps, XmmVar, Mem) + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86Mem) //! Scalar SP-FP square root (SSE). - INST_2x(sqrtss, kInstSqrtss, XmmVar, XmmVar) + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(sqrtss, kInstSqrtss, XmmVar, Mem) + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86Mem) //! Store streaming SIMD extension control/status (SSE). - INST_1x(stmxcsr, kInstStmxcsr, Mem) + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) //! Packed SP-FP subtract (SSE). - INST_2x(subps, kInstSubps, XmmVar, XmmVar) + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(subps, kInstSubps, XmmVar, Mem) + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86Mem) //! Scalar SP-FP subtract (SSE). - INST_2x(subss, kInstSubss, XmmVar, XmmVar) + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(subss, kInstSubss, XmmVar, Mem) + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86Mem) //! Unordered scalar SP-FP compare and set EFLAGS (SSE). - INST_2x(ucomiss, kInstUcomiss, XmmVar, XmmVar) + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(ucomiss, kInstUcomiss, XmmVar, Mem) + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86Mem) //! Unpack high packed SP-FP data (SSE). - INST_2x(unpckhps, kInstUnpckhps, XmmVar, XmmVar) + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(unpckhps, kInstUnpckhps, XmmVar, Mem) + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86Mem) //! Unpack low packed SP-FP data (SSE). - INST_2x(unpcklps, kInstUnpcklps, XmmVar, XmmVar) + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(unpcklps, kInstUnpcklps, XmmVar, Mem) + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86Mem) //! Packed SP-FP bitwise xor (SSE). - INST_2x(xorps, kInstXorps, XmmVar, XmmVar) + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(xorps, kInstXorps, XmmVar, Mem) + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86Mem) // -------------------------------------------------------------------------- // [SSE2] // -------------------------------------------------------------------------- //! Packed DP-FP add (SSE2). - INST_2x(addpd, kInstAddpd, XmmVar, XmmVar) + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addpd, kInstAddpd, XmmVar, Mem) + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86Mem) //! Scalar DP-FP add (SSE2). - INST_2x(addsd, kInstAddsd, XmmVar, XmmVar) + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addsd, kInstAddsd, XmmVar, Mem) + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86Mem) //! Packed DP-FP bitwise and-not (SSE2). - INST_2x(andnpd, kInstAndnpd, XmmVar, XmmVar) + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(andnpd, kInstAndnpd, XmmVar, Mem) + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86Mem) //! Packed DP-FP bitwise and (SSE2). - INST_2x(andpd, kInstAndpd, XmmVar, XmmVar) + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(andpd, kInstAndpd, XmmVar, Mem) + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86Mem) //! Flush cache line (SSE2). - INST_1x(clflush, kInstClflush, Mem) + INST_1x(clflush, kX86InstIdClflush, X86Mem) //! Packed DP-FP compare (SSE2). - INST_3i(cmppd, kInstCmppd, XmmVar, XmmVar, Imm) + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(cmppd, kInstCmppd, XmmVar, Mem, Imm) + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86Mem, Imm) //! Scalar SP-FP compare (SSE2). - INST_3i(cmpsd, kInstCmpsd, XmmVar, XmmVar, Imm) + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(cmpsd, kInstCmpsd, XmmVar, Mem, Imm) + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86Mem, Imm) //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). - INST_2x(comisd, kInstComisd, XmmVar, XmmVar) + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(comisd, kInstComisd, XmmVar, Mem) + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86Mem) //! Convert packed DWORD integers to packed DP-FP (SSE2). - INST_2x(cvtdq2pd, kInstCvtdq2pd, XmmVar, XmmVar) + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtdq2pd, kInstCvtdq2pd, XmmVar, Mem) + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86Mem) //! Convert packed DWORD integers to packed SP-FP (SSE2). - INST_2x(cvtdq2ps, kInstCvtdq2ps, XmmVar, XmmVar) + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtdq2ps, kInstCvtdq2ps, XmmVar, Mem) + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86Mem) //! Convert packed DP-FP to packed DWORDs (SSE2). - INST_2x(cvtpd2dq, kInstCvtpd2dq, XmmVar, XmmVar) + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtpd2dq, kInstCvtpd2dq, XmmVar, Mem) + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86Mem) //! Convert packed DP-FP to packed DWORDs (SSE2). - INST_2x(cvtpd2pi, kInstCvtpd2pi, MmVar, XmmVar) + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86XmmVar) //! \overload - INST_2x(cvtpd2pi, kInstCvtpd2pi, MmVar, Mem) + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86Mem) //! Convert packed DP-FP to packed SP-FP (SSE2). - INST_2x(cvtpd2ps, kInstCvtpd2ps, XmmVar, XmmVar) + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtpd2ps, kInstCvtpd2ps, XmmVar, Mem) + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86Mem) //! Convert packed DWORDs to packed DP-FP (SSE2). - INST_2x(cvtpi2pd, kInstCvtpi2pd, XmmVar, MmVar) + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86MmVar) //! \overload - INST_2x(cvtpi2pd, kInstCvtpi2pd, XmmVar, Mem) + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86Mem) //! Convert packed SP-FP to packed DWORDs (SSE2). - INST_2x(cvtps2dq, kInstCvtps2dq, XmmVar, XmmVar) + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtps2dq, kInstCvtps2dq, XmmVar, Mem) + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86Mem) //! Convert packed SP-FP to packed DP-FP (SSE2). - INST_2x(cvtps2pd, kInstCvtps2pd, XmmVar, XmmVar) + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtps2pd, kInstCvtps2pd, XmmVar, Mem) + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86Mem) //! Convert scalar DP-FP to DWORD (SSE2). - INST_2x(cvtsd2si, kInstCvtsd2si, GpVar, XmmVar) + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86XmmVar) //! \overload - INST_2x(cvtsd2si, kInstCvtsd2si, GpVar, Mem) + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86Mem) //! Convert scalar DP-FP to scalar SP-FP (SSE2). - INST_2x(cvtsd2ss, kInstCvtsd2ss, XmmVar, XmmVar) + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtsd2ss, kInstCvtsd2ss, XmmVar, Mem) + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86Mem) //! Convert DWORD to scalar DP-FP (SSE2). - INST_2x(cvtsi2sd, kInstCvtsi2sd, XmmVar, GpVar) + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86GpVar) //! \overload - INST_2x(cvtsi2sd, kInstCvtsi2sd, XmmVar, Mem) + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86Mem) //! Convert scalar SP-FP to DP-FP (SSE2). - INST_2x(cvtss2sd, kInstCvtss2sd, XmmVar, XmmVar) + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvtss2sd, kInstCvtss2sd, XmmVar, Mem) + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86Mem) //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). - INST_2x(cvttpd2pi, kInstCvttpd2pi, MmVar, XmmVar) + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86XmmVar) //! \overload - INST_2x(cvttpd2pi, kInstCvttpd2pi, MmVar, Mem) + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86Mem) //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). - INST_2x(cvttpd2dq, kInstCvttpd2dq, XmmVar, XmmVar) + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvttpd2dq, kInstCvttpd2dq, XmmVar, Mem) + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86Mem) //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). - INST_2x(cvttps2dq, kInstCvttps2dq, XmmVar, XmmVar) + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(cvttps2dq, kInstCvttps2dq, XmmVar, Mem) + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86Mem) //! Convert with truncation scalar DP-FP to DWORD (SSE2). - INST_2x(cvttsd2si, kInstCvttsd2si, GpVar, XmmVar) + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86XmmVar) //! \overload - INST_2x(cvttsd2si, kInstCvttsd2si, GpVar, Mem) + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86Mem) //! Packed DP-FP divide (SSE2). - INST_2x(divpd, kInstDivpd, XmmVar, XmmVar) + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(divpd, kInstDivpd, XmmVar, Mem) + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86Mem) //! Scalar DP-FP divide (SSE2). - INST_2x(divsd, kInstDivsd, XmmVar, XmmVar) + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(divsd, kInstDivsd, XmmVar, Mem) + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86Mem) //! Load fence (SSE2). - INST_0x(lfence, kInstLfence) + INST_0x(lfence, kX86InstIdLfence) //! Store selected bytes of OWORD (SSE2). - INST_3x(maskmovdqu, kInstMaskmovdqu, GpVar /* zdi */, XmmVar, XmmVar) + INST_3x(maskmovdqu, kX86InstIdMaskmovdqu, X86GpVar /* zdi */, X86XmmVar, X86XmmVar) //! Packed DP-FP maximum (SSE2). - INST_2x(maxpd, kInstMaxpd, XmmVar, XmmVar) + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(maxpd, kInstMaxpd, XmmVar, Mem) + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86Mem) //! Scalar DP-FP maximum (SSE2). - INST_2x(maxsd, kInstMaxsd, XmmVar, XmmVar) + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(maxsd, kInstMaxsd, XmmVar, Mem) + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86Mem) //! Memory fence (SSE2). - INST_0x(mfence, kInstMfence) + INST_0x(mfence, kX86InstIdMfence) //! Packed DP-FP minimum (SSE2). - INST_2x(minpd, kInstMinpd, XmmVar, XmmVar) + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(minpd, kInstMinpd, XmmVar, Mem) + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86Mem) //! Scalar DP-FP minimum (SSE2). - INST_2x(minsd, kInstMinsd, XmmVar, XmmVar) + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(minsd, kInstMinsd, XmmVar, Mem) + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86Mem) //! Move aligned OWORD (SSE2). - INST_2x(movdqa, kInstMovdqa, XmmVar, XmmVar) + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movdqa, kInstMovdqa, XmmVar, Mem) + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86Mem) //! \overload - INST_2x(movdqa, kInstMovdqa, Mem, XmmVar) + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmVar) //! Move unaligned OWORD (SSE2). - INST_2x(movdqu, kInstMovdqu, XmmVar, XmmVar) + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movdqu, kInstMovdqu, XmmVar, Mem) + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86Mem) //! \overload - INST_2x(movdqu, kInstMovdqu, Mem, XmmVar) + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmVar) //! Extract packed SP-FP sign mask (SSE2). - INST_2x(movmskps, kInstMovmskps, GpVar, XmmVar) + INST_2x(movmskps, kX86InstIdMovmskps, X86GpVar, X86XmmVar) //! Extract packed DP-FP sign mask (SSE2). - INST_2x(movmskpd, kInstMovmskpd, GpVar, XmmVar) + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpVar, X86XmmVar) //! Move scalar DP-FP (SSE2). - INST_2x(movsd, kInstMovsd, XmmVar, XmmVar) + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movsd, kInstMovsd, XmmVar, Mem) + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86Mem) //! \overload - INST_2x(movsd, kInstMovsd, Mem, XmmVar) + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmVar) //! Move aligned packed DP-FP (SSE2). - INST_2x(movapd, kInstMovapd, XmmVar, XmmVar) + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movapd, kInstMovapd, XmmVar, Mem) + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86Mem) //! \overload - INST_2x(movapd, kInstMovapd, Mem, XmmVar) + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmVar) //! Move QWORD from Xmm to Mm register (SSE2). - INST_2x(movdq2q, kInstMovdq2q, MmVar, XmmVar) + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmVar, X86XmmVar) //! Move QWORD from Mm to Xmm register (SSE2). - INST_2x(movq2dq, kInstMovq2dq, XmmVar, MmVar) + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmVar, X86MmVar) //! Move high packed DP-FP (SSE2). - INST_2x(movhpd, kInstMovhpd, XmmVar, Mem) + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmVar, X86Mem) //! \overload - INST_2x(movhpd, kInstMovhpd, Mem, XmmVar) + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmVar) //! Move low packed DP-FP (SSE2). - INST_2x(movlpd, kInstMovlpd, XmmVar, Mem) + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmVar, X86Mem) //! \overload - INST_2x(movlpd, kInstMovlpd, Mem, XmmVar) + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmVar) //! Store OWORD using NT hint (SSE2). - INST_2x(movntdq, kInstMovntdq, Mem, XmmVar) + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmVar) //! Store DWORD using NT hint (SSE2). - INST_2x(movnti, kInstMovnti, Mem, GpVar) + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpVar) //! Store packed DP-FP using NT hint (SSE2). - INST_2x(movntpd, kInstMovntpd, Mem, XmmVar) + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmVar) //! Move unaligned packed DP-FP (SSE2). - INST_2x(movupd, kInstMovupd, XmmVar, XmmVar) + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movupd, kInstMovupd, XmmVar, Mem) + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86Mem) //! \overload - INST_2x(movupd, kInstMovupd, Mem, XmmVar) + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmVar) //! Packed DP-FP multiply (SSE2). - INST_2x(mulpd, kInstMulpd, XmmVar, XmmVar) + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(mulpd, kInstMulpd, XmmVar, Mem) + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86Mem) //! Scalar DP-FP multiply (SSE2). - INST_2x(mulsd, kInstMulsd, XmmVar, XmmVar) + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(mulsd, kInstMulsd, XmmVar, Mem) + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86Mem) //! Packed DP-FP bitwise or (SSE2). - INST_2x(orpd, kInstOrpd, XmmVar, XmmVar) + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(orpd, kInstOrpd, XmmVar, Mem) + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86Mem) //! Pack WORDs to BYTEs with signed saturation (SSE2). - INST_2x(packsswb, kInstPacksswb, XmmVar, XmmVar) + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(packsswb, kInstPacksswb, XmmVar, Mem) + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86Mem) //! Pack DWORDs to WORDs with signed saturation (SSE2). - INST_2x(packssdw, kInstPackssdw, XmmVar, XmmVar) + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(packssdw, kInstPackssdw, XmmVar, Mem) + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86Mem) //! Pack WORDs to BYTEs with unsigned saturation (SSE2). - INST_2x(packuswb, kInstPackuswb, XmmVar, XmmVar) + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(packuswb, kInstPackuswb, XmmVar, Mem) + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86Mem) //! Packed BYTE add (SSE2). - INST_2x(paddb, kInstPaddb, XmmVar, XmmVar) + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddb, kInstPaddb, XmmVar, Mem) + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86Mem) //! Packed WORD add (SSE2). - INST_2x(paddw, kInstPaddw, XmmVar, XmmVar) + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddw, kInstPaddw, XmmVar, Mem) + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86Mem) //! Packed DWORD add (SSE2). - INST_2x(paddd, kInstPaddd, XmmVar, XmmVar) + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddd, kInstPaddd, XmmVar, Mem) + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86Mem) //! Packed QWORD add (SSE2). - INST_2x(paddq, kInstPaddq, MmVar, MmVar) + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86MmVar) //! \overload - INST_2x(paddq, kInstPaddq, MmVar, Mem) + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86Mem) //! Packed QWORD add (SSE2). - INST_2x(paddq, kInstPaddq, XmmVar, XmmVar) + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddq, kInstPaddq, XmmVar, Mem) + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86Mem) //! Packed BYTE add with saturation (SSE2). - INST_2x(paddsb, kInstPaddsb, XmmVar, XmmVar) + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddsb, kInstPaddsb, XmmVar, Mem) + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86Mem) //! Packed WORD add with saturation (SSE2). - INST_2x(paddsw, kInstPaddsw, XmmVar, XmmVar) + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddsw, kInstPaddsw, XmmVar, Mem) + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86Mem) //! Packed BYTE add with unsigned saturation (SSE2). - INST_2x(paddusb, kInstPaddusb, XmmVar, XmmVar) + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddusb, kInstPaddusb, XmmVar, Mem) + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86Mem) //! Packed WORD add with unsigned saturation (SSE2). - INST_2x(paddusw, kInstPaddusw, XmmVar, XmmVar) + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(paddusw, kInstPaddusw, XmmVar, Mem) + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86Mem) //! Packed bitwise and (SSE2). - INST_2x(pand, kInstPand, XmmVar, XmmVar) + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pand, kInstPand, XmmVar, Mem) + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86Mem) //! Packed bitwise and-not (SSE2). - INST_2x(pandn, kInstPandn, XmmVar, XmmVar) + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pandn, kInstPandn, XmmVar, Mem) + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86Mem) //! Spin loop hint (SSE2). - INST_0x(pause, kInstPause) + INST_0x(pause, kX86InstIdPause) //! Packed BYTE average (SSE2). - INST_2x(pavgb, kInstPavgb, XmmVar, XmmVar) + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pavgb, kInstPavgb, XmmVar, Mem) + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86Mem) //! Packed WORD average (SSE2). - INST_2x(pavgw, kInstPavgw, XmmVar, XmmVar) + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pavgw, kInstPavgw, XmmVar, Mem) + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86Mem) //! Packed BYTE compare for equality (SSE2). - INST_2x(pcmpeqb, kInstPcmpeqb, XmmVar, XmmVar) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpeqb, kInstPcmpeqb, XmmVar, Mem) + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86Mem) //! Packed WROD compare for equality (SSE2). - INST_2x(pcmpeqw, kInstPcmpeqw, XmmVar, XmmVar) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpeqw, kInstPcmpeqw, XmmVar, Mem) + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86Mem) //! Packed DWORD compare for equality (SSE2). - INST_2x(pcmpeqd, kInstPcmpeqd, XmmVar, XmmVar) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpeqd, kInstPcmpeqd, XmmVar, Mem) + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86Mem) //! Packed BYTE compare if greater than (SSE2). - INST_2x(pcmpgtb, kInstPcmpgtb, XmmVar, XmmVar) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpgtb, kInstPcmpgtb, XmmVar, Mem) + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86Mem) //! Packed WORD compare if greater than (SSE2). - INST_2x(pcmpgtw, kInstPcmpgtw, XmmVar, XmmVar) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpgtw, kInstPcmpgtw, XmmVar, Mem) + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86Mem) //! Packed DWORD compare if greater than (SSE2). - INST_2x(pcmpgtd, kInstPcmpgtd, XmmVar, XmmVar) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpgtd, kInstPcmpgtd, XmmVar, Mem) + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86Mem) //! Extract WORD based on selector (SSE2). - INST_3i(pextrw, kInstPextrw, GpVar, XmmVar, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86XmmVar, Imm) //! Insert WORD based on selector (SSE2). - INST_3i(pinsrw, kInstPinsrw, XmmVar, GpVar, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86GpVar, Imm) //! \overload - INST_3i(pinsrw, kInstPinsrw, XmmVar, Mem, Imm) + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86Mem, Imm) //! Packed WORD maximum (SSE2). - INST_2x(pmaxsw, kInstPmaxsw, XmmVar, XmmVar) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxsw, kInstPmaxsw, XmmVar, Mem) + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86Mem) //! Packed BYTE unsigned maximum (SSE2). - INST_2x(pmaxub, kInstPmaxub, XmmVar, XmmVar) + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxub, kInstPmaxub, XmmVar, Mem) + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86Mem) //! Packed WORD minimum (SSE2). - INST_2x(pminsw, kInstPminsw, XmmVar, XmmVar) + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminsw, kInstPminsw, XmmVar, Mem) + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86Mem) //! Packed BYTE unsigned minimum (SSE2). - INST_2x(pminub, kInstPminub, XmmVar, XmmVar) + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminub, kInstPminub, XmmVar, Mem) + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86Mem) //! Move BYTE mask (SSE2). - INST_2x(pmovmskb, kInstPmovmskb, GpVar, XmmVar) + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86XmmVar) //! Packed WORD multiply high (SSE2). - INST_2x(pmulhw, kInstPmulhw, XmmVar, XmmVar) + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmulhw, kInstPmulhw, XmmVar, Mem) + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86Mem) //! Packed WORD unsigned multiply high (SSE2). - INST_2x(pmulhuw, kInstPmulhuw, XmmVar, XmmVar) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmulhuw, kInstPmulhuw, XmmVar, Mem) + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86Mem) //! Packed WORD multiply low (SSE2). - INST_2x(pmullw, kInstPmullw, XmmVar, XmmVar) + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmullw, kInstPmullw, XmmVar, Mem) + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86Mem) //! Packed DWORD multiply to QWORD (SSE2). - INST_2x(pmuludq, kInstPmuludq, MmVar, MmVar) + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86MmVar) //! \overload - INST_2x(pmuludq, kInstPmuludq, MmVar, Mem) + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86Mem) //! Packed DWORD multiply to QWORD (SSE2). - INST_2x(pmuludq, kInstPmuludq, XmmVar, XmmVar) + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmuludq, kInstPmuludq, XmmVar, Mem) + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86Mem) //! Packed bitwise or (SSE2). - INST_2x(por, kInstPor, XmmVar, XmmVar) + INST_2x(por, kX86InstIdPor, X86XmmVar, X86XmmVar) //! \overload - INST_2x(por, kInstPor, XmmVar, Mem) + INST_2x(por, kX86InstIdPor, X86XmmVar, X86Mem) //! Packed DWORD shift left logical (SSE2). - INST_2x(pslld, kInstPslld, XmmVar, XmmVar) + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pslld, kInstPslld, XmmVar, Mem) + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86Mem) //! \overload - INST_2i(pslld, kInstPslld, XmmVar, Imm) + INST_2i(pslld, kX86InstIdPslld, X86XmmVar, Imm) //! Packed QWORD shift left logical (SSE2). - INST_2x(psllq, kInstPsllq, XmmVar, XmmVar) + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psllq, kInstPsllq, XmmVar, Mem) + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86Mem) //! \overload - INST_2i(psllq, kInstPsllq, XmmVar, Imm) + INST_2i(psllq, kX86InstIdPsllq, X86XmmVar, Imm) //! Packed WORD shift left logical (SSE2). - INST_2x(psllw, kInstPsllw, XmmVar, XmmVar) + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psllw, kInstPsllw, XmmVar, Mem) + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86Mem) //! \overload - INST_2i(psllw, kInstPsllw, XmmVar, Imm) + INST_2i(psllw, kX86InstIdPsllw, X86XmmVar, Imm) //! Packed OWORD shift left logical (SSE2). - INST_2i(pslldq, kInstPslldq, XmmVar, Imm) + INST_2i(pslldq, kX86InstIdPslldq, X86XmmVar, Imm) //! Packed DWORD shift right arithmetic (SSE2). - INST_2x(psrad, kInstPsrad, XmmVar, XmmVar) + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psrad, kInstPsrad, XmmVar, Mem) + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86Mem) //! \overload - INST_2i(psrad, kInstPsrad, XmmVar, Imm) + INST_2i(psrad, kX86InstIdPsrad, X86XmmVar, Imm) //! Packed WORD shift right arithmetic (SSE2). - INST_2x(psraw, kInstPsraw, XmmVar, XmmVar) + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psraw, kInstPsraw, XmmVar, Mem) + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86Mem) //! \overload - INST_2i(psraw, kInstPsraw, XmmVar, Imm) + INST_2i(psraw, kX86InstIdPsraw, X86XmmVar, Imm) //! Packed BYTE subtract (SSE2). - INST_2x(psubb, kInstPsubb, XmmVar, XmmVar) + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubb, kInstPsubb, XmmVar, Mem) + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86Mem) //! Packed DWORD subtract (SSE2). - INST_2x(psubd, kInstPsubd, XmmVar, XmmVar) + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubd, kInstPsubd, XmmVar, Mem) + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86Mem) //! Packed QWORD subtract (SSE2). - INST_2x(psubq, kInstPsubq, MmVar, MmVar) + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86MmVar) //! \overload - INST_2x(psubq, kInstPsubq, MmVar, Mem) + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86Mem) //! Packed QWORD subtract (SSE2). - INST_2x(psubq, kInstPsubq, XmmVar, XmmVar) + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubq, kInstPsubq, XmmVar, Mem) + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86Mem) //! Packed WORD subtract (SSE2). - INST_2x(psubw, kInstPsubw, XmmVar, XmmVar) + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubw, kInstPsubw, XmmVar, Mem) + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86Mem) //! Packed WORD to DWORD multiply and add (SSE2). - INST_2x(pmaddwd, kInstPmaddwd, XmmVar, XmmVar) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaddwd, kInstPmaddwd, XmmVar, Mem) + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86Mem) //! Packed DWORD shuffle (SSE2). - INST_3i(pshufd, kInstPshufd, XmmVar, XmmVar, Imm) + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pshufd, kInstPshufd, XmmVar, Mem, Imm) + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86Mem, Imm) //! Packed WORD shuffle high (SSE2). - INST_3i(pshufhw, kInstPshufhw, XmmVar, XmmVar, Imm) + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pshufhw, kInstPshufhw, XmmVar, Mem, Imm) + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86Mem, Imm) //! Packed WORD shuffle low (SSE2). - INST_3i(pshuflw, kInstPshuflw, XmmVar, XmmVar, Imm) + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pshuflw, kInstPshuflw, XmmVar, Mem, Imm) + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86Mem, Imm) //! Packed DWORD shift right logical (SSE2). - INST_2x(psrld, kInstPsrld, XmmVar, XmmVar) + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psrld, kInstPsrld, XmmVar, Mem) + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86Mem) //! \overload - INST_2i(psrld, kInstPsrld, XmmVar, Imm) + INST_2i(psrld, kX86InstIdPsrld, X86XmmVar, Imm) //! Packed QWORD shift right logical (SSE2). - INST_2x(psrlq, kInstPsrlq, XmmVar, XmmVar) + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psrlq, kInstPsrlq, XmmVar, Mem) + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86Mem) //! \overload - INST_2i(psrlq, kInstPsrlq, XmmVar, Imm) + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmVar, Imm) //! Scalar OWORD shift right logical (SSE2). - INST_2i(psrldq, kInstPsrldq, XmmVar, Imm) + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmVar, Imm) //! Packed WORD shift right logical (SSE2). - INST_2x(psrlw, kInstPsrlw, XmmVar, XmmVar) + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psrlw, kInstPsrlw, XmmVar, Mem) + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86Mem) //! \overload - INST_2i(psrlw, kInstPsrlw, XmmVar, Imm) + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmVar, Imm) //! Packed BYTE subtract with saturation (SSE2). - INST_2x(psubsb, kInstPsubsb, XmmVar, XmmVar) + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubsb, kInstPsubsb, XmmVar, Mem) + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86Mem) //! Packed WORD subtract with saturation (SSE2). - INST_2x(psubsw, kInstPsubsw, XmmVar, XmmVar) + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubsw, kInstPsubsw, XmmVar, Mem) + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86Mem) //! Packed BYTE subtract with unsigned saturation (SSE2). - INST_2x(psubusb, kInstPsubusb, XmmVar, XmmVar) + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubusb, kInstPsubusb, XmmVar, Mem) + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86Mem) //! Packed WORD subtract with unsigned saturation (SSE2). - INST_2x(psubusw, kInstPsubusw, XmmVar, XmmVar) + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psubusw, kInstPsubusw, XmmVar, Mem) + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86Mem) //! Unpack high packed BYTEs to WORDs (SSE2). - INST_2x(punpckhbw, kInstPunpckhbw, XmmVar, XmmVar) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpckhbw, kInstPunpckhbw, XmmVar, Mem) + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86Mem) //! Unpack high packed DWORDs to QWORDs (SSE2). - INST_2x(punpckhdq, kInstPunpckhdq, XmmVar, XmmVar) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpckhdq, kInstPunpckhdq, XmmVar, Mem) + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86Mem) //! Unpack high packed QWORDs to OWORD (SSE2). - INST_2x(punpckhqdq, kInstPunpckhqdq, XmmVar, XmmVar) + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpckhqdq, kInstPunpckhqdq, XmmVar, Mem) + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86Mem) //! Unpack high packed WORDs to DWORDs (SSE2). - INST_2x(punpckhwd, kInstPunpckhwd, XmmVar, XmmVar) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpckhwd, kInstPunpckhwd, XmmVar, Mem) + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86Mem) //! Unpack low packed BYTEs to WORDs (SSE2). - INST_2x(punpcklbw, kInstPunpcklbw, XmmVar, XmmVar) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpcklbw, kInstPunpcklbw, XmmVar, Mem) + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86Mem) //! Unpack low packed DWORDs to QWORDs (SSE2). - INST_2x(punpckldq, kInstPunpckldq, XmmVar, XmmVar) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpckldq, kInstPunpckldq, XmmVar, Mem) + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86Mem) //! Unpack low packed QWORDs to OWORD (SSE2). - INST_2x(punpcklqdq, kInstPunpcklqdq, XmmVar, XmmVar) + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpcklqdq, kInstPunpcklqdq, XmmVar, Mem) + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86Mem) //! Unpack low packed WORDs to DWORDs (SSE2). - INST_2x(punpcklwd, kInstPunpcklwd, XmmVar, XmmVar) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(punpcklwd, kInstPunpcklwd, XmmVar, Mem) + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86Mem) //! Packed bitwise xor (SSE2). - INST_2x(pxor, kInstPxor, XmmVar, XmmVar) + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pxor, kInstPxor, XmmVar, Mem) + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86Mem) //! Shuffle DP-FP (SSE2). - INST_3i(shufpd, kInstShufpd, XmmVar, XmmVar, Imm) + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(shufpd, kInstShufpd, XmmVar, Mem, Imm) + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86Mem, Imm) //! Packed DP-FP square root (SSE2). - INST_2x(sqrtpd, kInstSqrtpd, XmmVar, XmmVar) + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(sqrtpd, kInstSqrtpd, XmmVar, Mem) + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86Mem) //! Scalar DP-FP square root (SSE2). - INST_2x(sqrtsd, kInstSqrtsd, XmmVar, XmmVar) + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(sqrtsd, kInstSqrtsd, XmmVar, Mem) + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86Mem) //! Packed DP-FP subtract (SSE2). - INST_2x(subpd, kInstSubpd, XmmVar, XmmVar) + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(subpd, kInstSubpd, XmmVar, Mem) + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86Mem) //! Scalar DP-FP subtract (SSE2). - INST_2x(subsd, kInstSubsd, XmmVar, XmmVar) + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(subsd, kInstSubsd, XmmVar, Mem) + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86Mem) //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). - INST_2x(ucomisd, kInstUcomisd, XmmVar, XmmVar) + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(ucomisd, kInstUcomisd, XmmVar, Mem) + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86Mem) //! Unpack and interleave high packed DP-FP (SSE2). - INST_2x(unpckhpd, kInstUnpckhpd, XmmVar, XmmVar) + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(unpckhpd, kInstUnpckhpd, XmmVar, Mem) + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86Mem) //! Unpack and interleave low packed DP-FP (SSE2). - INST_2x(unpcklpd, kInstUnpcklpd, XmmVar, XmmVar) + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(unpcklpd, kInstUnpcklpd, XmmVar, Mem) + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86Mem) //! Packed DP-FP bitwise xor (SSE2). - INST_2x(xorpd, kInstXorpd, XmmVar, XmmVar) + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(xorpd, kInstXorpd, XmmVar, Mem) + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86Mem) // -------------------------------------------------------------------------- // [SSE3] // -------------------------------------------------------------------------- //! Packed DP-FP add/subtract (SSE3). - INST_2x(addsubpd, kInstAddsubpd, XmmVar, XmmVar) + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addsubpd, kInstAddsubpd, XmmVar, Mem) + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86Mem) //! Packed SP-FP add/subtract (SSE3). - INST_2x(addsubps, kInstAddsubps, XmmVar, XmmVar) + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(addsubps, kInstAddsubps, XmmVar, Mem) + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86Mem) - // //! Store integer with truncation (SSE3). - // INST_1x(fisttp, kInstFisttp, Mem) + //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop + //! the FPU stack (FPU / SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) //! Packed DP-FP horizontal add (SSE3). - INST_2x(haddpd, kInstHaddpd, XmmVar, XmmVar) + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(haddpd, kInstHaddpd, XmmVar, Mem) + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86Mem) //! Packed SP-FP horizontal add (SSE3). - INST_2x(haddps, kInstHaddps, XmmVar, XmmVar) + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(haddps, kInstHaddps, XmmVar, Mem) + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86Mem) //! Packed DP-FP horizontal subtract (SSE3). - INST_2x(hsubpd, kInstHsubpd, XmmVar, XmmVar) + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(hsubpd, kInstHsubpd, XmmVar, Mem) + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86Mem) //! Packed SP-FP horizontal subtract (SSE3). - INST_2x(hsubps, kInstHsubps, XmmVar, XmmVar) + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86XmmVar) //! \overload - INST_2x(hsubps, kInstHsubps, XmmVar, Mem) + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86Mem) //! Load 128-bits unaligned (SSE3). - INST_2x(lddqu, kInstLddqu, XmmVar, Mem) + INST_2x(lddqu, kX86InstIdLddqu, X86XmmVar, X86Mem) // //! Setup monitor address (SSE3). - // INST_0x(monitor, kInstMonitor) + // INST_0x(monitor, kX86InstIdMonitor) //! Move one DP-FP and duplicate (SSE3). - INST_2x(movddup, kInstMovddup, XmmVar, XmmVar) + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movddup, kInstMovddup, XmmVar, Mem) + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86Mem) //! Move packed SP-FP high and duplicate (SSE3). - INST_2x(movshdup, kInstMovshdup, XmmVar, XmmVar) + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movshdup, kInstMovshdup, XmmVar, Mem) + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86Mem) //! Move packed SP-FP low and duplicate (SSE3). - INST_2x(movsldup, kInstMovsldup, XmmVar, XmmVar) + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86XmmVar) //! \overload - INST_2x(movsldup, kInstMovsldup, XmmVar, Mem) + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86Mem) // //! Monitor wait (SSE3). - // INST_0x(mwait, kInstMwait) + // INST_0x(mwait, kX86InstIdMwait) // -------------------------------------------------------------------------- // [SSSE3] // -------------------------------------------------------------------------- //! Packed BYTE sign (SSSE3). - INST_2x(psignb, kInstPsignb, MmVar, MmVar) + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86MmVar) //! \overload - INST_2x(psignb, kInstPsignb, MmVar, Mem) + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86Mem) //! PackedBYTE sign (SSSE3). - INST_2x(psignb, kInstPsignb, XmmVar, XmmVar) + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psignb, kInstPsignb, XmmVar, Mem) + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86Mem) //! Packed DWORD sign (SSSE3). - INST_2x(psignd, kInstPsignd, MmVar, MmVar) + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86MmVar) //! \overload - INST_2x(psignd, kInstPsignd, MmVar, Mem) + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86Mem) //! Packed DWORD sign (SSSE3). - INST_2x(psignd, kInstPsignd, XmmVar, XmmVar) + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psignd, kInstPsignd, XmmVar, Mem) + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86Mem) //! Packed WORD sign (SSSE3). - INST_2x(psignw, kInstPsignw, MmVar, MmVar) + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86MmVar) //! \overload - INST_2x(psignw, kInstPsignw, MmVar, Mem) + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86Mem) //! Packed WORD sign (SSSE3). - INST_2x(psignw, kInstPsignw, XmmVar, XmmVar) + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(psignw, kInstPsignw, XmmVar, Mem) + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86Mem) //! Packed DWORD horizontal add (SSSE3). - INST_2x(phaddd, kInstPhaddd, MmVar, MmVar) + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86MmVar) //! \overload - INST_2x(phaddd, kInstPhaddd, MmVar, Mem) + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86Mem) //! Packed DWORD horizontal add (SSSE3). - INST_2x(phaddd, kInstPhaddd, XmmVar, XmmVar) + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phaddd, kInstPhaddd, XmmVar, Mem) + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86Mem) //! Packed WORD horizontal add with saturation (SSSE3). - INST_2x(phaddsw, kInstPhaddsw, MmVar, MmVar) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86MmVar) //! \overload - INST_2x(phaddsw, kInstPhaddsw, MmVar, Mem) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86Mem) //! Packed WORD horizontal add with with saturation (SSSE3). - INST_2x(phaddsw, kInstPhaddsw, XmmVar, XmmVar) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phaddsw, kInstPhaddsw, XmmVar, Mem) + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86Mem) //! Packed WORD horizontal add (SSSE3). - INST_2x(phaddw, kInstPhaddw, MmVar, MmVar) + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86MmVar) //! \overload - INST_2x(phaddw, kInstPhaddw, MmVar, Mem) + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86Mem) //! Packed WORD horizontal add (SSSE3). - INST_2x(phaddw, kInstPhaddw, XmmVar, XmmVar) + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phaddw, kInstPhaddw, XmmVar, Mem) + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86Mem) //! Packed DWORD horizontal subtract (SSSE3). - INST_2x(phsubd, kInstPhsubd, MmVar, MmVar) + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86MmVar) //! \overload - INST_2x(phsubd, kInstPhsubd, MmVar, Mem) + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86Mem) //! Packed DWORD horizontal subtract (SSSE3). - INST_2x(phsubd, kInstPhsubd, XmmVar, XmmVar) + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phsubd, kInstPhsubd, XmmVar, Mem) + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86Mem) //! Packed WORD horizontal subtract with saturation (SSSE3). - INST_2x(phsubsw, kInstPhsubsw, MmVar, MmVar) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86MmVar) //! \overload - INST_2x(phsubsw, kInstPhsubsw, MmVar, Mem) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86Mem) //! Packed WORD horizontal subtract with saturation (SSSE3). - INST_2x(phsubsw, kInstPhsubsw, XmmVar, XmmVar) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phsubsw, kInstPhsubsw, XmmVar, Mem) + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86Mem) //! Packed WORD horizontal subtract (SSSE3). - INST_2x(phsubw, kInstPhsubw, MmVar, MmVar) + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86MmVar) //! \overload - INST_2x(phsubw, kInstPhsubw, MmVar, Mem) + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86Mem) //! Packed WORD horizontal subtract (SSSE3). - INST_2x(phsubw, kInstPhsubw, XmmVar, XmmVar) + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phsubw, kInstPhsubw, XmmVar, Mem) + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86Mem) //! Packed multiply and add signed and unsigned bytes (SSSE3). - INST_2x(pmaddubsw, kInstPmaddubsw, MmVar, MmVar) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmaddubsw, kInstPmaddubsw, MmVar, Mem) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86Mem) //! Packed multiply and add signed and unsigned bytes (SSSE3). - INST_2x(pmaddubsw, kInstPmaddubsw, XmmVar, XmmVar) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaddubsw, kInstPmaddubsw, XmmVar, Mem) + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86Mem) //! Packed BYTE absolute value (SSSE3). - INST_2x(pabsb, kInstPabsb, MmVar, MmVar) + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86MmVar) //! \overload - INST_2x(pabsb, kInstPabsb, MmVar, Mem) + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86Mem) //! Packed BYTE absolute value (SSSE3). - INST_2x(pabsb, kInstPabsb, XmmVar, XmmVar) + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pabsb, kInstPabsb, XmmVar, Mem) + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86Mem) //! Packed DWORD absolute value (SSSE3). - INST_2x(pabsd, kInstPabsd, MmVar, MmVar) + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86MmVar) //! \overload - INST_2x(pabsd, kInstPabsd, MmVar, Mem) + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86Mem) //! Packed DWORD absolute value (SSSE3). - INST_2x(pabsd, kInstPabsd, XmmVar, XmmVar) + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pabsd, kInstPabsd, XmmVar, Mem) + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86Mem) //! Packed WORD absolute value (SSSE3). - INST_2x(pabsw, kInstPabsw, MmVar, MmVar) + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86MmVar) //! \overload - INST_2x(pabsw, kInstPabsw, MmVar, Mem) + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86Mem) //! Packed WORD absolute value (SSSE3). - INST_2x(pabsw, kInstPabsw, XmmVar, XmmVar) + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pabsw, kInstPabsw, XmmVar, Mem) + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86Mem) //! Packed WORD multiply high, round and scale (SSSE3). - INST_2x(pmulhrsw, kInstPmulhrsw, MmVar, MmVar) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86MmVar) //! \overload - INST_2x(pmulhrsw, kInstPmulhrsw, MmVar, Mem) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86Mem) //! Packed WORD multiply high, round and scale (SSSE3). - INST_2x(pmulhrsw, kInstPmulhrsw, XmmVar, XmmVar) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmulhrsw, kInstPmulhrsw, XmmVar, Mem) + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86Mem) //! Packed BYTE shuffle (SSSE3). - INST_2x(pshufb, kInstPshufb, MmVar, MmVar) + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86MmVar) //! \overload - INST_2x(pshufb, kInstPshufb, MmVar, Mem) + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86Mem) //! Packed BYTE shuffle (SSSE3). - INST_2x(pshufb, kInstPshufb, XmmVar, XmmVar) + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pshufb, kInstPshufb, XmmVar, Mem) + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86Mem) //! Packed align right (SSSE3). - INST_3i(palignr, kInstPalignr, MmVar, MmVar, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86MmVar, Imm) //! \overload - INST_3i(palignr, kInstPalignr, MmVar, Mem, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86Mem, Imm) //! Packed align right (SSSE3). - INST_3i(palignr, kInstPalignr, XmmVar, XmmVar, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(palignr, kInstPalignr, XmmVar, Mem, Imm) + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86Mem, Imm) // -------------------------------------------------------------------------- // [SSE4.1] // -------------------------------------------------------------------------- //! Packed DP-FP blend (SSE4.1). - INST_3i(blendpd, kInstBlendpd, XmmVar, XmmVar, Imm) + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(blendpd, kInstBlendpd, XmmVar, Mem, Imm) + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86Mem, Imm) //! Packed SP-FP blend (SSE4.1). - INST_3i(blendps, kInstBlendps, XmmVar, XmmVar, Imm) + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(blendps, kInstBlendps, XmmVar, Mem, Imm) + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86Mem, Imm) //! Packed DP-FP variable blend (SSE4.1). - INST_3x(blendvpd, kInstBlendvpd, XmmVar, XmmVar, XmmVar) + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86XmmVar, X86XmmVar) //! \overload - INST_3x(blendvpd, kInstBlendvpd, XmmVar, Mem, XmmVar) + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86Mem, X86XmmVar) //! Packed SP-FP variable blend (SSE4.1). - INST_3x(blendvps, kInstBlendvps, XmmVar, XmmVar, XmmVar) + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86XmmVar, X86XmmVar) //! \overload - INST_3x(blendvps, kInstBlendvps, XmmVar, Mem, XmmVar) + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86Mem, X86XmmVar) //! Packed DP-FP dot product (SSE4.1). - INST_3i(dppd, kInstDppd, XmmVar, XmmVar, Imm) + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(dppd, kInstDppd, XmmVar, Mem, Imm) + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86Mem, Imm) //! Packed SP-FP dot product (SSE4.1). - INST_3i(dpps, kInstDpps, XmmVar, XmmVar, Imm) + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(dpps, kInstDpps, XmmVar, Mem, Imm) + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86Mem, Imm) //! Extract SP-FP based on selector (SSE4.1). - INST_3i(extractps, kInstExtractps, GpVar, XmmVar, Imm) + INST_3i(extractps, kX86InstIdExtractps, X86GpVar, X86XmmVar, Imm) //! \overload - INST_3i(extractps, kInstExtractps, Mem, XmmVar, Imm) + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmVar, Imm) //! Insert SP-FP based on selector (SSE4.1). - INST_3i(insertps, kInstInsertps, XmmVar, XmmVar, Imm) + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(insertps, kInstInsertps, XmmVar, Mem, Imm) + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86Mem, Imm) //! Load OWORD aligned using NT hint (SSE4.1). - INST_2x(movntdqa, kInstMovntdqa, XmmVar, Mem) + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmVar, X86Mem) //! Packed WORD sums of absolute difference (SSE4.1). - INST_3i(mpsadbw, kInstMpsadbw, XmmVar, XmmVar, Imm) + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(mpsadbw, kInstMpsadbw, XmmVar, Mem, Imm) + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86Mem, Imm) //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). - INST_2x(packusdw, kInstPackusdw, XmmVar, XmmVar) + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(packusdw, kInstPackusdw, XmmVar, Mem) + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86Mem) //! Packed BYTE variable blend (SSE4.1). - INST_3x(pblendvb, kInstPblendvb, XmmVar, XmmVar, XmmVar) + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86XmmVar, X86XmmVar) //! \overload - INST_3x(pblendvb, kInstPblendvb, XmmVar, Mem, XmmVar) + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86Mem, X86XmmVar) //! Packed WORD blend (SSE4.1). - INST_3i(pblendw, kInstPblendw, XmmVar, XmmVar, Imm) + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pblendw, kInstPblendw, XmmVar, Mem, Imm) + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86Mem, Imm) //! Packed QWORD compare for equality (SSE4.1). - INST_2x(pcmpeqq, kInstPcmpeqq, XmmVar, XmmVar) + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpeqq, kInstPcmpeqq, XmmVar, Mem) + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86Mem) //! Extract BYTE based on selector (SSE4.1). - INST_3i(pextrb, kInstPextrb, GpVar, XmmVar, Imm) + INST_3i(pextrb, kX86InstIdPextrb, X86GpVar, X86XmmVar, Imm) //! \overload - INST_3i(pextrb, kInstPextrb, Mem, XmmVar, Imm) + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmVar, Imm) //! Extract DWORD based on selector (SSE4.1). - INST_3i(pextrd, kInstPextrd, GpVar, XmmVar, Imm) + INST_3i(pextrd, kX86InstIdPextrd, X86GpVar, X86XmmVar, Imm) //! \overload - INST_3i(pextrd, kInstPextrd, Mem, XmmVar, Imm) + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmVar, Imm) //! Extract QWORD based on selector (SSE4.1). - INST_3i(pextrq, kInstPextrq, GpVar, XmmVar, Imm) + INST_3i(pextrq, kX86InstIdPextrq, X86GpVar, X86XmmVar, Imm) //! \overload - INST_3i(pextrq, kInstPextrq, Mem, XmmVar, Imm) + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmVar, Imm) //! Extract WORD based on selector (SSE4.1). - INST_3i(pextrw, kInstPextrw, Mem, XmmVar, Imm) + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmVar, Imm) //! Packed WORD horizontal minimum (SSE4.1). - INST_2x(phminposuw, kInstPhminposuw, XmmVar, XmmVar) + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(phminposuw, kInstPhminposuw, XmmVar, Mem) + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86Mem) //! Insert BYTE based on selector (SSE4.1). - INST_3i(pinsrb, kInstPinsrb, XmmVar, GpVar, Imm) + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86GpVar, Imm) //! \overload - INST_3i(pinsrb, kInstPinsrb, XmmVar, Mem, Imm) + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86Mem, Imm) //! Insert DWORD based on selector (SSE4.1). - INST_3i(pinsrd, kInstPinsrd, XmmVar, GpVar, Imm) + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86GpVar, Imm) //! \overload - INST_3i(pinsrd, kInstPinsrd, XmmVar, Mem, Imm) + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86Mem, Imm) //! Insert QWORD based on selector (SSE4.1). - INST_3i(pinsrq, kInstPinsrq, XmmVar, GpVar, Imm) + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86GpVar, Imm) //! \overload - INST_3i(pinsrq, kInstPinsrq, XmmVar, Mem, Imm) + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86Mem, Imm) //! Packed BYTE maximum (SSE4.1). - INST_2x(pmaxsb, kInstPmaxsb, XmmVar, XmmVar) + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxsb, kInstPmaxsb, XmmVar, Mem) + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86Mem) //! Packed DWORD maximum (SSE4.1). - INST_2x(pmaxsd, kInstPmaxsd, XmmVar, XmmVar) + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxsd, kInstPmaxsd, XmmVar, Mem) + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86Mem) //! Packed DWORD unsigned maximum (SSE4.1). - INST_2x(pmaxud, kInstPmaxud, XmmVar, XmmVar) + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxud,kInstPmaxud , XmmVar, Mem) + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmVar, X86Mem) //! Packed WORD unsigned maximum (SSE4.1). - INST_2x(pmaxuw, kInstPmaxuw, XmmVar, XmmVar) + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmaxuw, kInstPmaxuw, XmmVar, Mem) + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86Mem) //! Packed BYTE minimum (SSE4.1). - INST_2x(pminsb, kInstPminsb, XmmVar, XmmVar) + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminsb, kInstPminsb, XmmVar, Mem) + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86Mem) //! Packed DWORD minimum (SSE4.1). - INST_2x(pminsd, kInstPminsd, XmmVar, XmmVar) + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminsd, kInstPminsd, XmmVar, Mem) + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86Mem) //! Packed WORD unsigned minimum (SSE4.1). - INST_2x(pminuw, kInstPminuw, XmmVar, XmmVar) + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminuw, kInstPminuw, XmmVar, Mem) + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86Mem) //! Packed DWORD unsigned minimum (SSE4.1). - INST_2x(pminud, kInstPminud, XmmVar, XmmVar) + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pminud, kInstPminud, XmmVar, Mem) + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86Mem) //! Packed BYTE to DWORD with sign extend (SSE4.1). - INST_2x(pmovsxbd, kInstPmovsxbd, XmmVar, XmmVar) + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxbd, kInstPmovsxbd, XmmVar, Mem) + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86Mem) //! Packed BYTE to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxbq, kInstPmovsxbq, XmmVar, XmmVar) + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxbq, kInstPmovsxbq, XmmVar, Mem) + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86Mem) //! Packed BYTE to WORD with sign extend (SSE4.1). - INST_2x(pmovsxbw, kInstPmovsxbw, XmmVar, XmmVar) + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxbw, kInstPmovsxbw, XmmVar, Mem) + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86Mem) //! Packed DWORD to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxdq, kInstPmovsxdq, XmmVar, XmmVar) + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxdq, kInstPmovsxdq, XmmVar, Mem) + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86Mem) //! Packed WORD to DWORD with sign extend (SSE4.1). - INST_2x(pmovsxwd, kInstPmovsxwd, XmmVar, XmmVar) + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxwd, kInstPmovsxwd, XmmVar, Mem) + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86Mem) //! Packed WORD to QWORD with sign extend (SSE4.1). - INST_2x(pmovsxwq, kInstPmovsxwq, XmmVar, XmmVar) + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovsxwq, kInstPmovsxwq, XmmVar, Mem) + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86Mem) //! BYTE to DWORD with zero extend (SSE4.1). - INST_2x(pmovzxbd, kInstPmovzxbd, XmmVar, XmmVar) + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxbd, kInstPmovzxbd, XmmVar, Mem) + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86Mem) //! Packed BYTE to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxbq, kInstPmovzxbq, XmmVar, XmmVar) + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxbq, kInstPmovzxbq, XmmVar, Mem) + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86Mem) //! BYTE to WORD with zero extend (SSE4.1). - INST_2x(pmovzxbw, kInstPmovzxbw, XmmVar, XmmVar) + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxbw, kInstPmovzxbw, XmmVar, Mem) + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86Mem) //! Packed DWORD to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxdq, kInstPmovzxdq, XmmVar, XmmVar) + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxdq, kInstPmovzxdq, XmmVar, Mem) + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86Mem) //! Packed WORD to DWORD with zero extend (SSE4.1). - INST_2x(pmovzxwd, kInstPmovzxwd, XmmVar, XmmVar) + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxwd, kInstPmovzxwd, XmmVar, Mem) + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86Mem) //! Packed WORD to QWORD with zero extend (SSE4.1). - INST_2x(pmovzxwq, kInstPmovzxwq, XmmVar, XmmVar) + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmovzxwq, kInstPmovzxwq, XmmVar, Mem) + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86Mem) //! Packed DWORD to QWORD multiply (SSE4.1). - INST_2x(pmuldq, kInstPmuldq, XmmVar, XmmVar) + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmuldq, kInstPmuldq, XmmVar, Mem) + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86Mem) //! Packed DWORD multiply low (SSE4.1). - INST_2x(pmulld, kInstPmulld, XmmVar, XmmVar) + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pmulld, kInstPmulld, XmmVar, Mem) + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86Mem) //! Logical compare (SSE4.1). - INST_2x(ptest, kInstPtest, XmmVar, XmmVar) + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86XmmVar) //! \overload - INST_2x(ptest, kInstPtest, XmmVar, Mem) + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86Mem) //! Packed DP-FP round (SSE4.1). - INST_3i(roundpd, kInstRoundpd, XmmVar, XmmVar, Imm) + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(roundpd, kInstRoundpd, XmmVar, Mem, Imm) + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86Mem, Imm) //! Packed SP-FP round (SSE4.1). - INST_3i(roundps, kInstRoundps, XmmVar, XmmVar, Imm) + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(roundps, kInstRoundps, XmmVar, Mem, Imm) + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86Mem, Imm) //! Scalar DP-FP round (SSE4.1). - INST_3i(roundsd, kInstRoundsd, XmmVar, XmmVar, Imm) + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(roundsd, kInstRoundsd, XmmVar, Mem, Imm) + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86Mem, Imm) //! Scalar SP-FP round (SSE4.1). - INST_3i(roundss, kInstRoundss, XmmVar, XmmVar, Imm) + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(roundss, kInstRoundss, XmmVar, Mem, Imm) + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86Mem, Imm) // -------------------------------------------------------------------------- // [SSE4.2] // -------------------------------------------------------------------------- //! Packed compare explicit length strings, return index (SSE4.2). - INST_3i(pcmpestri, kInstPcmpestri, XmmVar, XmmVar, Imm) + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pcmpestri, kInstPcmpestri, XmmVar, Mem, Imm) + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86Mem, Imm) //! Packed compare explicit length strings, return mask (SSE4.2). - INST_3i(pcmpestrm, kInstPcmpestrm, XmmVar, XmmVar, Imm) + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pcmpestrm, kInstPcmpestrm, XmmVar, Mem, Imm) + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86Mem, Imm) //! Packed compare implicit length strings, return index (SSE4.2). - INST_3i(pcmpistri, kInstPcmpistri, XmmVar, XmmVar, Imm) + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pcmpistri, kInstPcmpistri, XmmVar, Mem, Imm) + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86Mem, Imm) //! Packed compare implicit length strings, return mask (SSE4.2). - INST_3i(pcmpistrm, kInstPcmpistrm, XmmVar, XmmVar, Imm) + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(pcmpistrm, kInstPcmpistrm, XmmVar, Mem, Imm) + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86Mem, Imm) //! Packed QWORD compare if greater than (SSE4.2). - INST_2x(pcmpgtq, kInstPcmpgtq, XmmVar, XmmVar) + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86XmmVar) //! \overload - INST_2x(pcmpgtq, kInstPcmpgtq, XmmVar, Mem) + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86Mem) // -------------------------------------------------------------------------- // [AESNI] // -------------------------------------------------------------------------- //! Perform a single round of the AES decryption flow. - INST_2x(aesdec, kInstAesdec, XmmVar, XmmVar) + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86XmmVar) //! \overload - INST_2x(aesdec, kInstAesdec, XmmVar, Mem) + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86Mem) //! Perform the last round of the AES decryption flow. - INST_2x(aesdeclast, kInstAesdeclast, XmmVar, XmmVar) + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86XmmVar) //! \overload - INST_2x(aesdeclast, kInstAesdeclast, XmmVar, Mem) + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86Mem) //! Perform a single round of the AES encryption flow. - INST_2x(aesenc, kInstAesenc, XmmVar, XmmVar) + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86XmmVar) //! \overload - INST_2x(aesenc, kInstAesenc, XmmVar, Mem) + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86Mem) //! Perform the last round of the AES encryption flow. - INST_2x(aesenclast, kInstAesenclast, XmmVar, XmmVar) + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86XmmVar) //! \overload - INST_2x(aesenclast, kInstAesenclast, XmmVar, Mem) + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86Mem) //! Perform the InvMixColumns transformation. - INST_2x(aesimc, kInstAesimc, XmmVar, XmmVar) + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86XmmVar) //! \overload - INST_2x(aesimc, kInstAesimc, XmmVar, Mem) + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86Mem) //! Assist in expanding the AES cipher key. - INST_3i(aeskeygenassist, kInstAeskeygenassist, XmmVar, XmmVar, Imm) + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86XmmVar, Imm) //! \overload - INST_3i(aeskeygenassist, kInstAeskeygenassist, XmmVar, Mem, Imm) + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86Mem, Imm) // -------------------------------------------------------------------------- // [PCLMULQDQ] // -------------------------------------------------------------------------- //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). - INST_3i(pclmulqdq, kInstPclmulqdq, XmmVar, XmmVar, Imm); + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86XmmVar, Imm); //! \overload - INST_3i(pclmulqdq, kInstPclmulqdq, XmmVar, Mem, Imm); -}; - -//! \} - -} // x86x64 namespace -} // asmjit namespace - -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -//! \addtogroup asmjit_x86x64_general -//! \{ - -struct Compiler : public X86X64Compiler { - ASMJIT_NO_COPY(Compiler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a `x86::Compiler` instance. - ASMJIT_API Compiler(Runtime* runtime); - //! Destroy the `x86::Compiler` instance. - ASMJIT_API ~Compiler(); - - // ------------------------------------------------------------------------- - // [Options] - // ------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(Compiler) - - // -------------------------------------------------------------------------- - // [X86-Only Instructions] - // -------------------------------------------------------------------------- - - //! Decimal adjust AL after addition (32-bit). - INST_1x(daa, kInstDaa, GpVar) - //! Decimal adjust AL after subtraction (32-bit). - INST_1x(das, kInstDas, GpVar) -}; - -//! \} - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -//! \addtogroup asmjit_x86x64_general -//! \{ - -struct Compiler : public X86X64Compiler { - ASMJIT_NO_COPY(Compiler) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a `x64::Compiler` instance. - ASMJIT_API Compiler(Runtime* runtime); - //! Destroy the `x64::Compiler` instance. - ASMJIT_API ~Compiler(); - - // ------------------------------------------------------------------------- - // [Options] - // ------------------------------------------------------------------------- - - ASMJIT_X86X64_EMIT_OPTIONS(Compiler) - - // -------------------------------------------------------------------------- - // [X64-Only Instructions] - // -------------------------------------------------------------------------- - - //! Convert DWORD to QWORD (RAX <- Sign Extend EAX). - INST_1x(cdqe, kInstCdqe, GpVar /* eax */) - //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX). - INST_2x(cqo, kInstCdq, GpVar /* rdx */, GpVar /* rax */) - - //! Compares the 128-bit value in RDX:RAX with the memory operand (X64). - ASMJIT_INLINE InstNode* cmpxchg16b( - const GpVar& cmp_edx, const GpVar& cmp_eax, - const GpVar& cmp_ecx, const GpVar& cmp_ebx, - const Mem& dst) { - - return emit(kInstCmpxchg16b, cmp_edx, cmp_eax, cmp_ecx, cmp_ebx, dst); - } - - //! Move DWORD to QWORD with sign-extension. - INST_2x(movsxd, kInstMovsxd, GpVar, GpVar) - //! \overload - INST_2x(movsxd, kInstMovsxd, GpVar, Mem) - - //! Load ECX/RCX QWORDs from DS:[ESI/RSI] to RAX. - INST_3x_(rep_lodsq, kInstRepLodsq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Move ECX/RCX QWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. - INST_3x_(rep_movsq, kInstRepMovsq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Fill ECX/RCX QWORDs at ES:[EDI/RDI] with RAX. - INST_3x_(rep_stosq, kInstRepStosq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - - //! Repeated find nonmatching QWORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. - INST_3x_(repe_cmpsq, kInstRepeCmpsq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find non-RAX QWORD starting at ES:[EDI/RDI]. - INST_3x_(repe_scasq, kInstRepeScasq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - - //! Find matching QWORDs in [RDI] and [RSI]. - INST_3x_(repne_cmpsq, kInstRepneCmpsq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - //! Find RAX, starting at ES:[EDI/RDI]. - INST_3x_(repne_scasq, kInstRepneScasq, GpVar, GpVar, GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) - - using X86X64Compiler::movq; - - //! \overload - INST_2x(movq, kInstMovq, GpVar, MmVar) - //! \overload - INST_2x(movq, kInstMovq, MmVar, GpVar) - - //! \overload - INST_2x(movq, kInstMovq, GpVar, XmmVar) - //! \overload - INST_2x(movq, kInstMovq, XmmVar, GpVar) -}; - -//! \} - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - -// ============================================================================ -// [CodeGen-End] -// ============================================================================ + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86Mem, Imm); #undef INST_0x @@ -4215,6 +5469,11 @@ struct Compiler : public X86X64Compiler { #undef INST_4x #undef INST_4x_ #undef INST_4i +}; + +//! \} + +} // asmjit namespace // [Api-End] #include "../apiend.h" diff --git a/src/asmjit/x86/x86context.cpp b/src/asmjit/x86/x86context.cpp index e835fd6..779a597 100644 --- a/src/asmjit/x86/x86context.cpp +++ b/src/asmjit/x86/x86context.cpp @@ -18,46 +18,252 @@ #include "../x86/x86compiler.h" #include "../x86/x86context_p.h" #include "../x86/x86cpuinfo.h" -#include "../x86/x86func.h" +#include "../x86/x86scheduler_p.h" // [Api-Begin] #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ // [Forward Declarations] // ============================================================================ -static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opList, uint32_t opCount); +static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount); // ============================================================================ -// [asmjit::x86x64::X86X64Context - Construction / Destruction] +// [asmjit::X86Context - Utils] // ============================================================================ -X86X64Context::X86X64Context(X86X64Compiler* compiler) : BaseContext(compiler) { - // Setup x86 specific data. -#if defined(ASMJIT_BUILD_X86) - if (compiler->getArch() == kArchX86) { - _zsp = x86::esp; - _zbp = x86::ebp; - _memSlot._vmem.type = kMemTypeStackIndex; - _memSlot.setGpdBase(true); - _baseRegsCount = x86::kRegCountGp; - } -#endif // ASMJIT_BUILD_X86 +// Getting `VarClass` is the only safe operation when dealing with denormalized +// `varType`. Any other property would require to map vType to the architecture +// specific type. +static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + return _x86VarInfo[vType].getClass(); +} - // Setup x64 specific data. -#if defined(ASMJIT_BUILD_X64) - if (compiler->getArch() == kArchX64) { - _zsp = x64::rsp; - _zbp = x64::rbp; - _memSlot._vmem.type = kMemTypeStackIndex; - _memSlot.setGpdBase(false); - _baseRegsCount = x64::kRegCountGp; +// ============================================================================ +// [asmjit::X86Context - Annotate] +// ============================================================================ + +// Annotation is also used by ASMJIT_TRACE. +#if !defined(ASMJIT_DISABLE_LOGGER) +static void X86Context_annotateVariable(X86Context* self, + StringBuilder& sb, const VarData* vd) { + + const char* name = vd->getName(); + if (name != NULL && name[0] != '\0') { + sb.appendString(name); } -#endif // ASMJIT_BUILD_X64 + else { + sb.appendChar('v'); + sb.appendUInt(vd->getId() & kOperandIdNum); + } +} + +static void X86Context_annotateOperand(X86Context* self, + StringBuilder& sb, const Operand* op) { + + if (op->isVar()) { + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(op->getId())); + } + else if (op->isMem()) { + const X86Mem* m = static_cast(op); + bool isAbsolute = false; + + sb.appendChar('['); + switch (m->getMemType()) { + case kMemTypeBaseIndex: + case kMemTypeStackIndex: + // [base + index << shift + displacement] + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getBase())); + break; + + case kMemTypeLabel: + // [label + index << shift + displacement] + sb.appendFormat("L%u", m->getBase()); + break; + + case kMemTypeAbsolute: + // [absolute] + isAbsolute = true; + sb.appendUInt(static_cast(m->getDisplacement()), 16); + break; + } + + if (m->hasIndex()) { + sb.appendChar('+'); + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex())); + + if (m->getShift()) { + sb.appendChar('*'); + sb.appendChar("1248"[m->getShift() & 3]); + } + } + + if (m->getDisplacement() && !isAbsolute) { + uint32_t base = 10; + int32_t dispOffset = m->getDisplacement(); + + char prefix = '+'; + if (dispOffset < 0) { + dispOffset = -dispOffset; + prefix = '-'; + } + + sb.appendChar(prefix); + /* + if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { + sb.appendString("0x", 2); + base = 16; + } + */ + sb.appendUInt(static_cast(dispOffset), base); + } + + sb.appendChar(']'); + } + else if (op->isImm()) { + const Imm* i = static_cast(op); + int64_t val = i->getInt64(); + + /* + if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast(val) > 9) + sb.appendUInt(static_cast(val), 16); + else*/ + sb.appendInt(val, 10); + } + else if (op->isLabel()) { + sb.appendFormat("L%u", op->getId()); + } + else { + sb.appendString("None", 4); + } +} + +static bool X86Context_annotateInstruction(X86Context* self, + StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { + + sb.appendString(_x86InstInfo[code].getInstName()); + for (uint32_t i = 0; i < opCount; i++) { + if (i == 0) + sb.appendChar(' '); + else + sb.appendString(", ", 2); + X86Context_annotateOperand(self, sb, &opList[i]); + } + return true; +} +#endif // !ASMJIT_DISABLE_LOGGER + +#if defined(ASMJIT_TRACE) +static void X86Context_traceNode(X86Context* self, Node* node_) { + StringBuilderT<256> sb; + + switch (node_->getType()) { + case kNodeTypeAlign: { + AlignNode* node = static_cast(node_); + sb.appendFormat(".align %u (%s)", + node->getOffset(), + node->getMode() == kAlignCode ? "code" : "data"); + break; + } + + case kNodeTypeEmbed: { + EmbedNode* node = static_cast(node_); + sb.appendFormat(".embed (%u bytes)", node->getSize()); + break; + } + + case kNodeTypeComment: { + CommentNode* node = static_cast(node_); + sb.appendFormat("; %s", node->getComment()); + break; + } + + case kNodeTypeHint: { + HintNode* node = static_cast(node_); + static const char* hint[16] = { + "alloc", + "spill", + "save", + "save-unuse", + "unuse" + }; + sb.appendFormat("[%s] %s", + hint[node->getHint()], node->getVd()->getName()); + break; + } + + case kNodeTypeTarget: { + TargetNode* node = static_cast(node_); + sb.appendFormat("L%u: (NumRefs=%u)", + node->getLabelId(), + node->getNumRefs()); + break; + } + + case kNodeTypeInst: { + InstNode* node = static_cast(node_); + X86Context_annotateInstruction(self, sb, + node->getCode(), node->getOpList(), node->getOpCount()); + break; + } + + case kNodeTypeFunc: { + FuncNode* node = static_cast(node_); + sb.appendFormat("[func]"); + break; + } + + case kNodeTypeEnd: { + EndNode* node = static_cast(node_); + sb.appendFormat("[end]"); + break; + } + + case kNodeTypeRet: { + RetNode* node = static_cast(node_); + sb.appendFormat("[ret]"); + break; + } + + case kNodeTypeCall: { + CallNode* node = static_cast(node_); + sb.appendFormat("[call]"); + break; + } + + case kNodeTypeSArg: { + SArgNode* node = static_cast(node_); + sb.appendFormat("[sarg]"); + break; + } + + default: { + sb.appendFormat("[unknown]"); + break; + } + } + + ASMJIT_TLOG("[%05u] %s\n", node_->getFlowId(), sb.getData()); +} +#endif // ASMJIT_TRACE + +// ============================================================================ +// [asmjit::X86Context - Construction / Destruction] +// ============================================================================ + +X86Context::X86Context(X86Compiler* compiler) : Context(compiler) { + _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86VarMap, _list); + _regCount = compiler->_regCount; + + _zsp = compiler->zsp; + _zbp = compiler->zbp; + + _memSlot._vmem.type = kMemTypeStackIndex; + _memSlot.setGpdBase(compiler->getArch() == kArchX86); #if !defined(ASMJIT_DISABLE_LOGGER) _emitComments = compiler->hasLogger(); @@ -67,23 +273,23 @@ X86X64Context::X86X64Context(X86X64Compiler* compiler) : BaseContext(compiler) { reset(); } -X86X64Context::~X86X64Context() {} +X86Context::~X86Context() {} // ============================================================================ -// [asmjit::x86x64::X86X64Context - Reset] +// [asmjit::X86Context - Reset] // ============================================================================ -void X86X64Context::reset() { - BaseContext::reset(); +void X86Context::reset() { + Context::reset(); _x86State.reset(0); _clobberedRegs.reset(); _stackFrameCell = NULL; - _gaRegs[kRegClassGp ] = IntUtil::bits(_baseRegsCount) & ~IntUtil::mask(kRegIndexSp); - _gaRegs[kRegClassFp ] = IntUtil::bits(kRegCountFp); - _gaRegs[kRegClassMm ] = IntUtil::bits(kRegCountMm); - _gaRegs[kRegClassXyz] = IntUtil::bits(_baseRegsCount); + _gaRegs[kX86RegClassGp ] = IntUtil::bits(_regCount.getGp()) & ~IntUtil::mask(kX86RegIndexSp); + _gaRegs[kX86RegClassFp ] = IntUtil::bits(_regCount.getFp()); + _gaRegs[kX86RegClassMm ] = IntUtil::bits(_regCount.getMm()); + _gaRegs[kX86RegClassXyz] = IntUtil::bits(_regCount.getXyz()); _argBaseReg = kInvalidReg; // Used by patcher. _varBaseReg = kInvalidReg; // Used by patcher. @@ -96,286 +302,302 @@ void X86X64Context::reset() { } // ============================================================================ -// [asmjit::x86x64::X86X64SpecialInst] +// [asmjit::X86SpecialInst] // ============================================================================ -struct X86X64SpecialInst { +struct X86SpecialInst { uint8_t inReg; uint8_t outReg; uint16_t flags; }; -static const X86X64SpecialInst x86SpecialInstCpuid[] = { - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, - { kInvalidReg, kRegIndexBx, kVarAttrOutReg }, - { kInvalidReg, kRegIndexCx, kVarAttrOutReg }, - { kInvalidReg, kRegIndexDx, kVarAttrOutReg } +static const X86SpecialInst x86SpecialInstCpuid[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kX86RegIndexBx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg } }; -static const X86X64SpecialInst x86SpecialInstCbwCdqeCwde[] = { - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstCbwCdqeCwde[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstCdqCwdCqo[] = { - { kInvalidReg, kRegIndexDx, kVarAttrOutReg }, - { kRegIndexAx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstCdqCwdCqo[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstCmpxchg[] = { - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstCmpxchg[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstCmpxchg8b16b[] = { - { kRegIndexDx, kRegIndexDx, kVarAttrInOutReg }, - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, - { kRegIndexCx, kInvalidReg, kVarAttrInReg }, - { kRegIndexBx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstCmpxchg8b16b[] = { + { kX86RegIndexDx, kX86RegIndexDx, kVarAttrInOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexBx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstDaaDas[] = { - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstDaaDas[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstDiv[] = { - { kInvalidReg, kRegIndexDx, kVarAttrInOutReg }, - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstDiv[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrInOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstJecxz[] = { - { kRegIndexCx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstJecxz[] = { + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstMul[] = { - { kInvalidReg, kRegIndexDx, kVarAttrOutReg }, - { kRegIndexAx, kRegIndexAx, kVarAttrInOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstLods[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstMovPtr[] = { - { kInvalidReg, kRegIndexAx, kVarAttrOutReg }, - { kRegIndexAx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstMul[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstLahf[] = { - { kInvalidReg, kRegIndexAx, kVarAttrOutReg } +static const X86SpecialInst x86SpecialInstMovPtr[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstSahf[] = { - { kRegIndexAx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstMovsCmps[] = { + { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg }, + { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstMaskmovqMaskmovdqu[] = { - { kInvalidReg, kRegIndexDi, kVarAttrInReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstLahf[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg } }; -static const X86X64SpecialInst x86SpecialInstRot[] = { - { kInvalidReg, kInvalidReg, kVarAttrInOutReg }, - { kRegIndexCx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstSahf[] = { + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstShlrd[] = { - { kInvalidReg, kInvalidReg, kVarAttrInOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg }, - { kRegIndexCx, kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstMaskmovqMaskmovdqu[] = { + { kInvalidReg , kX86RegIndexDi, kVarAttrInReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstRdtscRdtscp[] = { - { kInvalidReg, kRegIndexDx, kVarAttrOutReg }, - { kInvalidReg, kRegIndexAx, kVarAttrOutReg }, - { kInvalidReg, kRegIndexCx, kVarAttrOutReg } +static const X86SpecialInst x86SpecialInstRdtscRdtscp[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg } }; -static const X86X64SpecialInst x86SpecialInstRepLod[] = { - { kInvalidReg, kRegIndexAx, kVarAttrOutReg }, - { kRegIndexSi, kInvalidReg, kVarAttrInReg }, - { kRegIndexCx, kRegIndexCx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstRot[] = { + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstRepMovCmp[] = { - { kRegIndexDi, kInvalidReg, kVarAttrInReg }, - { kRegIndexSi, kInvalidReg, kVarAttrInReg }, - { kRegIndexCx, kRegIndexCx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstScas[] = { + { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstRepSto[] = { - { kRegIndexDi, kInvalidReg, kVarAttrInReg }, - { kRegIndexAx, kInvalidReg, kVarAttrInReg }, - { kRegIndexCx, kRegIndexCx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstShlrd[] = { + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } }; -static const X86X64SpecialInst x86SpecialInstRepSca[] = { - { kRegIndexDi, kInvalidReg, kVarAttrInReg }, - { kRegIndexAx, kInvalidReg, kVarAttrInReg }, - { kRegIndexCx, kRegIndexCx, kVarAttrInOutReg } +static const X86SpecialInst x86SpecialInstStos[] = { + { kX86RegIndexDi, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } }; -static const X86X64SpecialInst x86SpecialInstBlend[] = { - { kInvalidReg, kInvalidReg, kVarAttrOutReg }, - { kInvalidReg, kInvalidReg, kVarAttrInReg }, - { 0 , kInvalidReg, kVarAttrInReg } +static const X86SpecialInst x86SpecialInstBlend[] = { + { kInvalidReg , kInvalidReg , kVarAttrOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { 0 , kInvalidReg , kVarAttrInReg } }; -static ASMJIT_INLINE const X86X64SpecialInst* X86X64SpecialInst_get(uint32_t code, const Operand* opList, uint32_t opCount) { +static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t code, const Operand* opList, uint32_t opCount) { switch (code) { - case kInstCpuid: + case kX86InstIdCpuid: return x86SpecialInstCpuid; - case kInstCbw: - case kInstCdqe: - case kInstCwde: + case kX86InstIdCbw: + case kX86InstIdCdqe: + case kX86InstIdCwde: return x86SpecialInstCbwCdqeCwde; - case kInstCdq: - case kInstCwd: - case kInstCqo: + case kX86InstIdCdq: + case kX86InstIdCwd: + case kX86InstIdCqo: return x86SpecialInstCdqCwdCqo; - case kInstCmpxchg: + case kX86InstIdCmpsB: + case kX86InstIdCmpsD: + case kX86InstIdCmpsQ: + case kX86InstIdCmpsW: + case kX86InstIdRepeCmpsB: + case kX86InstIdRepeCmpsD: + case kX86InstIdRepeCmpsQ: + case kX86InstIdRepeCmpsW: + case kX86InstIdRepneCmpsB: + case kX86InstIdRepneCmpsD: + case kX86InstIdRepneCmpsQ: + case kX86InstIdRepneCmpsW: + return x86SpecialInstMovsCmps; + + case kX86InstIdCmpxchg: return x86SpecialInstCmpxchg; - case kInstCmpxchg8b: - case kInstCmpxchg16b: + case kX86InstIdCmpxchg8b: + case kX86InstIdCmpxchg16b: return x86SpecialInstCmpxchg8b16b; - case kInstDaa: - case kInstDas: + case kX86InstIdDaa: + case kX86InstIdDas: return x86SpecialInstDaaDas; - case kInstJecxz: + case kX86InstIdJecxz: return x86SpecialInstJecxz; - case kInstIdiv: - case kInstDiv: + case kX86InstIdIdiv: + case kX86InstIdDiv: return x86SpecialInstDiv; - case kInstImul: + case kX86InstIdImul: if (opCount == 2) return NULL; if (opCount == 3 && !(opList[0].isVar() && opList[1].isVar() && opList[2].isVarOrMem())) return NULL; // ... Fall through ... - case kInstMul: + case kX86InstIdMul: return x86SpecialInstMul; - case kInstMovPtr: + case kX86InstIdMovPtr: return x86SpecialInstMovPtr; - case kInstLahf: + case kX86InstIdLodsB: + case kX86InstIdLodsD: + case kX86InstIdLodsQ: + case kX86InstIdLodsW: + case kX86InstIdRepLodsB: + case kX86InstIdRepLodsD: + case kX86InstIdRepLodsQ: + case kX86InstIdRepLodsW: + return x86SpecialInstLods; + + case kX86InstIdMovsB: + case kX86InstIdMovsD: + case kX86InstIdMovsQ: + case kX86InstIdMovsW: + case kX86InstIdRepMovsB: + case kX86InstIdRepMovsD: + case kX86InstIdRepMovsQ: + case kX86InstIdRepMovsW: + return x86SpecialInstMovsCmps; + + case kX86InstIdLahf: return x86SpecialInstLahf; - case kInstSahf: + case kX86InstIdSahf: return x86SpecialInstSahf; - case kInstMaskmovq: - case kInstMaskmovdqu: + case kX86InstIdMaskmovq: + case kX86InstIdMaskmovdqu: return x86SpecialInstMaskmovqMaskmovdqu; // Not supported. - case kInstEnter: - case kInstLeave: + case kX86InstIdEnter: + case kX86InstIdLeave: return NULL; // Not supported. - case kInstRet: + case kX86InstIdRet: return NULL; - case kInstMonitor: - case kInstMwait: + case kX86InstIdMonitor: + case kX86InstIdMwait: // TODO: [COMPILER] Monitor/MWait. return NULL; - case kInstPop: + case kX86InstIdPop: // TODO: [COMPILER] Pop. return NULL; // Not supported. - case kInstPopa: - case kInstPopf: + case kX86InstIdPopa: + case kX86InstIdPopf: return NULL; - case kInstPush: + case kX86InstIdPush: // TODO: [COMPILER] Push. return NULL; // Not supported. - case kInstPusha: - case kInstPushf: + case kX86InstIdPusha: + case kX86InstIdPushf: return NULL; // Rot instruction is special only if the last operand is a variable. - case kInstRcl: - case kInstRcr: - case kInstRol: - case kInstRor: - case kInstSal: - case kInstSar: - case kInstShl: - case kInstShr: + case kX86InstIdRcl: + case kX86InstIdRcr: + case kX86InstIdRol: + case kX86InstIdRor: + case kX86InstIdSal: + case kX86InstIdSar: + case kX86InstIdShl: + case kX86InstIdShr: if (!opList[1].isVar()) return NULL; return x86SpecialInstRot; // Shld/Shrd instruction is special only if the last operand is a variable. - case kInstShld: - case kInstShrd: + case kX86InstIdShld: + case kX86InstIdShrd: if (!opList[2].isVar()) return NULL; return x86SpecialInstShlrd; - case kInstRdtsc: - case kInstRdtscp: + case kX86InstIdRdtsc: + case kX86InstIdRdtscp: return x86SpecialInstRdtscRdtscp; - case kInstRepLodsb: - case kInstRepLodsd: - case kInstRepLodsq: - case kInstRepLodsw: - return x86SpecialInstRepLod; + case kX86InstIdScasB: + case kX86InstIdScasD: + case kX86InstIdScasQ: + case kX86InstIdScasW: + case kX86InstIdRepeScasB: + case kX86InstIdRepeScasD: + case kX86InstIdRepeScasQ: + case kX86InstIdRepeScasW: + case kX86InstIdRepneScasB: + case kX86InstIdRepneScasD: + case kX86InstIdRepneScasQ: + case kX86InstIdRepneScasW: + return x86SpecialInstScas; - case kInstRepMovsb: - case kInstRepMovsd: - case kInstRepMovsq: - case kInstRepMovsw: - return x86SpecialInstRepMovCmp; + case kX86InstIdStosB: + case kX86InstIdStosD: + case kX86InstIdStosQ: + case kX86InstIdStosW: + case kX86InstIdRepStosB: + case kX86InstIdRepStosD: + case kX86InstIdRepStosQ: + case kX86InstIdRepStosW: + return x86SpecialInstStos; - case kInstRepeCmpsb: - case kInstRepeCmpsd: - case kInstRepeCmpsq: - case kInstRepeCmpsw: - return x86SpecialInstRepMovCmp; - - case kInstRepneCmpsb: - case kInstRepneCmpsd: - case kInstRepneCmpsq: - case kInstRepneCmpsw: - return x86SpecialInstRepMovCmp; - - case kInstRepStosb: - case kInstRepStosd: - case kInstRepStosq: - case kInstRepStosw: - return x86SpecialInstRepSto; - - case kInstRepeScasb: - case kInstRepeScasd: - case kInstRepeScasq: - case kInstRepeScasw: - return x86SpecialInstRepSca; - - case kInstRepneScasb: - case kInstRepneScasd: - case kInstRepneScasq: - case kInstRepneScasw: - return x86SpecialInstRepSca; - - case kInstBlendvpd: - case kInstBlendvps: - case kInstPblendvb: + case kX86InstIdBlendvpd: + case kX86InstIdBlendvps: + case kX86InstIdPblendvb: return x86SpecialInstBlend; default: @@ -384,14 +606,14 @@ static ASMJIT_INLINE const X86X64SpecialInst* X86X64SpecialInst_get(uint32_t cod } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitLoad] +// [asmjit::X86Context - EmitLoad] // ============================================================================ -void X86X64Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) { +void X86Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) { ASMJIT_ASSERT(regIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); - Mem m = getVarMem(vd); + X86Compiler* compiler = getCompiler(); + X86Mem m = getVarMem(vd); Node* node = NULL; bool comment = _emitComments; @@ -399,26 +621,26 @@ void X86X64Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) switch (vd->getType()) { case kVarTypeInt8: case kVarTypeUInt8: - node = compiler->emit(kInstMov, gpb_lo(regIndex), m); + node = compiler->emit(kX86InstIdMov, x86::gpb_lo(regIndex), m); if (comment) goto _Comment; break; case kVarTypeInt16: case kVarTypeUInt16: - node = compiler->emit(kInstMov, gpw(regIndex), m); + node = compiler->emit(kX86InstIdMov, x86::gpw(regIndex), m); if (comment) goto _Comment; break; case kVarTypeInt32: case kVarTypeUInt32: - node = compiler->emit(kInstMov, gpd(regIndex), m); + node = compiler->emit(kX86InstIdMov, x86::gpd(regIndex), m); if (comment) goto _Comment; break; #if defined(ASMJIT_BUILD_X64) case kVarTypeInt64: case kVarTypeUInt64: - node = compiler->emit(kInstMov, x64::gpq(regIndex), m); + node = compiler->emit(kX86InstIdMov, x86::gpq(regIndex), m); if (comment) goto _Comment; break; #endif // ASMJIT_BUILD_X64 @@ -428,33 +650,33 @@ void X86X64Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) // TODO: [COMPILER] FPU. break; - case kVarTypeMm: - node = compiler->emit(kInstMovq, mm(regIndex), m); + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, x86::mm(regIndex), m); if (comment) goto _Comment; break; - case kVarTypeXmm: - node = compiler->emit(kInstMovdqa, xmm(regIndex), m); + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovdqa, x86::xmm(regIndex), m); if (comment) goto _Comment; break; - case kVarTypeXmmSs: - node = compiler->emit(kInstMovss, xmm(regIndex), m); + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, x86::xmm(regIndex), m); if (comment) goto _Comment; break; - case kVarTypeXmmSd: - node = compiler->emit(kInstMovsd, xmm(regIndex), m); + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, x86::xmm(regIndex), m); if (comment) goto _Comment; break; - case kVarTypeXmmPs: - node = compiler->emit(kInstMovaps, xmm(regIndex), m); + case kX86VarTypeXmmPs: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(regIndex), m); if (comment) goto _Comment; break; - case kVarTypeXmmPd: - node = compiler->emit(kInstMovapd, xmm(regIndex), m); + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovapd, x86::xmm(regIndex), m); if (comment) goto _Comment; break; } @@ -465,14 +687,14 @@ _Comment: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitSave] +// [asmjit::X86Context - EmitSave] // ============================================================================ -void X86X64Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) { +void X86Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) { ASMJIT_ASSERT(regIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); - Mem m = getVarMem(vd); + X86Compiler* compiler = getCompiler(); + X86Mem m = getVarMem(vd); Node* node = NULL; bool comment = _emitComments; @@ -480,26 +702,26 @@ void X86X64Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) switch (vd->getType()) { case kVarTypeInt8: case kVarTypeUInt8: - node = compiler->emit(kInstMov, m, gpb_lo(regIndex)); + node = compiler->emit(kX86InstIdMov, m, x86::gpb_lo(regIndex)); if (comment) goto _Comment; break; case kVarTypeInt16: case kVarTypeUInt16: - node = compiler->emit(kInstMov, m, gpw(regIndex)); + node = compiler->emit(kX86InstIdMov, m, x86::gpw(regIndex)); if (comment) goto _Comment; break; case kVarTypeInt32: case kVarTypeUInt32: - node = compiler->emit(kInstMov, m, gpd(regIndex)); + node = compiler->emit(kX86InstIdMov, m, x86::gpd(regIndex)); if (comment) goto _Comment; break; #if defined(ASMJIT_BUILD_X64) case kVarTypeInt64: case kVarTypeUInt64: - node = compiler->emit(kInstMov, m, x64::gpq(regIndex)); + node = compiler->emit(kX86InstIdMov, m, x86::gpq(regIndex)); if (comment) goto _Comment; break; #endif // ASMJIT_BUILD_X64 @@ -509,33 +731,33 @@ void X86X64Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) // TODO: [COMPILER] FPU. break; - case kVarTypeMm: - node = compiler->emit(kInstMovq, m, mm(regIndex)); + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, m, x86::mm(regIndex)); if (comment) goto _Comment; break; - case kVarTypeXmm: - node = compiler->emit(kInstMovdqa, m, xmm(regIndex)); + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovdqa, m, x86::xmm(regIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmSs: - node = compiler->emit(kInstMovss, m, xmm(regIndex)); + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, m, x86::xmm(regIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmSd: - node = compiler->emit(kInstMovsd, m, xmm(regIndex)); + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, m, x86::xmm(regIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmPs: - node = compiler->emit(kInstMovaps, m, xmm(regIndex)); + case kX86VarTypeXmmPs: + node = compiler->emit(kX86InstIdMovaps, m, x86::xmm(regIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmPd: - node = compiler->emit(kInstMovapd, m, xmm(regIndex)); + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovapd, m, x86::xmm(regIndex)); if (comment) goto _Comment; break; } @@ -546,14 +768,14 @@ _Comment: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitMove] +// [asmjit::X86Context - EmitMove] // ============================================================================ -void X86X64Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason) { +void X86Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason) { ASMJIT_ASSERT(toRegIndex != kInvalidReg); ASMJIT_ASSERT(fromRegIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); + X86Compiler* compiler = getCompiler(); Node* node = NULL; bool comment = _emitComments; @@ -565,14 +787,14 @@ void X86X64Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegI case kVarTypeUInt16: case kVarTypeInt32: case kVarTypeUInt32: - node = compiler->emit(kInstMov, gpd(toRegIndex), gpd(fromRegIndex)); + node = compiler->emit(kX86InstIdMov, x86::gpd(toRegIndex), x86::gpd(fromRegIndex)); if (comment) goto _Comment; break; #if defined(ASMJIT_BUILD_X64) case kVarTypeInt64: case kVarTypeUInt64: - node = compiler->emit(kInstMov, x64::gpq(toRegIndex), x64::gpq(fromRegIndex)); + node = compiler->emit(kX86InstIdMov, x86::gpq(toRegIndex), x86::gpq(fromRegIndex)); if (comment) goto _Comment; break; #endif // ASMJIT_BUILD_X64 @@ -582,29 +804,29 @@ void X86X64Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegI // TODO: [COMPILER] FPU. break; - case kVarTypeMm: - node = compiler->emit(kInstMovq, mm(toRegIndex), mm(fromRegIndex)); + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, x86::mm(toRegIndex), x86::mm(fromRegIndex)); if (comment) goto _Comment; break; - case kVarTypeXmm: - node = compiler->emit(kInstMovaps, xmm(toRegIndex), xmm(fromRegIndex)); + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmSs: - node = compiler->emit(kInstMovss, xmm(toRegIndex), xmm(fromRegIndex)); + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmSd: - node = compiler->emit(kInstMovsd, xmm(toRegIndex), xmm(fromRegIndex)); + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); if (comment) goto _Comment; break; - case kVarTypeXmmPs: - case kVarTypeXmmPd: - node = compiler->emit(kInstMovaps, xmm(toRegIndex), xmm(fromRegIndex)); + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); if (comment) goto _Comment; break; } @@ -615,14 +837,14 @@ _Comment: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitSwap] +// [asmjit::X86Context - EmitSwap] // ============================================================================ -void X86X64Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason) { +void X86Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason) { ASMJIT_ASSERT(aIndex != kInvalidReg); ASMJIT_ASSERT(bIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); + X86Compiler* compiler = getCompiler(); Node* node = NULL; bool comment = _emitComments; @@ -631,13 +853,13 @@ void X86X64Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint uint32_t vType = IntUtil::iMax(aVd->getType(), bVd->getType()); if (vType == kVarTypeInt64 || vType == kVarTypeUInt64) { - node = compiler->emit(kInstXchg, x64::gpq(aIndex), x64::gpq(bIndex)); + node = compiler->emit(kX86InstIdXchg, x86::gpq(aIndex), x86::gpq(bIndex)); if (comment) goto _Comment; return; } #endif // ASMJIT_BUILD_X64 - node = compiler->emit(kInstXchg, gpd(aIndex), gpd(bIndex)); + node = compiler->emit(kX86InstIdXchg, x86::gpd(aIndex), x86::gpd(bIndex)); if (comment) goto _Comment; return; @@ -646,45 +868,47 @@ _Comment: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitPushSequence / EmitPopSequence] +// [asmjit::X86Context - EmitPushSequence / EmitPopSequence] // ============================================================================ -void X86X64Context::emitPushSequence(uint32_t regs) { - X86X64Compiler* compiler = getCompiler(); +void X86Context::emitPushSequence(uint32_t regs) { + X86Compiler* compiler = getCompiler(); uint32_t i = 0; - GpReg gpReg(_zsp); + X86GpReg gpReg(_zsp); while (regs != 0) { - ASMJIT_ASSERT(i < _baseRegsCount); + ASMJIT_ASSERT(i < _regCount.getGp()); if ((regs & 0x1) != 0) - compiler->emit(kInstPush, gpReg.setIndex(i)); + compiler->emit(kX86InstIdPush, gpReg.setIndex(i)); i++; regs >>= 1; } } -void X86X64Context::emitPopSequence(uint32_t regs) { - X86X64Compiler* compiler = getCompiler(); - int32_t i; - uint32_t mask; +void X86Context::emitPopSequence(uint32_t regs) { + X86Compiler* compiler = getCompiler(); if (regs == 0) return; - GpReg gpReg(_zsp); - for (i = _baseRegsCount - 1, mask = 0x1 << static_cast(i); i >= 0; i--, mask >>= 1) { - if ((regs & mask) == 0) - continue; - compiler->emit(kInstPop, gpReg.setIndex(i)); + int32_t i = static_cast(_regCount.getGp()) - 1; + uint32_t mask = 0x1 << static_cast(i); + + X86GpReg gpReg(_zsp); + while (i >= 0) { + if ((regs & mask) != 0) + compiler->emit(kX86InstIdPop, gpReg.setIndex(i)); + i--; + mask >>= 1; } } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitConvertVarToVar] +// [asmjit::X86Context - EmitConvertVarToVar] // ============================================================================ -void X86X64Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex) { - X86X64Compiler* compiler = getCompiler(); +void X86Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex) { + X86Compiler* compiler = getCompiler(); switch (dstType) { case kVarTypeInt8: @@ -697,16 +921,16 @@ void X86X64Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uin case kVarTypeUInt64: break; - case kVarTypeXmmPs: - if (srcType == kVarTypeXmmPd || srcType == kVarTypeYmmPd) { - compiler->emit(kInstCvtpd2ps, xmm(dstIndex), xmm(srcIndex)); + case kX86VarTypeXmmPs: + if (srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) { + compiler->emit(kX86InstIdCvtpd2ps, x86::xmm(dstIndex), x86::xmm(srcIndex)); return; } // ... Fall through ... - case kVarTypeXmmSs: - if (srcType == kVarTypeXmmSd || srcType == kVarTypeXmmPd || srcType == kVarTypeYmmPd) { - compiler->emit(kInstCvtsd2ss, xmm(dstIndex), xmm(srcIndex)); + case kX86VarTypeXmmSs: + if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) { + compiler->emit(kX86InstIdCvtsd2ss, x86::xmm(dstIndex), x86::xmm(srcIndex)); break; } @@ -716,16 +940,16 @@ void X86X64Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uin } break; - case kVarTypeXmmPd: - if (srcType == kVarTypeXmmPs || srcType == kVarTypeYmmPs) { - compiler->emit(kInstCvtps2pd, xmm(dstIndex), xmm(srcIndex)); + case kX86VarTypeXmmPd: + if (srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) { + compiler->emit(kX86InstIdCvtps2pd, x86::xmm(dstIndex), x86::xmm(srcIndex)); return; } // ... Fall through ... - case kVarTypeXmmSd: - if (srcType == kVarTypeXmmSs || srcType == kVarTypeXmmPs || srcType == kVarTypeYmmPs) { - compiler->emit(kInstCvtss2sd, xmm(dstIndex), xmm(srcIndex)); + case kX86VarTypeXmmSd: + if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) { + compiler->emit(kX86InstIdCvtss2sd, x86::xmm(dstIndex), x86::xmm(srcIndex)); return; } @@ -738,17 +962,17 @@ void X86X64Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uin } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitMoveVarOnStack / EmitMoveImmOnStack] +// [asmjit::X86Context - EmitMoveVarOnStack / EmitMoveImmOnStack] // ============================================================================ -void X86X64Context::emitMoveVarOnStack( - uint32_t dstType, const Mem* dst, +void X86Context::emitMoveVarOnStack( + uint32_t dstType, const X86Mem* dst, uint32_t srcType, uint32_t srcIndex) { ASMJIT_ASSERT(srcIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); + X86Compiler* compiler = getCompiler(); - Mem m0(*dst); + X86Mem m0(*dst); X86Reg r0; X86Reg r1; @@ -763,11 +987,11 @@ void X86X64Context::emitMoveVarOnStack( goto _MovGpD; // Move DWORD (Mm). - if (IntUtil::inInterval(srcType, kVarTypeMm, kVarTypeMm)) + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) goto _MovMmD; // Move DWORD (Xmm). - if (IntUtil::inInterval(srcType, kVarTypeXmm, kVarTypeXmmPd)) + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) goto _MovXmmD; break; @@ -777,9 +1001,9 @@ void X86X64Context::emitMoveVarOnStack( // Extend BYTE->WORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { r1.setSize(1); - r1.setCode(kRegTypeGpbLo, srcIndex); + r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kInstMovsx : kInstMovzx; + instCode = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } @@ -788,11 +1012,11 @@ void X86X64Context::emitMoveVarOnStack( goto _MovGpD; // Move DWORD (Mm). - if (IntUtil::inInterval(srcType, kVarTypeMm, kVarTypeMm)) + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) goto _MovMmD; // Move DWORD (Xmm). - if (IntUtil::inInterval(srcType, kVarTypeXmm, kVarTypeXmmPd)) + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) goto _MovXmmD; break; @@ -802,18 +1026,18 @@ void X86X64Context::emitMoveVarOnStack( // Extend BYTE->DWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { r1.setSize(1); - r1.setCode(kRegTypeGpbLo, srcIndex); + r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kInstMovsx : kInstMovzx; + instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } // Extend WORD->DWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { r1.setSize(2); - r1.setCode(kRegTypeGpw, srcIndex); + r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kInstMovsx : kInstMovzx; + instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } @@ -822,11 +1046,11 @@ void X86X64Context::emitMoveVarOnStack( goto _MovGpD; // Move DWORD (Mm). - if (IntUtil::inInterval(srcType, kVarTypeMm, kVarTypeMm)) + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) goto _MovMmD; // Move DWORD (Xmm). - if (IntUtil::inInterval(srcType, kVarTypeXmm, kVarTypeXmmPd)) + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) goto _MovXmmD; break; @@ -835,27 +1059,27 @@ void X86X64Context::emitMoveVarOnStack( // Extend BYTE->QWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { r1.setSize(1); - r1.setCode(kRegTypeGpbLo, srcIndex); + r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kInstMovsx : kInstMovzx; + instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpXQ; } // Extend WORD->QWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { r1.setSize(2); - r1.setCode(kRegTypeGpw, srcIndex); + r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kInstMovsx : kInstMovzx; + instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpXQ; } // Extend DWORD->QWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt32, kVarTypeUInt32)) { r1.setSize(4); - r1.setCode(kRegTypeGpd, srcIndex); + r1.setCode(kX86RegTypeGpd, srcIndex); - instCode = kInstMovsxd; + instCode = kX86InstIdMovsxd; if (dstType == kVarTypeInt64 && srcType == kVarTypeInt32) goto _ExtendMovGpXQ; else @@ -867,30 +1091,30 @@ void X86X64Context::emitMoveVarOnStack( goto _MovGpQ; // Move QWORD (Mm). - if (IntUtil::inInterval(srcType, kVarTypeMm, kVarTypeMm)) + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) goto _MovMmQ; // Move QWORD (Xmm). - if (IntUtil::inInterval(srcType, kVarTypeXmm, kVarTypeXmmPd)) + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) goto _MovXmmQ; break; - case kVarTypeMm: + case kX86VarTypeMm: // Extend BYTE->QWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { r1.setSize(1); - r1.setCode(kRegTypeGpbLo, srcIndex); + r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = kInstMovzx; + instCode = kX86InstIdMovzx; goto _ExtendMovGpXQ; } // Extend WORD->QWORD (Gp). if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { r1.setSize(2); - r1.setCode(kRegTypeGpw, srcIndex); + r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = kInstMovzx; + instCode = kX86InstIdMovzx; goto _ExtendMovGpXQ; } @@ -903,43 +1127,43 @@ void X86X64Context::emitMoveVarOnStack( goto _MovGpQ; // Move QWORD (Mm). - if (IntUtil::inInterval(srcType, kVarTypeMm, kVarTypeMm)) + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) goto _MovMmQ; // Move QWORD (Xmm). - if (IntUtil::inInterval(srcType, kVarTypeXmm, kVarTypeXmmPd)) + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) goto _MovXmmQ; break; case kVarTypeFp32: - case kVarTypeXmmSs: + case kX86VarTypeXmmSs: // Move FLOAT. - if (srcType == kVarTypeXmmSs || srcType == kVarTypeXmmPs || srcType == kVarTypeXmm) + if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeXmm) goto _MovXmmD; ASMJIT_ASSERT(!"Reached"); break; case kVarTypeFp64: - case kVarTypeXmmSd: + case kX86VarTypeXmmSd: // Move DOUBLE. - if (srcType == kVarTypeXmmSd || srcType == kVarTypeXmmPd || srcType == kVarTypeXmm) + if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeXmm) goto _MovXmmQ; ASMJIT_ASSERT(!"Reached"); break; - case kVarTypeXmm: + case kX86VarTypeXmm: // TODO: [COMPILER]. ASMJIT_ASSERT(!"Reached"); break; - case kVarTypeXmmPs: + case kX86VarTypeXmmPs: // TODO: [COMPILER]. ASMJIT_ASSERT(!"Reached"); break; - case kVarTypeXmmPd: + case kX86VarTypeXmmPd: // TODO: [COMPILER]. ASMJIT_ASSERT(!"Reached"); break; @@ -950,90 +1174,90 @@ void X86X64Context::emitMoveVarOnStack( _ExtendMovGpD: m0.setSize(4); r0.setSize(4); - r0.setCode(kRegTypeGpd, srcIndex); + r0.setCode(kX86RegTypeGpd, srcIndex); compiler->emit(instCode, r0, r1); - compiler->emit(kInstMov, m0, r0); + compiler->emit(kX86InstIdMov, m0, r0); return; _ExtendMovGpXQ: if (regSize == 8) { m0.setSize(8); r0.setSize(8); - r0.setCode(kRegTypeGpq, srcIndex); + r0.setCode(kX86RegTypeGpq, srcIndex); compiler->emit(instCode, r0, r1); - compiler->emit(kInstMov, m0, r0); + compiler->emit(kX86InstIdMov, m0, r0); } else { m0.setSize(4); r0.setSize(4); - r0.setCode(kRegTypeGpd, srcIndex); + r0.setCode(kX86RegTypeGpd, srcIndex); compiler->emit(instCode, r0, r1); _ExtendMovGpDQ: - compiler->emit(kInstMov, m0, r0); + compiler->emit(kX86InstIdMov, m0, r0); m0.adjust(4); - compiler->emit(kInstAnd, m0, 0); + compiler->emit(kX86InstIdAnd, m0, 0); } return; _ZeroExtendGpDQ: m0.setSize(4); r0.setSize(4); - r0.setCode(kRegTypeGpd, srcIndex); + r0.setCode(kX86RegTypeGpd, srcIndex); goto _ExtendMovGpDQ; // Move Gp. _MovGpD: m0.setSize(4); r0.setSize(4); - r0.setCode(kRegTypeGpd, srcIndex); - compiler->emit(kInstMov, m0, r0); + r0.setCode(kX86RegTypeGpd, srcIndex); + compiler->emit(kX86InstIdMov, m0, r0); return; _MovGpQ: m0.setSize(8); r0.setSize(8); - r0.setCode(kRegTypeGpq, srcIndex); - compiler->emit(kInstMov, m0, r0); + r0.setCode(kX86RegTypeGpq, srcIndex); + compiler->emit(kX86InstIdMov, m0, r0); return; // Move Mm. _MovMmD: m0.setSize(4); r0.setSize(8); - r0.setCode(kRegTypeMm, srcIndex); - compiler->emit(kInstMovd, m0, r0); + r0.setCode(kX86RegTypeMm, srcIndex); + compiler->emit(kX86InstIdMovd, m0, r0); return; _MovMmQ: m0.setSize(8); r0.setSize(8); - r0.setCode(kRegTypeMm, srcIndex); - compiler->emit(kInstMovq, m0, r0); + r0.setCode(kX86RegTypeMm, srcIndex); + compiler->emit(kX86InstIdMovq, m0, r0); return; // Move Xmm. _MovXmmD: m0.setSize(4); r0.setSize(16); - r0.setCode(kRegTypeXmm, srcIndex); - compiler->emit(kInstMovss, m0, r0); + r0.setCode(kX86RegTypeXmm, srcIndex); + compiler->emit(kX86InstIdMovss, m0, r0); return; _MovXmmQ: m0.setSize(8); r0.setSize(16); - r0.setCode(kRegTypeXmm, srcIndex); - compiler->emit(kInstMovlps, m0, r0); + r0.setCode(kX86RegTypeXmm, srcIndex); + compiler->emit(kX86InstIdMovlps, m0, r0); } -void X86X64Context::emitMoveImmOnStack(uint32_t dstType, const Mem* dst, const Imm* src) { - X86X64Compiler* compiler = getCompiler(); +void X86Context::emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src) { + X86Compiler* compiler = getCompiler(); - Mem mem(*dst); + X86Mem mem(*dst); Imm imm(*src); uint32_t regSize = compiler->getRegSize(); @@ -1047,20 +1271,20 @@ void X86X64Context::emitMoveImmOnStack(uint32_t dstType, const Mem* dst, const I case kVarTypeInt8: case kVarTypeUInt8: imm.truncateTo8Bits(); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); break; case kVarTypeInt16: case kVarTypeUInt16: imm.truncateTo16Bits(); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); break; case kVarTypeInt32: case kVarTypeUInt32: _Move32: imm.truncateTo32Bits(); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); break; case kVarTypeInt64: @@ -1071,15 +1295,15 @@ _Move64: // Lo-Part. imm.truncateTo32Bits(); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); // Hi-Part. mem.adjust(regSize); imm.setUInt32(hi); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); } else { - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); } break; @@ -1089,44 +1313,44 @@ _Move64: case kVarTypeFp64: goto _Move64; - case kVarTypeMm: + case kX86VarTypeMm: goto _Move64; - case kVarTypeXmm: - case kVarTypeXmmSs: - case kVarTypeXmmPs: - case kVarTypeXmmSd: - case kVarTypeXmmPd: + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPd: if (regSize == 4) { uint32_t hi = imm.getUInt32Hi(); // Lo-Part. imm.truncateTo32Bits(); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); // Hi-Part. mem.adjust(regSize); imm.setUInt32(hi); - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); // Zero part - performing AND should generate shorter code, because // 8-bit immediate can be used instead of 32-bit immediate required // by MOV instruction. mem.adjust(regSize); imm.setUInt32(0); - compiler->emit(kInstAnd, mem, imm); + compiler->emit(kX86InstIdAnd, mem, imm); mem.adjust(regSize); - compiler->emit(kInstAnd, mem, imm); + compiler->emit(kX86InstIdAnd, mem, imm); } else { // Lo-Hi parts. - compiler->emit(kInstMov, mem, imm); + compiler->emit(kX86InstIdMov, mem, imm); // Zero part. mem.adjust(regSize); imm.setUInt32(0); - compiler->emit(kInstAnd, mem, imm); + compiler->emit(kX86InstIdAnd, mem, imm); } break; @@ -1137,12 +1361,12 @@ _Move64: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - EmitMoveImmToReg] +// [asmjit::X86Context - EmitMoveImmToReg] // ============================================================================ -void X86X64Context::emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src) { +void X86Context::emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src) { ASMJIT_ASSERT(dstIndex != kInvalidReg); - X86X64Compiler* compiler = getCompiler(); + X86Compiler* compiler = getCompiler(); X86Reg r0; Imm imm(*src); @@ -1164,20 +1388,20 @@ _Move32Truncate: imm.truncateTo32Bits(); _Move32: r0.setSize(4); - r0.setCode(kRegTypeGpd, dstIndex); - compiler->emit(kInstMov, r0, imm); + r0.setCode(kX86RegTypeGpd, dstIndex); + compiler->emit(kX86InstIdMov, r0, imm); break; case kVarTypeInt64: case kVarTypeUInt64: - // Move to Gpd register will clear also high DWORD of Gpq register in + // Move to Gpd register will also clear high DWORD of Gpq register in // 64-bit mode. if (imm.isUInt32()) goto _Move32Truncate; r0.setSize(8); - r0.setCode(kRegTypeGpq, dstIndex); - compiler->emit(kInstMov, r0, imm); + r0.setCode(kX86RegTypeGpq, dstIndex); + compiler->emit(kX86InstIdMov, r0, imm); break; case kVarTypeFp32: @@ -1185,33 +1409,33 @@ _Move32: // TODO: [COMPILER] EmitMoveImmToReg. break; - case kVarTypeMm: + case kX86VarTypeMm: // TODO: [COMPILER] EmitMoveImmToReg. break; - case kVarTypeXmm: - case kVarTypeXmmSs: - case kVarTypeXmmSd: - case kVarTypeXmmPs: - case kVarTypeXmmPd: + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: // TODO: [COMPILER] EmitMoveImmToReg. break; } } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Register Management] +// [asmjit::X86Context - Register Management] // ============================================================================ #if defined(ASMJIT_DEBUG) template -static ASMJIT_INLINE void X86X64Context_checkStateVars(X86X64Context* self) { - VarState* state = self->getState(); +static ASMJIT_INLINE void X86Context_checkStateVars(X86Context* self) { + X86VarState* state = self->getState(); VarData** sVars = state->getListByClass(C); uint32_t regIndex; uint32_t regMask; - uint32_t regCount = self->getRegsCount(C); + uint32_t regCount = self->_regCount.get(C); uint32_t occupied = state->_occupied.get(C); uint32_t modified = state->_modified.get(C); @@ -1234,29 +1458,29 @@ static ASMJIT_INLINE void X86X64Context_checkStateVars(X86X64Context* self) { } } -void X86X64Context::_checkState() { - X86X64Context_checkStateVars(this); - X86X64Context_checkStateVars(this); - X86X64Context_checkStateVars(this); +void X86Context::_checkState() { + X86Context_checkStateVars(this); + X86Context_checkStateVars(this); + X86Context_checkStateVars(this); } #else -void X86X64Context::_checkState() {} +void X86Context::_checkState() {} #endif // ASMJIT_DEBUG // ============================================================================ -// [asmjit::x86x64::X86X64Context - State - Load] +// [asmjit::X86Context - State - Load] // ============================================================================ template -static ASMJIT_INLINE void X86X64Context_loadStateVars(X86X64Context* self, VarState* src) { - VarState* cur = self->getState(); +static ASMJIT_INLINE void X86Context_loadStateVars(X86Context* self, X86VarState* src) { + X86VarState* cur = self->getState(); VarData** cVars = cur->getListByClass(C); VarData** sVars = src->getListByClass(C); uint32_t regIndex; uint32_t modified = src->_modified.get(C); - uint32_t regCount = self->getRegsCount(C); + uint32_t regCount = self->_regCount.get(C); for (regIndex = 0; regIndex < regCount; regIndex++, modified >>= 1) { VarData* vd = sVars[regIndex]; @@ -1271,17 +1495,17 @@ static ASMJIT_INLINE void X86X64Context_loadStateVars(X86X64Context* self, VarSt } } -void X86X64Context::loadState(BaseVarState* src_) { - VarState* cur = getState(); - VarState* src = static_cast(src_); +void X86Context::loadState(VarState* src_) { + X86VarState* cur = getState(); + X86VarState* src = static_cast(src_); VarData** vdArray = _contextVd.getData(); uint32_t vdCount = static_cast(_contextVd.getLength()); // Load allocated variables. - X86X64Context_loadStateVars(this, src); - X86X64Context_loadStateVars(this, src); - X86X64Context_loadStateVars(this, src); + X86Context_loadStateVars(this, src); + X86Context_loadStateVars(this, src); + X86Context_loadStateVars(this, src); // Load masks. cur->_occupied = src->_occupied; @@ -1303,24 +1527,24 @@ void X86X64Context::loadState(BaseVarState* src_) { } // ============================================================================ -// [asmjit::x86x64::X86X64Context - State - Save] +// [asmjit::X86Context - State - Save] // ============================================================================ -BaseVarState* X86X64Context::saveState() { +VarState* X86Context::saveState() { VarData** vdArray = _contextVd.getData(); uint32_t vdCount = static_cast(_contextVd.getLength()); size_t size = IntUtil::alignTo( - sizeof(VarState) + vdCount * sizeof(StateCell), sizeof(void*)); + sizeof(X86VarState) + vdCount * sizeof(X86StateCell), sizeof(void*)); - VarState* cur = getState(); - VarState* dst = _baseZone.allocT(size); + X86VarState* cur = getState(); + X86VarState* dst = _baseZone.allocT(size); if (dst == NULL) return NULL; // Store links. - ::memcpy(dst->_list, cur->_list, VarState::kAllCount * sizeof(VarData*)); + ::memcpy(dst->_list, cur->_list, X86VarState::kAllCount * sizeof(VarData*)); // Store masks. dst->_occupied = cur->_occupied; @@ -1329,7 +1553,7 @@ BaseVarState* X86X64Context::saveState() { // Store cells. for (uint32_t i = 0; i < vdCount; i++) { VarData* vd = static_cast(vdArray[i]); - StateCell& cell = dst->_cells[i]; + X86StateCell& cell = dst->_cells[i]; cell.reset(); cell.setState(vd->getState()); @@ -1339,21 +1563,21 @@ BaseVarState* X86X64Context::saveState() { } // ============================================================================ -// [asmjit::x86x64::X86X64Context - State - Switch] +// [asmjit::X86Context - State - Switch] // ============================================================================ template -static ASMJIT_INLINE void X86X64Context_switchStateVars(X86X64Context* self, VarState* src) { - VarState* dst = self->getState(); +static ASMJIT_INLINE void X86Context_switchStateVars(X86Context* self, X86VarState* src) { + X86VarState* dst = self->getState(); VarData** dstVars = dst->getListByClass(C); VarData** srcVars = src->getListByClass(C); uint32_t regIndex; uint32_t regMask; - uint32_t regCount = self->getRegsCount(C); + uint32_t regCount = self->_regCount.get(C); - StateCell* cells = src->_cells; + X86StateCell* cells = src->_cells; bool didWork; do { @@ -1367,7 +1591,7 @@ static ASMJIT_INLINE void X86X64Context_switchStateVars(X86X64Context* self, Var continue; if (dVd != NULL) { - StateCell& cell = cells[dVd->getContextId()]; + X86StateCell& cell = cells[dVd->getContextId()]; if (cell.getState() != kVarStateReg) { if (cell.getState() == kVarStateMem) @@ -1395,7 +1619,7 @@ _MoveOrLoad: } if (dVd != NULL && sVd == NULL) { - StateCell& cell = cells[dVd->getContextId()]; + X86StateCell& cell = cells[dVd->getContextId()]; if (cell.getState() == kVarStateReg) continue; @@ -1408,11 +1632,11 @@ _MoveOrLoad: continue; } else { - StateCell& cell = cells[dVd->getContextId()]; + X86StateCell& cell = cells[dVd->getContextId()]; if (cell.getState() == kVarStateReg) { if (dVd->getRegIndex() != kInvalidReg && sVd->getRegIndex() != kInvalidReg) { - if (C == kRegClassGp) { + if (C == kX86RegClassGp) { self->swapGp(dVd, sVd); } else { @@ -1461,29 +1685,29 @@ _MoveOrLoad: } } -void X86X64Context::switchState(BaseVarState* src_) { +void X86Context::switchState(VarState* src_) { ASMJIT_ASSERT(src_ != NULL); - VarState* cur = getState(); - VarState* src = static_cast(src_); + X86VarState* cur = getState(); + X86VarState* src = static_cast(src_); // Ignore if both states are equal. if (cur == src) return; // Switch variables. - X86X64Context_switchStateVars(this, src); - X86X64Context_switchStateVars(this, src); - X86X64Context_switchStateVars(this, src); + X86Context_switchStateVars(this, src); + X86Context_switchStateVars(this, src); + X86Context_switchStateVars(this, src); // Calculate changed state. VarData** vdArray = _contextVd.getData(); uint32_t vdCount = static_cast(_contextVd.getLength()); - StateCell* cells = src->_cells; + X86StateCell* cells = src->_cells; for (uint32_t i = 0; i < vdCount; i++) { VarData* vd = static_cast(vdArray[i]); - StateCell& cell = cells[i]; + X86StateCell& cell = cells[i]; uint32_t vState = cell.getState(); if (vState != kVarStateReg) { @@ -1496,23 +1720,23 @@ void X86X64Context::switchState(BaseVarState* src_) { } // ============================================================================ -// [asmjit::x86x64::X86X64Context - State - Intersect] +// [asmjit::X86Context - State - Intersect] // ============================================================================ -void X86X64Context::intersectStates(BaseVarState* a_, BaseVarState* b_) { - VarState* aState = static_cast(a_); - VarState* bState = static_cast(b_); +void X86Context::intersectStates(VarState* a_, VarState* b_) { + X86VarState* aState = static_cast(a_); + X86VarState* bState = static_cast(b_); // TODO: [COMPILER] Intersect states. ASMJIT_X86_CHECK_STATE } // ============================================================================ -// [asmjit::x86x64::X86X64Context - GetJccFlow / GetOppositeJccFlow] +// [asmjit::X86Context - GetJccFlow / GetOppositeJccFlow] // ============================================================================ //! \internal -static ASMJIT_INLINE Node* X86X64Context_getJccFlow(JumpNode* jNode) { +static ASMJIT_INLINE Node* X86Context_getJccFlow(JumpNode* jNode) { if (jNode->isTaken()) return jNode->getTarget(); else @@ -1520,7 +1744,7 @@ static ASMJIT_INLINE Node* X86X64Context_getJccFlow(JumpNode* jNode) { } //! \internal -static ASMJIT_INLINE Node* X86X64Context_getOppositeJccFlow(JumpNode* jNode) { +static ASMJIT_INLINE Node* X86Context_getOppositeJccFlow(JumpNode* jNode) { if (jNode->isTaken()) return jNode->getNext(); else @@ -1528,46 +1752,46 @@ static ASMJIT_INLINE Node* X86X64Context_getOppositeJccFlow(JumpNode* jNode) { } // ============================================================================ -// [asmjit::x86x64::X86X64Context - SingleVarInst] +// [asmjit::X86Context - SingleVarInst] // ============================================================================ //! \internal -static void X86X64Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { +static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { switch (code) { // - andn reg, reg ; Set all bits in reg to 0. // - xor/pxor reg, reg ; Set all bits in reg to 0. // - sub/psub reg, reg ; Set all bits in reg to 0. // - pcmpgt reg, reg ; Set all bits in reg to 0. // - pcmpeq reg, reg ; Set all bits in reg to 1. - case kInstPandn : - case kInstXor : case kInstXorpd : case kInstXorps : case kInstPxor : - case kInstSub: - case kInstPsubb : case kInstPsubw : case kInstPsubd : case kInstPsubq : - case kInstPsubsb : case kInstPsubsw : case kInstPsubusb : case kInstPsubusw : - case kInstPcmpeqb : case kInstPcmpeqw : case kInstPcmpeqd : case kInstPcmpeqq : - case kInstPcmpgtb : case kInstPcmpgtw : case kInstPcmpgtd : case kInstPcmpgtq : + case kX86InstIdPandn : + case kX86InstIdXor : case kX86InstIdXorpd : case kX86InstIdXorps : case kX86InstIdPxor : + case kX86InstIdSub: + case kX86InstIdPsubb : case kX86InstIdPsubw : case kX86InstIdPsubd : case kX86InstIdPsubq : + case kX86InstIdPsubsb : case kX86InstIdPsubsw : case kX86InstIdPsubusb : case kX86InstIdPsubusw : + case kX86InstIdPcmpeqb : case kX86InstIdPcmpeqw : case kX86InstIdPcmpeqd : case kX86InstIdPcmpeqq : + case kX86InstIdPcmpgtb : case kX86InstIdPcmpgtw : case kX86InstIdPcmpgtd : case kX86InstIdPcmpgtq : va->delFlags(kVarAttrInReg); break; // - and reg, reg ; Nop. // - or reg, reg ; Nop. // - xchg reg, reg ; Nop. - case kInstAnd : case kInstAndpd : case kInstAndps : case kInstPand : - case kInstOr : case kInstOrpd : case kInstOrps : case kInstPor : - case kInstXchg : + case kX86InstIdAnd : case kX86InstIdAndpd : case kX86InstIdAndps : case kX86InstIdPand : + case kX86InstIdOr : case kX86InstIdOrpd : case kX86InstIdOrps : case kX86InstIdPor : + case kX86InstIdXchg : va->delFlags(kVarAttrOutReg); break; } } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Helpers] +// [asmjit::X86Context - Helpers] // ============================================================================ //! \internal //! //! Add unreachable-flow data to the unreachable flow list. -static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self, Node* node) { +static ASMJIT_INLINE Error X86Context_addUnreachableNode(X86Context* self, Node* node) { PodList::Link* link = self->_baseZone.allocT::Link>(); if (link == NULL) return self->setError(kErrorNoHeapMemory); @@ -1581,7 +1805,7 @@ static ASMJIT_INLINE Error X86X64Context_addUnreachableNode(X86X64Context* self, //! \internal //! //! Add jump-flow data to the jcc flow list. -static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, Node* node) { +static ASMJIT_INLINE Error X86Context_addJccNode(X86Context* self, Node* node) { PodList::Link* link = self->_baseZone.allocT::Link>(); if (link == NULL) @@ -1596,8 +1820,8 @@ static ASMJIT_INLINE Error X86X64Context_addJccNode(X86X64Context* self, Node* n //! \internal //! //! Get mask of all registers actually used to pass function arguments. -static ASMJIT_INLINE RegMask X86X64Context_getUsedArgs(X86X64Context* self, X86X64CallNode* node, X86X64FuncDecl* decl) { - RegMask regs; +static ASMJIT_INLINE X86RegMask X86Context_getUsedArgs(X86Context* self, X86CallNode* node, X86FuncDecl* decl) { + X86RegMask regs; regs.reset(); uint32_t i; @@ -1614,7 +1838,7 @@ static ASMJIT_INLINE RegMask X86X64Context_getUsedArgs(X86X64Context* self, X86X } // ============================================================================ -// [asmjit::x86x64::X86X64Context - SArg Insertion] +// [asmjit::X86Context - SArg Insertion] // ============================================================================ struct SArgData { @@ -1632,7 +1856,7 @@ struct SArgData { (S16 << 16) | (S17 << 17) | (S18 << 18) | (S19 << 19) | \ (S20 << 20) #define A 0 /* Auto-convert (doesn't need conversion step). */ -static const uint32_t X86X64Context_sArgConvTable[kVarTypeCount] = { +static const uint32_t X86Context_sArgConvTable[kX86VarTypeCount] = { // dst <- | i8| u8|i16|u16|i32|u32|i64|u64| iP| uP|f32|f64|mmx|xmm|xSs|xPs|xSd|xPd|ymm|yPs|yPd| //--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ SARG(i8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), @@ -1660,39 +1884,39 @@ static const uint32_t X86X64Context_sArgConvTable[kVarTypeCount] = { #undef A #undef SARG -static ASMJIT_INLINE bool X86X64Context_mustConvertSArg(X86X64Context* self, uint32_t aType, uint32_t sType) { - return (X86X64Context_sArgConvTable[aType] & (1 << sType)) != 0; +static ASMJIT_INLINE bool X86Context_mustConvertSArg(X86Context* self, uint32_t aType, uint32_t sType) { + return (X86Context_sArgConvTable[aType] & (1 << sType)) != 0; } -static ASMJIT_INLINE uint32_t X86X64Context_typeOfConvertedSArg(X86X64Context* self, uint32_t aType, uint32_t sType) { - ASMJIT_ASSERT(X86X64Context_mustConvertSArg(self, aType, sType)); +static ASMJIT_INLINE uint32_t X86Context_typeOfConvertedSArg(X86Context* self, uint32_t aType, uint32_t sType) { + ASMJIT_ASSERT(X86Context_mustConvertSArg(self, aType, sType)); if (IntUtil::inInterval(aType, _kVarTypeIntStart, _kVarTypeIntEnd)) return aType; if (aType == kVarTypeFp32) - return kVarTypeXmmSs; + return kX86VarTypeXmmSs; if (aType == kVarTypeFp64) - return kVarTypeXmmSd; + return kX86VarTypeXmmSd; - if (IntUtil::inInterval(aType, _kVarTypeXmmStart, _kVarTypeXmmEnd)) + if (IntUtil::inInterval(aType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd)) return aType; - if (IntUtil::inInterval(aType, _kVarTypeYmmStart, _kVarTypeYmmEnd)) + if (IntUtil::inInterval(aType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd)) return aType; ASMJIT_ASSERT(!"Reached"); return aType; } -static ASMJIT_INLINE Error X86X64Context_insertSArgNode( - X86X64Context* self, X86X64CallNode* call, +static ASMJIT_INLINE Error X86Context_insertSArgNode( + X86Context* self, X86CallNode* call, VarData* sVd, const uint32_t* gaRegs, const FuncInOut& arg, uint32_t argIndex, SArgData* sArgList, uint32_t& sArgCount) { - X86X64Compiler* compiler = self->getCompiler(); + X86Compiler* compiler = self->getCompiler(); uint32_t i; uint32_t aType = arg.getVarType(); @@ -1714,13 +1938,13 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode( sArgCount++; } - const VarInfo& sInfo = _varInfo[sType]; + const X86VarInfo& sInfo = _x86VarInfo[sType]; uint32_t sClass = sInfo.getClass(); - if (X86X64Context_mustConvertSArg(self, aType, sType)) { - uint32_t cType = X86X64Context_typeOfConvertedSArg(self, aType, sType); + if (X86Context_mustConvertSArg(self, aType, sType)) { + uint32_t cType = X86Context_typeOfConvertedSArg(self, aType, sType); - const VarInfo& cInfo = _varInfo[cType]; + const X86VarInfo& cInfo = _x86VarInfo[cType]; uint32_t cClass = cInfo.getClass(); while (++i < sArgCount) { @@ -1743,35 +1967,35 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode( if (sArg == NULL) return kErrorNoHeapMemory; - VarInst* vi = self->newVarInst(2); - if (vi == NULL) + X86VarMap* map = self->newVarMap(2); + if (map == NULL) return kErrorNoHeapMemory; ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(cVd)); ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(sVd)); - vi->_vaCount = 2; - vi->_count.reset(); - vi->_count.add(sClass); - vi->_count.add(cClass); + map->_vaCount = 2; + map->_count.reset(); + map->_count.add(sClass); + map->_count.add(cClass); - vi->_start.reset(); - vi->_inRegs.reset(); - vi->_outRegs.reset(); - vi->_clobberedRegs.reset(); + map->_start.reset(); + map->_inRegs.reset(); + map->_outRegs.reset(); + map->_clobberedRegs.reset(); if (sClass <= cClass) { - vi->_list[0].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); - vi->_list[1].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); - vi->_start.set(cClass, sClass != cClass); + map->_list[0].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); + map->_list[1].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); + map->_start.set(cClass, sClass != cClass); } else { - vi->_list[0].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); - vi->_list[1].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); - vi->_start.set(sClass, 1); + map->_list[0].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); + map->_list[1].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); + map->_start.set(sClass, 1); } - sArg->setVarInst(vi); + sArg->setMap(map); sArg->_args |= IntUtil::mask(argIndex); compiler->addNodeBefore(sArg, call); @@ -1794,20 +2018,20 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode( if (sArg == NULL) return kErrorNoHeapMemory; - VarInst* vi = self->newVarInst(1); - if (vi == NULL) + X86VarMap* map = self->newVarMap(1); + if (map == NULL) return kErrorNoHeapMemory; - vi->_vaCount = 1; - vi->_count.reset(); - vi->_count.add(sClass); - vi->_start.reset(); - vi->_inRegs.reset(); - vi->_outRegs.reset(); - vi->_clobberedRegs.reset(); - vi->_list[0].setup(sVd, kVarAttrInReg, 0, gaRegs[sClass]); + map->_vaCount = 1; + map->_count.reset(); + map->_count.add(sClass); + map->_start.reset(); + map->_inRegs.reset(); + map->_outRegs.reset(); + map->_clobberedRegs.reset(); + map->_list[0].setup(sVd, kVarAttrInReg, 0, gaRegs[sClass]); - sArg->setVarInst(vi); + sArg->setMap(map); sArgData->sArg = sArg; compiler->addNodeBefore(sArg, call); @@ -1819,7 +2043,7 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode( } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Fetch] +// [asmjit::X86Context - Fetch] // ============================================================================ //! \internal @@ -1829,9 +2053,11 @@ static ASMJIT_INLINE Error X86X64Context_insertSArgNode( //! For each node: //! - Create and assign groupId and flowId. //! - Collect all variables and merge them to vaList. -Error X86X64Context::fetch() { - X86X64Compiler* compiler = getCompiler(); - X86X64FuncNode* func = getFunc(); +Error X86Context::fetch() { + ASMJIT_TLOG("[Fetch] === Begin ===\n"); + + X86Compiler* compiler = getCompiler(); + X86FuncNode* func = getFunc(); uint32_t arch = compiler->getArch(); @@ -1850,26 +2076,26 @@ Error X86X64Context::fetch() { // Function flags. func->clearFuncFlags( kFuncFlagIsNaked | - kFuncFlagPushPop | - kFuncFlagEmms | - kFuncFlagSFence | - kFuncFlagLFence ); + kX86FuncFlagPushPop | + kX86FuncFlagEmms | + kX86FuncFlagSFence | + kX86FuncFlagLFence ); - if (func->getHint(kFuncHintNaked ) != 0) func->addFuncFlags(kFuncFlagIsNaked); - if (func->getHint(kFuncHintCompact) != 0) func->addFuncFlags(kFuncFlagPushPop | kFuncFlagEnter | kFuncFlagLeave); - if (func->getHint(kFuncHintPushPop) != 0) func->addFuncFlags(kFuncFlagPushPop); - if (func->getHint(kFuncHintEmms ) != 0) func->addFuncFlags(kFuncFlagEmms ); - if (func->getHint(kFuncHintSFence ) != 0) func->addFuncFlags(kFuncFlagSFence ); - if (func->getHint(kFuncHintLFence ) != 0) func->addFuncFlags(kFuncFlagLFence ); + if (func->getHint(kFuncHintNaked ) != 0) func->addFuncFlags(kFuncFlagIsNaked ); + if (func->getHint(kFuncHintCompact ) != 0) func->addFuncFlags(kX86FuncFlagPushPop | kX86FuncFlagEnter | kX86FuncFlagLeave); + if (func->getHint(kX86FuncHintPushPop) != 0) func->addFuncFlags(kX86FuncFlagPushPop); + if (func->getHint(kX86FuncHintEmms ) != 0) func->addFuncFlags(kX86FuncFlagEmms ); + if (func->getHint(kX86FuncHintSFence ) != 0) func->addFuncFlags(kX86FuncFlagSFence ); + if (func->getHint(kX86FuncHintLFence ) != 0) func->addFuncFlags(kX86FuncFlagLFence ); // Global allocable registers. uint32_t* gaRegs = _gaRegs; if (!func->hasFuncFlag(kFuncFlagIsNaked)) - gaRegs[kRegClassGp] &= ~IntUtil::mask(kRegIndexBp); + gaRegs[kX86RegClassGp] &= ~IntUtil::mask(kX86RegIndexBp); // Allowed index registers (Gp/Xmm/Ymm). - const uint32_t indexMask = IntUtil::bits(_baseRegsCount) & ~(IntUtil::mask(4, 12)); + const uint32_t indexMask = IntUtil::bits(_regCount.getGp()) & ~(IntUtil::mask(4, 12)); // -------------------------------------------------------------------------- // [VI Macros] @@ -1878,11 +2104,11 @@ Error X86X64Context::fetch() { #define VI_BEGIN() \ do { \ uint32_t vaCount = 0; \ - RegCount regCount; \ + X86RegCount regCount; \ \ - RegMask inRegs; \ - RegMask outRegs; \ - RegMask clobberedRegs; \ + X86RegMask inRegs; \ + X86RegMask outRegs; \ + X86RegMask clobberedRegs; \ \ regCount.reset(); \ inRegs.reset(); \ @@ -1893,20 +2119,20 @@ Error X86X64Context::fetch() { if (vaCount == 0 && clobberedRegs.isEmpty()) \ break; \ \ - VarInst* vi = newVarInst(vaCount); \ - if (vi == NULL) \ + X86VarMap* map = newVarMap(vaCount); \ + if (map == NULL) \ goto _NoMemory; \ \ - RegCount vaIndex; \ + X86RegCount vaIndex; \ vaIndex.makeIndex(regCount); \ \ - vi->_vaCount = vaCount; \ - vi->_count = regCount; \ - vi->_start = vaIndex; \ + map->_vaCount = vaCount; \ + map->_count = regCount; \ + map->_start = vaIndex; \ \ - vi->_inRegs = inRegs; \ - vi->_outRegs = outRegs; \ - vi->_clobberedRegs = clobberedRegs; \ + map->_inRegs = inRegs; \ + map->_outRegs = outRegs; \ + map->_clobberedRegs = clobberedRegs; \ \ VarAttr* va = vaTmpList; \ while (vaCount) { \ @@ -1925,13 +2151,13 @@ Error X86X64Context::fetch() { va->_allocableRegs &= ~inRegs.get(class_); \ \ vd->_va = NULL; \ - vi->getVa(index)[0] = va[0]; \ + map->getVa(index)[0] = va[0]; \ \ va++; \ vaCount--; \ } \ \ - _Node_->setVarInst(vi); \ + _Node_->setMap(map); \ } while (0) #define VI_ADD_VAR(_Vd_, _Va_, _Flags_, _NewAllocable_) \ @@ -1981,7 +2207,7 @@ _NextGroup: if (jLink == NULL) goto _Done; - node_ = X86X64Context_getOppositeJccFlow(static_cast(jLink->getValue())); + node_ = X86Context_getOppositeJccFlow(static_cast(jLink->getValue())); } flowId++; @@ -1989,6 +2215,10 @@ _NextGroup: next = node_->getNext(); node_->setFlowId(flowId); + ASMJIT_TSEC({ + X86Context_traceNode(this, node_); + }); + switch (node_->getType()) { // ---------------------------------------------------------------------- // [Align/Embed] @@ -2007,13 +2237,18 @@ _NextGroup: VI_BEGIN(); if (node->getHint() == kVarHintAlloc) { - uint32_t remain[kRegClassCount]; + uint32_t remain[kX86RegClassCount]; HintNode* cur = node; - remain[kRegClassGp ] = _baseRegsCount - 1 - func->hasFuncFlag(kFuncFlagIsNaked); - remain[kRegClassFp ] = kRegCountFp; - remain[kRegClassMm ] = kRegCountMm; - remain[kRegClassXyz] = _baseRegsCount; + remain[kX86RegClassGp ] = _regCount.getGp() - 1 - func->hasFuncFlag(kFuncFlagIsNaked); + remain[kX86RegClassFp ] = _regCount.getFp(); + remain[kX86RegClassMm ] = _regCount.getMm(); + + // Correct. Instead of using `getXyz()` which may be 32 in 64-bit + // mode we use `getGp()`. The reason is that not all registers are + // accessible by all instructions when using AVX512, this makes the + // algorithm safe. + remain[kX86RegClassXyz] = _regCount.getGp(); // Merge as many alloc-hints as possible. for (;;) { @@ -2070,7 +2305,7 @@ _NextGroup: switch (node->getHint()) { case kVarHintSpill: - flags = kVarAttrInMem; + flags = kVarAttrInMem | kVarAttrSpill; break; case kVarHintSave: flags = kVarAttrInMem; @@ -2112,15 +2347,15 @@ _NextGroup: uint32_t opCount = node->getOpCount(); if (opCount) { - const InstInfo* info = &_instInfo[code]; - const X86X64SpecialInst* special = NULL; + const X86InstExtendedInfo& extendedInfo = _x86InstInfo[code].getExtendedInfo(); + const X86SpecialInst* special = NULL; VI_BEGIN(); // Collect instruction flags and merge all 'VarAttr's. - if (info->isFp()) + if (extendedInfo.isFp()) flags |= kNodeFlagIsFp; - if (info->isSpecial() && (special = X86X64SpecialInst_get(code, opList, opCount)) != NULL) + if (extendedInfo.isSpecial() && (special = X86SpecialInst_get(code, opList, opCount)) != NULL) flags |= kNodeFlagIsSpecial; uint32_t gpAllowedMask = 0xFFFFFFFF; @@ -2135,7 +2370,7 @@ _NextGroup: VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask); if (static_cast(op)->isGpb()) { - va->addFlags(static_cast(op)->isGpbLo() ? kVarAttrGpbLo : kVarAttrGpbHi); + va->addFlags(static_cast(op)->isGpbLo() ? kX86VarAttrGpbLo : kX86VarAttrGpbHi); if (arch == kArchX86) { // If a byte register is accessed in 32-bit mode we have to limit // all allocable registers for that variable to eax/ebx/ecx/edx. @@ -2149,12 +2384,12 @@ _NextGroup: // half. To do that, we patch 'allocableRegs' of all variables // we collected until now and change the allocable restriction // for variables that come after. - if (static_cast(op)->isGpbHi()) { + if (static_cast(op)->isGpbHi()) { va->_allocableRegs &= 0x0F; if (gpAllowedMask != 0xFF) { for (uint32_t j = 0; j < i; j++) - vaTmpList[j]._allocableRegs &= vaTmpList[j].hasFlag(kVarAttrGpbHi) ? 0x0F : 0xFF; + vaTmpList[j]._allocableRegs &= vaTmpList[j].hasFlag(kX86VarAttrGpbHi) ? 0x0F : 0xFF; gpAllowedMask = 0xFF; } } @@ -2167,9 +2402,9 @@ _NextGroup: uint32_t c; if (static_cast(op)->isGp()) - c = kRegClassGp; + c = kX86RegClassGp; else - c = kRegClassXyz; + c = kX86RegClassXyz; if (inReg != kInvalidReg) { uint32_t mask = IntUtil::mask(inReg); @@ -2197,13 +2432,13 @@ _NextGroup: // Move instructions typically overwrite the first operand, // but there are some exceptions based on the operands' size // and type. - if (info->isMove()) { - uint32_t movSize = info->getMoveSize(); + if (extendedInfo.isMove()) { + uint32_t movSize = extendedInfo.getMoveSize(); uint32_t varSize = vd->getSize(); // Exception - If the source operand is a memory location // promote move size into 16 bytes. - if (info->isZeroIfMem() && opList[1].isMem()) + if (extendedInfo.isZeroIfMem() && opList[1].isMem()) movSize = 16; if (movSize >= varSize) { @@ -2229,11 +2464,11 @@ _NextGroup: } } // Comparison/Test instructions don't modify any operand. - else if (info->isTest()) { + else if (extendedInfo.isTest()) { combinedFlags = inFlags; } // Imul. - else if (code == kInstImul && opCount == 3) { + else if (code == kX86InstIdImul && opCount == 3) { combinedFlags = outFlags; } } @@ -2242,17 +2477,17 @@ _NextGroup: combinedFlags = inFlags; // Idiv is a special instruction, never handled here. - ASMJIT_ASSERT(code != kInstIdiv); + ASMJIT_ASSERT(code != kX86InstIdIdiv); // Xchg/Xadd/Imul. - if (info->isXchg() || (code == kInstImul && opCount == 3 && i == 1)) + if (extendedInfo.isXchg() || (code == kX86InstIdImul && opCount == 3 && i == 1)) combinedFlags = inFlags | outFlags; } va->addFlags(combinedFlags); } } else if (op->isMem()) { - Mem* m = static_cast(op); + X86Mem* m = static_cast(op); node->setMemOpIndex(i); if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) { @@ -2274,15 +2509,15 @@ _NextGroup: // Move to memory - setting the right flags is important // as if it's just move to the register. It's just a bit // simpler as there are no special cases. - if (info->isMove()) { - uint32_t movSize = IntUtil::iMax(info->getMoveSize(), m->getSize()); + if (extendedInfo.isMove()) { + uint32_t movSize = IntUtil::iMax(extendedInfo.getMoveSize(), m->getSize()); uint32_t varSize = vd->getSize(); if (movSize >= varSize) combinedFlags = outFlags; } // Comparison/Test instructions don't modify any operand. - else if (info->isTest()) { + else if (extendedInfo.isTest()) { combinedFlags = inFlags; } } @@ -2291,7 +2526,7 @@ _NextGroup: combinedFlags = inFlags; // Handle Xchg instruction (modifies both operands). - if (info->isXchg()) + if (extendedInfo.isXchg()) combinedFlags = inFlags | outFlags; } @@ -2303,7 +2538,7 @@ _NextGroup: if (OperandUtil::isVarId(m->getIndex())) { // Restrict allocation to all registers except ESP/RSP/R12. vd = compiler->getVdById(m->getIndex()); - VI_MERGE_VAR(vd, va, 0, gaRegs[kRegClassGp] & gpAllowedMask); + VI_MERGE_VAR(vd, va, 0, gaRegs[kX86RegClassGp] & gpAllowedMask); va->andAllocableRegs(indexMask); va->addFlags(kVarAttrInReg); } @@ -2315,7 +2550,7 @@ _NextGroup: // Handle instructions which result in zeros/ones or nop if used with the // same destination and source operand. if (vaCount == 1 && opCount >= 2 && opList[0].isVar() && opList[1].isVar() && !node->hasMemOp()) - X86X64Context_prepareSingleVarInst(code, &vaTmpList[0]); + X86Context_prepareSingleVarInst(code, &vaTmpList[0]); } VI_END(node_); @@ -2336,7 +2571,7 @@ _NextGroup: // natural flow of the function. if (jNode->isJmp()) { if (!jNext->isFetched()) - ASMJIT_PROPAGATE_ERROR(X86X64Context_addUnreachableNode(this, jNext)); + ASMJIT_PROPAGATE_ERROR(X86Context_addUnreachableNode(this, jNext)); node_ = jTarget; goto _Do; @@ -2347,7 +2582,7 @@ _NextGroup: // Update kNodeFlagIsTaken flag to true if this is a conditional // backward jump. This behavior can be overridden by using - // kCondHintUnlikely when the instruction is created. + // `kInstOptionTaken` when the instruction is created. if (!jNode->isTaken() && opCount == 1 && jTargetFlowId <= flowId) { jNode->addFlags(kNodeFlagIsTaken); } @@ -2357,9 +2592,9 @@ _NextGroup: goto _Do; } else { - ASMJIT_PROPAGATE_ERROR(X86X64Context_addJccNode(this, jNode)); + ASMJIT_PROPAGATE_ERROR(X86Context_addJccNode(this, jNode)); - node_ = X86X64Context_getJccFlow(jNode); + node_ = X86Context_getJccFlow(jNode); goto _Do; } } @@ -2373,7 +2608,7 @@ _NextGroup: case kNodeTypeFunc: { ASMJIT_ASSERT(node_ == func); - X86X64FuncDecl* decl = func->getDecl(); + X86FuncDecl* decl = func->getDecl(); VI_BEGIN(); for (uint32_t i = 0, argCount = decl->getArgCount(); i < argCount; i++) { @@ -2404,8 +2639,8 @@ _NextGroup: } else { if ((x86VarTypeToClass(aType) == vd->getClass()) || - (vType == kVarTypeXmmSs && aType == kVarTypeFp32) || - (vType == kVarTypeXmmSd && aType == kVarTypeFp64)) { + (vType == kX86VarTypeXmmSs && aType == kVarTypeFp32) || + (vType == kX86VarTypeXmmSd && aType == kVarTypeFp64)) { va->addFlags(kVarAttrOutMem); } else { @@ -2432,7 +2667,7 @@ _NextGroup: case kNodeTypeRet: { RetNode* node = static_cast(node_); - X86X64FuncDecl* decl = func->getDecl(); + X86FuncDecl* decl = func->getDecl(); if (decl->hasRet()) { const FuncInOut& ret = decl->getRet(0); @@ -2449,7 +2684,7 @@ _NextGroup: if (vd->getClass() == retClass) { // TODO: [COMPILER] Fix RetNode fetch. VI_MERGE_VAR(vd, va, 0, 0); - va->setInRegs(i == 0 ? IntUtil::mask(kRegIndexAx) : IntUtil::mask(kRegIndexDx)); + va->setInRegs(i == 0 ? IntUtil::mask(kX86RegIndexAx) : IntUtil::mask(kX86RegIndexDx)); va->addFlags(kVarAttrInReg); inRegs.add(retClass, va->getInRegs()); } @@ -2465,8 +2700,8 @@ _NextGroup: // ---------------------------------------------------------------------- case kNodeTypeCall: { - X86X64CallNode* node = static_cast(node_); - X86X64FuncDecl* decl = node->getDecl(); + X86CallNode* node = static_cast(node_); + X86FuncDecl* decl = node->getDecl(); Operand* target = &node->_target; Operand* argList = node->_args; @@ -2474,12 +2709,12 @@ _NextGroup: func->addFuncFlags(kFuncFlagIsCaller); func->mergeCallStackSize(node->_x86Decl.getArgStackSize()); - node->_usedArgs = X86X64Context_getUsedArgs(this, node, decl); + node->_usedArgs = X86Context_getUsedArgs(this, node, decl); uint32_t i; uint32_t argCount = decl->getArgCount(); uint32_t sArgCount = 0; - uint32_t gpAllocableMask = gaRegs[kRegClassGp] & ~node->_usedArgs.get(kRegClassGp); + uint32_t gpAllocableMask = gaRegs[kX86RegClassGp] & ~node->_usedArgs.get(kX86RegClassGp); VarData* vd; VarAttr* va; @@ -2496,7 +2731,7 @@ _NextGroup: va->addAllocableRegs(gpAllocableMask); } else if (target->isMem()) { - Mem* m = static_cast(target); + X86Mem* m = static_cast(target); if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) { vd = compiler->getVdById(m->getBase()); @@ -2554,7 +2789,7 @@ _NextGroup: // easier to handle argument conversions, because there will be at // most only one node per conversion. else { - if (X86X64Context_insertSArgNode(this, node, vd, gaRegs, arg, i, sArgList, sArgCount) != kErrorOk) + if (X86Context_insertSArgNode(this, node, vd, gaRegs, arg, i, sArgList, sArgCount) != kErrorOk) goto _NoMemory; } } @@ -2584,10 +2819,10 @@ _NextGroup: } // Init clobbered. - clobberedRegs.set(kRegClassGp , IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassGp ))); - clobberedRegs.set(kRegClassFp , IntUtil::bits(kRegCountFp )); - clobberedRegs.set(kRegClassMm , IntUtil::bits(kRegCountMm ) & (~decl->getPreserved(kRegClassMm ))); - clobberedRegs.set(kRegClassXyz, IntUtil::bits(_baseRegsCount) & (~decl->getPreserved(kRegClassXyz))); + clobberedRegs.set(kX86RegClassGp , IntUtil::bits(_regCount.getGp()) & (~decl->getPreserved(kX86RegClassGp))); + clobberedRegs.set(kX86RegClassFp , IntUtil::bits(_regCount.getFp())); + clobberedRegs.set(kX86RegClassMm , IntUtil::bits(_regCount.getMm()) & (~decl->getPreserved(kX86RegClassMm))); + clobberedRegs.set(kX86RegClassXyz, IntUtil::bits(_regCount.getXyz()) & (~decl->getPreserved(kX86RegClassXyz))); VI_END(node_); break; @@ -2601,6 +2836,7 @@ _NextGroup: } while (node_ != stop); _Done: + ASMJIT_TLOG("[Fetch] === Done ===\n\n"); return kErrorOk; // -------------------------------------------------------------------------- @@ -2608,312 +2844,15 @@ _Done: // -------------------------------------------------------------------------- _NoMemory: + ASMJIT_TLOG("[Fetch] === Out of Memory ===\n"); return compiler->setError(kErrorNoHeapMemory); } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Analyze] +// [asmjit::X86Context - Annotate] // ============================================================================ -//! \internal -struct LivenessTarget { - //! Previous target. - LivenessTarget* prev; - - //! Target node. - TargetNode* node; - //! Jumped from. - JumpNode* from; -}; - -Error X86X64Context::analyze() { - FuncNode* func = getFunc(); - - Node* node = func->getEnd(); - JumpNode* from = NULL; - - uint32_t bLen = static_cast( - ((_contextVd.getLength() + VarBits::kEntityBits - 1) / VarBits::kEntityBits)); - - LivenessTarget* ltCur = NULL; - LivenessTarget* ltUnused = NULL; - - // No variables. - if (bLen == 0) - return kErrorOk; - - VarBits* bCur = newBits(bLen); - if (bCur == NULL) - goto _NoMemory; - - // Allocate bits for code visited first time. -_OnVisit: - for (;;) { - if (node->hasLiveness()) { - if (bCur->_addBitsDelSource(node->getLiveness(), bCur, bLen)) - goto _OnPatch; - else - goto _OnDone; - } - - VarBits* bTmp = copyBits(bCur, bLen); - VarInst* vi = node->getVarInst(); - - if (bTmp == NULL) - goto _NoMemory; - node->setLiveness(bTmp); - - if (vi != NULL) { - uint32_t vaCount = vi->getVaCount(); - for (uint32_t i = 0; i < vaCount; i++) { - VarAttr* va = vi->getVa(i); - VarData* vd = va->getVd(); - - uint32_t flags = va->getFlags(); - uint32_t ctxId = vd->getContextId(); - - if ((flags & kVarAttrOutAll) && !(flags & kVarAttrInAll)) { - // Write-Only. - bTmp->setBit(ctxId); - bCur->delBit(ctxId); - } - else { - // Read-Only or Read/Write. - bTmp->setBit(ctxId); - bCur->setBit(ctxId); - } - } - } - - if (node->getType() == kNodeTypeTarget) - goto _OnTarget; - - if (node == func) - goto _OnDone; - - ASMJIT_ASSERT(node->getPrev()); - node = node->getPrev(); - } - - // Patch already generated liveness bits. -_OnPatch: - for (;;) { - ASMJIT_ASSERT(node->hasLiveness()); - VarBits* bNode = node->getLiveness(); - - if (!bNode->_addBitsDelSource(bCur, bLen)) - goto _OnDone; - - if (node->getType() == kNodeTypeTarget) - goto _OnTarget; - - if (node == func) - goto _OnDone; - - node = node->getPrev(); - } - -_OnTarget: - if (static_cast(node)->getNumRefs() != 0) { - // Push a new LivenessTarget onto the stack if needed. - if (ltCur == NULL || ltCur->node != node) { - // Allocate a new LivenessTarget object (from pool or zone). - LivenessTarget* ltTmp = ltUnused; - - if (ltTmp != NULL) { - ltUnused = ltUnused->prev; - } - else { - ltTmp = _baseZone.allocT( - sizeof(LivenessTarget) - sizeof(VarBits) + bLen * sizeof(uintptr_t)); - - if (ltTmp == NULL) - goto _NoMemory; - } - - // Initialize and make current - ltTmp->from will be set later on. - ltTmp->prev = ltCur; - ltTmp->node = static_cast(node); - ltCur = ltTmp; - - from = static_cast(node)->getFrom(); - ASMJIT_ASSERT(from != NULL); - } - else { - from = ltCur->from; - goto _OnJumpNext; - } - - // Visit/Patch. - do { - ltCur->from = from; - bCur->copyBits(node->getLiveness(), bLen); - - if (!from->hasLiveness()) { - node = from; - goto _OnVisit; - } - - // Issue #25: Moved '_OnJumpNext' here since it's important to patch - // code again if there are more live variables than before. -_OnJumpNext: - if (bCur->delBits(from->getLiveness(), bLen)) { - node = from; - goto _OnPatch; - } - - from = from->getJumpNext(); - } while (from != NULL); - - // Pop the current LivenessTarget from the stack. - { - LivenessTarget* ltTmp = ltCur; - - ltCur = ltCur->prev; - ltTmp->prev = ltUnused; - ltUnused = ltTmp; - } - } - - bCur->copyBits(node->getLiveness(), bLen); - node = node->getPrev(); - - if (node->isJmp() || !node->isFetched()) - goto _OnDone; - - if (!node->hasLiveness()) - goto _OnVisit; - - if (bCur->delBits(node->getLiveness(), bLen)) - goto _OnPatch; - -_OnDone: - if (ltCur != NULL) { - node = ltCur->node; - from = ltCur->from; - - goto _OnJumpNext; - } - return kErrorOk; - -_NoMemory: - return setError(kErrorNoHeapMemory); -} - -// ============================================================================ -// [asmjit::x86x64::X86X64Context - Annotate] -// ============================================================================ - -#if !defined(ASMJIT_DISABLE_LOGGER) -static void X86X64Context_annotateVariable(X86X64Context* self, - StringBuilder& sb, const VarData* vd) { - - const char* name = vd->getName(); - if (name != NULL && name[0] != '\0') { - sb.appendString(name); - } - else { - sb.appendChar('v'); - sb.appendUInt(vd->getId() & kOperandIdNum); - } -} - -static void X86X64Context_annotateOperand(X86X64Context* self, - StringBuilder& sb, const Operand* op) { - - if (op->isVar()) { - X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(op->getId())); - } - else if (op->isMem()) { - const Mem* m = static_cast(op); - bool isAbsolute = false; - - sb.appendChar('['); - switch (m->getMemType()) { - case kMemTypeBaseIndex: - case kMemTypeStackIndex: - // [base + index << shift + displacement] - X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getBase())); - break; - - case kMemTypeLabel: - // [label + index << shift + displacement] - sb.appendFormat("L%u", m->getBase()); - break; - - case kMemTypeAbsolute: - // [absolute] - isAbsolute = true; - sb.appendUInt(static_cast(m->getDisplacement()), 16); - break; - } - - if (m->hasIndex()) { - sb.appendChar('+'); - X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex())); - - if (m->getShift()) { - sb.appendChar('*'); - sb.appendChar("1248"[m->getShift() & 3]); - } - } - - if (m->getDisplacement() && !isAbsolute) { - uint32_t base = 10; - int32_t dispOffset = m->getDisplacement(); - - char prefix = '+'; - if (dispOffset < 0) { - dispOffset = -dispOffset; - prefix = '-'; - } - - sb.appendChar(prefix); - /* - if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { - sb.appendString("0x", 2); - base = 16; - } - */ - sb.appendUInt(static_cast(dispOffset), base); - } - - sb.appendChar(']'); - } - else if (op->isImm()) { - const Imm* i = static_cast(op); - int64_t val = i->getInt64(); - - /* - if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast(val) > 9) - sb.appendUInt(static_cast(val), 16); - else*/ - sb.appendInt(val, 10); - } - else if (op->isLabel()) { - sb.appendFormat("L%u", op->getId()); - } - else { - sb.appendString("None", 4); - } -} - -static bool X86X64Context_annotateInstruction(X86X64Context* self, - StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { - - sb.appendString(_instInfo[code].getName()); - for (uint32_t i = 0; i < opCount; i++) { - if (i == 0) - sb.appendChar(' '); - else - sb.appendString(", ", 2); - X86X64Context_annotateOperand(self, sb, &opList[i]); - } - return true; -} -#endif // !ASMJIT_DISABLE_LOGGER - -Error X86X64Context::annotate() { +Error X86Context::annotate() { #if !defined(ASMJIT_DISABLE_LOGGER) FuncNode* func = getFunc(); @@ -2924,12 +2863,11 @@ Error X86X64Context::annotate() { StringBuilderT<128> sb; uint32_t maxLen = 0; - while (node_ != end) { if (node_->getComment() == NULL) { if (node_->getType() == kNodeTypeInst) { InstNode* node = static_cast(node_); - X86X64Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount()); + X86Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount()); node_->setComment(static_cast(sa.dup(sb.getData(), sb.getLength() + 1))); maxLen = IntUtil::iMax(maxLen, static_cast(sb.getLength())); @@ -2947,28 +2885,28 @@ Error X86X64Context::annotate() { } // ============================================================================ -// [asmjit::x86x64::X86X64BaseAlloc] +// [asmjit::X86BaseAlloc] // ============================================================================ -struct X86X64BaseAlloc { +struct X86BaseAlloc { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE X86X64BaseAlloc(X86X64Context* context) { + ASMJIT_INLINE X86BaseAlloc(X86Context* context) { _context = context; _compiler = context->getCompiler(); } - ASMJIT_INLINE ~X86X64BaseAlloc() {} + ASMJIT_INLINE ~X86BaseAlloc() {} // -------------------------------------------------------------------------- // [Accessors] // -------------------------------------------------------------------------- //! Get the context. - ASMJIT_INLINE X86X64Context* getContext() const { return _context; } - //! Get the current state (always the same instance as X86X64Context::_x86State). - ASMJIT_INLINE VarState* getState() const { return _context->getState(); } + ASMJIT_INLINE X86Context* getContext() const { return _context; } + //! Get the current state (always the same instance as X86Context::_x86State). + ASMJIT_INLINE X86VarState* getState() const { return _context->getState(); } //! Get the node. ASMJIT_INLINE Node* getNode() const { return _node; } @@ -3001,9 +2939,9 @@ struct X86X64BaseAlloc { // -------------------------------------------------------------------------- protected: - // Just to prevent calling these methods by X86X64Context::translate(). + // Just to prevent calling these methods by X86Context::translate(). - ASMJIT_INLINE void init(Node* node, VarInst* vi); + ASMJIT_INLINE void init(Node* node, X86VarMap* map); ASMJIT_INLINE void cleanup(); // -------------------------------------------------------------------------- @@ -3021,15 +2959,15 @@ protected: // -------------------------------------------------------------------------- //! Context. - X86X64Context* _context; + X86Context* _context; //! Compiler. - X86X64Compiler* _compiler; + X86Compiler* _compiler; //! Node. Node* _node; - //! Variable instructions. - VarInst* _vi; + //! Variable map. + X86VarMap* _map; //! VarAttr list (per register class). VarAttr* _vaList[4]; @@ -3037,18 +2975,18 @@ protected: uint32_t _vaCount; //! VarAttr's total counter. - RegCount _count; + X86RegCount _count; //! VarAttr's done counter. - RegCount _done; + X86RegCount _done; }; // ============================================================================ -// [asmjit::x86x64::X86X64BaseAlloc - Init / Cleanup] +// [asmjit::X86BaseAlloc - Init / Cleanup] // ============================================================================ -ASMJIT_INLINE void X86X64BaseAlloc::init(Node* node, VarInst* vi) { +ASMJIT_INLINE void X86BaseAlloc::init(Node* node, X86VarMap* map) { _node = node; - _vi = vi; + _map = map; // We have to set the correct cursor in case any instruction is emitted // during the allocation phase; it has to be emitted before the current @@ -3057,17 +2995,17 @@ ASMJIT_INLINE void X86X64BaseAlloc::init(Node* node, VarInst* vi) { // Setup the lists of variables. { - VarAttr* va = vi->getVaList(); - _vaList[kRegClassGp ] = va; - _vaList[kRegClassFp ] = va + vi->getVaStart(kRegClassFp ); - _vaList[kRegClassMm ] = va + vi->getVaStart(kRegClassMm ); - _vaList[kRegClassXyz] = va + vi->getVaStart(kRegClassXyz); + VarAttr* va = map->getVaList(); + _vaList[kX86RegClassGp ] = va; + _vaList[kX86RegClassFp ] = va + map->getVaStart(kX86RegClassFp ); + _vaList[kX86RegClassMm ] = va + map->getVaStart(kX86RegClassMm ); + _vaList[kX86RegClassXyz] = va + map->getVaStart(kX86RegClassXyz); } // Setup counters. - _vaCount = vi->getVaCount(); + _vaCount = map->getVaCount(); - _count = vi->_count; + _count = map->_count; _done.reset(); // Connect Vd->Va. @@ -3079,7 +3017,7 @@ ASMJIT_INLINE void X86X64BaseAlloc::init(Node* node, VarInst* vi) { } } -ASMJIT_INLINE void X86X64BaseAlloc::cleanup() { +ASMJIT_INLINE void X86BaseAlloc::cleanup() { // Disconnect Vd->Va. for (uint32_t i = 0; i < _vaCount; i++) { VarAttr* va = &_vaList[0][i]; @@ -3090,11 +3028,11 @@ ASMJIT_INLINE void X86X64BaseAlloc::cleanup() { } // ============================================================================ -// [asmjit::x86x64::X86X64BaseAlloc - Unuse] +// [asmjit::X86BaseAlloc - Unuse] // ============================================================================ template -ASMJIT_INLINE void X86X64BaseAlloc::unuseBefore() { +ASMJIT_INLINE void X86BaseAlloc::unuseBefore() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); @@ -3115,7 +3053,7 @@ ASMJIT_INLINE void X86X64BaseAlloc::unuseBefore() { } template -ASMJIT_INLINE void X86X64BaseAlloc::unuseAfter() { +ASMJIT_INLINE void X86BaseAlloc::unuseAfter() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); @@ -3128,19 +3066,19 @@ ASMJIT_INLINE void X86X64BaseAlloc::unuseAfter() { } // ============================================================================ -// [asmjit::x86x64::X86X64VarAlloc] +// [asmjit::X86VarAlloc] // ============================================================================ //! \internal //! //! Register allocator context (asm instructions). -struct X86X64VarAlloc : public X86X64BaseAlloc { +struct X86VarAlloc : public X86BaseAlloc { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE X86X64VarAlloc(X86X64Context* context) : X86X64BaseAlloc(context) {} - ASMJIT_INLINE ~X86X64VarAlloc() {} + ASMJIT_INLINE X86VarAlloc(X86Context* context) : X86BaseAlloc(context) {} + ASMJIT_INLINE ~X86VarAlloc() {} // -------------------------------------------------------------------------- // [Run] @@ -3153,9 +3091,9 @@ struct X86X64VarAlloc : public X86X64BaseAlloc { // -------------------------------------------------------------------------- protected: - // Just to prevent calling these methods by X86X64Context::translate(). + // Just to prevent calling these methods by X86Context::translate(). - ASMJIT_INLINE void init(Node* node, VarInst* vi); + ASMJIT_INLINE void init(Node* node, X86VarMap* map); ASMJIT_INLINE void cleanup(); // -------------------------------------------------------------------------- @@ -3202,55 +3140,55 @@ protected: // -------------------------------------------------------------------------- //! Will alloc to these registers. - RegMask _willAlloc; + X86RegMask _willAlloc; //! Will spill these registers. - RegMask _willSpill; + X86RegMask _willSpill; }; // ============================================================================ -// [asmjit::X86X64VarAlloc - Run] +// [asmjit::X86VarAlloc - Run] // ============================================================================ -ASMJIT_INLINE Error X86X64VarAlloc::run(Node* node_) { +ASMJIT_INLINE Error X86VarAlloc::run(Node* node_) { // Initialize. - VarInst* vi = node_->getVarInst(); - if (vi == NULL) + X86VarMap* map = node_->getMap(); + if (map == NULL) return kErrorOk; // Initialize the allocator; connect Vd->Va. - init(node_, vi); + init(node_, map); // Unuse overwritten variables. - unuseBefore(); - unuseBefore(); - unuseBefore(); + unuseBefore(); + unuseBefore(); + unuseBefore(); // Plan the allocation. Planner assigns input/output registers for each // variable and decides whether to allocate it in register or stack. - plan(); - plan(); - plan(); + plan(); + plan(); + plan(); // Spill all variables marked by plan(). - spill(); - spill(); - spill(); + spill(); + spill(); + spill(); // Alloc all variables marked by plan(). - alloc(); - alloc(); - alloc(); + alloc(); + alloc(); + alloc(); // Translate node operands. if (node_->getType() == kNodeTypeInst) { InstNode* node = static_cast(node_); - ASMJIT_PROPAGATE_ERROR(X86X64Context_translateOperands(_context, node->getOpList(), node->getOpCount())); + ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, node->getOpList(), node->getOpCount())); } else if (node_->getType() == kNodeTypeSArg) { SArgNode* node = static_cast(node_); - X86X64CallNode* call = static_cast(node->getCall()); - X86X64FuncDecl* decl = call->getDecl(); + X86CallNode* call = static_cast(node->getCall()); + X86FuncDecl* decl = call->getDecl(); uint32_t argIndex = 0; uint32_t argMask = node->_args; @@ -3274,7 +3212,7 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(Node* node_) { FuncInOut& arg = decl->getArg(argIndex); ASMJIT_ASSERT(arg.hasStackOffset()); - Mem dst = ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); + X86Mem dst = x86::ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); _context->emitMoveVarOnStack(arg.getVarType(), &dst, sVd->getType(), sVd->getRegIndex()); } @@ -3284,50 +3222,50 @@ ASMJIT_INLINE Error X86X64VarAlloc::run(Node* node_) { } // Mark variables as modified. - modified(); - modified(); - modified(); + modified(); + modified(); + modified(); // Cleanup; disconnect Vd->Va. cleanup(); // Update clobbered mask. _context->_clobberedRegs.add(_willAlloc); - _context->_clobberedRegs.add(vi->_clobberedRegs); + _context->_clobberedRegs.add(map->_clobberedRegs); // Unuse. - unuseAfter(); - unuseAfter(); - unuseAfter(); + unuseAfter(); + unuseAfter(); + unuseAfter(); return kErrorOk; } // ============================================================================ -// [asmjit::x86x64::X86X64VarAlloc - Init / Cleanup] +// [asmjit::X86VarAlloc - Init / Cleanup] // ============================================================================ -ASMJIT_INLINE void X86X64VarAlloc::init(Node* node, VarInst* vi) { - X86X64BaseAlloc::init(node, vi); +ASMJIT_INLINE void X86VarAlloc::init(Node* node, X86VarMap* map) { + X86BaseAlloc::init(node, map); // These will block planner from assigning them during planning. Planner will // add more registers when assigning registers to variables that don't need // any specific register. - _willAlloc = vi->_inRegs; - _willAlloc.add(vi->_outRegs); + _willAlloc = map->_inRegs; + _willAlloc.add(map->_outRegs); _willSpill.reset(); } -ASMJIT_INLINE void X86X64VarAlloc::cleanup() { - X86X64BaseAlloc::cleanup(); +ASMJIT_INLINE void X86VarAlloc::cleanup() { + X86BaseAlloc::cleanup(); } // ============================================================================ -// [asmjit::x86x64::X86X64VarAlloc - Plan / Spill / Alloc] +// [asmjit::X86VarAlloc - Plan / Spill / Alloc] // ============================================================================ template -ASMJIT_INLINE void X86X64VarAlloc::plan() { +ASMJIT_INLINE void X86VarAlloc::plan() { if (isVaDone(C)) return; @@ -3339,7 +3277,7 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks. @@ -3362,6 +3300,13 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { uint32_t mandatoryRegs = va->getInRegs(); uint32_t allocableRegs = va->getAllocableRegs(); + ASMJIT_TLOG("[RA-PLAN ] %s (%s)\n", + vd->getName(), + (vaFlags & kVarAttrInOutReg) == kVarAttrOutReg ? "Out Reg" : "In/Out Reg"); + + ASMJIT_TLOG("[RA-PLAN ] RegMask=%08X Mandatory=%08X Allocable=%08X\n", + regMask, mandatoryRegs, allocableRegs); + if (regMask != 0) { // Special path for planning output-only registers. if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) { @@ -3382,7 +3327,9 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { willAlloc |= regMask; } + ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n"); addVaDone(C); + continue; } } @@ -3401,21 +3348,26 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { willAlloc |= regMask; } + ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n"); addVaDone(C); + continue; } } + + // Trace it here so we don't pollute log by `WillFree` of zero regMask. + ASMJIT_TLOG("[RA-PLAN ] WillFree\n"); } // Variable is not allocated or allocated in register that doesn't // match inRegs or allocableRegs. The next step is to pick the best - // register for this variable. If inRegs contains any register the + // register for this variable. If `inRegs` contains any register the // decision is simple - we have to follow, in other case will use - // the advantage of guessAlloc() to find a register (or registers) + // the advantage of `guessAlloc()` to find a register (or registers) // by looking ahead. But the best way to find a good register is not // here since now we have no information about the registers that // will be freed. So instead of finding register here, we just mark - // the current register (if variable is allocated) as 'willFree' so + // the current register (if variable is allocated) as `willFree` so // the planner can use this information in second step to plan other // allocation of other variables. willFree |= regMask; @@ -3423,11 +3375,15 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { } else { // Memory access - if variable is allocated it has to be freed. + ASMJIT_TLOG("[RA-PLAN ] %s (Memory)\n", vd->getName()); + if (regMask != 0) { + ASMJIT_TLOG("[RA-PLAN ] WillFree\n"); willFree |= regMask; continue; } else { + ASMJIT_TLOG("[RA-PLAN ] Done\n"); va->addFlags(kVarAttrAllocInDone); addVaDone(C); continue; @@ -3453,8 +3409,7 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { if (vaFlags & kVarAttrAllocOutDone) continue; - // We skip all registers that have assigned outRegIndex. The only - // important thing is to not forget to spill it if occupied. + // Skip all registers that have assigned outRegIndex. Spill if occupied. if (va->hasOutRegIndex()) { uint32_t outRegs = IntUtil::mask(va->getOutRegIndex()); willSpill |= occupied & outRegs; @@ -3465,8 +3420,8 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { if (vaFlags & kVarAttrAllocInDone) continue; - // We skip all registers that have assigned inRegIndex (it indicates that - // the register to allocate into is known). + // We skip all registers that have assigned inRegIndex, indicates that + // the register to allocate in is known. if (va->hasInRegIndex()) { uint32_t inRegs = va->getInRegs(); willSpill |= occupied & inRegs; @@ -3483,6 +3438,8 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { ASMJIT_ASSERT(m != 0); uint32_t candidateRegs = m & ~occupied; + uint32_t homeMask = vd->getHomeMask(); + uint32_t regIndex; uint32_t regMask; @@ -3492,6 +3449,9 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { candidateRegs = m; } + if (candidateRegs & homeMask) + candidateRegs &= homeMask; + regIndex = IntUtil::findFirstBit(candidateRegs); regMask = IntUtil::mask(regIndex); @@ -3505,8 +3465,9 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { willAlloc |= regMask; willSpill |= regMask & occupied; - willFree &= ~regMask; - occupied |= regMask; + willFree &=~regMask; + occupied |= regMask; + continue; } else if ((vaFlags & kVarAttrInOutMem) != 0) { @@ -3523,14 +3484,14 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() { } template -ASMJIT_INLINE void X86X64VarAlloc::spill() { +ASMJIT_INLINE void X86VarAlloc::spill() { uint32_t m = _willSpill.get(C); uint32_t i = static_cast(0) - 1; if (m == 0) return; - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); // Available registers for decision if move has any benefit over spill. @@ -3545,18 +3506,23 @@ ASMJIT_INLINE void X86X64VarAlloc::spill() { VarData* vd = sVars[i]; ASMJIT_ASSERT(vd != NULL); - ASMJIT_ASSERT(vd->getVa() == NULL || (vd->getVa()->getFlags() & kVarAttrInOutReg) == 0); + + VarAttr* va = vd->getVa(); + ASMJIT_ASSERT(va == NULL || !va->hasFlag(kVarAttrInOutReg)); if (vd->isModified() && availableRegs) { - uint32_t m = guessSpill(vd, availableRegs); + // Don't check for alternatives if the variable has to be spilled. + if (va == NULL || !va->hasFlag(kVarAttrSpill)) { + uint32_t altRegs = guessSpill(vd, availableRegs); - if (m != 0) { - uint32_t regIndex = IntUtil::findFirstBit(m); - uint32_t regMask = IntUtil::mask(regIndex); + if (altRegs != 0) { + uint32_t regIndex = IntUtil::findFirstBit(altRegs); + uint32_t regMask = IntUtil::mask(regIndex); - _context->move(vd, regIndex); - availableRegs ^= regMask; - continue; + _context->move(vd, regIndex); + availableRegs ^= regMask; + continue; + } } } @@ -3565,14 +3531,14 @@ ASMJIT_INLINE void X86X64VarAlloc::spill() { } template -ASMJIT_INLINE void X86X64VarAlloc::alloc() { +ASMJIT_INLINE void X86VarAlloc::alloc() { if (isVaDone(C)) return; VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); uint32_t i; @@ -3600,7 +3566,7 @@ ASMJIT_INLINE void X86X64VarAlloc::alloc() { // allocation tasks by a single 'xchg' instruction, swapping // two registers required by the instruction/node or one register // required with another non-required. - if (C == kRegClassGp && aIndex != kInvalidReg) { + if (C == kX86RegClassGp && aIndex != kInvalidReg) { VarAttr* bVa = bVd->getVa(); _context->swapGp(aVd, bVd); @@ -3660,24 +3626,32 @@ ASMJIT_INLINE void X86X64VarAlloc::alloc() { } // ============================================================================ -// [asmjit::x86x64::X86X64VarAlloc - GuessAlloc / GuessSpill] +// [asmjit::X86VarAlloc - GuessAlloc / GuessSpill] // ============================================================================ template -ASMJIT_INLINE uint32_t X86X64VarAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { +ASMJIT_INLINE uint32_t X86VarAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { ASMJIT_ASSERT(allocableRegs != 0); - // Stop now if there is only one bit (register) set in 'allocableRegs' mask. + // Stop now if there is only one bit (register) set in `allocableRegs` mask. if (IntUtil::isPowerOf2(allocableRegs)) return allocableRegs; - uint32_t i; + uint32_t cId = vd->getContextId(); uint32_t safeRegs = allocableRegs; + + uint32_t i; uint32_t maxLookAhead = _compiler->getMaxLookAhead(); // Look ahead and calculate mask of special registers on both - input/output. Node* node = _node; for (i = 0; i < maxLookAhead; i++) { + VarBits* liveness = node->getLiveness(); + + // If the variable becomes dead it doesn't make sense to continue. + if (liveness != NULL && !liveness->getBit(cId)) + break; + // Stop on 'RetNode' and 'EndNode. if (node->hasFlag(kNodeFlagIsRet)) break; @@ -3693,47 +3667,63 @@ ASMJIT_INLINE uint32_t X86X64VarAlloc::guessAlloc(VarData* vd, uint32_t allocabl node = node->getNext(); ASMJIT_ASSERT(node != NULL); - VarInst* vi = node->getVarInst(); - if (vi != NULL) { - VarAttr* va = vi->findVaByClass(C, vd); - if (va != NULL) { - uint32_t inRegs = va->getInRegs(); - if (inRegs != 0) { - safeRegs = allocableRegs; - allocableRegs &= inRegs; + X86VarMap* map = node->getMap(); + if (map != NULL) { + VarAttr* va = map->findVaByClass(C, vd); + uint32_t mask; + if (va != NULL) { + // If the variable is overwritten it doesn't mase sense to continue. + if (!(va->getFlags() & kVarAttrInAll)) + break; + + mask = va->getAllocableRegs(); + if (mask != 0) { + allocableRegs &= mask; if (allocableRegs == 0) - goto _UseSafeRegs; - else - return allocableRegs; + break; + safeRegs = allocableRegs; } + + mask = va->getInRegs(); + if (mask != 0) { + allocableRegs &= mask; + if (allocableRegs == 0) + break; + safeRegs = allocableRegs; + break; + } + + allocableRegs &= ~(map->_outRegs.get(C) | map->_clobberedRegs.get(C)); + if (allocableRegs == 0) + break; + } + else { + allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C)); + if (allocableRegs == 0) + break; } safeRegs = allocableRegs; - allocableRegs &= ~(vi->_inRegs.get(C) | vi->_outRegs.get(C) | vi->_clobberedRegs.get(C)); - - if (allocableRegs == 0) - break; } } -_UseSafeRegs: return safeRegs; } template -ASMJIT_INLINE uint32_t X86X64VarAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { +ASMJIT_INLINE uint32_t X86VarAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { ASMJIT_ASSERT(allocableRegs != 0); return 0; } // ============================================================================ -// [asmjit::x86x64::X86X64VarAlloc - Modified] +// [asmjit::X86VarAlloc - Modified] // ============================================================================ template -ASMJIT_INLINE void X86X64VarAlloc::modified() { +ASMJIT_INLINE void X86VarAlloc::modified() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); @@ -3753,41 +3743,41 @@ ASMJIT_INLINE void X86X64VarAlloc::modified() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc] +// [asmjit::X86CallAlloc] // ============================================================================ //! \internal //! //! Register allocator context (function call). -struct X86X64CallAlloc : public X86X64BaseAlloc { +struct X86CallAlloc : public X86BaseAlloc { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE X86X64CallAlloc(X86X64Context* context) : X86X64BaseAlloc(context) {} - ASMJIT_INLINE ~X86X64CallAlloc() {} + ASMJIT_INLINE X86CallAlloc(X86Context* context) : X86BaseAlloc(context) {} + ASMJIT_INLINE ~X86CallAlloc() {} // -------------------------------------------------------------------------- // [Accessors] // -------------------------------------------------------------------------- //! Get the node. - ASMJIT_INLINE X86X64CallNode* getNode() const { return static_cast(_node); } + ASMJIT_INLINE X86CallNode* getNode() const { return static_cast(_node); } // -------------------------------------------------------------------------- // [Run] // -------------------------------------------------------------------------- - ASMJIT_INLINE Error run(X86X64CallNode* node); + ASMJIT_INLINE Error run(X86CallNode* node); // -------------------------------------------------------------------------- // [Init / Cleanup] // -------------------------------------------------------------------------- protected: - // Just to prevent calling these methods from X86X64Context::translate(). + // Just to prevent calling these methods from X86Context::translate(). - ASMJIT_INLINE void init(X86X64CallNode* node, VarInst* vi); + ASMJIT_INLINE void init(X86CallNode* node, X86VarMap* map); ASMJIT_INLINE void cleanup(); // -------------------------------------------------------------------------- @@ -3851,78 +3841,78 @@ protected: // -------------------------------------------------------------------------- //! Will alloc to these registers. - RegMask _willAlloc; + X86RegMask _willAlloc; //! Will spill these registers. - RegMask _willSpill; + X86RegMask _willSpill; }; // ============================================================================ -// [asmjit::X86X64CallAlloc - Run] +// [asmjit::X86CallAlloc - Run] // ============================================================================ -ASMJIT_INLINE Error X86X64CallAlloc::run(X86X64CallNode* node) { +ASMJIT_INLINE Error X86CallAlloc::run(X86CallNode* node) { // Initialize. - VarInst* vi = node->getVarInst(); - if (vi == NULL) + X86VarMap* map = node->getMap(); + if (map == NULL) return kErrorOk; // Initialize the allocator; prepare basics and connect Vd->Va. - init(node, vi); + init(node, map); // Plan register allocation. Planner is only able to assign one register per // variable. If any variable is used multiple times it will be handled later. - plan(); - plan(); - plan(); + plan(); + plan(); + plan(); // Spill. - spill(); - spill(); - spill(); + spill(); + spill(); + spill(); // Alloc. - alloc(); - alloc(); - alloc(); + alloc(); + alloc(); + alloc(); // Unuse clobbered registers that are not used to pass function arguments and // save variables used to pass function arguments that will be reused later on. - save(); - save(); - save(); + save(); + save(); + save(); // Allocate immediates in registers and on the stack. allocImmsOnStack(); // Duplicate. - duplicate(); - duplicate(); - duplicate(); + duplicate(); + duplicate(); + duplicate(); // Translate call operand. - ASMJIT_PROPAGATE_ERROR(X86X64Context_translateOperands(_context, &node->_target, 1)); + ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, &node->_target, 1)); // To emit instructions after call. _compiler->_setCursor(node); // If the callee pops stack it has to be manually adjusted back. - X86X64FuncDecl* decl = node->getDecl(); + X86FuncDecl* decl = node->getDecl(); if (decl->getCalleePopsStack() && decl->getArgStackSize() != 0) { - _compiler->emit(kInstSub, _context->_zsp, static_cast(decl->getArgStackSize())); + _compiler->emit(kX86InstIdSub, _context->_zsp, static_cast(decl->getArgStackSize())); } // Clobber. - clobber(); - clobber(); - clobber(); + clobber(); + clobber(); + clobber(); // Return. ret(); // Unuse. - unuseAfter(); - unuseAfter(); - unuseAfter(); + unuseAfter(); + unuseAfter(); + unuseAfter(); // Cleanup; disconnect Vd->Va. cleanup(); @@ -3931,29 +3921,29 @@ ASMJIT_INLINE Error X86X64CallAlloc::run(X86X64CallNode* node) { } // ============================================================================ -// [asmjit::X86X64CallAlloc - Init / Cleanup] +// [asmjit::X86CallAlloc - Init / Cleanup] // ============================================================================ -ASMJIT_INLINE void X86X64CallAlloc::init(X86X64CallNode* node, VarInst* vi) { - X86X64BaseAlloc::init(node, vi); +ASMJIT_INLINE void X86CallAlloc::init(X86CallNode* node, X86VarMap* map) { + X86BaseAlloc::init(node, map); // Create mask of all registers that will be used to pass function arguments. _willAlloc = node->_usedArgs; _willSpill.reset(); } -ASMJIT_INLINE void X86X64CallAlloc::cleanup() { - X86X64BaseAlloc::cleanup(); +ASMJIT_INLINE void X86CallAlloc::cleanup() { + X86BaseAlloc::cleanup(); } // ============================================================================ -// [asmjit::X86X64CallAlloc - Plan / Spill / Alloc] +// [asmjit::X86CallAlloc - Plan / Spill / Alloc] // ============================================================================ template -ASMJIT_INLINE void X86X64CallAlloc::plan() { +ASMJIT_INLINE void X86CallAlloc::plan() { uint32_t i; - uint32_t clobbered = _vi->_clobberedRegs.get(C); + uint32_t clobbered = _map->_clobberedRegs.get(C); uint32_t willAlloc = _willAlloc.get(C); uint32_t willFree = clobbered & ~willAlloc; @@ -3961,7 +3951,7 @@ ASMJIT_INLINE void X86X64CallAlloc::plan() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks. @@ -4026,7 +4016,7 @@ ASMJIT_INLINE void X86X64CallAlloc::plan() { // All registers except Gp used by call itself must have inRegIndex. uint32_t m = va->getInRegs(); - if (C != kRegClassGp || m) { + if (C != kX86RegClassGp || m) { ASMJIT_ASSERT(m != 0); va->setInRegIndex(IntUtil::findFirstBit(m)); willSpill |= occupied & m; @@ -4067,14 +4057,14 @@ ASMJIT_INLINE void X86X64CallAlloc::plan() { } template -ASMJIT_INLINE void X86X64CallAlloc::spill() { +ASMJIT_INLINE void X86CallAlloc::spill() { uint32_t m = _willSpill.get(C); uint32_t i = static_cast(0) - 1; if (m == 0) return; - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); // Available registers for decision if move has any benefit over spill. @@ -4109,14 +4099,14 @@ ASMJIT_INLINE void X86X64CallAlloc::spill() { } template -ASMJIT_INLINE void X86X64CallAlloc::alloc() { +ASMJIT_INLINE void X86CallAlloc::alloc() { if (isVaDone(C)) return; VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); - VarState* state = getState(); + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); uint32_t i; @@ -4145,7 +4135,7 @@ ASMJIT_INLINE void X86X64CallAlloc::alloc() { // allocation tasks by a single 'xchg' instruction, swapping // two registers required by the instruction/node or one register // required with another non-required. - if (C == kRegClassGp) { + if (C == kX86RegClassGp) { _context->swapGp(aVd, bVd); aVa->addFlags(kVarAttrAllocInDone); @@ -4184,12 +4174,12 @@ ASMJIT_INLINE void X86X64CallAlloc::alloc() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - AllocImmsOnStack] +// [asmjit::X86CallAlloc - AllocImmsOnStack] // ============================================================================ -ASMJIT_INLINE void X86X64CallAlloc::allocImmsOnStack() { - X86X64CallNode* node = getNode(); - X86X64FuncDecl* decl = node->getDecl(); +ASMJIT_INLINE void X86CallAlloc::allocImmsOnStack() { + X86CallNode* node = getNode(); + X86FuncDecl* decl = node->getDecl(); uint32_t argCount = decl->getArgCount(); Operand* argList = node->_args; @@ -4204,7 +4194,7 @@ ASMJIT_INLINE void X86X64CallAlloc::allocImmsOnStack() { const FuncInOut& arg = decl->getArg(i); if (arg.hasStackOffset()) { - Mem dst = ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); + X86Mem dst = x86::ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); _context->emitMoveImmOnStack(arg.getVarType(), &dst, &imm); } else { @@ -4214,11 +4204,11 @@ ASMJIT_INLINE void X86X64CallAlloc::allocImmsOnStack() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - Duplicate] +// [asmjit::X86CallAlloc - Duplicate] // ============================================================================ template -ASMJIT_INLINE void X86X64CallAlloc::duplicate() { +ASMJIT_INLINE void X86CallAlloc::duplicate() { VarAttr* list = getVaListByClass(C); uint32_t count = getVaCountByClass(C); @@ -4250,11 +4240,11 @@ ASMJIT_INLINE void X86X64CallAlloc::duplicate() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - GuessAlloc / GuessSpill] +// [asmjit::X86CallAlloc - GuessAlloc / GuessSpill] // ============================================================================ template -ASMJIT_INLINE uint32_t X86X64CallAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { +ASMJIT_INLINE uint32_t X86CallAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { ASMJIT_ASSERT(allocableRegs != 0); // Stop now if there is only one bit (register) set in 'allocableRegs' mask. @@ -4283,9 +4273,9 @@ ASMJIT_INLINE uint32_t X86X64CallAlloc::guessAlloc(VarData* vd, uint32_t allocab node = node->getNext(); ASMJIT_ASSERT(node != NULL); - VarInst* vi = node->getVarInst(); - if (vi != NULL) { - VarAttr* va = vi->findVaByClass(C, vd); + X86VarMap* map = node->getMap(); + if (map != NULL) { + VarAttr* va = map->findVaByClass(C, vd); if (va != NULL) { uint32_t inRegs = va->getInRegs(); if (inRegs != 0) { @@ -4300,7 +4290,7 @@ ASMJIT_INLINE uint32_t X86X64CallAlloc::guessAlloc(VarData* vd, uint32_t allocab } safeRegs = allocableRegs; - allocableRegs &= ~(vi->_inRegs.get(C) | vi->_outRegs.get(C) | vi->_clobberedRegs.get(C)); + allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C)); if (allocableRegs == 0) break; @@ -4312,23 +4302,23 @@ _UseSafeRegs: } template -ASMJIT_INLINE uint32_t X86X64CallAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { +ASMJIT_INLINE uint32_t X86CallAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { ASMJIT_ASSERT(allocableRegs != 0); return 0; } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - Save] +// [asmjit::X86CallAlloc - Save] // ============================================================================ template -ASMJIT_INLINE void X86X64CallAlloc::save() { - VarState* state = getState(); +ASMJIT_INLINE void X86CallAlloc::save() { + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); uint32_t i; - uint32_t affected = _vi->_clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C); + uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C); for (i = 0; affected != 0; i++, affected >>= 1) { if (affected & 0x1) { @@ -4345,16 +4335,16 @@ ASMJIT_INLINE void X86X64CallAlloc::save() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - Clobber] +// [asmjit::X86CallAlloc - Clobber] // ============================================================================ template -ASMJIT_INLINE void X86X64CallAlloc::clobber() { - VarState* state = getState(); +ASMJIT_INLINE void X86CallAlloc::clobber() { + X86VarState* state = getState(); VarData** sVars = state->getListByClass(C); uint32_t i; - uint32_t affected = _vi->_clobberedRegs.get(C) & state->_occupied.get(C); + uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C); for (i = 0; affected != 0; i++, affected >>= 1) { if (affected & 0x1) { @@ -4374,12 +4364,12 @@ ASMJIT_INLINE void X86X64CallAlloc::clobber() { } // ============================================================================ -// [asmjit::x86x64::X86X64CallAlloc - Ret] +// [asmjit::X86CallAlloc - Ret] // ============================================================================ -ASMJIT_INLINE void X86X64CallAlloc::ret() { - X86X64CallNode* node = getNode(); - X86X64FuncDecl* decl = node->getDecl(); +ASMJIT_INLINE void X86CallAlloc::ret() { + X86CallNode* node = getNode(); + X86FuncDecl* decl = node->getDecl(); uint32_t i; Operand* retList = node->_ret; @@ -4395,33 +4385,33 @@ ASMJIT_INLINE void X86X64CallAlloc::ret() { uint32_t regIndex = ret.getRegIndex(); switch (vd->getClass()) { - case kRegClassGp: + case kX86RegClassGp: if (vd->getRegIndex() != kInvalidReg) - _context->unuse(vd); - _context->attach(vd, regIndex, true); + _context->unuse(vd); + _context->attach(vd, regIndex, true); break; - case kRegClassMm: + case kX86RegClassMm: if (vd->getRegIndex() != kInvalidReg) - _context->unuse(vd); - _context->attach(vd, regIndex, true); + _context->unuse(vd); + _context->attach(vd, regIndex, true); break; - case kRegClassXyz: + case kX86RegClassXyz: if (vd->getRegIndex() != kInvalidReg) - _context->unuse(vd); - _context->attach(vd, regIndex, true); + _context->unuse(vd); + _context->attach(vd, regIndex, true); break; } } } // ============================================================================ -// [asmjit::x86x64::X86X64Context - TranslateOperands] +// [asmjit::X86Context - TranslateOperands] // ============================================================================ //! \internal -static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opList, uint32_t opCount) { - X86X64Compiler* compiler = self->getCompiler(); - const VarInfo* varInfo = _varInfo; +static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount) { + X86Compiler* compiler = self->getCompiler(); + const X86VarInfo* varInfo = _x86VarInfo; uint32_t hasGpdBase = compiler->getRegSize() == 4; @@ -4438,7 +4428,7 @@ static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opLis op->_vreg.index = vd->getRegIndex(); } else if (op->isMem()) { - Mem* m = static_cast(op); + X86Mem* m = static_cast(op); if (m->isBaseIndexType() && OperandUtil::isVarId(m->getBase())) { VarData* vd = compiler->getVdById(m->getBase()); @@ -4451,7 +4441,7 @@ static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opLis if (!vd->isMemArg()) self->getVarCell(vd); - // Offset will be patched later by X86X64Context_patchFuncMem(). + // Offset will be patched later by X86Context_patchFuncMem(). m->setGpdBase(hasGpdBase); m->adjust(vd->isMemArg() ? self->_argActualDisp : self->_varActualDisp); } @@ -4460,7 +4450,7 @@ static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opLis if (OperandUtil::isVarId(m->getIndex())) { VarData* vd = compiler->getVdById(m->getIndex()); ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); - ASMJIT_ASSERT(vd->getRegIndex() != kRegIndexR12); + ASMJIT_ASSERT(vd->getRegIndex() != kX86RegIndexR12); op->_vmem.index = vd->getRegIndex(); } } @@ -4470,24 +4460,24 @@ static Error X86X64Context_translateOperands(X86X64Context* self, Operand* opLis } // ============================================================================ -// [asmjit::x86x64::X86X64Context - TranslatePrologEpilog] +// [asmjit::X86Context - TranslatePrologEpilog] // ============================================================================ //! \internal -static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { - X86X64Compiler* compiler = self->getCompiler(); - X86X64FuncDecl* decl = func->getDecl(); +static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { + X86Compiler* compiler = self->getCompiler(); + X86FuncDecl* decl = func->getDecl(); - RegMask& clobberedRegs = self->_clobberedRegs; + X86RegMask& clobberedRegs = self->_clobberedRegs; uint32_t regSize = compiler->getRegSize(); // Setup "Save-Restore" registers. - func->_saveRestoreRegs.set(kRegClassGp , clobberedRegs.get(kRegClassGp ) & decl->getPreserved(kRegClassGp )); - func->_saveRestoreRegs.set(kRegClassFp , 0); - func->_saveRestoreRegs.set(kRegClassMm , clobberedRegs.get(kRegClassMm ) & decl->getPreserved(kRegClassMm )); - func->_saveRestoreRegs.set(kRegClassXyz, clobberedRegs.get(kRegClassXyz) & decl->getPreserved(kRegClassXyz)); + func->_saveRestoreRegs.set(kX86RegClassGp , clobberedRegs.get(kX86RegClassGp ) & decl->getPreserved(kX86RegClassGp )); + func->_saveRestoreRegs.set(kX86RegClassFp , 0); + func->_saveRestoreRegs.set(kX86RegClassMm , clobberedRegs.get(kX86RegClassMm ) & decl->getPreserved(kX86RegClassMm )); + func->_saveRestoreRegs.set(kX86RegClassXyz, clobberedRegs.get(kX86RegClassXyz) & decl->getPreserved(kX86RegClassXyz)); - ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kRegClassGp, IntUtil::mask(kRegIndexSp))); + ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kX86RegClassGp, IntUtil::mask(kX86RegIndexSp))); // Setup required stack alignment and kFuncFlagIsStackMisaligned. { @@ -4497,7 +4487,7 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { // Require 16-byte alignment if 8-byte vars are used. if (self->_mem8ByteVarsUsed) requiredStackAlignment = 16; - else if (func->_saveRestoreRegs.get(kRegClassMm) || func->_saveRestoreRegs.get(kRegClassXyz)) + else if (func->_saveRestoreRegs.get(kX86RegClassMm) || func->_saveRestoreRegs.get(kX86RegClassXyz)) requiredStackAlignment = 16; else if (IntUtil::inInterval(func->getRequiredStackAlignment(), 8, 16)) requiredStackAlignment = 16; @@ -4525,24 +4515,24 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { self->_stackFrameCell = cell; if (decl->getArgStackSize() > 0) { - func->addFuncFlags(kFuncFlagMoveArgs); + func->addFuncFlags(kX86FuncFlagMoveArgs); func->setExtraStackSize(decl->getArgStackSize()); } // Get temporary register which will be used to align the stack frame. - uint32_t fRegMask = IntUtil::bits(self->_baseRegsCount); + uint32_t fRegMask = IntUtil::bits(self->_regCount.getGp()); uint32_t stackFrameCopyRegs; - fRegMask &= ~(decl->getUsed(kRegClassGp) | IntUtil::mask(kRegIndexSp)); + fRegMask &= ~(decl->getUsed(kX86RegClassGp) | IntUtil::mask(kX86RegIndexSp)); stackFrameCopyRegs = fRegMask; // Try to remove modified registers from the mask. - uint32_t tRegMask = fRegMask & ~self->getClobberedRegs(kRegClassGp); + uint32_t tRegMask = fRegMask & ~self->getClobberedRegs(kX86RegClassGp); if (tRegMask != 0) fRegMask = tRegMask; // Try to remove preserved registers from the mask. - tRegMask = fRegMask & ~decl->getPreserved(kRegClassGp); + tRegMask = fRegMask & ~decl->getPreserved(kX86RegClassGp); if (tRegMask != 0) fRegMask = tRegMask; @@ -4555,16 +4545,16 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { // and epilog), however we shouldn't save it twice, so we will remove it // from '_saveRestoreRegs' in case that it is preserved. fRegMask = IntUtil::mask(fRegIndex); - if ((fRegMask & decl->getPreserved(kRegClassGp)) != 0) { - func->_saveRestoreRegs.del(kRegClassGp, fRegMask); + if ((fRegMask & decl->getPreserved(kX86RegClassGp)) != 0) { + func->_saveRestoreRegs.del(kX86RegClassGp, fRegMask); func->_isStackFrameRegPreserved = true; } - if (func->hasFuncFlag(kFuncFlagMoveArgs)) { + if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) { uint32_t maxRegs = (func->getArgStackSize() + regSize - 1) / regSize; stackFrameCopyRegs &= ~fRegMask; - tRegMask = stackFrameCopyRegs & self->getClobberedRegs(kRegClassGp); + tRegMask = stackFrameCopyRegs & self->getClobberedRegs(kX86RegClassGp); uint32_t tRegCnt = IntUtil::bitCount(tRegMask); if (tRegCnt > 1 || (tRegCnt > 0 && tRegCnt <= maxRegs)) @@ -4572,13 +4562,13 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { else stackFrameCopyRegs = IntUtil::keepNOnesFromRight(stackFrameCopyRegs, IntUtil::iMin(maxRegs, 2)); - func->_saveRestoreRegs.add(kRegClassGp, stackFrameCopyRegs & decl->getPreserved(kRegClassGp)); + func->_saveRestoreRegs.add(kX86RegClassGp, stackFrameCopyRegs & decl->getPreserved(kX86RegClassGp)); IntUtil::indexNOnesFromRight(func->_stackFrameCopyGpIndex, stackFrameCopyRegs, maxRegs); } } // If function is not naked we generate standard "EBP/RBP" stack frame. else if (!func->isNaked()) { - uint32_t fRegIndex = kRegIndexBp; + uint32_t fRegIndex = kX86RegIndexBp; func->_stackFrameRegIndex = static_cast(fRegIndex); func->_isStackFrameRegPreserved = true; @@ -4593,11 +4583,11 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { // Setup stack size used to save preserved registers. { - uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassGp )) * regSize; - uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassMm )) * 8; - uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kRegClassXyz)) * 16; + uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassGp )) * regSize; + uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassMm )) * 8; + uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassXyz)) * 16; - if (func->hasFuncFlag(kFuncFlagPushPop)) { + if (func->hasFuncFlag(kX86FuncFlagPushPop)) { func->_pushPopStackSize = memGpSize; func->_moveStackSize = memXmmSize + IntUtil::alignTo(memMmSize, 16); } @@ -4633,7 +4623,7 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { func->_alignedMemStackSize = IntUtil::alignTo(func->_memStackSize, func->_requiredStackAlignment); if (func->isNaked()) { - self->_argBaseReg = kRegIndexSp; + self->_argBaseReg = kX86RegIndexSp; if (func->isStackAdjusted()) { if (func->isStackMisaligned()) { @@ -4659,11 +4649,12 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { } } else { - self->_argBaseReg = kRegIndexBp; - self->_argBaseOffset = regSize; // Caused by "push zbp". + self->_argBaseReg = kX86RegIndexBp; + // Caused by "push zbp". + self->_argBaseOffset = regSize; } - self->_varBaseReg = kRegIndexSp; + self->_varBaseReg = kX86RegIndexSp; self->_varBaseOffset = func->getCallStackSize(); if (!func->isStackAdjusted()) { @@ -4677,8 +4668,8 @@ static Error X86X64Context_initFunc(X86X64Context* self, X86X64FuncNode* func) { } //! \internal -static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* func, Node* stop) { - X86X64Compiler* compiler = self->getCompiler(); +static Error X86Context_patchFuncMem(X86Context* self, X86FuncNode* func, Node* stop) { + X86Compiler* compiler = self->getCompiler(); Node* node = func; do { @@ -4686,7 +4677,7 @@ static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* fun InstNode* iNode = static_cast(node); if (iNode->hasMemOp()) { - Mem* m = iNode->getMemOp(); + X86Mem* m = iNode->getMemOp(); if (m->getMemType() == kMemTypeStackIndex && OperandUtil::isVarId(m->getBase())) { VarData* vd = compiler->getVdById(m->getBase()); @@ -4716,9 +4707,9 @@ static Error X86X64Context_patchFuncMem(X86X64Context* self, X86X64FuncNode* fun } //! \internal -static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64FuncNode* func) { - X86X64Compiler* compiler = self->getCompiler(); - X86X64FuncDecl* decl = func->getDecl(); +static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* func) { + X86Compiler* compiler = self->getCompiler(); + X86FuncDecl* decl = func->getDecl(); uint32_t regSize = compiler->getRegSize(); @@ -4746,17 +4737,17 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func } uint32_t i, mask; - uint32_t regsGp = func->getSaveRestoreRegs(kRegClassGp ); - uint32_t regsMm = func->getSaveRestoreRegs(kRegClassMm ); - uint32_t regsXmm = func->getSaveRestoreRegs(kRegClassXyz); + uint32_t regsGp = func->getSaveRestoreRegs(kX86RegClassGp ); + uint32_t regsMm = func->getSaveRestoreRegs(kX86RegClassMm ); + uint32_t regsXmm = func->getSaveRestoreRegs(kX86RegClassXyz); bool earlyPushPop = false; bool useLeaEpilog = false; - GpReg gpReg(self->_zsp); - GpReg fpReg(self->_zbp); + X86GpReg gpReg(self->_zsp); + X86GpReg fpReg(self->_zbp); - Mem fpOffset; + X86Mem fpOffset; // -------------------------------------------------------------------------- // [Prolog] @@ -4764,33 +4755,28 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func compiler->_setCursor(func->getEntryNode()); -#if !defined(ASMJIT_DISABLE_LOGGER) - if (compiler->hasLogger()) - compiler->comment("Prolog"); -#endif // !ASMJIT_DISABLE_LOGGER - // Entry. if (func->isNaked()) { if (func->isStackMisaligned()) { fpReg.setIndex(func->getStackFrameRegIndex()); - fpOffset = ptr(self->_zsp, static_cast(self->_stackFrameCell->getOffset())); + fpOffset = x86::ptr(self->_zsp, static_cast(self->_stackFrameCell->getOffset())); - earlyPushPop = func->hasFuncFlag(kFuncFlagPushPop); + earlyPushPop = func->hasFuncFlag(kX86FuncFlagPushPop); if (earlyPushPop) self->emitPushSequence(regsGp); if (func->isStackFrameRegPreserved()) - compiler->emit(kInstPush, fpReg); + compiler->emit(kX86InstIdPush, fpReg); - compiler->emit(kInstMov, fpReg, self->_zsp); + compiler->emit(kX86InstIdMov, fpReg, self->_zsp); } } else { - compiler->emit(kInstPush, fpReg); - compiler->emit(kInstMov, fpReg, self->_zsp); + compiler->emit(kX86InstIdPush, fpReg); + compiler->emit(kX86InstIdMov, fpReg, self->_zsp); } - if (func->hasFuncFlag(kFuncFlagPushPop) && !earlyPushPop) { + if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop) { self->emitPushSequence(regsGp); if (func->isStackMisaligned() && regsGp != 0) useLeaEpilog = true; @@ -4801,13 +4787,13 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func stackBase = static_cast(func->getAlignedMemStackSize() + func->getCallStackSize()); if (stackSize) - compiler->emit(kInstSub, self->_zsp, stackSize); + compiler->emit(kX86InstIdSub, self->_zsp, stackSize); if (func->isStackMisaligned()) - compiler->emit(kInstAnd, self->_zsp, -stackAlignment); + compiler->emit(kX86InstIdAnd, self->_zsp, -stackAlignment); if (func->isStackMisaligned() && func->isNaked()) - compiler->emit(kInstMov, fpOffset, fpReg); + compiler->emit(kX86InstIdMov, fpOffset, fpReg); } else { stackBase = -static_cast(func->getAlignStackSize() + func->getMoveStackSize()); @@ -4817,22 +4803,22 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func stackPtr = stackBase; for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMovaps, oword_ptr(self->_zsp, stackPtr), xmm(i)); + compiler->emit(kX86InstIdMovaps, x86::oword_ptr(self->_zsp, stackPtr), x86::xmm(i)); stackPtr += 16; } } for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMovq, qword_ptr(self->_zsp, stackPtr), mm(i)); + compiler->emit(kX86InstIdMovq, x86::qword_ptr(self->_zsp, stackPtr), x86::mm(i)); stackPtr += 8; } } - if (!func->hasFuncFlag(kFuncFlagPushPop)) { + if (!func->hasFuncFlag(kX86FuncFlagPushPop)) { for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMov, ptr(self->_zsp, stackPtr), gpReg.setIndex(i)); + compiler->emit(kX86InstIdMov, x86::ptr(self->_zsp, stackPtr), gpReg.setIndex(i)); stackPtr += regSize; } } @@ -4842,14 +4828,14 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func // [Move-Args] // -------------------------------------------------------------------------- - if (func->hasFuncFlag(kFuncFlagMoveArgs)) { + if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) { uint32_t argStackPos = 0; uint32_t argStackSize = decl->getArgStackSize(); uint32_t moveIndex = 0; uint32_t moveCount = (argStackSize + regSize - 1) / regSize; - GpReg r[8]; + X86GpReg r[8]; uint32_t numRegs = 0; for (i = 0; i < 6; i++) @@ -4865,58 +4851,48 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func if (func->isStackFrameRegPreserved()) dSrc += regSize; - Mem mSrc = ptr(fpReg, dSrc); - Mem mDst = ptr(self->_zsp, dDst); + X86Mem mSrc = x86::ptr(fpReg, dSrc); + X86Mem mDst = x86::ptr(self->_zsp, dDst); while (moveIndex < moveCount) { uint32_t numMovs = IntUtil::iMin(moveCount - moveIndex, numRegs); for (i = 0; i < numMovs; i++) - compiler->emit(kInstMov, r[i], mSrc.adjusted((moveIndex + i) * regSize)); + compiler->emit(kX86InstIdMov, r[i], mSrc.adjusted((moveIndex + i) * regSize)); for (i = 0; i < numMovs; i++) - compiler->emit(kInstMov, mDst.adjusted((moveIndex + i) * regSize), r[i]); + compiler->emit(kX86InstIdMov, mDst.adjusted((moveIndex + i) * regSize), r[i]); argStackPos += numMovs * regSize; moveIndex += numMovs; } } -#if !defined(ASMJIT_DISABLE_LOGGER) - if (compiler->hasLogger()) - compiler->comment("Body"); -#endif // !ASMJIT_DISABLE_LOGGER - // -------------------------------------------------------------------------- // [Epilog] // -------------------------------------------------------------------------- compiler->_setCursor(func->getExitNode()); -#if !defined(ASMJIT_DISABLE_LOGGER) - if (compiler->hasLogger()) - compiler->comment("Epilog"); -#endif // !ASMJIT_DISABLE_LOGGER - // Restore Xmm/Mm/Gp (Mov). stackPtr = stackBase; for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMovaps, xmm(i), oword_ptr(self->_zsp, stackPtr)); + compiler->emit(kX86InstIdMovaps, x86::xmm(i), x86::oword_ptr(self->_zsp, stackPtr)); stackPtr += 16; } } for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMovq, mm(i), qword_ptr(self->_zsp, stackPtr)); + compiler->emit(kX86InstIdMovq, x86::mm(i), x86::qword_ptr(self->_zsp, stackPtr)); stackPtr += 8; } } - if (!func->hasFuncFlag(kFuncFlagPushPop)) { + if (!func->hasFuncFlag(kX86FuncFlagPushPop)) { for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) { if (mask & 0x1) { - compiler->emit(kInstMov, gpReg.setIndex(i), ptr(self->_zsp, stackPtr)); + compiler->emit(kX86InstIdMov, gpReg.setIndex(i), x86::ptr(self->_zsp, stackPtr)); stackPtr += regSize; } } @@ -4924,36 +4900,36 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func // Adjust stack. if (useLeaEpilog) { - compiler->emit(kInstLea, self->_zsp, ptr(fpReg, -static_cast(func->getPushPopStackSize()))); + compiler->emit(kX86InstIdLea, self->_zsp, x86::ptr(fpReg, -static_cast(func->getPushPopStackSize()))); } else if (!func->isStackMisaligned()) { if (func->isStackAdjusted() && stackSize != 0) - compiler->emit(kInstAdd, self->_zsp, stackSize); + compiler->emit(kX86InstIdAdd, self->_zsp, stackSize); } // Restore Gp (Push/Pop). - if (func->hasFuncFlag(kFuncFlagPushPop) && !earlyPushPop) + if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop) self->emitPopSequence(regsGp); // Emms. - if (func->hasFuncFlag(kFuncFlagEmms)) - compiler->emit(kInstEmms); + if (func->hasFuncFlag(kX86FuncFlagEmms)) + compiler->emit(kX86InstIdEmms); // MFence/SFence/LFence. - if (func->hasFuncFlag(kFuncFlagSFence) & func->hasFuncFlag(kFuncFlagLFence)) - compiler->emit(kInstMfence); - else if (func->hasFuncFlag(kFuncFlagSFence)) - compiler->emit(kInstSfence); - else if (func->hasFuncFlag(kFuncFlagLFence)) - compiler->emit(kInstLfence); + if (func->hasFuncFlag(kX86FuncFlagSFence) & func->hasFuncFlag(kX86FuncFlagLFence)) + compiler->emit(kX86InstIdMfence); + else if (func->hasFuncFlag(kX86FuncFlagSFence)) + compiler->emit(kX86InstIdSfence); + else if (func->hasFuncFlag(kX86FuncFlagLFence)) + compiler->emit(kX86InstIdLfence); // Leave. if (func->isNaked()) { if (func->isStackMisaligned()) { - compiler->emit(kInstMov, self->_zsp, fpOffset); + compiler->emit(kX86InstIdMov, self->_zsp, fpOffset); if (func->isStackFrameRegPreserved()) - compiler->emit(kInstPop, fpReg); + compiler->emit(kX86InstIdPop, fpReg); if (earlyPushPop) self->emitPopSequence(regsGp); @@ -4961,33 +4937,33 @@ static Error X86X64Context_translatePrologEpilog(X86X64Context* self, X86X64Func } else { if (useLeaEpilog) { - compiler->emit(kInstPop, fpReg); + compiler->emit(kX86InstIdPop, fpReg); } - else if (func->hasFuncFlag(kFuncFlagLeave)) { - compiler->emit(kInstLeave); + else if (func->hasFuncFlag(kX86FuncFlagLeave)) { + compiler->emit(kX86InstIdLeave); } else { - compiler->emit(kInstMov, self->_zsp, fpReg); - compiler->emit(kInstPop, fpReg); + compiler->emit(kX86InstIdMov, self->_zsp, fpReg); + compiler->emit(kX86InstIdPop, fpReg); } } // Emit return. if (decl->getCalleePopsStack()) - compiler->emit(kInstRet, static_cast(decl->getArgStackSize())); + compiler->emit(kX86InstIdRet, static_cast(decl->getArgStackSize())); else - compiler->emit(kInstRet); + compiler->emit(kX86InstIdRet); return kErrorOk; } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Translate - Jump] +// [asmjit::X86Context - Translate - Jump] // ============================================================================ //! \internal -static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, TargetNode* jTarget) { - X86X64Compiler* compiler = self->getCompiler(); +static void X86Context_translateJump(X86Context* self, JumpNode* jNode, TargetNode* jTarget) { + X86Compiler* compiler = self->getCompiler(); Node* extNode = self->getExtraBlock(); // TODO: [COMPILER] State Change. @@ -5018,10 +4994,10 @@ static void X86X64Context_translateJump(X86X64Context* self, JumpNode* jNode, Ta } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Translate - Ret] +// [asmjit::X86Context - Translate - Ret] // ============================================================================ -static Error X86X64Context_translateRet(X86X64Context* self, RetNode* rNode, TargetNode* exitTarget) { +static Error X86Context_translateRet(X86Context* self, RetNode* rNode, TargetNode* exitTarget) { Node* node = rNode->getNext(); while (node != NULL) { @@ -5059,7 +5035,7 @@ static Error X86X64Context_translateRet(X86X64Context* self, RetNode* rNode, Tar _EmitRet: { - X86X64Compiler* compiler = self->getCompiler(); + X86Compiler* compiler = self->getCompiler(); compiler->_setCursor(rNode); compiler->jmp(exitTarget->getLabel()); @@ -5068,16 +5044,18 @@ _EmitRet: } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Translate - Func] +// [asmjit::X86Context - Translate - Func] // ============================================================================ -Error X86X64Context::translate() { - X86X64Compiler* compiler = getCompiler(); - X86X64FuncNode* func = getFunc(); +Error X86Context::translate() { + ASMJIT_TLOG("[Translate] === Begin ===\n"); + + X86Compiler* compiler = getCompiler(); + X86FuncNode* func = getFunc(); // Register allocator contexts. - X86X64VarAlloc vAlloc(this); - X86X64CallAlloc cAlloc(this); + X86VarAlloc vAlloc(this); + X86CallAlloc cAlloc(this); // Flow. Node* node_ = func; @@ -5103,11 +5081,11 @@ _NextGroup: node_ = jLink->getValue(); jLink = jLink->getNext(); - Node* jFlow = X86X64Context_getOppositeJccFlow(static_cast(node_)); + Node* jFlow = X86Context_getOppositeJccFlow(static_cast(node_)); loadState(node_->getState()); if (jFlow->getState()) { - X86X64Context_translateJump(this, + X86Context_translateJump(this, static_cast(node_), static_cast(jFlow)); @@ -5126,6 +5104,10 @@ _NextGroup: next = node_->getNext(); node_->addFlags(kNodeFlagIsTranslated); + ASMJIT_TSEC({ + X86Context_traceNode(this, node_); + }); + switch (node_->getType()) { // ---------------------------------------------------------------------- // [Align / Embed] @@ -5155,12 +5137,12 @@ _NextGroup: case kNodeTypeSArg: // Update VarAttr's unuse flags based on liveness of the next node. if (!node_->isJcc()) { - VarInst* vi = static_cast(node_->getVarInst()); + X86VarMap* map = static_cast(node_->getMap()); VarBits* liveness = next->getLiveness(); - if (vi != NULL && liveness != NULL) { - VarAttr* vaList = vi->getVaList(); - uint32_t vaCount = vi->getVaCount(); + if (map != NULL && liveness != NULL) { + VarAttr* vaList = map->getVaList(); + uint32_t vaCount = map->getVaCount(); for (uint32_t i = 0; i < vaCount; i++) { VarAttr* va = &vaList[i]; @@ -5173,7 +5155,7 @@ _NextGroup: } if (node_->getType() == kNodeTypeCall) { - ASMJIT_PROPAGATE_ERROR(cAlloc.run(static_cast(node_))); + ASMJIT_PROPAGATE_ERROR(cAlloc.run(static_cast(node_))); break; } // ... Fall through ... @@ -5207,16 +5189,16 @@ _NextGroup: // TODO: [COMPILER] State - Do intersection of two states if possible. } - BaseVarState* savedState = saveState(); + VarState* savedState = saveState(); node->setState(savedState); - X86X64Context_translateJump(this, node, jTarget); + X86Context_translateJump(this, node, jTarget); next = jNext; } else if (jNext->isTranslated()) { ASMJIT_ASSERT(jNext->getType() == kNodeTypeTarget); - BaseVarState* savedState = saveState(); + VarState* savedState = saveState(); node->setState(savedState); compiler->_setCursor(node); @@ -5226,13 +5208,13 @@ _NextGroup: } else { node->setState(saveState()); - next = X86X64Context_getJccFlow(node); + next = X86Context_getJccFlow(node); } } } else if (node_->isRet()) { ASMJIT_PROPAGATE_ERROR( - X86X64Context_translateRet(this, static_cast(node_), func->getExitNode())); + X86Context_translateRet(this, static_cast(node_), func->getExitNode())); } break; } @@ -5244,10 +5226,10 @@ _NextGroup: case kNodeTypeFunc: { ASMJIT_ASSERT(node_ == func); - X86X64FuncDecl* decl = func->getDecl(); - VarInst* vi = func->getVarInst(); + X86FuncDecl* decl = func->getDecl(); + X86VarMap* map = func->getMap(); - if (vi != NULL) { + if (map != NULL) { uint32_t i; uint32_t argCount = func->_x86Decl.getArgCount(); @@ -5255,7 +5237,7 @@ _NextGroup: const FuncInOut& arg = decl->getArg(i); VarData* vd = func->getArg(i); - VarAttr* va = vi->findVa(vd); + VarAttr* va = map->findVa(vd); ASMJIT_ASSERT(va != NULL); if (va->getFlags() & kVarAttrUnuse) @@ -5264,9 +5246,9 @@ _NextGroup: uint32_t regIndex = va->getOutRegIndex(); if (regIndex != kInvalidReg && (va->getFlags() & kVarAttrOutConv) == 0) { switch (vd->getClass()) { - case kRegClassGp : attach(vd, regIndex, true); break; - case kRegClassMm : attach(vd, regIndex, true); break; - case kRegClassXyz: attach(vd, regIndex, true); break; + case kX86RegClassGp : attach(vd, regIndex, true); break; + case kX86RegClassMm : attach(vd, regIndex, true); break; + case kX86RegClassXyz: attach(vd, regIndex, true); break; } } else if (va->hasFlag(kVarAttrOutConv)) { @@ -5301,19 +5283,126 @@ _NextGroup: } _Done: - ASMJIT_PROPAGATE_ERROR(X86X64Context_initFunc(this, func)); - ASMJIT_PROPAGATE_ERROR(X86X64Context_patchFuncMem(this, func, stop)); - ASMJIT_PROPAGATE_ERROR(X86X64Context_translatePrologEpilog(this, func)); + ASMJIT_PROPAGATE_ERROR(X86Context_initFunc(this, func)); + ASMJIT_PROPAGATE_ERROR(X86Context_patchFuncMem(this, func, stop)); + ASMJIT_PROPAGATE_ERROR(X86Context_translatePrologEpilog(this, func)); + ASMJIT_TLOG("[Translate] === Done ===\n\n"); return kErrorOk; } // ============================================================================ -// [asmjit::x86x64::X86X64Context - Serialize] +// [asmjit::X86Context - Schedule] +// ============================================================================ + +Error X86Context::schedule() { + X86Compiler* compiler = getCompiler(); + X86Scheduler scheduler(compiler, + static_cast(compiler->getRuntime()->getCpuInfo())); + + Node* node_ = getFunc(); + Node* stop = getStop(); + + PodList::Link* jLink = _jccList.getFirst(); + + // -------------------------------------------------------------------------- + // [Loop] + // -------------------------------------------------------------------------- + +_Advance: + while (node_->isScheduled()) { +_NextGroup: + if (jLink == NULL) + goto _Done; + + // We always go to the next instruction in the main loop so we have to + // jump to the `jcc` target here. + node_ = static_cast(jLink->getValue())->getTarget(); + jLink = jLink->getNext(); + } + + // Find interval that can be passed to scheduler. + for (;;) { + Node* schedStart = node_; + + for (;;) { + Node* next = node_->getNext(); + node_->addFlags(kNodeFlagIsScheduled); + + // Shouldn't happen here, investigate if hit. + ASMJIT_ASSERT(node_ != stop); + + uint32_t nodeType = node_->getType(); + if (nodeType != kNodeTypeInst) { + // If we didn't reach any instruction node we simply advance. In this + // case no informative nodes will be removed and everything else just + // skipped. + if (schedStart == node_) { + node_ = next; + if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet) + goto _NextGroup; + else + goto _Advance; + } + + // Remove informative nodes if we are in a middle of instruction + // stream. + // + // TODO: Shouldn't be there an option for this? Maybe it can be useful + // to stop if there is a comment or something. I'm not sure if it's + // good to always remove. + if (node_->isInformative()) { + compiler->removeNode(node_); + node_ = next; + continue; + } + + break; + } + + // Stop if `node_` is `jmp` or `jcc`. + if (node_->isJmpOrJcc()) + break; + + node_ = next; + } + + // If the stream is less than 3 instructions it will not be passed to + // scheduler. + if (schedStart != node_ && + schedStart->getNext() != node_ && + schedStart->getNext() != node_->getPrev()) { + + scheduler.run(schedStart, node_); + } + + // If node is `jmp` we follow it as well. + if (node_->isJmp()) { + node_ = static_cast(node_)->getTarget(); + goto _Advance; + } + + // Handle stop nodes. + { + uint32_t nodeType = node_->getType(); + if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet) + goto _NextGroup; + } + + node_ = node_->getNext(); + goto _Advance; + } + +_Done: + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - Serialize] // ============================================================================ template -static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64Assembler* assembler, Node* start, Node* stop) { +static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* assembler, Node* start, Node* stop) { Node* node_ = start; StringBuilder& sb = self->_stringBuilder; @@ -5352,7 +5441,7 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As if (node_->hasLiveness()) { VarBits* liveness = node_->getLiveness(); - VarInst* vi = static_cast(node_->getVarInst()); + X86VarMap* map = static_cast(node_->getMap()); uint32_t i; for (i = 0; i < vdCount; i++) { @@ -5360,11 +5449,11 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As sb.getData()[offset + i] = '.'; } - if (vi != NULL) { - uint32_t vaCount = vi->getVaCount(); + if (map != NULL) { + uint32_t vaCount = map->getVaCount(); for (i = 0; i < vaCount; i++) { - VarAttr* va = vi->getVa(i); + VarAttr* va = map->getVa(i); VarData* vd = va->getVd(); uint32_t flags = va->getFlags(); @@ -5436,116 +5525,116 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As if (node->isSpecial()) { switch (code) { - case kInstCpuid: + case kX86InstIdCpuid: break; - case kInstCbw: - case kInstCdq: - case kInstCdqe: - case kInstCwd: - case kInstCwde: - case kInstCqo: + case kX86InstIdCbw: + case kX86InstIdCdq: + case kX86InstIdCdqe: + case kX86InstIdCwd: + case kX86InstIdCwde: + case kX86InstIdCqo: break; - case kInstCmpxchg: + case kX86InstIdCmpxchg: o0 = &opList[1]; o1 = &opList[2]; break; - case kInstCmpxchg8b : - case kInstCmpxchg16b: + case kX86InstIdCmpxchg8b : + case kX86InstIdCmpxchg16b: o0 = &opList[4]; break; - case kInstDaa: - case kInstDas: + case kX86InstIdDaa: + case kX86InstIdDas: break; - case kInstImul: - case kInstMul: - case kInstIdiv: - case kInstDiv: + case kX86InstIdImul: + case kX86InstIdMul: + case kX86InstIdIdiv: + case kX86InstIdDiv: // Assume "Mul/Div dst_hi (implicit), dst_lo (implicit), src (explicit)". ASMJIT_ASSERT(opCount == 3); o0 = &opList[2]; break; - case kInstMovPtr: + case kX86InstIdMovPtr: break; - case kInstLahf: - case kInstSahf: + case kX86InstIdLahf: + case kX86InstIdSahf: break; - case kInstMaskmovq: - case kInstMaskmovdqu: + case kX86InstIdMaskmovq: + case kX86InstIdMaskmovdqu: o0 = &opList[1]; o1 = &opList[2]; break; - case kInstEnter: + case kX86InstIdEnter: o0 = &opList[0]; o1 = &opList[1]; break; - case kInstLeave: + case kX86InstIdLeave: break; - case kInstRet: + case kX86InstIdRet: if (opCount > 0) o0 = &opList[0]; break; - case kInstMonitor: - case kInstMwait: + case kX86InstIdMonitor: + case kX86InstIdMwait: break; - case kInstPop: + case kX86InstIdPop: o0 = &opList[0]; break; - case kInstPopa: - case kInstPopf: + case kX86InstIdPopa: + case kX86InstIdPopf: break; - case kInstPush: + case kX86InstIdPush: o0 = &opList[0]; break; - case kInstPusha: - case kInstPushf: + case kX86InstIdPusha: + case kX86InstIdPushf: break; - case kInstRcl: - case kInstRcr: - case kInstRol: - case kInstRor: - case kInstSal: - case kInstSar: - case kInstShl: - case kInstShr: + case kX86InstIdRcl: + case kX86InstIdRcr: + case kX86InstIdRol: + case kX86InstIdRor: + case kX86InstIdSal: + case kX86InstIdSar: + case kX86InstIdShl: + case kX86InstIdShr: o0 = &opList[0]; - o1 = &cl; + o1 = &x86::cl; break; - case kInstShld: - case kInstShrd: + case kX86InstIdShld: + case kX86InstIdShrd: o0 = &opList[0]; o1 = &opList[1]; - o2 = &cl; + o2 = &x86::cl; break; - case kInstRdtsc: - case kInstRdtscp: + case kX86InstIdRdtsc: + case kX86InstIdRdtscp: break; - case kInstRepLodsb : case kInstRepLodsd : case kInstRepLodsq : case kInstRepLodsw : - case kInstRepMovsb : case kInstRepMovsd : case kInstRepMovsq : case kInstRepMovsw : - case kInstRepStosb : case kInstRepStosd : case kInstRepStosq : case kInstRepStosw : - case kInstRepeCmpsb : case kInstRepeCmpsd : case kInstRepeCmpsq : case kInstRepeCmpsw : - case kInstRepeScasb : case kInstRepeScasd : case kInstRepeScasq : case kInstRepeScasw : - case kInstRepneCmpsb: case kInstRepneCmpsd: case kInstRepneCmpsq: case kInstRepneCmpsw: - case kInstRepneScasb: case kInstRepneScasd: case kInstRepneScasq: case kInstRepneScasw: + case kX86InstIdRepLodsB : case kX86InstIdRepLodsD : case kX86InstIdRepLodsQ : case kX86InstIdRepLodsW : + case kX86InstIdRepMovsB : case kX86InstIdRepMovsD : case kX86InstIdRepMovsQ : case kX86InstIdRepMovsW : + case kX86InstIdRepStosB : case kX86InstIdRepStosD : case kX86InstIdRepStosQ : case kX86InstIdRepStosW : + case kX86InstIdRepeCmpsB : case kX86InstIdRepeCmpsD : case kX86InstIdRepeCmpsQ : case kX86InstIdRepeCmpsW : + case kX86InstIdRepeScasB : case kX86InstIdRepeScasD : case kX86InstIdRepeScasQ : case kX86InstIdRepeScasW : + case kX86InstIdRepneCmpsB: case kX86InstIdRepneCmpsD: case kX86InstIdRepneCmpsQ: case kX86InstIdRepneCmpsW: + case kX86InstIdRepneScasB: case kX86InstIdRepneScasD: case kX86InstIdRepneScasQ: case kX86InstIdRepneScasW: break; default: @@ -5574,8 +5663,8 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As // Function call adds nodes before and after, but it's required to emit // the call instruction by itself. case kNodeTypeCall: { - X86X64CallNode* node = static_cast(node_); - assembler->emit(kInstCall, node->_target, noOperand, noOperand); + X86CallNode* node = static_cast(node_); + assembler->emit(kX86InstIdCall, node->_target, noOperand, noOperand); break; } @@ -5589,16 +5678,15 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As return kErrorOk; } -Error X86X64Context::serialize(BaseAssembler* assembler, Node* start, Node* stop) { +Error X86Context::serialize(Assembler* assembler, Node* start, Node* stop) { #if !defined(ASMJIT_DISABLE_LOGGER) if (assembler->hasLogger()) - return X86X64Context_serialize<1>(this, static_cast(assembler), start, stop); + return X86Context_serialize<1>(this, static_cast(assembler), start, stop); #endif // !ASMJIT_DISABLE_LOGGER - return X86X64Context_serialize<0>(this, static_cast(assembler), start, stop); + return X86Context_serialize<0>(this, static_cast(assembler), start, stop); } -} // x86x64 namespace } // asmjit namespace // [Api-End] diff --git a/src/asmjit/x86/x86context_p.h b/src/asmjit/x86/x86context_p.h index 2224c5e..64bfc11 100644 --- a/src/asmjit/x86/x86context_p.h +++ b/src/asmjit/x86/x86context_p.h @@ -22,10 +22,12 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { + +//! \addtogroup asmjit_x86_compiler +//! \{ // ============================================================================ -// [asmjit::Context] +// [asmjit::X86Context] // ============================================================================ #if defined(ASMJIT_DEBUG) @@ -34,27 +36,24 @@ namespace x86x64 { # define ASMJIT_X86_CHECK_STATE #endif // ASMJIT_DEBUG -//! \addtogroup asmjit_x86x64_tree -//! \{ - //! \internal //! -//! Compiler context is used by `X86X64Compiler`. +//! 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 X86X64Context : public BaseContext { - ASMJIT_NO_COPY(X86X64Context) +struct X86Context : public Context { + ASMJIT_NO_COPY(X86Context) // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - //! Create a new `X86X64Context` instance. - X86X64Context(X86X64Compiler* compiler); - //! Destroy the `X86X64Context` instance. - virtual ~X86X64Context(); + //! Create a new `X86Context` instance. + X86Context(X86Compiler* compiler); + //! Destroy the `X86Context` instance. + virtual ~X86Context(); // -------------------------------------------------------------------------- // [Reset] @@ -62,22 +61,26 @@ struct X86X64Context : public BaseContext { virtual void reset(); + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isX64() const { + return _zsp.getSize() == 16; + } + // -------------------------------------------------------------------------- // [Accessors] // -------------------------------------------------------------------------- - //! Get compiler as `X86X64Compiler`. - ASMJIT_INLINE X86X64Compiler* getCompiler() const { - return static_cast(_compiler); + //! Get compiler as `X86Compiler`. + ASMJIT_INLINE X86Compiler* getCompiler() const { + return static_cast(_compiler); } - //! Get function as `X86X64FuncNode`. - ASMJIT_INLINE X86X64FuncNode* getFunc() const { - return reinterpret_cast(_func); - } - - ASMJIT_INLINE bool isX64() const { - return _baseRegsCount == 16; + //! Get function as `X86FuncNode`. + ASMJIT_INLINE X86FuncNode* getFunc() const { + return reinterpret_cast(_func); } //! Get clobbered registers (global). @@ -89,9 +92,9 @@ struct X86X64Context : public BaseContext { // [Helpers] // -------------------------------------------------------------------------- - ASMJIT_INLINE VarInst* newVarInst(uint32_t vaCount) { - return static_cast( - _baseZone.alloc(sizeof(VarInst) + vaCount * sizeof(VarAttr))); + ASMJIT_INLINE X86VarMap* newVarMap(uint32_t vaCount) { + return static_cast( + _baseZone.alloc(sizeof(X86VarMap) + vaCount * sizeof(VarAttr))); } // -------------------------------------------------------------------------- @@ -107,8 +110,8 @@ struct X86X64Context : public BaseContext { 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 Mem* dst, uint32_t srcType, uint32_t srcIndex); - void emitMoveImmOnStack(uint32_t dstType, const Mem* dst, const Imm* src); + 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); @@ -118,13 +121,6 @@ struct X86X64Context : public BaseContext { void _checkState(); - ASMJIT_INLINE uint32_t getRegsCount(uint32_t c) const { - if (c == kRegClassGp || c == kRegClassXyz) - return _baseRegsCount; - else - return 8; - } - ASMJIT_INLINE uint32_t getRegSize() const { return _zsp.getSize(); } @@ -137,19 +133,20 @@ struct X86X64Context : public BaseContext { //! //! Attach a register to the 'VarData', changing 'VarData' members to show //! that the variable is currently alive and linking variable with the - //! current 'VarState'. + //! 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 != kRegClassGp || regIndex != kRegIndexSp); + 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; @@ -163,7 +160,7 @@ struct X86X64Context : public BaseContext { //! //! The opposite of 'Attach'. Detach resets the members in 'VarData' //! (regIndex, state and changed flags) and unlinks the variable with the - //! current 'VarState'. + //! current 'X86VarState'. template ASMJIT_INLINE void detach(VarData* vd, uint32_t regIndex, uint32_t vState) { ASMJIT_ASSERT(vd->getClass() == C); @@ -189,7 +186,7 @@ struct X86X64Context : public BaseContext { //! Rebase. //! - //! Change the register of the 'VarData' changing also the current 'VarState'. + //! 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 @@ -281,11 +278,11 @@ struct X86X64Context : public BaseContext { ASMJIT_INLINE void swapGp(VarData* aVd, VarData* bVd) { ASMJIT_ASSERT(aVd != bVd); - ASMJIT_ASSERT(aVd->getClass() == kRegClassGp); + ASMJIT_ASSERT(aVd->getClass() == kX86RegClassGp); ASMJIT_ASSERT(aVd->getState() == kVarStateReg); ASMJIT_ASSERT(aVd->getRegIndex() != kInvalidReg); - ASMJIT_ASSERT(bVd->getClass() == kRegClassGp); + ASMJIT_ASSERT(bVd->getClass() == kX86RegClassGp); ASMJIT_ASSERT(bVd->getState() == kVarStateReg); ASMJIT_ASSERT(bVd->getRegIndex() != kInvalidReg); @@ -297,11 +294,11 @@ struct X86X64Context : public BaseContext { aVd->setRegIndex(bIndex); bVd->setRegIndex(aIndex); - _x86State.getListByClass(kRegClassGp)[aIndex] = bVd; - _x86State.getListByClass(kRegClassGp)[bIndex] = aVd; + _x86State.getListByClass(kX86RegClassGp)[aIndex] = bVd; + _x86State.getListByClass(kX86RegClassGp)[bIndex] = aVd; uint32_t m = aVd->isModified() ^ bVd->isModified(); - _x86State._modified.xor_(kRegClassGp, (m << aIndex) | (m << bIndex)); + _x86State._modified.xor_(kX86RegClassGp, (m << aIndex) | (m << bIndex)); ASMJIT_X86_CHECK_STATE } @@ -310,7 +307,7 @@ struct X86X64Context : public BaseContext { // [Alloc / Spill] // -------------------------------------------------------------------------- - //! Alloc + //! Alloc. template ASMJIT_INLINE void alloc(VarData* vd, uint32_t regIndex) { ASMJIT_ASSERT(vd->getClass() == C); @@ -415,35 +412,34 @@ struct X86X64Context : public BaseContext { // [State] // -------------------------------------------------------------------------- - //! Get state as `VarState`. - ASMJIT_INLINE VarState* getState() const { - return const_cast(&_x86State); + //! Get state as `X86VarState`. + ASMJIT_INLINE X86VarState* getState() const { + return const_cast(&_x86State); } - virtual void loadState(BaseVarState* src); - virtual BaseVarState* saveState(); + virtual void loadState(VarState* src); + virtual VarState* saveState(); - virtual void switchState(BaseVarState* src); - virtual void intersectStates(BaseVarState* a, BaseVarState* b); + virtual void switchState(VarState* src); + virtual void intersectStates(VarState* a, VarState* b); // -------------------------------------------------------------------------- // [Memory] // -------------------------------------------------------------------------- - ASMJIT_INLINE Mem getVarMem(VarData* vd) { + ASMJIT_INLINE X86Mem getVarMem(VarData* vd) { (void)getVarCell(vd); - Mem mem(_memSlot); + X86Mem mem(_memSlot); mem.setBase(vd->getId()); return mem; } // -------------------------------------------------------------------------- - // [Prepare] + // [Fetch] // -------------------------------------------------------------------------- virtual Error fetch(); - virtual Error analyze(); // -------------------------------------------------------------------------- // [Annotate] @@ -457,37 +453,43 @@ struct X86X64Context : public BaseContext { virtual Error translate(); + // -------------------------------------------------------------------------- + // [Schedule] + // -------------------------------------------------------------------------- + + virtual Error schedule(); + // -------------------------------------------------------------------------- // [Serialize] // -------------------------------------------------------------------------- - virtual Error serialize(BaseAssembler* assembler, Node* start, Node* stop); + virtual Error serialize(Assembler* assembler, Node* start, Node* stop); // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- + //! Count of X86/X64 registers. + X86RegCount _regCount; //! X86/X64 stack-pointer (esp or rsp). - GpReg _zsp; + X86GpReg _zsp; //! X86/X64 frame-pointer (ebp or rbp). - GpReg _zbp; + X86GpReg _zbp; //! Temporary memory operand. - Mem _memSlot; + X86Mem _memSlot; //! X86/X64 specific compiler state, linked to `_state`. - VarState _x86State; + X86VarState _x86State; //! Clobbered registers (for the whole function). - RegMask _clobberedRegs; + X86RegMask _clobberedRegs; //! Memory cell where is stored address used to restore manually //! aligned stack. MemCell* _stackFrameCell; //! Global allocable registers mask. - uint32_t _gaRegs[kRegClassCount]; + uint32_t _gaRegs[kX86RegClassCount]; - //! X86/X64 number of Gp/Xmm registers. - uint8_t _baseRegsCount; //! Function arguments base pointer (register). uint8_t _argBaseReg; //! Function variables base pointer (register). @@ -511,7 +513,6 @@ struct X86X64Context : public BaseContext { //! \} -} // x86x64 namespace } // asmjit namespace // [Api-End] diff --git a/src/asmjit/x86/x86cpuinfo.cpp b/src/asmjit/x86/x86cpuinfo.cpp index bc51f61..75ed0b0 100644 --- a/src/asmjit/x86/x86cpuinfo.cpp +++ b/src/asmjit/x86/x86cpuinfo.cpp @@ -25,33 +25,31 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ -// [asmjit::x86x64::CpuVendor] +// [asmjit::X86CpuVendor] // ============================================================================ -struct CpuVendor { +struct X86CpuVendor { uint32_t id; char text[12]; }; -static const CpuVendor cpuVendorTable[] = { +static const X86CpuVendor x86CpuVendorList[] = { { kCpuVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } }, { kCpuVendorAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } }, - { kCpuVendorAmd , { 'A', 'M', 'D', 'i', 's', 'b', 'e', 't', 't', 'e', 'r', '!' } }, { kCpuVendorVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } }, { kCpuVendorVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } } }; -static ASMJIT_INLINE bool cpuVendorEq(const CpuVendor& info, const char* vendorString) { +static ASMJIT_INLINE bool x86CpuVendorEq(const X86CpuVendor& info, const char* vendorString) { const uint32_t* a = reinterpret_cast(info.text); const uint32_t* b = reinterpret_cast(vendorString); return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]); } -static ASMJIT_INLINE void simplifyBrandString(char* s) { +static ASMJIT_INLINE void x86SimplifyBrandString(char* s) { // Always clear the current character in the buffer. It ensures that there // is no garbage after the string NULL terminator. char* d = s; @@ -82,7 +80,7 @@ _Skip: } // ============================================================================ -// [asmjit::x86x64::CpuUtil] +// [asmjit::X86CpuUtil] // ============================================================================ // This is messy, I know. Cpuid is implemented as intrinsic in VS2005, but @@ -92,7 +90,7 @@ _Skip: // callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here. #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) -void CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, CpuId* outResult) { +void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) { #if defined(_MSC_VER) // 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler. @@ -136,35 +134,43 @@ void CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, CpuId* outResult) { #endif // COMPILER } -void CpuUtil::detect(CpuInfo* cpuInfo) { - CpuId regs; +void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { + X86CpuId regs; uint32_t i; uint32_t maxId; // Clear everything except the '_size' member. ::memset(reinterpret_cast(cpuInfo) + sizeof(uint32_t), - 0, sizeof(BaseCpuInfo) - sizeof(uint32_t)); + 0, sizeof(CpuInfo) - sizeof(uint32_t)); // Fill safe defaults. - ::memcpy(cpuInfo->_vendorString, "Unknown", 8); - cpuInfo->_coresCount = BaseCpuInfo::detectNumberOfCores(); + cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount(); + + // -------------------------------------------------------------------------- + // [CPUID EAX=0x00000000] + // -------------------------------------------------------------------------- // Get vendor string/id. callCpuId(0, 0, ®s); maxId = regs.eax; + ::memcpy(cpuInfo->_vendorString, ®s.ebx, 4); ::memcpy(cpuInfo->_vendorString + 4, ®s.edx, 4); ::memcpy(cpuInfo->_vendorString + 8, ®s.ecx, 4); - for (i = 0; i < ASMJIT_ARRAY_SIZE(cpuVendorTable); i++) { - if (cpuVendorEq(cpuVendorTable[i], cpuInfo->_vendorString)) { - cpuInfo->_vendorId = cpuVendorTable[i].id; + for (i = 0; i < ASMJIT_ARRAY_SIZE(x86CpuVendorList); i++) { + if (x86CpuVendorEq(x86CpuVendorList[i], cpuInfo->_vendorString)) { + cpuInfo->_vendorId = x86CpuVendorList[i].id; break; } } + // -------------------------------------------------------------------------- + // [CPUID EAX=0x00000001] + // -------------------------------------------------------------------------- + // Get feature flags in ecx/edx and family/model in eax. callCpuId(1, 0, ®s); @@ -184,60 +190,64 @@ void CpuUtil::detect(CpuInfo* cpuInfo) { cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8; cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF); - if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kCpuFeatureSse3); - if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kCpuFeaturePclmulqdq); - if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kCpuFeatureMonitorMWait); - if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kCpuFeatureSsse3); - if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kCpuFeatureCmpXchg16B); - if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kCpuFeatureSse41); - if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kCpuFeatureSse42); - if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kCpuFeatureMovbe); - if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kCpuFeaturePopcnt); - if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kCpuFeatureAesni); - if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kCpuFeatureRdrand); + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSse3); + if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePclmulqdq); + if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMonitorMWait); + if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSsse3); + if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg16B); + if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSse41); + if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSse42); + if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMovbe); + if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePopcnt); + if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAesni); + if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRdrand); - if (regs.edx & 0x00000010U) cpuInfo->addFeature(kCpuFeatureRdtsc); - if (regs.edx & 0x00000100U) cpuInfo->addFeature(kCpuFeatureCmpXchg8B); - if (regs.edx & 0x00008000U) cpuInfo->addFeature(kCpuFeatureCmov); - if (regs.edx & 0x00800000U) cpuInfo->addFeature(kCpuFeatureMmx); - if (regs.edx & 0x01000000U) cpuInfo->addFeature(kCpuFeatureFxsr); - if (regs.edx & 0x02000000U) cpuInfo->addFeature(kCpuFeatureSse).addFeature(kCpuFeatureMmxExt); - if (regs.edx & 0x04000000U) cpuInfo->addFeature(kCpuFeatureSse).addFeature(kCpuFeatureSse2); - if (regs.edx & 0x10000000U) cpuInfo->addFeature(kCpuFeatureMultithreading); + if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRdtsc); + if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg8B); + if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCmov); + if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMmx); + if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFxsr); + if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureSse2); + if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMultithreading); if (cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) { // AMD sets Multithreading to ON if it has more cores. - if (cpuInfo->_coresCount == 1) - cpuInfo->_coresCount = 2; + if (cpuInfo->_hwThreadsCount == 1) + cpuInfo->_hwThreadsCount = 2; } // Detect AVX. if (regs.ecx & 0x10000000U) { - cpuInfo->addFeature(kCpuFeatureAvx); + cpuInfo->addFeature(kX86CpuFeatureAvx); - if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kCpuFeatureXop); - if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kCpuFeatureFma3); - if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kCpuFeatureFma4); - if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kCpuFeatureF16C); + if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXop); + if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFma3); + if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFma4); + if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C); } // Detect new features if the processor supports CPUID-07. if (maxId >= 7) { callCpuId(7, 0, ®s); - if (regs.ebx & 0x00000001) cpuInfo->addFeature(kCpuFeatureFsGsBase); - if (regs.ebx & 0x00000008) cpuInfo->addFeature(kCpuFeatureBmi); - if (regs.ebx & 0x00000010) cpuInfo->addFeature(kCpuFeatureHle); - if (regs.ebx & 0x00000100) cpuInfo->addFeature(kCpuFeatureBmi2); - if (regs.ebx & 0x00000200) cpuInfo->addFeature(kCpuFeatureRepMovsbStosbExt); - if (regs.ebx & 0x00000800) cpuInfo->addFeature(kCpuFeatureRtm); + if (regs.ebx & 0x00000001) cpuInfo->addFeature(kX86CpuFeatureFsGsBase); + if (regs.ebx & 0x00000008) cpuInfo->addFeature(kX86CpuFeatureBmi); + if (regs.ebx & 0x00000010) cpuInfo->addFeature(kX86CpuFeatureHle); + if (regs.ebx & 0x00000100) cpuInfo->addFeature(kX86CpuFeatureBmi2); + if (regs.ebx & 0x00000200) cpuInfo->addFeature(kX86CpuFeatureRepMovsbStosbExt); + if (regs.ebx & 0x00000800) cpuInfo->addFeature(kX86CpuFeatureRtm); // AVX2 depends on AVX. - if (cpuInfo->hasFeature(kCpuFeatureAvx)) { - if (regs.ebx & 0x00000020) cpuInfo->addFeature(kCpuFeatureAvx2); + if (cpuInfo->hasFeature(kX86CpuFeatureAvx)) { + if (regs.ebx & 0x00000020) cpuInfo->addFeature(kX86CpuFeatureAvx2); } } + // -------------------------------------------------------------------------- + // [CPUID EAX=0x80000000] + // -------------------------------------------------------------------------- + // Calling cpuid with 0x80000000 as the in argument gets the number of valid // extended IDs. callCpuId(0x80000000, 0, ®s); @@ -250,18 +260,18 @@ void CpuUtil::detect(CpuInfo* cpuInfo) { switch (i) { case 0x80000001: - if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kCpuFeatureLahfSahf); - if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kCpuFeatureLzcnt); - if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kCpuFeatureSse4A); - if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kCpuFeatureMsse); - if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kCpuFeaturePrefetch); + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf); + if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLzcnt); + if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSse4A); + if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMsse); + if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePrefetch); - if (regs.edx & 0x00100000U) cpuInfo->addFeature(kCpuFeatureExecuteDisableBit); - if (regs.edx & 0x00200000U) cpuInfo->addFeature(kCpuFeatureFfxsr); - if (regs.edx & 0x00400000U) cpuInfo->addFeature(kCpuFeatureMmxExt); - if (regs.edx & 0x08000000U) cpuInfo->addFeature(kCpuFeatureRdtscp); - if (regs.edx & 0x40000000U) cpuInfo->addFeature(kCpuFeature3dNowExt).addFeature(kCpuFeatureMmxExt); - if (regs.edx & 0x80000000U) cpuInfo->addFeature(kCpuFeature3dNow); + if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureExecuteDisableBit); + if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFfxsr); + if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRdtscp); + if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3dNowExt).addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3dNow); break; case 0x80000002: @@ -280,11 +290,10 @@ void CpuUtil::detect(CpuInfo* cpuInfo) { } // Simplify the brand string (remove unnecessary spaces to make printing nicer). - simplifyBrandString(cpuInfo->_brandString); + x86SimplifyBrandString(cpuInfo->_brandString); } #endif -} // x86x64 namespace } // asmjit namespace // [Api-End] diff --git a/src/asmjit/x86/x86cpuinfo.h b/src/asmjit/x86/x86cpuinfo.h index a91c311..7e71f2c 100644 --- a/src/asmjit/x86/x86cpuinfo.h +++ b/src/asmjit/x86/x86cpuinfo.h @@ -15,120 +15,119 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ // [Forward Declarations] // ============================================================================ -struct CpuInfo; +struct X86CpuInfo; -//! \addtogroup asmjit_x86x64_general +//! \addtogroup asmjit_x86_general //! \{ // ============================================================================ -// [asmjit::x86x64::kCpuFeature] +// [asmjit::kX86CpuFeature] // ============================================================================ //! X86 CPU features. -ASMJIT_ENUM(kCpuFeature) { +ASMJIT_ENUM(kX86CpuFeature) { //! Cpu has multithreading. - kCpuFeatureMultithreading = 1, + kX86CpuFeatureMultithreading = 1, //! Cpu has execute disable bit. - kCpuFeatureExecuteDisableBit, + kX86CpuFeatureExecuteDisableBit, //! Cpu has RDTSC. - kCpuFeatureRdtsc, + kX86CpuFeatureRdtsc, //! Cpu has RDTSCP. - kCpuFeatureRdtscp, + kX86CpuFeatureRdtscp, //! Cpu has CMOV. - kCpuFeatureCmov, + kX86CpuFeatureCmov, //! Cpu has CMPXCHG8B. - kCpuFeatureCmpXchg8B, + kX86CpuFeatureCmpXchg8B, //! Cpu has CMPXCHG16B (x64). - kCpuFeatureCmpXchg16B, + kX86CpuFeatureCmpXchg16B, //! Cpu has CLFUSH. - kCpuFeatureClflush, + kX86CpuFeatureClflush, //! Cpu has PREFETCH. - kCpuFeaturePrefetch, + kX86CpuFeaturePrefetch, //! Cpu has LAHF/SAHF. - kCpuFeatureLahfSahf, + kX86CpuFeatureLahfSahf, //! Cpu has FXSAVE/FXRSTOR. - kCpuFeatureFxsr, + kX86CpuFeatureFxsr, //! Cpu has FXSAVE/FXRSTOR optimizations. - kCpuFeatureFfxsr, + kX86CpuFeatureFfxsr, //! Cpu has MMX. - kCpuFeatureMmx, + kX86CpuFeatureMmx, //! Cpu has extended MMX. - kCpuFeatureMmxExt, + kX86CpuFeatureMmxExt, //! Cpu has 3dNow! - kCpuFeature3dNow, + kX86CpuFeature3dNow, //! Cpu has enchanced 3dNow! - kCpuFeature3dNowExt, + kX86CpuFeature3dNowExt, //! Cpu has SSE. - kCpuFeatureSse, + kX86CpuFeatureSse, //! Cpu has SSE2. - kCpuFeatureSse2, + kX86CpuFeatureSse2, //! Cpu has SSE3. - kCpuFeatureSse3, + kX86CpuFeatureSse3, //! Cpu has Supplemental SSE3 (SSSE3). - kCpuFeatureSsse3, + kX86CpuFeatureSsse3, //! Cpu has SSE4.A. - kCpuFeatureSse4A, + kX86CpuFeatureSse4A, //! Cpu has SSE4.1. - kCpuFeatureSse41, + kX86CpuFeatureSse41, //! Cpu has SSE4.2. - kCpuFeatureSse42, + kX86CpuFeatureSse42, //! Cpu has Misaligned SSE (MSSE). - kCpuFeatureMsse, + kX86CpuFeatureMsse, //! Cpu has MONITOR and MWAIT. - kCpuFeatureMonitorMWait, + kX86CpuFeatureMonitorMWait, //! Cpu has MOVBE. - kCpuFeatureMovbe, + kX86CpuFeatureMovbe, //! Cpu has POPCNT. - kCpuFeaturePopcnt, + kX86CpuFeaturePopcnt, //! Cpu has LZCNT. - kCpuFeatureLzcnt, + kX86CpuFeatureLzcnt, //! Cpu has AESNI. - kCpuFeatureAesni, + kX86CpuFeatureAesni, //! Cpu has PCLMULQDQ. - kCpuFeaturePclmulqdq, + kX86CpuFeaturePclmulqdq, //! Cpu has RDRAND. - kCpuFeatureRdrand, + kX86CpuFeatureRdrand, //! Cpu has AVX. - kCpuFeatureAvx, + kX86CpuFeatureAvx, //! Cpu has AVX2. - kCpuFeatureAvx2, + kX86CpuFeatureAvx2, //! Cpu has F16C. - kCpuFeatureF16C, + kX86CpuFeatureF16C, //! Cpu has FMA3. - kCpuFeatureFma3, + kX86CpuFeatureFma3, //! Cpu has FMA4. - kCpuFeatureFma4, + kX86CpuFeatureFma4, //! Cpu has XOP. - kCpuFeatureXop, + kX86CpuFeatureXop, //! Cpu has BMI. - kCpuFeatureBmi, + kX86CpuFeatureBmi, //! Cpu has BMI2. - kCpuFeatureBmi2, + kX86CpuFeatureBmi2, //! Cpu has HLE. - kCpuFeatureHle, + kX86CpuFeatureHle, //! Cpu has RTM. - kCpuFeatureRtm, + kX86CpuFeatureRtm, //! Cpu has FSGSBASE. - kCpuFeatureFsGsBase, + kX86CpuFeatureFsGsBase, //! Cpu has enhanced REP MOVSB/STOSB. - kCpuFeatureRepMovsbStosbExt, + kX86CpuFeatureRepMovsbStosbExt, //! Count of X86/X64 Cpu features. - kCpuFeatureCount + kX86CpuFeatureCount }; // ============================================================================ -// [asmjit::x86x64::CpuId] +// [asmjit::X86CpuId] // ============================================================================ //! X86/X64 CPUID output. -union CpuId { +union X86CpuId { //! EAX/EBX/ECX/EDX output. uint32_t i[4]; @@ -145,33 +144,33 @@ union CpuId { }; // ============================================================================ -// [asmjit::x86x64::CpuUtil] +// [asmjit::X86CpuUtil] // ============================================================================ #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) //! CPU utilities available only if the host processor is X86/X64. -struct CpuUtil { +struct X86CpuUtil { //! Get the result of calling CPUID instruction to `out`. - ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, CpuId* out); + ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out); //! Detect the Host CPU. - ASMJIT_API static void detect(CpuInfo* cpuInfo); + ASMJIT_API static void detect(X86CpuInfo* cpuInfo); }; #endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 // ============================================================================ -// [asmjit::x86x64::CpuInfo] +// [asmjit::X86CpuInfo] // ============================================================================ -struct CpuInfo : public BaseCpuInfo { - ASMJIT_NO_COPY(CpuInfo) +struct X86CpuInfo : public CpuInfo { + ASMJIT_NO_COPY(X86CpuInfo) // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : - BaseCpuInfo(size) {} + ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) : + CpuInfo(size) {} // -------------------------------------------------------------------------- // [Accessors] @@ -201,10 +200,12 @@ struct CpuInfo : public BaseCpuInfo { // [Statics] // -------------------------------------------------------------------------- - //! Get global instance of `x86x64::CpuInfo`. - static ASMJIT_INLINE const CpuInfo* getHost() { - return static_cast(BaseCpuInfo::getHost()); +#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] @@ -222,7 +223,6 @@ struct CpuInfo : public BaseCpuInfo { //! \} -} // x86x64 namespace } // asmjit namespace // [Api-End] diff --git a/src/asmjit/x86/x86func.cpp b/src/asmjit/x86/x86func.cpp deleted file mode 100644 index 18421cc..0000000 --- a/src/asmjit/x86/x86func.cpp +++ /dev/null @@ -1,547 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Export] -#define ASMJIT_EXPORTS - -// [Guard] -#include "../build.h" -#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) - -// [Dependencies - AsmJit] -#include "../base/globals.h" -#include "../base/intutil.h" -#include "../base/string.h" -#include "../x86/x86func.h" -#include "../x86/x86operand.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -namespace x86x64 { - -// ============================================================================ -// [asmjit::X86X64FuncDecl - Helpers] -// ============================================================================ - -static ASMJIT_INLINE bool x86ArgIsInt(uint32_t aType) { - ASMJIT_ASSERT(aType < kVarTypeCount); - return IntUtil::inInterval(aType, _kVarTypeIntStart, _kVarTypeIntEnd); -} - -static ASMJIT_INLINE bool x86ArgIsFp(uint32_t aType) { - ASMJIT_ASSERT(aType < kVarTypeCount); - return IntUtil::inInterval(aType, _kVarTypeFpStart, _kVarTypeFpEnd); -} - -static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) { - if (aType == kVarTypeFp32) - return kVarTypeXmmSs; - if (aType == kVarTypeFp64) - return kVarTypeXmmSd; - return aType; -} - -//! Get an architecture from calling convention. -//! -//! Returns `kArchX86` or `kArchX64` depending on `conv`. -static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) { - return IntUtil::inInterval(conv, kFuncConvX64W, kFuncConvX64U) ? kArchX64 : kArchX86; -} - -// ============================================================================ -// [asmjit::X86X64FuncDecl - SetPrototype] -// ============================================================================ - -#define R(_Index_) kRegIndex##_Index_ -static uint32_t X86X64FuncDecl_initConv(X86X64FuncDecl* self, uint32_t arch, uint32_t conv) { - // Setup defaults. - self->_argStackSize = 0; - self->_redZoneSize = 0; - self->_spillZoneSize = 0; - - self->_convention = static_cast(conv); - self->_calleePopsStack = false; - self->_direction = kFuncDirRtl; - - self->_passed.reset(); - self->_preserved.reset(); - - ::memset(self->_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderGp)); - ::memset(self->_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)); - - // -------------------------------------------------------------------------- - // [X86 Support] - // -------------------------------------------------------------------------- - -#if defined(ASMJIT_BUILD_X86) - if (arch == kArchX86) { - self->_preserved.set(kRegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di))); - - switch (conv) { - case kFuncConvCDecl: - break; - - case kFuncConvStdCall: - self->_calleePopsStack = true; - break; - - case kFuncConvMsThisCall: - self->_calleePopsStack = true; - self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx))); - self->_passedOrderGp[0] = R(Cx); - break; - - case kFuncConvMsFastCall: - self->_calleePopsStack = true; - self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx), R(Cx))); - self->_passedOrderGp[0] = R(Cx); - self->_passedOrderGp[1] = R(Dx); - break; - - case kFuncConvBorlandFastCall: - self->_calleePopsStack = true; - self->_direction = kFuncDirLtr; - self->_passed.set(kRegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); - self->_passedOrderGp[0] = R(Ax); - self->_passedOrderGp[1] = R(Dx); - self->_passedOrderGp[2] = R(Cx); - break; - - case kFuncConvGccFastCall: - self->_calleePopsStack = true; - self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx), R(Dx))); - self->_passedOrderGp[0] = R(Cx); - self->_passedOrderGp[1] = R(Dx); - break; - - case kFuncConvGccRegParm1: - self->_passed.set(kRegClassGp, IntUtil::mask(R(Ax))); - self->_passedOrderGp[0] = R(Ax); - break; - - case kFuncConvGccRegParm2: - self->_passed.set(kRegClassGp, IntUtil::mask(R(Ax), R(Dx))); - self->_passedOrderGp[0] = R(Ax); - self->_passedOrderGp[1] = R(Dx); - break; - - case kFuncConvGccRegParm3: - self->_passed.set(kRegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); - self->_passedOrderGp[0] = R(Ax); - self->_passedOrderGp[1] = R(Dx); - self->_passedOrderGp[2] = R(Cx); - break; - - default: - ASMJIT_ASSERT(!"Reached"); - } - - return kErrorOk; - } -#endif // ASMJIT_BUILD_X86 - - // -------------------------------------------------------------------------- - // [X64 Support] - // -------------------------------------------------------------------------- - -#if defined(ASMJIT_BUILD_X64) - switch (conv) { - case kFuncConvX64W: - self->_spillZoneSize = 32; - - self->_passed.set(kRegClassGp, IntUtil::mask(R(Cx), R(Dx), 8, 9)); - self->_passedOrderGp[0] = R(Cx); - self->_passedOrderGp[1] = R(Dx); - self->_passedOrderGp[2] = 8; - self->_passedOrderGp[3] = 9; - - self->_passed.set(kRegClassXyz, IntUtil::mask(0, 1, 2, 3)); - self->_passedOrderXmm[0] = 0; - self->_passedOrderXmm[1] = 1; - self->_passedOrderXmm[2] = 2; - self->_passedOrderXmm[3] = 3; - - self->_preserved.set(kRegClassGp , IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), 12, 13, 14, 15)); - self->_preserved.set(kRegClassXyz, IntUtil::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); - break; - - case kFuncConvX64U: - self->_redZoneSize = 128; - - self->_passed.set(kRegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), 8, 9)); - self->_passedOrderGp[0] = R(Di); - self->_passedOrderGp[1] = R(Si); - self->_passedOrderGp[2] = R(Dx); - self->_passedOrderGp[3] = R(Cx); - self->_passedOrderGp[4] = 8; - self->_passedOrderGp[5] = 9; - - self->_passed.set(kRegClassXyz, IntUtil::mask(0, 1, 2, 3, 4, 5, 6, 7)); - self->_passedOrderXmm[0] = 0; - self->_passedOrderXmm[1] = 1; - self->_passedOrderXmm[2] = 2; - self->_passedOrderXmm[3] = 3; - self->_passedOrderXmm[4] = 4; - self->_passedOrderXmm[5] = 5; - self->_passedOrderXmm[6] = 6; - self->_passedOrderXmm[7] = 7; - - self->_preserved.set(kRegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), 12, 13, 14, 15)); - break; - - default: - ASMJIT_ASSERT(!"Reached"); - } -#endif // ASMJIT_BUILD_X64 - - return kErrorOk; -} -#undef R - -static Error X86X64FuncDecl_initFunc(X86X64FuncDecl* self, uint32_t arch, - uint32_t ret, const uint32_t* argList, uint32_t argCount) { - - ASMJIT_ASSERT(argCount <= kFuncArgCount); - - uint32_t conv = self->_convention; - uint32_t regSize = (arch == kArchX86) ? 4 : 8; - - int32_t i = 0; - int32_t gpPos = 0; - int32_t xmmPos = 0; - int32_t stackOffset = 0; - - const uint8_t* varMapping; - -#if defined(ASMJIT_BUILD_X86) - if (arch == kArchX86) - varMapping = x86::_varMapping; -#endif // ASMJIT_BUILD_X86 - -#if defined(ASMJIT_BUILD_X64) - if (arch == kArchX64) - varMapping = x64::_varMapping; -#endif // ASMJIT_BUILD_X64 - - self->_argCount = static_cast(argCount); - self->_retCount = 0; - - for (i = 0; i < static_cast(argCount); i++) { - FuncInOut& arg = self->getArg(i); - arg._varType = static_cast(argList[i]); - arg._regIndex = kInvalidReg; - arg._stackOffset = kFuncStackInvalid; - } - - for (; i < kFuncArgCount; i++) { - self->_argList[i].reset(); - } - - self->_retList[0].reset(); - self->_retList[1].reset(); - self->_argStackSize = 0; - self->_used.reset(); - - if (ret != kVarTypeInvalid) { - ret = varMapping[ret]; - switch (ret) { - case kVarTypeInt64: - case kVarTypeUInt64: - // 64-bit value is returned in EDX:EAX on x86. -#if defined(ASMJIT_BUILD_X86) - if (arch == kArchX86) { - self->_retCount = 2; - self->_retList[0]._varType = kVarTypeUInt32; - self->_retList[0]._regIndex = kRegIndexAx; - self->_retList[1]._varType = static_cast(ret - 2); - self->_retList[1]._regIndex = kRegIndexDx; - } -#endif // ASMJIT_BUILD_X86 - // ... Fall through ... - - case kVarTypeInt8: - case kVarTypeUInt8: - case kVarTypeInt16: - case kVarTypeUInt16: - case kVarTypeInt32: - case kVarTypeUInt32: - self->_retCount = 1; - self->_retList[0]._varType = static_cast(ret); - self->_retList[0]._regIndex = kRegIndexAx; - break; - - case kVarTypeMm: - self->_retCount = 1; - self->_retList[0]._varType = static_cast(ret); - self->_retList[0]._regIndex = 0; - break; - - case kVarTypeFp32: - self->_retCount = 1; - if (arch == kArchX86) { - self->_retList[0]._varType = kVarTypeFp32; - self->_retList[0]._regIndex = 0; - } - else { - self->_retList[0]._varType = kVarTypeXmmSs; - self->_retList[0]._regIndex = 0; - } - break; - - case kVarTypeFp64: - self->_retCount = 1; - if (arch == kArchX86) { - self->_retList[0]._varType = kVarTypeFp64; - self->_retList[0]._regIndex = 0; - } - else { - self->_retList[0]._varType = kVarTypeXmmSd; - self->_retList[0]._regIndex = 0; - break; - } - break; - - case kVarTypeXmm: - case kVarTypeXmmSs: - case kVarTypeXmmSd: - case kVarTypeXmmPs: - case kVarTypeXmmPd: - self->_retCount = 1; - self->_retList[0]._varType = static_cast(ret); - self->_retList[0]._regIndex = 0; - break; - } - } - - if (self->_argCount == 0) - return kErrorOk; - -#if defined(ASMJIT_BUILD_X86) - if (arch == kArchX86) { - // Register arguments (Integer), always left-to-right. - for (i = 0; i != static_cast(argCount); i++) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) - continue; - - if (self->_passedOrderGp[gpPos] == kInvalidReg) - continue; - - arg._regIndex = self->_passedOrderGp[gpPos++]; - self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); - } - - // Stack arguments. - int32_t iStart = static_cast(argCount - 1); - int32_t iEnd = -1; - int32_t iStep = -1; - - if (self->_direction == kFuncDirLtr) { - iStart = 0; - iEnd = static_cast(argCount); - iStep = 1; - } - - for (i = iStart; i != iEnd; i += iStep) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (arg.hasRegIndex()) - continue; - - if (x86ArgIsInt(varType)) { - stackOffset -= 4; - arg._stackOffset = static_cast(stackOffset); - } - else if (x86ArgIsFp(varType)) { - int32_t size = static_cast(_varInfo[varType].getSize()); - stackOffset -= size; - arg._stackOffset = static_cast(stackOffset); - } - } - } -#endif // ASMJIT_BUILD_X86 - -#if defined(ASMJIT_BUILD_X64) - if (arch == kArchX64) { - if (conv == kFuncConvX64W) { - int32_t argMax = IntUtil::iMin(argCount, 4); - - // Register arguments (Gp/Xmm), always left-to-right. - for (i = 0; i != argMax; i++) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) { - arg._regIndex = self->_passedOrderGp[i]; - self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); - continue; - } - - if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { - arg._varType = static_cast(x86ArgTypeToXmmType(varType)); - arg._regIndex = self->_passedOrderXmm[i]; - self->_used.add(kRegClassXyz, IntUtil::mask(arg.getRegIndex())); - } - } - - // Stack arguments (always right-to-left). - for (i = argCount - 1; i != -1; i--) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (arg.hasRegIndex()) - continue; - - if (x86ArgIsInt(varType)) { - stackOffset -= 8; // Always 8 bytes. - arg._stackOffset = stackOffset; - } - else if (x86ArgIsFp(varType)) { - stackOffset -= 8; // Always 8 bytes (float/double). - arg._stackOffset = stackOffset; - } - } - - // 32 bytes shadow space (X64W calling convention specific). - stackOffset -= 4 * 8; - } - else { - // Register arguments (Gp), always left-to-right. - for (i = 0; i != static_cast(argCount); i++) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) - continue; - - if (self->_passedOrderGp[gpPos] == kInvalidReg) - continue; - - arg._regIndex = self->_passedOrderGp[gpPos++]; - self->_used.add(kRegClassGp, IntUtil::mask(arg.getRegIndex())); - } - - // Register arguments (Xmm), always left-to-right. - for (i = 0; i != static_cast(argCount); i++) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (x86ArgIsFp(varType)) { - arg._varType = static_cast(x86ArgTypeToXmmType(varType)); - arg._regIndex = self->_passedOrderXmm[xmmPos++]; - self->_used.add(kRegClassXyz, IntUtil::mask(arg.getRegIndex())); - } - } - - // Stack arguments. - for (i = argCount - 1; i != -1; i--) { - FuncInOut& arg = self->getArg(i); - uint32_t varType = varMapping[arg.getVarType()]; - - if (arg.hasRegIndex()) - continue; - - if (x86ArgIsInt(varType)) { - stackOffset -= 8; - arg._stackOffset = static_cast(stackOffset); - } - else if (x86ArgIsFp(varType)) { - int32_t size = static_cast(_varInfo[varType].getSize()); - - stackOffset -= size; - arg._stackOffset = static_cast(stackOffset); - } - } - } - } -#endif // ASMJIT_BUILD_X64 - - // Modify the stack offset, thus in result all parameters would have positive - // non-zero stack offset. - for (i = 0; i < static_cast(argCount); i++) { - FuncInOut& arg = self->getArg(i); - if (!arg.hasRegIndex()) { - arg._stackOffset += static_cast(static_cast(regSize) - stackOffset); - } - } - - self->_argStackSize = static_cast(-stackOffset); - return kErrorOk; -} - -Error X86X64FuncDecl::setPrototype(uint32_t conv, const FuncPrototype& p) { - if (conv == kFuncConvNone || conv >= _kFuncConvCount) - return kErrorInvalidArgument; - - if (p.getArgCount() > kFuncArgCount) - return kErrorInvalidArgument; - - // Validate that the required convention is supported by the current asmjit - // configuration, if only one target is compiled. - uint32_t arch = x86GetArchFromCConv(conv); -#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) - if (arch == kArchX64) - return kErrorInvalidState; -#endif // ASMJIT_BUILD_X86 && !ASMJIT_BUILD_X64 - -#if !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) - if (arch == kArchX86) - return kErrorInvalidState; -#endif // !ASMJIT_BUILD_X86 && ASMJIT_BUILD_X64 - - ASMJIT_PROPAGATE_ERROR(X86X64FuncDecl_initConv(this, arch, conv)); - ASMJIT_PROPAGATE_ERROR(X86X64FuncDecl_initFunc(this, arch, p.getRet(), p.getArgList(), p.getArgCount())); - - return kErrorOk; -} - -// ============================================================================ -// [asmjit::X86X64FuncDecl - Reset] -// ============================================================================ - -void X86X64FuncDecl::reset() { - uint32_t i; - - _convention = kFuncConvNone; - _calleePopsStack = false; - _direction = kFuncDirRtl; - _reserved0 = 0; - - _argCount = 0; - _retCount = 0; - - _argStackSize = 0; - _redZoneSize = 0; - _spillZoneSize = 0; - - for (i = 0; i < ASMJIT_ARRAY_SIZE(_argList); i++) { - _argList[i].reset(); - } - - _retList[0].reset(); - _retList[1].reset(); - - _used.reset(); - _passed.reset(); - _preserved.reset(); - - ::memset(_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderGp)); - ::memset(_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderXmm)); -} - -} // x86x64 namespace -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) diff --git a/src/asmjit/x86/x86func.h b/src/asmjit/x86/x86func.h deleted file mode 100644 index bfc7919..0000000 --- a/src/asmjit/x86/x86func.h +++ /dev/null @@ -1,492 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_X86_X86FUNC_H -#define _ASMJIT_X86_X86FUNC_H - -#include "../build.h" -#if !defined(ASMJIT_DISABLE_COMPILER) - -// [Dependencies - AsmJit] -#include "../base/func.h" -#include "../x86/x86util.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -namespace x86x64 { - -//! \addtogroup asmjit_x86x64_tree -//! \{ - -// ============================================================================ -// [asmjit::x86x64::kFuncConv] -// ============================================================================ - -//! 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: -//! - `kFuncConvCDecl` - Calling convention for C runtime. -//! - `kFuncConvStdCall` - Calling convention for WinAPI functions. -//! - `kFuncConvMsThisCall` - Calling convention for C++ members under -//! Windows (produced by MSVC and all MSVC compatible compilers). -//! - `kFuncConvMsFastCall` - Fastest calling convention that can be used -//! by MSVC compiler. -//! - `kFuncConvBorlandFastCall` - Borland fastcall convention. -//! - `kFuncConvGccFastCall` - GCC fastcall convention (2 register arguments). -//! - `kFuncConvGccRegParm1` - GCC regparm(1) convention. -//! - `kFuncConvGccRegParm2` - GCC regparm(2) convention. -//! - `kFuncConvGccRegParm3` - GCC regparm(3) convention. -//! -//! List of calling conventions for 64-bit x86 mode (x64): -//! - `kFuncConvX64W` - Windows 64-bit calling convention (WIN64 ABI). -//! - `kFuncConvX64U` - 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 `BaseCompiler::addFunc()` method. -ASMJIT_ENUM(kFuncConv) { - // -------------------------------------------------------------------------- - // [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 . - kFuncConvX64W = 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. - kFuncConvX64U = 2, - - // -------------------------------------------------------------------------- - // [X86] - // -------------------------------------------------------------------------- - - //! Cdecl calling convention (used by C runtime). - //! - //! Compatible across MSVC and GCC. - //! - //! Arguments direction: - //! - Right to Left - //! - //! Stack is cleaned by: - //! - Caller. - kFuncConvCDecl = 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. - kFuncConvStdCall = 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. - kFuncConvMsThisCall = 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. - kFuncConvMsFastCall = 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. - kFuncConvBorlandFastCall = 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 `kFuncConvMsFastCall`. - kFuncConvGccFastCall = 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. - kFuncConvGccRegParm1 = 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. - kFuncConvGccRegParm2 = 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. - kFuncConvGccRegParm3 = 11, - - //! \internal - //! - //! Count of function calling conventions. - _kFuncConvCount = 12, - - // -------------------------------------------------------------------------- - // [Host] - // -------------------------------------------------------------------------- - -#if defined(ASMJIT_DOCGEN) - //! Default calling convention for current platform / operating system. - kFuncConvHost = DependsOnHost, - - //! Default C calling convention based on current compiler's settings. - kFuncConvHostCDecl = DependsOnHost, - - //! Compatibility for `__stdcall` calling convention. - //! - //! \note This enumeration is always set to a value which is compatible with - //! current compilers __stdcall calling convention. In 64-bit mode the value - //! is compatible with `kFuncConvX64W` or `kFuncConvX64U`. - kFuncConvHostStdCall = DependsOnHost, - - //! Compatibility for `__fastcall` calling convention. - //! - //! \note This enumeration is always set to a value which is compatible with - //! current compilers `__fastcall` calling convention. In 64-bit mode the value - //! is compatible with `kFuncConvX64W` or `kFuncConvX64U`. - kFuncConvHostFastCall = DependsOnHost -#elif defined(ASMJIT_HOST_X86) - // X86. - kFuncConvHost = kFuncConvCDecl, - kFuncConvHostCDecl = kFuncConvCDecl, - kFuncConvHostStdCall = kFuncConvStdCall, -#if defined(_MSC_VER) - kFuncConvHostFastCall = kFuncConvMsFastCall -#elif defined(__GNUC__) - kFuncConvHostFastCall = kFuncConvGccFastCall -#elif defined(__BORLANDC__) - kFuncConvHostFastCall = kFuncConvBorlandFastCall -#else -#error "kFuncConvHostFastCall not determined." -#endif -#else - // X64. -#if defined(ASMJIT_OS_WINDOWS) - kFuncConvHost = kFuncConvX64W, -#else - kFuncConvHost = kFuncConvX64U, -#endif - kFuncConvHostCDecl = kFuncConvHost, - kFuncConvHostStdCall = kFuncConvHost, - kFuncConvHostFastCall = kFuncConvHost -#endif -}; - -// ============================================================================ -// [asmjit::x86x64::kFuncHint] -// ============================================================================ - -//! X86 function hints. -ASMJIT_ENUM(kFuncHint) { - //! Use push/pop sequences instead of mov sequences in function prolog - //! and epilog. - kFuncHintPushPop = 16, - //! Add emms instruction to the function epilog. - kFuncHintEmms = 17, - //! Add sfence instruction to the function epilog. - kFuncHintSFence = 18, - //! Add lfence instruction to the function epilog. - kFuncHintLFence = 19 -}; - -// ============================================================================ -// [asmjit::x86x64::kFuncFlags] -// ============================================================================ - -//! X86 function flags. -ASMJIT_ENUM(kFuncFlags) { - //! Whether to emit register load/save sequence using push/pop pairs. - kFuncFlagPushPop = 0x00010000, - - //! Whether to emit `enter` instead of three instructions in case - //! that the function is not naked or misaligned. - kFuncFlagEnter = 0x00020000, - - //! Whether to emit `leave` instead of two instructions in case - //! that the function is not naked or misaligned. - kFuncFlagLeave = 0x00040000, - - //! Whether it's required to move arguments to a new stack location, - //! because of manual aligning. - kFuncFlagMoveArgs = 0x00080000, - - //! Whether to emit `emms` instruction in epilog (auto-detected). - kFuncFlagEmms = 0x01000000, - - //! Whether to emit `sfence` instruction in epilog (auto-detected). - //! - //! `kFuncFlagSFence` with `kFuncFlagLFence` results in emitting `mfence`. - kFuncFlagSFence = 0x02000000, - - //! Whether to emit `lfence` instruction in epilog (auto-detected). - //! - //! `kFuncFlagSFence` with `kFuncFlagLFence` results in emitting `mfence`. - kFuncFlagLFence = 0x04000000 -}; - -// ============================================================================ -// [asmjit::x86x64::X86X64FuncDecl] -// ============================================================================ - -//! X86 function, including calling convention, arguments and their -//! register indices or stack positions. -struct X86X64FuncDecl : public FuncDecl { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new `X86X64FuncDecl` instance. - ASMJIT_INLINE X86X64FuncDecl() { - 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. - RegMask _used; - - //! Passed registers (defined by the calling convention). - RegMask _passed; - //! Preserved registers (defined by the calling convention). - RegMask _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]; -}; - -//! \} - -} // x86x64 namespace -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // !ASMJIT_DISABLE_COMPILER -#endif // _ASMJIT_X86_X86FUNC_H diff --git a/src/asmjit/x86/x86inst.cpp b/src/asmjit/x86/x86inst.cpp index 01aa912..39beacc 100644 --- a/src/asmjit/x86/x86inst.cpp +++ b/src/asmjit/x86/x86inst.cpp @@ -18,17 +18,67 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ -// [asmjit::x86x64::Inst] +// [Macros] // ============================================================================ -#if !defined(ASMJIT_DISABLE_INST_NAMES) -// Autogenerated by src-gendefs.js: -// -// ${kInstData:Begin} -const char _instName[] = +#if !defined(ASMJIT_DISABLE_NAMES) +# define INST_NAME_INDEX(_Code_) _Code_##_NameIndex +#else +# define INST_NAME_INDEX(_Code_) 0 +#endif + +#define G(_Group_) kX86InstGroup##_Group_ +#define F(_Flags_) kX86InstFlag##_Flags_ +#define O(_Op_) kX86InstOp##_Op_ +#define E(_Flags_) 0 + +#define U 0 +#define L kX86InstOpCode_L_True + +#define O_000000(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F00(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F01(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F01 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F0F(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F38(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F3A(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660000(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F00(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F38(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F3A(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_9B0000(_OpCode_, _R_) (kX86InstOpCode_PP_9B | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20000(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F00(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F38(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30000(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F00(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F38(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_00_M03(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_00_M08(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_00_M09(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_66_M03(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_66_M08(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_66_M09(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_00_X(_OpCode_, _R_) (kX86InstOpCode_PP_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_9B_X(_OpCode_, _R_) (kX86InstOpCode_PP_9B | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define INST(_Code_, _Name_, _Group_, _Flags_, _MoveSize_, _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_, _EFlags_, _OpCode0_, _OpCode1_) \ + { INST_NAME_INDEX(_Code_), _Code_##_ExtendedIndex, _OpCode0_ } + +// ============================================================================ +// [asmjit::X86Inst] +// ============================================================================ + +// ${X86InstData:Begin} +// Automatically generated, do not edit. +#if !defined(ASMJIT_DISABLE_NAMES) +const char _x86InstName[] = "\0" "adc\0" "add\0" @@ -107,6 +157,10 @@ const char _instName[] = "cmp\0" "cmppd\0" "cmpps\0" + "cmps_b\0" + "cmps_d\0" + "cmps_q\0" + "cmps_w\0" "cmpsd\0" "cmpss\0" "cmpxchg\0" @@ -297,6 +351,10 @@ const char _instName[] = "lea\0" "leave\0" "lfence\0" + "lods_b\0" + "lods_d\0" + "lods_q\0" + "lods_w\0" "lzcnt\0" "maskmovdqu\0" "maskmovq\0" @@ -336,6 +394,10 @@ const char _instName[] = "movntq\0" "movq\0" "movq2dq\0" + "movs_b\0" + "movs_d\0" + "movs_q\0" + "movs_w\0" "movsd\0" "movshdup\0" "movsldup\0" @@ -525,34 +587,34 @@ const char _instName[] = "rdrand\0" "rdtsc\0" "rdtscp\0" - "rep lodsb\0" - "rep lodsd\0" - "rep lodsq\0" - "rep lodsw\0" - "rep movsb\0" - "rep movsd\0" - "rep movsq\0" - "rep movsw\0" - "rep stosb\0" - "rep stosd\0" - "rep stosq\0" - "rep stosw\0" - "repe cmpsb\0" - "repe cmpsd\0" - "repe cmpsq\0" - "repe cmpsw\0" - "repe scasb\0" - "repe scasd\0" - "repe scasq\0" - "repe scasw\0" - "repne cmpsb\0" - "repne cmpsd\0" - "repne cmpsq\0" - "repne cmpsw\0" - "repne scasb\0" - "repne scasd\0" - "repne scasq\0" - "repne scasw\0" + "rep lods_b\0" + "rep lods_d\0" + "rep lods_q\0" + "rep lods_w\0" + "rep movs_b\0" + "rep movs_d\0" + "rep movs_q\0" + "rep movs_w\0" + "rep stos_b\0" + "rep stos_d\0" + "rep stos_q\0" + "rep stos_w\0" + "repe cmps_b\0" + "repe cmps_d\0" + "repe cmps_q\0" + "repe cmps_w\0" + "repe scas_b\0" + "repe scas_d\0" + "repe scas_q\0" + "repe scas_w\0" + "repne cmps_b\0" + "repne cmps_d\0" + "repne cmps_q\0" + "repne cmps_w\0" + "repne scas_b\0" + "repne scas_d\0" + "repne scas_q\0" + "repne scas_w\0" "ret\0" "rol\0" "ror\0" @@ -568,6 +630,10 @@ const char _instName[] = "sar\0" "sarx\0" "sbb\0" + "scas_b\0" + "scas_d\0" + "scas_q\0" + "scas_w\0" "seta\0" "setae\0" "setb\0" @@ -614,6 +680,10 @@ const char _instName[] = "stc\0" "std\0" "stmxcsr\0" + "stos_b\0" + "stos_d\0" + "stos_q\0" + "stos_w\0" "sub\0" "subpd\0" "subps\0" @@ -1060,2157 +1130,3505 @@ const char _instName[] = "xorpd\0" "xorps\0"; -enum kInstAlphaIndex { - kInstAlphaIndexFirst = 'a', - kInstAlphaIndexLast = 'z', - kInstAlphaIndexInvalid = 0xFFFF +// Automatically generated, do not edit. +enum kX86InstAlphaIndex { + kX86InstAlphaIndexFirst = 'a', + kX86InstAlphaIndexLast = 'z', + kX86InstAlphaIndexInvalid = 0xFFFF }; -static const uint16_t _instAlphaIndex[26] = { - kInstAdc, - kInstBextr, - kInstCall, - kInstDaa, - kInstEmms, - kInstF2xm1, +// Automatically generated, do not edit. +static const uint16_t _x86InstAlphaIndex[26] = { + kX86InstIdAdc, + kX86InstIdBextr, + kX86InstIdCall, + kX86InstIdDaa, + kX86InstIdEmms, + kX86InstIdF2xm1, 0xFFFF, - kInstHaddpd, - kInstIdiv, - kInstJa, + kX86InstIdHaddpd, + kX86InstIdIdiv, + kX86InstIdJa, 0xFFFF, - kInstLahf, - kInstMaskmovdqu, - kInstNeg, - kInstOr, - kInstPabsb, + kX86InstIdLahf, + kX86InstIdMaskmovdqu, + kX86InstIdNeg, + kX86InstIdOr, + kX86InstIdPabsb, 0xFFFF, - kInstRcl, - kInstSahf, - kInstTest, - kInstUcomisd, - kInstVaddpd, - kInstWrfsbase, - kInstXadd, + kX86InstIdRcl, + kX86InstIdSahf, + kX86InstIdTest, + kX86InstIdUcomisd, + kX86InstIdVaddpd, + kX86InstIdWrfsbase, + kX86InstIdXadd, 0xFFFF, 0xFFFF }; -enum kInstData_NameIndex { - kInstNone_NameIndex = 0, - kInstAdc_NameIndex = 1, - kInstAdd_NameIndex = 5, - kInstAddpd_NameIndex = 9, - kInstAddps_NameIndex = 15, - kInstAddsd_NameIndex = 21, - kInstAddss_NameIndex = 27, - kInstAddsubpd_NameIndex = 33, - kInstAddsubps_NameIndex = 42, - kInstAesdec_NameIndex = 51, - kInstAesdeclast_NameIndex = 58, - kInstAesenc_NameIndex = 69, - kInstAesenclast_NameIndex = 76, - kInstAesimc_NameIndex = 87, - kInstAeskeygenassist_NameIndex = 94, - kInstAnd_NameIndex = 110, - kInstAndn_NameIndex = 114, - kInstAndnpd_NameIndex = 119, - kInstAndnps_NameIndex = 126, - kInstAndpd_NameIndex = 133, - kInstAndps_NameIndex = 139, - kInstBextr_NameIndex = 145, - kInstBlendpd_NameIndex = 151, - kInstBlendps_NameIndex = 159, - kInstBlendvpd_NameIndex = 167, - kInstBlendvps_NameIndex = 176, - kInstBlsi_NameIndex = 185, - kInstBlsmsk_NameIndex = 190, - kInstBlsr_NameIndex = 197, - kInstBsf_NameIndex = 202, - kInstBsr_NameIndex = 206, - kInstBswap_NameIndex = 210, - kInstBt_NameIndex = 216, - kInstBtc_NameIndex = 219, - kInstBtr_NameIndex = 223, - kInstBts_NameIndex = 227, - kInstBzhi_NameIndex = 231, - kInstCall_NameIndex = 236, - kInstCbw_NameIndex = 241, - kInstCdq_NameIndex = 245, - kInstCdqe_NameIndex = 249, - kInstClc_NameIndex = 254, - kInstCld_NameIndex = 258, - kInstClflush_NameIndex = 262, - kInstCmc_NameIndex = 270, - kInstCmova_NameIndex = 274, - kInstCmovae_NameIndex = 280, - kInstCmovb_NameIndex = 287, - kInstCmovbe_NameIndex = 293, - kInstCmovc_NameIndex = 300, - kInstCmove_NameIndex = 306, - kInstCmovg_NameIndex = 312, - kInstCmovge_NameIndex = 318, - kInstCmovl_NameIndex = 325, - kInstCmovle_NameIndex = 331, - kInstCmovna_NameIndex = 338, - kInstCmovnae_NameIndex = 345, - kInstCmovnb_NameIndex = 353, - kInstCmovnbe_NameIndex = 360, - kInstCmovnc_NameIndex = 368, - kInstCmovne_NameIndex = 375, - kInstCmovng_NameIndex = 382, - kInstCmovnge_NameIndex = 389, - kInstCmovnl_NameIndex = 397, - kInstCmovnle_NameIndex = 404, - kInstCmovno_NameIndex = 412, - kInstCmovnp_NameIndex = 419, - kInstCmovns_NameIndex = 426, - kInstCmovnz_NameIndex = 433, - kInstCmovo_NameIndex = 440, - kInstCmovp_NameIndex = 446, - kInstCmovpe_NameIndex = 452, - kInstCmovpo_NameIndex = 459, - kInstCmovs_NameIndex = 466, - kInstCmovz_NameIndex = 472, - kInstCmp_NameIndex = 478, - kInstCmppd_NameIndex = 482, - kInstCmpps_NameIndex = 488, - kInstCmpsd_NameIndex = 494, - kInstCmpss_NameIndex = 500, - kInstCmpxchg_NameIndex = 506, - kInstCmpxchg16b_NameIndex = 514, - kInstCmpxchg8b_NameIndex = 525, - kInstComisd_NameIndex = 535, - kInstComiss_NameIndex = 542, - kInstCpuid_NameIndex = 549, - kInstCqo_NameIndex = 555, - kInstCrc32_NameIndex = 559, - kInstCvtdq2pd_NameIndex = 565, - kInstCvtdq2ps_NameIndex = 574, - kInstCvtpd2dq_NameIndex = 583, - kInstCvtpd2pi_NameIndex = 592, - kInstCvtpd2ps_NameIndex = 601, - kInstCvtpi2pd_NameIndex = 610, - kInstCvtpi2ps_NameIndex = 619, - kInstCvtps2dq_NameIndex = 628, - kInstCvtps2pd_NameIndex = 637, - kInstCvtps2pi_NameIndex = 646, - kInstCvtsd2si_NameIndex = 655, - kInstCvtsd2ss_NameIndex = 664, - kInstCvtsi2sd_NameIndex = 673, - kInstCvtsi2ss_NameIndex = 682, - kInstCvtss2sd_NameIndex = 691, - kInstCvtss2si_NameIndex = 700, - kInstCvttpd2dq_NameIndex = 709, - kInstCvttpd2pi_NameIndex = 719, - kInstCvttps2dq_NameIndex = 729, - kInstCvttps2pi_NameIndex = 739, - kInstCvttsd2si_NameIndex = 749, - kInstCvttss2si_NameIndex = 759, - kInstCwd_NameIndex = 769, - kInstCwde_NameIndex = 773, - kInstDaa_NameIndex = 778, - kInstDas_NameIndex = 782, - kInstDec_NameIndex = 786, - kInstDiv_NameIndex = 790, - kInstDivpd_NameIndex = 794, - kInstDivps_NameIndex = 800, - kInstDivsd_NameIndex = 806, - kInstDivss_NameIndex = 812, - kInstDppd_NameIndex = 818, - kInstDpps_NameIndex = 823, - kInstEmms_NameIndex = 828, - kInstEnter_NameIndex = 833, - kInstExtractps_NameIndex = 839, - kInstF2xm1_NameIndex = 849, - kInstFabs_NameIndex = 855, - kInstFadd_NameIndex = 860, - kInstFaddp_NameIndex = 865, - kInstFbld_NameIndex = 871, - kInstFbstp_NameIndex = 876, - kInstFchs_NameIndex = 882, - kInstFclex_NameIndex = 887, - kInstFcmovb_NameIndex = 893, - kInstFcmovbe_NameIndex = 900, - kInstFcmove_NameIndex = 908, - kInstFcmovnb_NameIndex = 915, - kInstFcmovnbe_NameIndex = 923, - kInstFcmovne_NameIndex = 932, - kInstFcmovnu_NameIndex = 940, - kInstFcmovu_NameIndex = 948, - kInstFcom_NameIndex = 955, - kInstFcomi_NameIndex = 960, - kInstFcomip_NameIndex = 966, - kInstFcomp_NameIndex = 973, - kInstFcompp_NameIndex = 979, - kInstFcos_NameIndex = 986, - kInstFdecstp_NameIndex = 991, - kInstFdiv_NameIndex = 999, - kInstFdivp_NameIndex = 1004, - kInstFdivr_NameIndex = 1010, - kInstFdivrp_NameIndex = 1016, - kInstFemms_NameIndex = 1023, - kInstFfree_NameIndex = 1029, - kInstFiadd_NameIndex = 1035, - kInstFicom_NameIndex = 1041, - kInstFicomp_NameIndex = 1047, - kInstFidiv_NameIndex = 1054, - kInstFidivr_NameIndex = 1060, - kInstFild_NameIndex = 1067, - kInstFimul_NameIndex = 1072, - kInstFincstp_NameIndex = 1078, - kInstFinit_NameIndex = 1086, - kInstFist_NameIndex = 1092, - kInstFistp_NameIndex = 1097, - kInstFisttp_NameIndex = 1103, - kInstFisub_NameIndex = 1110, - kInstFisubr_NameIndex = 1116, - kInstFld_NameIndex = 1123, - kInstFld1_NameIndex = 1127, - kInstFldcw_NameIndex = 1132, - kInstFldenv_NameIndex = 1138, - kInstFldl2e_NameIndex = 1145, - kInstFldl2t_NameIndex = 1152, - kInstFldlg2_NameIndex = 1159, - kInstFldln2_NameIndex = 1166, - kInstFldpi_NameIndex = 1173, - kInstFldz_NameIndex = 1179, - kInstFmul_NameIndex = 1184, - kInstFmulp_NameIndex = 1189, - kInstFnclex_NameIndex = 1195, - kInstFninit_NameIndex = 1202, - kInstFnop_NameIndex = 1209, - kInstFnsave_NameIndex = 1214, - kInstFnstcw_NameIndex = 1221, - kInstFnstenv_NameIndex = 1228, - kInstFnstsw_NameIndex = 1236, - kInstFpatan_NameIndex = 1243, - kInstFprem_NameIndex = 1250, - kInstFprem1_NameIndex = 1256, - kInstFptan_NameIndex = 1263, - kInstFrndint_NameIndex = 1269, - kInstFrstor_NameIndex = 1277, - kInstFsave_NameIndex = 1284, - kInstFscale_NameIndex = 1290, - kInstFsin_NameIndex = 1297, - kInstFsincos_NameIndex = 1302, - kInstFsqrt_NameIndex = 1310, - kInstFst_NameIndex = 1316, - kInstFstcw_NameIndex = 1320, - kInstFstenv_NameIndex = 1326, - kInstFstp_NameIndex = 1333, - kInstFstsw_NameIndex = 1338, - kInstFsub_NameIndex = 1344, - kInstFsubp_NameIndex = 1349, - kInstFsubr_NameIndex = 1355, - kInstFsubrp_NameIndex = 1361, - kInstFtst_NameIndex = 1368, - kInstFucom_NameIndex = 1373, - kInstFucomi_NameIndex = 1379, - kInstFucomip_NameIndex = 1386, - kInstFucomp_NameIndex = 1394, - kInstFucompp_NameIndex = 1401, - kInstFwait_NameIndex = 1409, - kInstFxam_NameIndex = 1415, - kInstFxch_NameIndex = 1420, - kInstFxrstor_NameIndex = 1425, - kInstFxsave_NameIndex = 1433, - kInstFxtract_NameIndex = 1440, - kInstFyl2x_NameIndex = 1448, - kInstFyl2xp1_NameIndex = 1454, - kInstHaddpd_NameIndex = 1462, - kInstHaddps_NameIndex = 1469, - kInstHsubpd_NameIndex = 1476, - kInstHsubps_NameIndex = 1483, - kInstIdiv_NameIndex = 1490, - kInstImul_NameIndex = 1495, - kInstInc_NameIndex = 1500, - kInstInsertps_NameIndex = 1504, - kInstInt_NameIndex = 1513, - kInstJa_NameIndex = 1517, - kInstJae_NameIndex = 1520, - kInstJb_NameIndex = 1524, - kInstJbe_NameIndex = 1527, - kInstJc_NameIndex = 1531, - kInstJe_NameIndex = 1534, - kInstJg_NameIndex = 1537, - kInstJge_NameIndex = 1540, - kInstJl_NameIndex = 1544, - kInstJle_NameIndex = 1547, - kInstJna_NameIndex = 1551, - kInstJnae_NameIndex = 1555, - kInstJnb_NameIndex = 1560, - kInstJnbe_NameIndex = 1564, - kInstJnc_NameIndex = 1569, - kInstJne_NameIndex = 1573, - kInstJng_NameIndex = 1577, - kInstJnge_NameIndex = 1581, - kInstJnl_NameIndex = 1586, - kInstJnle_NameIndex = 1590, - kInstJno_NameIndex = 1595, - kInstJnp_NameIndex = 1599, - kInstJns_NameIndex = 1603, - kInstJnz_NameIndex = 1607, - kInstJo_NameIndex = 1611, - kInstJp_NameIndex = 1614, - kInstJpe_NameIndex = 1617, - kInstJpo_NameIndex = 1621, - kInstJs_NameIndex = 1625, - kInstJz_NameIndex = 1628, - kInstJecxz_NameIndex = 1631, - kInstJmp_NameIndex = 1637, - kInstLahf_NameIndex = 1641, - kInstLddqu_NameIndex = 1646, - kInstLdmxcsr_NameIndex = 1652, - kInstLea_NameIndex = 1660, - kInstLeave_NameIndex = 1664, - kInstLfence_NameIndex = 1670, - kInstLzcnt_NameIndex = 1677, - kInstMaskmovdqu_NameIndex = 1683, - kInstMaskmovq_NameIndex = 1694, - kInstMaxpd_NameIndex = 1703, - kInstMaxps_NameIndex = 1709, - kInstMaxsd_NameIndex = 1715, - kInstMaxss_NameIndex = 1721, - kInstMfence_NameIndex = 1727, - kInstMinpd_NameIndex = 1734, - kInstMinps_NameIndex = 1740, - kInstMinsd_NameIndex = 1746, - kInstMinss_NameIndex = 1752, - kInstMonitor_NameIndex = 1758, - kInstMov_NameIndex = 1766, - kInstMovPtr_NameIndex = 1770, - kInstMovapd_NameIndex = 1778, - kInstMovaps_NameIndex = 1785, - kInstMovbe_NameIndex = 1792, - kInstMovd_NameIndex = 1798, - kInstMovddup_NameIndex = 1803, - kInstMovdq2q_NameIndex = 1811, - kInstMovdqa_NameIndex = 1819, - kInstMovdqu_NameIndex = 1826, - kInstMovhlps_NameIndex = 1833, - kInstMovhpd_NameIndex = 1841, - kInstMovhps_NameIndex = 1848, - kInstMovlhps_NameIndex = 1855, - kInstMovlpd_NameIndex = 1863, - kInstMovlps_NameIndex = 1870, - kInstMovmskpd_NameIndex = 1877, - kInstMovmskps_NameIndex = 1886, - kInstMovntdq_NameIndex = 1895, - kInstMovntdqa_NameIndex = 1903, - kInstMovnti_NameIndex = 1912, - kInstMovntpd_NameIndex = 1919, - kInstMovntps_NameIndex = 1927, - kInstMovntq_NameIndex = 1935, - kInstMovq_NameIndex = 1942, - kInstMovq2dq_NameIndex = 1947, - kInstMovsd_NameIndex = 1955, - kInstMovshdup_NameIndex = 1961, - kInstMovsldup_NameIndex = 1970, - kInstMovss_NameIndex = 1979, - kInstMovsx_NameIndex = 1985, - kInstMovsxd_NameIndex = 1991, - kInstMovupd_NameIndex = 1998, - kInstMovups_NameIndex = 2005, - kInstMovzx_NameIndex = 2012, - kInstMpsadbw_NameIndex = 2018, - kInstMul_NameIndex = 2026, - kInstMulpd_NameIndex = 2030, - kInstMulps_NameIndex = 2036, - kInstMulsd_NameIndex = 2042, - kInstMulss_NameIndex = 2048, - kInstMulx_NameIndex = 2054, - kInstMwait_NameIndex = 2059, - kInstNeg_NameIndex = 2065, - kInstNop_NameIndex = 2069, - kInstNot_NameIndex = 2073, - kInstOr_NameIndex = 2077, - kInstOrpd_NameIndex = 2080, - kInstOrps_NameIndex = 2085, - kInstPabsb_NameIndex = 2090, - kInstPabsd_NameIndex = 2096, - kInstPabsw_NameIndex = 2102, - kInstPackssdw_NameIndex = 2108, - kInstPacksswb_NameIndex = 2117, - kInstPackusdw_NameIndex = 2126, - kInstPackuswb_NameIndex = 2135, - kInstPaddb_NameIndex = 2144, - kInstPaddd_NameIndex = 2150, - kInstPaddq_NameIndex = 2156, - kInstPaddsb_NameIndex = 2162, - kInstPaddsw_NameIndex = 2169, - kInstPaddusb_NameIndex = 2176, - kInstPaddusw_NameIndex = 2184, - kInstPaddw_NameIndex = 2192, - kInstPalignr_NameIndex = 2198, - kInstPand_NameIndex = 2206, - kInstPandn_NameIndex = 2211, - kInstPause_NameIndex = 2217, - kInstPavgb_NameIndex = 2223, - kInstPavgw_NameIndex = 2229, - kInstPblendvb_NameIndex = 2235, - kInstPblendw_NameIndex = 2244, - kInstPclmulqdq_NameIndex = 2252, - kInstPcmpeqb_NameIndex = 2262, - kInstPcmpeqd_NameIndex = 2270, - kInstPcmpeqq_NameIndex = 2278, - kInstPcmpeqw_NameIndex = 2286, - kInstPcmpestri_NameIndex = 2294, - kInstPcmpestrm_NameIndex = 2304, - kInstPcmpgtb_NameIndex = 2314, - kInstPcmpgtd_NameIndex = 2322, - kInstPcmpgtq_NameIndex = 2330, - kInstPcmpgtw_NameIndex = 2338, - kInstPcmpistri_NameIndex = 2346, - kInstPcmpistrm_NameIndex = 2356, - kInstPdep_NameIndex = 2366, - kInstPext_NameIndex = 2371, - kInstPextrb_NameIndex = 2376, - kInstPextrd_NameIndex = 2383, - kInstPextrq_NameIndex = 2390, - kInstPextrw_NameIndex = 2397, - kInstPf2id_NameIndex = 2404, - kInstPf2iw_NameIndex = 2410, - kInstPfacc_NameIndex = 2416, - kInstPfadd_NameIndex = 2422, - kInstPfcmpeq_NameIndex = 2428, - kInstPfcmpge_NameIndex = 2436, - kInstPfcmpgt_NameIndex = 2444, - kInstPfmax_NameIndex = 2452, - kInstPfmin_NameIndex = 2458, - kInstPfmul_NameIndex = 2464, - kInstPfnacc_NameIndex = 2470, - kInstPfpnacc_NameIndex = 2477, - kInstPfrcp_NameIndex = 2485, - kInstPfrcpit1_NameIndex = 2491, - kInstPfrcpit2_NameIndex = 2500, - kInstPfrsqit1_NameIndex = 2509, - kInstPfrsqrt_NameIndex = 2518, - kInstPfsub_NameIndex = 2526, - kInstPfsubr_NameIndex = 2532, - kInstPhaddd_NameIndex = 2539, - kInstPhaddsw_NameIndex = 2546, - kInstPhaddw_NameIndex = 2554, - kInstPhminposuw_NameIndex = 2561, - kInstPhsubd_NameIndex = 2572, - kInstPhsubsw_NameIndex = 2579, - kInstPhsubw_NameIndex = 2587, - kInstPi2fd_NameIndex = 2594, - kInstPi2fw_NameIndex = 2600, - kInstPinsrb_NameIndex = 2606, - kInstPinsrd_NameIndex = 2613, - kInstPinsrq_NameIndex = 2620, - kInstPinsrw_NameIndex = 2627, - kInstPmaddubsw_NameIndex = 2634, - kInstPmaddwd_NameIndex = 2644, - kInstPmaxsb_NameIndex = 2652, - kInstPmaxsd_NameIndex = 2659, - kInstPmaxsw_NameIndex = 2666, - kInstPmaxub_NameIndex = 2673, - kInstPmaxud_NameIndex = 2680, - kInstPmaxuw_NameIndex = 2687, - kInstPminsb_NameIndex = 2694, - kInstPminsd_NameIndex = 2701, - kInstPminsw_NameIndex = 2708, - kInstPminub_NameIndex = 2715, - kInstPminud_NameIndex = 2722, - kInstPminuw_NameIndex = 2729, - kInstPmovmskb_NameIndex = 2736, - kInstPmovsxbd_NameIndex = 2745, - kInstPmovsxbq_NameIndex = 2754, - kInstPmovsxbw_NameIndex = 2763, - kInstPmovsxdq_NameIndex = 2772, - kInstPmovsxwd_NameIndex = 2781, - kInstPmovsxwq_NameIndex = 2790, - kInstPmovzxbd_NameIndex = 2799, - kInstPmovzxbq_NameIndex = 2808, - kInstPmovzxbw_NameIndex = 2817, - kInstPmovzxdq_NameIndex = 2826, - kInstPmovzxwd_NameIndex = 2835, - kInstPmovzxwq_NameIndex = 2844, - kInstPmuldq_NameIndex = 2853, - kInstPmulhrsw_NameIndex = 2860, - kInstPmulhuw_NameIndex = 2869, - kInstPmulhw_NameIndex = 2877, - kInstPmulld_NameIndex = 2884, - kInstPmullw_NameIndex = 2891, - kInstPmuludq_NameIndex = 2898, - kInstPop_NameIndex = 2906, - kInstPopa_NameIndex = 2910, - kInstPopcnt_NameIndex = 2915, - kInstPopf_NameIndex = 2922, - kInstPor_NameIndex = 2927, - kInstPrefetch_NameIndex = 2931, - kInstPrefetch3dNow_NameIndex = 2940, - kInstPrefetchw3dNow_NameIndex = 2955, - kInstPsadbw_NameIndex = 2971, - kInstPshufb_NameIndex = 2978, - kInstPshufd_NameIndex = 2985, - kInstPshufhw_NameIndex = 2992, - kInstPshuflw_NameIndex = 3000, - kInstPshufw_NameIndex = 3008, - kInstPsignb_NameIndex = 3015, - kInstPsignd_NameIndex = 3022, - kInstPsignw_NameIndex = 3029, - kInstPslld_NameIndex = 3036, - kInstPslldq_NameIndex = 3042, - kInstPsllq_NameIndex = 3049, - kInstPsllw_NameIndex = 3055, - kInstPsrad_NameIndex = 3061, - kInstPsraw_NameIndex = 3067, - kInstPsrld_NameIndex = 3073, - kInstPsrldq_NameIndex = 3079, - kInstPsrlq_NameIndex = 3086, - kInstPsrlw_NameIndex = 3092, - kInstPsubb_NameIndex = 3098, - kInstPsubd_NameIndex = 3104, - kInstPsubq_NameIndex = 3110, - kInstPsubsb_NameIndex = 3116, - kInstPsubsw_NameIndex = 3123, - kInstPsubusb_NameIndex = 3130, - kInstPsubusw_NameIndex = 3138, - kInstPsubw_NameIndex = 3146, - kInstPswapd_NameIndex = 3152, - kInstPtest_NameIndex = 3159, - kInstPunpckhbw_NameIndex = 3165, - kInstPunpckhdq_NameIndex = 3175, - kInstPunpckhqdq_NameIndex = 3185, - kInstPunpckhwd_NameIndex = 3196, - kInstPunpcklbw_NameIndex = 3206, - kInstPunpckldq_NameIndex = 3216, - kInstPunpcklqdq_NameIndex = 3226, - kInstPunpcklwd_NameIndex = 3237, - kInstPush_NameIndex = 3247, - kInstPusha_NameIndex = 3252, - kInstPushf_NameIndex = 3258, - kInstPxor_NameIndex = 3264, - kInstRcl_NameIndex = 3269, - kInstRcpps_NameIndex = 3273, - kInstRcpss_NameIndex = 3279, - kInstRcr_NameIndex = 3285, - kInstRdfsbase_NameIndex = 3289, - kInstRdgsbase_NameIndex = 3298, - kInstRdrand_NameIndex = 3307, - kInstRdtsc_NameIndex = 3314, - kInstRdtscp_NameIndex = 3320, - kInstRepLodsb_NameIndex = 3327, - kInstRepLodsd_NameIndex = 3337, - kInstRepLodsq_NameIndex = 3347, - kInstRepLodsw_NameIndex = 3357, - kInstRepMovsb_NameIndex = 3367, - kInstRepMovsd_NameIndex = 3377, - kInstRepMovsq_NameIndex = 3387, - kInstRepMovsw_NameIndex = 3397, - kInstRepStosb_NameIndex = 3407, - kInstRepStosd_NameIndex = 3417, - kInstRepStosq_NameIndex = 3427, - kInstRepStosw_NameIndex = 3437, - kInstRepeCmpsb_NameIndex = 3447, - kInstRepeCmpsd_NameIndex = 3458, - kInstRepeCmpsq_NameIndex = 3469, - kInstRepeCmpsw_NameIndex = 3480, - kInstRepeScasb_NameIndex = 3491, - kInstRepeScasd_NameIndex = 3502, - kInstRepeScasq_NameIndex = 3513, - kInstRepeScasw_NameIndex = 3524, - kInstRepneCmpsb_NameIndex = 3535, - kInstRepneCmpsd_NameIndex = 3547, - kInstRepneCmpsq_NameIndex = 3559, - kInstRepneCmpsw_NameIndex = 3571, - kInstRepneScasb_NameIndex = 3583, - kInstRepneScasd_NameIndex = 3595, - kInstRepneScasq_NameIndex = 3607, - kInstRepneScasw_NameIndex = 3619, - kInstRet_NameIndex = 3631, - kInstRol_NameIndex = 3635, - kInstRor_NameIndex = 3639, - kInstRorx_NameIndex = 3643, - kInstRoundpd_NameIndex = 3648, - kInstRoundps_NameIndex = 3656, - kInstRoundsd_NameIndex = 3664, - kInstRoundss_NameIndex = 3672, - kInstRsqrtps_NameIndex = 3680, - kInstRsqrtss_NameIndex = 3688, - kInstSahf_NameIndex = 3696, - kInstSal_NameIndex = 3701, - kInstSar_NameIndex = 3705, - kInstSarx_NameIndex = 3709, - kInstSbb_NameIndex = 3714, - kInstSeta_NameIndex = 3718, - kInstSetae_NameIndex = 3723, - kInstSetb_NameIndex = 3729, - kInstSetbe_NameIndex = 3734, - kInstSetc_NameIndex = 3740, - kInstSete_NameIndex = 3745, - kInstSetg_NameIndex = 3750, - kInstSetge_NameIndex = 3755, - kInstSetl_NameIndex = 3761, - kInstSetle_NameIndex = 3766, - kInstSetna_NameIndex = 3772, - kInstSetnae_NameIndex = 3778, - kInstSetnb_NameIndex = 3785, - kInstSetnbe_NameIndex = 3791, - kInstSetnc_NameIndex = 3798, - kInstSetne_NameIndex = 3804, - kInstSetng_NameIndex = 3810, - kInstSetnge_NameIndex = 3816, - kInstSetnl_NameIndex = 3823, - kInstSetnle_NameIndex = 3829, - kInstSetno_NameIndex = 3836, - kInstSetnp_NameIndex = 3842, - kInstSetns_NameIndex = 3848, - kInstSetnz_NameIndex = 3854, - kInstSeto_NameIndex = 3860, - kInstSetp_NameIndex = 3865, - kInstSetpe_NameIndex = 3870, - kInstSetpo_NameIndex = 3876, - kInstSets_NameIndex = 3882, - kInstSetz_NameIndex = 3887, - kInstSfence_NameIndex = 3892, - kInstShl_NameIndex = 3899, - kInstShld_NameIndex = 3903, - kInstShlx_NameIndex = 3908, - kInstShr_NameIndex = 3913, - kInstShrd_NameIndex = 3917, - kInstShrx_NameIndex = 3922, - kInstShufpd_NameIndex = 3927, - kInstShufps_NameIndex = 3934, - kInstSqrtpd_NameIndex = 3941, - kInstSqrtps_NameIndex = 3948, - kInstSqrtsd_NameIndex = 3955, - kInstSqrtss_NameIndex = 3962, - kInstStc_NameIndex = 3969, - kInstStd_NameIndex = 3973, - kInstStmxcsr_NameIndex = 3977, - kInstSub_NameIndex = 3985, - kInstSubpd_NameIndex = 3989, - kInstSubps_NameIndex = 3995, - kInstSubsd_NameIndex = 4001, - kInstSubss_NameIndex = 4007, - kInstTest_NameIndex = 4013, - kInstTzcnt_NameIndex = 4018, - kInstUcomisd_NameIndex = 4024, - kInstUcomiss_NameIndex = 4032, - kInstUd2_NameIndex = 4040, - kInstUnpckhpd_NameIndex = 4044, - kInstUnpckhps_NameIndex = 4053, - kInstUnpcklpd_NameIndex = 4062, - kInstUnpcklps_NameIndex = 4071, - kInstVaddpd_NameIndex = 4080, - kInstVaddps_NameIndex = 4087, - kInstVaddsd_NameIndex = 4094, - kInstVaddss_NameIndex = 4101, - kInstVaddsubpd_NameIndex = 4108, - kInstVaddsubps_NameIndex = 4118, - kInstVaesdec_NameIndex = 4128, - kInstVaesdeclast_NameIndex = 4136, - kInstVaesenc_NameIndex = 4148, - kInstVaesenclast_NameIndex = 4156, - kInstVaesimc_NameIndex = 4168, - kInstVaeskeygenassist_NameIndex = 4176, - kInstVandnpd_NameIndex = 4193, - kInstVandnps_NameIndex = 4201, - kInstVandpd_NameIndex = 4209, - kInstVandps_NameIndex = 4216, - kInstVblendpd_NameIndex = 4223, - kInstVblendps_NameIndex = 4232, - kInstVblendvpd_NameIndex = 4241, - kInstVblendvps_NameIndex = 4251, - kInstVbroadcastf128_NameIndex = 4261, - kInstVbroadcasti128_NameIndex = 4276, - kInstVbroadcastsd_NameIndex = 4291, - kInstVbroadcastss_NameIndex = 4304, - kInstVcmppd_NameIndex = 4317, - kInstVcmpps_NameIndex = 4324, - kInstVcmpsd_NameIndex = 4331, - kInstVcmpss_NameIndex = 4338, - kInstVcomisd_NameIndex = 4345, - kInstVcomiss_NameIndex = 4353, - kInstVcvtdq2pd_NameIndex = 4361, - kInstVcvtdq2ps_NameIndex = 4371, - kInstVcvtpd2dq_NameIndex = 4381, - kInstVcvtpd2ps_NameIndex = 4391, - kInstVcvtph2ps_NameIndex = 4401, - kInstVcvtps2dq_NameIndex = 4411, - kInstVcvtps2pd_NameIndex = 4421, - kInstVcvtps2ph_NameIndex = 4431, - kInstVcvtsd2si_NameIndex = 4441, - kInstVcvtsd2ss_NameIndex = 4451, - kInstVcvtsi2sd_NameIndex = 4461, - kInstVcvtsi2ss_NameIndex = 4471, - kInstVcvtss2sd_NameIndex = 4481, - kInstVcvtss2si_NameIndex = 4491, - kInstVcvttpd2dq_NameIndex = 4501, - kInstVcvttps2dq_NameIndex = 4512, - kInstVcvttsd2si_NameIndex = 4523, - kInstVcvttss2si_NameIndex = 4534, - kInstVdivpd_NameIndex = 4545, - kInstVdivps_NameIndex = 4552, - kInstVdivsd_NameIndex = 4559, - kInstVdivss_NameIndex = 4566, - kInstVdppd_NameIndex = 4573, - kInstVdpps_NameIndex = 4579, - kInstVextractf128_NameIndex = 4585, - kInstVextracti128_NameIndex = 4598, - kInstVextractps_NameIndex = 4611, - kInstVfmadd132pd_NameIndex = 4622, - kInstVfmadd132ps_NameIndex = 4634, - kInstVfmadd132sd_NameIndex = 4646, - kInstVfmadd132ss_NameIndex = 4658, - kInstVfmadd213pd_NameIndex = 4670, - kInstVfmadd213ps_NameIndex = 4682, - kInstVfmadd213sd_NameIndex = 4694, - kInstVfmadd213ss_NameIndex = 4706, - kInstVfmadd231pd_NameIndex = 4718, - kInstVfmadd231ps_NameIndex = 4730, - kInstVfmadd231sd_NameIndex = 4742, - kInstVfmadd231ss_NameIndex = 4754, - kInstVfmaddpd_NameIndex = 4766, - kInstVfmaddps_NameIndex = 4775, - kInstVfmaddsd_NameIndex = 4784, - kInstVfmaddss_NameIndex = 4793, - kInstVfmaddsub132pd_NameIndex = 4802, - kInstVfmaddsub132ps_NameIndex = 4817, - kInstVfmaddsub213pd_NameIndex = 4832, - kInstVfmaddsub213ps_NameIndex = 4847, - kInstVfmaddsub231pd_NameIndex = 4862, - kInstVfmaddsub231ps_NameIndex = 4877, - kInstVfmaddsubpd_NameIndex = 4892, - kInstVfmaddsubps_NameIndex = 4904, - kInstVfmsub132pd_NameIndex = 4916, - kInstVfmsub132ps_NameIndex = 4928, - kInstVfmsub132sd_NameIndex = 4940, - kInstVfmsub132ss_NameIndex = 4952, - kInstVfmsub213pd_NameIndex = 4964, - kInstVfmsub213ps_NameIndex = 4976, - kInstVfmsub213sd_NameIndex = 4988, - kInstVfmsub213ss_NameIndex = 5000, - kInstVfmsub231pd_NameIndex = 5012, - kInstVfmsub231ps_NameIndex = 5024, - kInstVfmsub231sd_NameIndex = 5036, - kInstVfmsub231ss_NameIndex = 5048, - kInstVfmsubadd132pd_NameIndex = 5060, - kInstVfmsubadd132ps_NameIndex = 5075, - kInstVfmsubadd213pd_NameIndex = 5090, - kInstVfmsubadd213ps_NameIndex = 5105, - kInstVfmsubadd231pd_NameIndex = 5120, - kInstVfmsubadd231ps_NameIndex = 5135, - kInstVfmsubaddpd_NameIndex = 5150, - kInstVfmsubaddps_NameIndex = 5162, - kInstVfmsubpd_NameIndex = 5174, - kInstVfmsubps_NameIndex = 5183, - kInstVfmsubsd_NameIndex = 5192, - kInstVfmsubss_NameIndex = 5201, - kInstVfnmadd132pd_NameIndex = 5210, - kInstVfnmadd132ps_NameIndex = 5223, - kInstVfnmadd132sd_NameIndex = 5236, - kInstVfnmadd132ss_NameIndex = 5249, - kInstVfnmadd213pd_NameIndex = 5262, - kInstVfnmadd213ps_NameIndex = 5275, - kInstVfnmadd213sd_NameIndex = 5288, - kInstVfnmadd213ss_NameIndex = 5301, - kInstVfnmadd231pd_NameIndex = 5314, - kInstVfnmadd231ps_NameIndex = 5327, - kInstVfnmadd231sd_NameIndex = 5340, - kInstVfnmadd231ss_NameIndex = 5353, - kInstVfnmaddpd_NameIndex = 5366, - kInstVfnmaddps_NameIndex = 5376, - kInstVfnmaddsd_NameIndex = 5386, - kInstVfnmaddss_NameIndex = 5396, - kInstVfnmsub132pd_NameIndex = 5406, - kInstVfnmsub132ps_NameIndex = 5419, - kInstVfnmsub132sd_NameIndex = 5432, - kInstVfnmsub132ss_NameIndex = 5445, - kInstVfnmsub213pd_NameIndex = 5458, - kInstVfnmsub213ps_NameIndex = 5471, - kInstVfnmsub213sd_NameIndex = 5484, - kInstVfnmsub213ss_NameIndex = 5497, - kInstVfnmsub231pd_NameIndex = 5510, - kInstVfnmsub231ps_NameIndex = 5523, - kInstVfnmsub231sd_NameIndex = 5536, - kInstVfnmsub231ss_NameIndex = 5549, - kInstVfnmsubpd_NameIndex = 5562, - kInstVfnmsubps_NameIndex = 5572, - kInstVfnmsubsd_NameIndex = 5582, - kInstVfnmsubss_NameIndex = 5592, - kInstVfrczpd_NameIndex = 5602, - kInstVfrczps_NameIndex = 5610, - kInstVfrczsd_NameIndex = 5618, - kInstVfrczss_NameIndex = 5626, - kInstVgatherdpd_NameIndex = 5634, - kInstVgatherdps_NameIndex = 5645, - kInstVgatherqpd_NameIndex = 5656, - kInstVgatherqps_NameIndex = 5667, - kInstVhaddpd_NameIndex = 5678, - kInstVhaddps_NameIndex = 5686, - kInstVhsubpd_NameIndex = 5694, - kInstVhsubps_NameIndex = 5702, - kInstVinsertf128_NameIndex = 5710, - kInstVinserti128_NameIndex = 5722, - kInstVinsertps_NameIndex = 5734, - kInstVlddqu_NameIndex = 5744, - kInstVldmxcsr_NameIndex = 5751, - kInstVmaskmovdqu_NameIndex = 5760, - kInstVmaskmovpd_NameIndex = 5772, - kInstVmaskmovps_NameIndex = 5783, - kInstVmaxpd_NameIndex = 5794, - kInstVmaxps_NameIndex = 5801, - kInstVmaxsd_NameIndex = 5808, - kInstVmaxss_NameIndex = 5815, - kInstVminpd_NameIndex = 5822, - kInstVminps_NameIndex = 5829, - kInstVminsd_NameIndex = 5836, - kInstVminss_NameIndex = 5843, - kInstVmovapd_NameIndex = 5850, - kInstVmovaps_NameIndex = 5858, - kInstVmovd_NameIndex = 5866, - kInstVmovddup_NameIndex = 5872, - kInstVmovdqa_NameIndex = 5881, - kInstVmovdqu_NameIndex = 5889, - kInstVmovhlps_NameIndex = 5897, - kInstVmovhpd_NameIndex = 5906, - kInstVmovhps_NameIndex = 5914, - kInstVmovlhps_NameIndex = 5922, - kInstVmovlpd_NameIndex = 5931, - kInstVmovlps_NameIndex = 5939, - kInstVmovmskpd_NameIndex = 5947, - kInstVmovmskps_NameIndex = 5957, - kInstVmovntdq_NameIndex = 5967, - kInstVmovntdqa_NameIndex = 5976, - kInstVmovntpd_NameIndex = 5986, - kInstVmovntps_NameIndex = 5995, - kInstVmovq_NameIndex = 6004, - kInstVmovsd_NameIndex = 6010, - kInstVmovshdup_NameIndex = 6017, - kInstVmovsldup_NameIndex = 6027, - kInstVmovss_NameIndex = 6037, - kInstVmovupd_NameIndex = 6044, - kInstVmovups_NameIndex = 6052, - kInstVmpsadbw_NameIndex = 6060, - kInstVmulpd_NameIndex = 6069, - kInstVmulps_NameIndex = 6076, - kInstVmulsd_NameIndex = 6083, - kInstVmulss_NameIndex = 6090, - kInstVorpd_NameIndex = 6097, - kInstVorps_NameIndex = 6103, - kInstVpabsb_NameIndex = 6109, - kInstVpabsd_NameIndex = 6116, - kInstVpabsw_NameIndex = 6123, - kInstVpackssdw_NameIndex = 6130, - kInstVpacksswb_NameIndex = 6140, - kInstVpackusdw_NameIndex = 6150, - kInstVpackuswb_NameIndex = 6160, - kInstVpaddb_NameIndex = 6170, - kInstVpaddd_NameIndex = 6177, - kInstVpaddq_NameIndex = 6184, - kInstVpaddsb_NameIndex = 6191, - kInstVpaddsw_NameIndex = 6199, - kInstVpaddusb_NameIndex = 6207, - kInstVpaddusw_NameIndex = 6216, - kInstVpaddw_NameIndex = 6225, - kInstVpalignr_NameIndex = 6232, - kInstVpand_NameIndex = 6241, - kInstVpandn_NameIndex = 6247, - kInstVpavgb_NameIndex = 6254, - kInstVpavgw_NameIndex = 6261, - kInstVpblendd_NameIndex = 6268, - kInstVpblendvb_NameIndex = 6277, - kInstVpblendw_NameIndex = 6287, - kInstVpbroadcastb_NameIndex = 6296, - kInstVpbroadcastd_NameIndex = 6309, - kInstVpbroadcastq_NameIndex = 6322, - kInstVpbroadcastw_NameIndex = 6335, - kInstVpclmulqdq_NameIndex = 6348, - kInstVpcmov_NameIndex = 6359, - kInstVpcmpeqb_NameIndex = 6366, - kInstVpcmpeqd_NameIndex = 6375, - kInstVpcmpeqq_NameIndex = 6384, - kInstVpcmpeqw_NameIndex = 6393, - kInstVpcmpestri_NameIndex = 6402, - kInstVpcmpestrm_NameIndex = 6413, - kInstVpcmpgtb_NameIndex = 6424, - kInstVpcmpgtd_NameIndex = 6433, - kInstVpcmpgtq_NameIndex = 6442, - kInstVpcmpgtw_NameIndex = 6451, - kInstVpcmpistri_NameIndex = 6460, - kInstVpcmpistrm_NameIndex = 6471, - kInstVpcomb_NameIndex = 6482, - kInstVpcomd_NameIndex = 6489, - kInstVpcomq_NameIndex = 6496, - kInstVpcomub_NameIndex = 6503, - kInstVpcomud_NameIndex = 6511, - kInstVpcomuq_NameIndex = 6519, - kInstVpcomuw_NameIndex = 6527, - kInstVpcomw_NameIndex = 6535, - kInstVperm2f128_NameIndex = 6542, - kInstVperm2i128_NameIndex = 6553, - kInstVpermd_NameIndex = 6564, - kInstVpermil2pd_NameIndex = 6571, - kInstVpermil2ps_NameIndex = 6582, - kInstVpermilpd_NameIndex = 6593, - kInstVpermilps_NameIndex = 6603, - kInstVpermpd_NameIndex = 6613, - kInstVpermps_NameIndex = 6621, - kInstVpermq_NameIndex = 6629, - kInstVpextrb_NameIndex = 6636, - kInstVpextrd_NameIndex = 6644, - kInstVpextrq_NameIndex = 6652, - kInstVpextrw_NameIndex = 6660, - kInstVpgatherdd_NameIndex = 6668, - kInstVpgatherdq_NameIndex = 6679, - kInstVpgatherqd_NameIndex = 6690, - kInstVpgatherqq_NameIndex = 6701, - kInstVphaddbd_NameIndex = 6712, - kInstVphaddbq_NameIndex = 6721, - kInstVphaddbw_NameIndex = 6730, - kInstVphaddd_NameIndex = 6739, - kInstVphadddq_NameIndex = 6747, - kInstVphaddsw_NameIndex = 6756, - kInstVphaddubd_NameIndex = 6765, - kInstVphaddubq_NameIndex = 6775, - kInstVphaddubw_NameIndex = 6785, - kInstVphaddudq_NameIndex = 6795, - kInstVphadduwd_NameIndex = 6805, - kInstVphadduwq_NameIndex = 6815, - kInstVphaddw_NameIndex = 6825, - kInstVphaddwd_NameIndex = 6833, - kInstVphaddwq_NameIndex = 6842, - kInstVphminposuw_NameIndex = 6851, - kInstVphsubbw_NameIndex = 6863, - kInstVphsubd_NameIndex = 6872, - kInstVphsubdq_NameIndex = 6880, - kInstVphsubsw_NameIndex = 6889, - kInstVphsubw_NameIndex = 6898, - kInstVphsubwd_NameIndex = 6906, - kInstVpinsrb_NameIndex = 6915, - kInstVpinsrd_NameIndex = 6923, - kInstVpinsrq_NameIndex = 6931, - kInstVpinsrw_NameIndex = 6939, - kInstVpmacsdd_NameIndex = 6947, - kInstVpmacsdqh_NameIndex = 6956, - kInstVpmacsdql_NameIndex = 6966, - kInstVpmacssdd_NameIndex = 6976, - kInstVpmacssdqh_NameIndex = 6986, - kInstVpmacssdql_NameIndex = 6997, - kInstVpmacsswd_NameIndex = 7008, - kInstVpmacssww_NameIndex = 7018, - kInstVpmacswd_NameIndex = 7028, - kInstVpmacsww_NameIndex = 7037, - kInstVpmadcsswd_NameIndex = 7046, - kInstVpmadcswd_NameIndex = 7057, - kInstVpmaddubsw_NameIndex = 7067, - kInstVpmaddwd_NameIndex = 7078, - kInstVpmaskmovd_NameIndex = 7087, - kInstVpmaskmovq_NameIndex = 7098, - kInstVpmaxsb_NameIndex = 7109, - kInstVpmaxsd_NameIndex = 7117, - kInstVpmaxsw_NameIndex = 7125, - kInstVpmaxub_NameIndex = 7133, - kInstVpmaxud_NameIndex = 7141, - kInstVpmaxuw_NameIndex = 7149, - kInstVpminsb_NameIndex = 7157, - kInstVpminsd_NameIndex = 7165, - kInstVpminsw_NameIndex = 7173, - kInstVpminub_NameIndex = 7181, - kInstVpminud_NameIndex = 7189, - kInstVpminuw_NameIndex = 7197, - kInstVpmovmskb_NameIndex = 7205, - kInstVpmovsxbd_NameIndex = 7215, - kInstVpmovsxbq_NameIndex = 7225, - kInstVpmovsxbw_NameIndex = 7235, - kInstVpmovsxdq_NameIndex = 7245, - kInstVpmovsxwd_NameIndex = 7255, - kInstVpmovsxwq_NameIndex = 7265, - kInstVpmovzxbd_NameIndex = 7275, - kInstVpmovzxbq_NameIndex = 7285, - kInstVpmovzxbw_NameIndex = 7295, - kInstVpmovzxdq_NameIndex = 7305, - kInstVpmovzxwd_NameIndex = 7315, - kInstVpmovzxwq_NameIndex = 7325, - kInstVpmuldq_NameIndex = 7335, - kInstVpmulhrsw_NameIndex = 7343, - kInstVpmulhuw_NameIndex = 7353, - kInstVpmulhw_NameIndex = 7362, - kInstVpmulld_NameIndex = 7370, - kInstVpmullw_NameIndex = 7378, - kInstVpmuludq_NameIndex = 7386, - kInstVpor_NameIndex = 7395, - kInstVpperm_NameIndex = 7400, - kInstVprotb_NameIndex = 7407, - kInstVprotd_NameIndex = 7414, - kInstVprotq_NameIndex = 7421, - kInstVprotw_NameIndex = 7428, - kInstVpsadbw_NameIndex = 7435, - kInstVpshab_NameIndex = 7443, - kInstVpshad_NameIndex = 7450, - kInstVpshaq_NameIndex = 7457, - kInstVpshaw_NameIndex = 7464, - kInstVpshlb_NameIndex = 7471, - kInstVpshld_NameIndex = 7478, - kInstVpshlq_NameIndex = 7485, - kInstVpshlw_NameIndex = 7492, - kInstVpshufb_NameIndex = 7499, - kInstVpshufd_NameIndex = 7507, - kInstVpshufhw_NameIndex = 7515, - kInstVpshuflw_NameIndex = 7524, - kInstVpsignb_NameIndex = 7533, - kInstVpsignd_NameIndex = 7541, - kInstVpsignw_NameIndex = 7549, - kInstVpslld_NameIndex = 7557, - kInstVpslldq_NameIndex = 7564, - kInstVpsllq_NameIndex = 7572, - kInstVpsllvd_NameIndex = 7579, - kInstVpsllvq_NameIndex = 7587, - kInstVpsllw_NameIndex = 7595, - kInstVpsrad_NameIndex = 7602, - kInstVpsravd_NameIndex = 7609, - kInstVpsraw_NameIndex = 7617, - kInstVpsrld_NameIndex = 7624, - kInstVpsrldq_NameIndex = 7631, - kInstVpsrlq_NameIndex = 7639, - kInstVpsrlvd_NameIndex = 7646, - kInstVpsrlvq_NameIndex = 7654, - kInstVpsrlw_NameIndex = 7662, - kInstVpsubb_NameIndex = 7669, - kInstVpsubd_NameIndex = 7676, - kInstVpsubq_NameIndex = 7683, - kInstVpsubsb_NameIndex = 7690, - kInstVpsubsw_NameIndex = 7698, - kInstVpsubusb_NameIndex = 7706, - kInstVpsubusw_NameIndex = 7715, - kInstVpsubw_NameIndex = 7724, - kInstVptest_NameIndex = 7731, - kInstVpunpckhbw_NameIndex = 7738, - kInstVpunpckhdq_NameIndex = 7749, - kInstVpunpckhqdq_NameIndex = 7760, - kInstVpunpckhwd_NameIndex = 7772, - kInstVpunpcklbw_NameIndex = 7783, - kInstVpunpckldq_NameIndex = 7794, - kInstVpunpcklqdq_NameIndex = 7805, - kInstVpunpcklwd_NameIndex = 7817, - kInstVpxor_NameIndex = 7828, - kInstVrcpps_NameIndex = 7834, - kInstVrcpss_NameIndex = 7841, - kInstVroundpd_NameIndex = 7848, - kInstVroundps_NameIndex = 7857, - kInstVroundsd_NameIndex = 7866, - kInstVroundss_NameIndex = 7875, - kInstVrsqrtps_NameIndex = 7884, - kInstVrsqrtss_NameIndex = 7893, - kInstVshufpd_NameIndex = 7902, - kInstVshufps_NameIndex = 7910, - kInstVsqrtpd_NameIndex = 7918, - kInstVsqrtps_NameIndex = 7926, - kInstVsqrtsd_NameIndex = 7934, - kInstVsqrtss_NameIndex = 7942, - kInstVstmxcsr_NameIndex = 7950, - kInstVsubpd_NameIndex = 7959, - kInstVsubps_NameIndex = 7966, - kInstVsubsd_NameIndex = 7973, - kInstVsubss_NameIndex = 7980, - kInstVtestpd_NameIndex = 7987, - kInstVtestps_NameIndex = 7995, - kInstVucomisd_NameIndex = 8003, - kInstVucomiss_NameIndex = 8012, - kInstVunpckhpd_NameIndex = 8021, - kInstVunpckhps_NameIndex = 8031, - kInstVunpcklpd_NameIndex = 8041, - kInstVunpcklps_NameIndex = 8051, - kInstVxorpd_NameIndex = 8061, - kInstVxorps_NameIndex = 8068, - kInstVzeroall_NameIndex = 8075, - kInstVzeroupper_NameIndex = 8084, - kInstWrfsbase_NameIndex = 8095, - kInstWrgsbase_NameIndex = 8104, - kInstXadd_NameIndex = 8113, - kInstXchg_NameIndex = 8118, - kInstXor_NameIndex = 8123, - kInstXorpd_NameIndex = 8127, - kInstXorps_NameIndex = 8133 +// Automatically generated, do not edit. +enum kX86InstData_NameIndex { + kInstIdNone_NameIndex = 0, + kX86InstIdAdc_NameIndex = 1, + kX86InstIdAdd_NameIndex = 5, + kX86InstIdAddpd_NameIndex = 9, + kX86InstIdAddps_NameIndex = 15, + kX86InstIdAddsd_NameIndex = 21, + kX86InstIdAddss_NameIndex = 27, + kX86InstIdAddsubpd_NameIndex = 33, + kX86InstIdAddsubps_NameIndex = 42, + kX86InstIdAesdec_NameIndex = 51, + kX86InstIdAesdeclast_NameIndex = 58, + kX86InstIdAesenc_NameIndex = 69, + kX86InstIdAesenclast_NameIndex = 76, + kX86InstIdAesimc_NameIndex = 87, + kX86InstIdAeskeygenassist_NameIndex = 94, + kX86InstIdAnd_NameIndex = 110, + kX86InstIdAndn_NameIndex = 114, + kX86InstIdAndnpd_NameIndex = 119, + kX86InstIdAndnps_NameIndex = 126, + kX86InstIdAndpd_NameIndex = 133, + kX86InstIdAndps_NameIndex = 139, + kX86InstIdBextr_NameIndex = 145, + kX86InstIdBlendpd_NameIndex = 151, + kX86InstIdBlendps_NameIndex = 159, + kX86InstIdBlendvpd_NameIndex = 167, + kX86InstIdBlendvps_NameIndex = 176, + kX86InstIdBlsi_NameIndex = 185, + kX86InstIdBlsmsk_NameIndex = 190, + kX86InstIdBlsr_NameIndex = 197, + kX86InstIdBsf_NameIndex = 202, + kX86InstIdBsr_NameIndex = 206, + kX86InstIdBswap_NameIndex = 210, + kX86InstIdBt_NameIndex = 216, + kX86InstIdBtc_NameIndex = 219, + kX86InstIdBtr_NameIndex = 223, + kX86InstIdBts_NameIndex = 227, + kX86InstIdBzhi_NameIndex = 231, + kX86InstIdCall_NameIndex = 236, + kX86InstIdCbw_NameIndex = 241, + kX86InstIdCdq_NameIndex = 245, + kX86InstIdCdqe_NameIndex = 249, + kX86InstIdClc_NameIndex = 254, + kX86InstIdCld_NameIndex = 258, + kX86InstIdClflush_NameIndex = 262, + kX86InstIdCmc_NameIndex = 270, + kX86InstIdCmova_NameIndex = 274, + kX86InstIdCmovae_NameIndex = 280, + kX86InstIdCmovb_NameIndex = 287, + kX86InstIdCmovbe_NameIndex = 293, + kX86InstIdCmovc_NameIndex = 300, + kX86InstIdCmove_NameIndex = 306, + kX86InstIdCmovg_NameIndex = 312, + kX86InstIdCmovge_NameIndex = 318, + kX86InstIdCmovl_NameIndex = 325, + kX86InstIdCmovle_NameIndex = 331, + kX86InstIdCmovna_NameIndex = 338, + kX86InstIdCmovnae_NameIndex = 345, + kX86InstIdCmovnb_NameIndex = 353, + kX86InstIdCmovnbe_NameIndex = 360, + kX86InstIdCmovnc_NameIndex = 368, + kX86InstIdCmovne_NameIndex = 375, + kX86InstIdCmovng_NameIndex = 382, + kX86InstIdCmovnge_NameIndex = 389, + kX86InstIdCmovnl_NameIndex = 397, + kX86InstIdCmovnle_NameIndex = 404, + kX86InstIdCmovno_NameIndex = 412, + kX86InstIdCmovnp_NameIndex = 419, + kX86InstIdCmovns_NameIndex = 426, + kX86InstIdCmovnz_NameIndex = 433, + kX86InstIdCmovo_NameIndex = 440, + kX86InstIdCmovp_NameIndex = 446, + kX86InstIdCmovpe_NameIndex = 452, + kX86InstIdCmovpo_NameIndex = 459, + kX86InstIdCmovs_NameIndex = 466, + kX86InstIdCmovz_NameIndex = 472, + kX86InstIdCmp_NameIndex = 478, + kX86InstIdCmppd_NameIndex = 482, + kX86InstIdCmpps_NameIndex = 488, + kX86InstIdCmpsB_NameIndex = 494, + kX86InstIdCmpsD_NameIndex = 501, + kX86InstIdCmpsQ_NameIndex = 508, + kX86InstIdCmpsW_NameIndex = 515, + kX86InstIdCmpsd_NameIndex = 522, + kX86InstIdCmpss_NameIndex = 528, + kX86InstIdCmpxchg_NameIndex = 534, + kX86InstIdCmpxchg16b_NameIndex = 542, + kX86InstIdCmpxchg8b_NameIndex = 553, + kX86InstIdComisd_NameIndex = 563, + kX86InstIdComiss_NameIndex = 570, + kX86InstIdCpuid_NameIndex = 577, + kX86InstIdCqo_NameIndex = 583, + kX86InstIdCrc32_NameIndex = 587, + kX86InstIdCvtdq2pd_NameIndex = 593, + kX86InstIdCvtdq2ps_NameIndex = 602, + kX86InstIdCvtpd2dq_NameIndex = 611, + kX86InstIdCvtpd2pi_NameIndex = 620, + kX86InstIdCvtpd2ps_NameIndex = 629, + kX86InstIdCvtpi2pd_NameIndex = 638, + kX86InstIdCvtpi2ps_NameIndex = 647, + kX86InstIdCvtps2dq_NameIndex = 656, + kX86InstIdCvtps2pd_NameIndex = 665, + kX86InstIdCvtps2pi_NameIndex = 674, + kX86InstIdCvtsd2si_NameIndex = 683, + kX86InstIdCvtsd2ss_NameIndex = 692, + kX86InstIdCvtsi2sd_NameIndex = 701, + kX86InstIdCvtsi2ss_NameIndex = 710, + kX86InstIdCvtss2sd_NameIndex = 719, + kX86InstIdCvtss2si_NameIndex = 728, + kX86InstIdCvttpd2dq_NameIndex = 737, + kX86InstIdCvttpd2pi_NameIndex = 747, + kX86InstIdCvttps2dq_NameIndex = 757, + kX86InstIdCvttps2pi_NameIndex = 767, + kX86InstIdCvttsd2si_NameIndex = 777, + kX86InstIdCvttss2si_NameIndex = 787, + kX86InstIdCwd_NameIndex = 797, + kX86InstIdCwde_NameIndex = 801, + kX86InstIdDaa_NameIndex = 806, + kX86InstIdDas_NameIndex = 810, + kX86InstIdDec_NameIndex = 814, + kX86InstIdDiv_NameIndex = 818, + kX86InstIdDivpd_NameIndex = 822, + kX86InstIdDivps_NameIndex = 828, + kX86InstIdDivsd_NameIndex = 834, + kX86InstIdDivss_NameIndex = 840, + kX86InstIdDppd_NameIndex = 846, + kX86InstIdDpps_NameIndex = 851, + kX86InstIdEmms_NameIndex = 856, + kX86InstIdEnter_NameIndex = 861, + kX86InstIdExtractps_NameIndex = 867, + kX86InstIdF2xm1_NameIndex = 877, + kX86InstIdFabs_NameIndex = 883, + kX86InstIdFadd_NameIndex = 888, + kX86InstIdFaddp_NameIndex = 893, + kX86InstIdFbld_NameIndex = 899, + kX86InstIdFbstp_NameIndex = 904, + kX86InstIdFchs_NameIndex = 910, + kX86InstIdFclex_NameIndex = 915, + kX86InstIdFcmovb_NameIndex = 921, + kX86InstIdFcmovbe_NameIndex = 928, + kX86InstIdFcmove_NameIndex = 936, + kX86InstIdFcmovnb_NameIndex = 943, + kX86InstIdFcmovnbe_NameIndex = 951, + kX86InstIdFcmovne_NameIndex = 960, + kX86InstIdFcmovnu_NameIndex = 968, + kX86InstIdFcmovu_NameIndex = 976, + kX86InstIdFcom_NameIndex = 983, + kX86InstIdFcomi_NameIndex = 988, + kX86InstIdFcomip_NameIndex = 994, + kX86InstIdFcomp_NameIndex = 1001, + kX86InstIdFcompp_NameIndex = 1007, + kX86InstIdFcos_NameIndex = 1014, + kX86InstIdFdecstp_NameIndex = 1019, + kX86InstIdFdiv_NameIndex = 1027, + kX86InstIdFdivp_NameIndex = 1032, + kX86InstIdFdivr_NameIndex = 1038, + kX86InstIdFdivrp_NameIndex = 1044, + kX86InstIdFemms_NameIndex = 1051, + kX86InstIdFfree_NameIndex = 1057, + kX86InstIdFiadd_NameIndex = 1063, + kX86InstIdFicom_NameIndex = 1069, + kX86InstIdFicomp_NameIndex = 1075, + kX86InstIdFidiv_NameIndex = 1082, + kX86InstIdFidivr_NameIndex = 1088, + kX86InstIdFild_NameIndex = 1095, + kX86InstIdFimul_NameIndex = 1100, + kX86InstIdFincstp_NameIndex = 1106, + kX86InstIdFinit_NameIndex = 1114, + kX86InstIdFist_NameIndex = 1120, + kX86InstIdFistp_NameIndex = 1125, + kX86InstIdFisttp_NameIndex = 1131, + kX86InstIdFisub_NameIndex = 1138, + kX86InstIdFisubr_NameIndex = 1144, + kX86InstIdFld_NameIndex = 1151, + kX86InstIdFld1_NameIndex = 1155, + kX86InstIdFldcw_NameIndex = 1160, + kX86InstIdFldenv_NameIndex = 1166, + kX86InstIdFldl2e_NameIndex = 1173, + kX86InstIdFldl2t_NameIndex = 1180, + kX86InstIdFldlg2_NameIndex = 1187, + kX86InstIdFldln2_NameIndex = 1194, + kX86InstIdFldpi_NameIndex = 1201, + kX86InstIdFldz_NameIndex = 1207, + kX86InstIdFmul_NameIndex = 1212, + kX86InstIdFmulp_NameIndex = 1217, + kX86InstIdFnclex_NameIndex = 1223, + kX86InstIdFninit_NameIndex = 1230, + kX86InstIdFnop_NameIndex = 1237, + kX86InstIdFnsave_NameIndex = 1242, + kX86InstIdFnstcw_NameIndex = 1249, + kX86InstIdFnstenv_NameIndex = 1256, + kX86InstIdFnstsw_NameIndex = 1264, + kX86InstIdFpatan_NameIndex = 1271, + kX86InstIdFprem_NameIndex = 1278, + kX86InstIdFprem1_NameIndex = 1284, + kX86InstIdFptan_NameIndex = 1291, + kX86InstIdFrndint_NameIndex = 1297, + kX86InstIdFrstor_NameIndex = 1305, + kX86InstIdFsave_NameIndex = 1312, + kX86InstIdFscale_NameIndex = 1318, + kX86InstIdFsin_NameIndex = 1325, + kX86InstIdFsincos_NameIndex = 1330, + kX86InstIdFsqrt_NameIndex = 1338, + kX86InstIdFst_NameIndex = 1344, + kX86InstIdFstcw_NameIndex = 1348, + kX86InstIdFstenv_NameIndex = 1354, + kX86InstIdFstp_NameIndex = 1361, + kX86InstIdFstsw_NameIndex = 1366, + kX86InstIdFsub_NameIndex = 1372, + kX86InstIdFsubp_NameIndex = 1377, + kX86InstIdFsubr_NameIndex = 1383, + kX86InstIdFsubrp_NameIndex = 1389, + kX86InstIdFtst_NameIndex = 1396, + kX86InstIdFucom_NameIndex = 1401, + kX86InstIdFucomi_NameIndex = 1407, + kX86InstIdFucomip_NameIndex = 1414, + kX86InstIdFucomp_NameIndex = 1422, + kX86InstIdFucompp_NameIndex = 1429, + kX86InstIdFwait_NameIndex = 1437, + kX86InstIdFxam_NameIndex = 1443, + kX86InstIdFxch_NameIndex = 1448, + kX86InstIdFxrstor_NameIndex = 1453, + kX86InstIdFxsave_NameIndex = 1461, + kX86InstIdFxtract_NameIndex = 1468, + kX86InstIdFyl2x_NameIndex = 1476, + kX86InstIdFyl2xp1_NameIndex = 1482, + kX86InstIdHaddpd_NameIndex = 1490, + kX86InstIdHaddps_NameIndex = 1497, + kX86InstIdHsubpd_NameIndex = 1504, + kX86InstIdHsubps_NameIndex = 1511, + kX86InstIdIdiv_NameIndex = 1518, + kX86InstIdImul_NameIndex = 1523, + kX86InstIdInc_NameIndex = 1528, + kX86InstIdInsertps_NameIndex = 1532, + kX86InstIdInt_NameIndex = 1541, + kX86InstIdJa_NameIndex = 1545, + kX86InstIdJae_NameIndex = 1548, + kX86InstIdJb_NameIndex = 1552, + kX86InstIdJbe_NameIndex = 1555, + kX86InstIdJc_NameIndex = 1559, + kX86InstIdJe_NameIndex = 1562, + kX86InstIdJg_NameIndex = 1565, + kX86InstIdJge_NameIndex = 1568, + kX86InstIdJl_NameIndex = 1572, + kX86InstIdJle_NameIndex = 1575, + kX86InstIdJna_NameIndex = 1579, + kX86InstIdJnae_NameIndex = 1583, + kX86InstIdJnb_NameIndex = 1588, + kX86InstIdJnbe_NameIndex = 1592, + kX86InstIdJnc_NameIndex = 1597, + kX86InstIdJne_NameIndex = 1601, + kX86InstIdJng_NameIndex = 1605, + kX86InstIdJnge_NameIndex = 1609, + kX86InstIdJnl_NameIndex = 1614, + kX86InstIdJnle_NameIndex = 1618, + kX86InstIdJno_NameIndex = 1623, + kX86InstIdJnp_NameIndex = 1627, + kX86InstIdJns_NameIndex = 1631, + kX86InstIdJnz_NameIndex = 1635, + kX86InstIdJo_NameIndex = 1639, + kX86InstIdJp_NameIndex = 1642, + kX86InstIdJpe_NameIndex = 1645, + kX86InstIdJpo_NameIndex = 1649, + kX86InstIdJs_NameIndex = 1653, + kX86InstIdJz_NameIndex = 1656, + kX86InstIdJecxz_NameIndex = 1659, + kX86InstIdJmp_NameIndex = 1665, + kX86InstIdLahf_NameIndex = 1669, + kX86InstIdLddqu_NameIndex = 1674, + kX86InstIdLdmxcsr_NameIndex = 1680, + kX86InstIdLea_NameIndex = 1688, + kX86InstIdLeave_NameIndex = 1692, + kX86InstIdLfence_NameIndex = 1698, + kX86InstIdLodsB_NameIndex = 1705, + kX86InstIdLodsD_NameIndex = 1712, + kX86InstIdLodsQ_NameIndex = 1719, + kX86InstIdLodsW_NameIndex = 1726, + kX86InstIdLzcnt_NameIndex = 1733, + kX86InstIdMaskmovdqu_NameIndex = 1739, + kX86InstIdMaskmovq_NameIndex = 1750, + kX86InstIdMaxpd_NameIndex = 1759, + kX86InstIdMaxps_NameIndex = 1765, + kX86InstIdMaxsd_NameIndex = 1771, + kX86InstIdMaxss_NameIndex = 1777, + kX86InstIdMfence_NameIndex = 1783, + kX86InstIdMinpd_NameIndex = 1790, + kX86InstIdMinps_NameIndex = 1796, + kX86InstIdMinsd_NameIndex = 1802, + kX86InstIdMinss_NameIndex = 1808, + kX86InstIdMonitor_NameIndex = 1814, + kX86InstIdMov_NameIndex = 1822, + kX86InstIdMovPtr_NameIndex = 1826, + kX86InstIdMovapd_NameIndex = 1834, + kX86InstIdMovaps_NameIndex = 1841, + kX86InstIdMovbe_NameIndex = 1848, + kX86InstIdMovd_NameIndex = 1854, + kX86InstIdMovddup_NameIndex = 1859, + kX86InstIdMovdq2q_NameIndex = 1867, + kX86InstIdMovdqa_NameIndex = 1875, + kX86InstIdMovdqu_NameIndex = 1882, + kX86InstIdMovhlps_NameIndex = 1889, + kX86InstIdMovhpd_NameIndex = 1897, + kX86InstIdMovhps_NameIndex = 1904, + kX86InstIdMovlhps_NameIndex = 1911, + kX86InstIdMovlpd_NameIndex = 1919, + kX86InstIdMovlps_NameIndex = 1926, + kX86InstIdMovmskpd_NameIndex = 1933, + kX86InstIdMovmskps_NameIndex = 1942, + kX86InstIdMovntdq_NameIndex = 1951, + kX86InstIdMovntdqa_NameIndex = 1959, + kX86InstIdMovnti_NameIndex = 1968, + kX86InstIdMovntpd_NameIndex = 1975, + kX86InstIdMovntps_NameIndex = 1983, + kX86InstIdMovntq_NameIndex = 1991, + kX86InstIdMovq_NameIndex = 1998, + kX86InstIdMovq2dq_NameIndex = 2003, + kX86InstIdMovsB_NameIndex = 2011, + kX86InstIdMovsD_NameIndex = 2018, + kX86InstIdMovsQ_NameIndex = 2025, + kX86InstIdMovsW_NameIndex = 2032, + kX86InstIdMovsd_NameIndex = 2039, + kX86InstIdMovshdup_NameIndex = 2045, + kX86InstIdMovsldup_NameIndex = 2054, + kX86InstIdMovss_NameIndex = 2063, + kX86InstIdMovsx_NameIndex = 2069, + kX86InstIdMovsxd_NameIndex = 2075, + kX86InstIdMovupd_NameIndex = 2082, + kX86InstIdMovups_NameIndex = 2089, + kX86InstIdMovzx_NameIndex = 2096, + kX86InstIdMpsadbw_NameIndex = 2102, + kX86InstIdMul_NameIndex = 2110, + kX86InstIdMulpd_NameIndex = 2114, + kX86InstIdMulps_NameIndex = 2120, + kX86InstIdMulsd_NameIndex = 2126, + kX86InstIdMulss_NameIndex = 2132, + kX86InstIdMulx_NameIndex = 2138, + kX86InstIdMwait_NameIndex = 2143, + kX86InstIdNeg_NameIndex = 2149, + kX86InstIdNop_NameIndex = 2153, + kX86InstIdNot_NameIndex = 2157, + kX86InstIdOr_NameIndex = 2161, + kX86InstIdOrpd_NameIndex = 2164, + kX86InstIdOrps_NameIndex = 2169, + kX86InstIdPabsb_NameIndex = 2174, + kX86InstIdPabsd_NameIndex = 2180, + kX86InstIdPabsw_NameIndex = 2186, + kX86InstIdPackssdw_NameIndex = 2192, + kX86InstIdPacksswb_NameIndex = 2201, + kX86InstIdPackusdw_NameIndex = 2210, + kX86InstIdPackuswb_NameIndex = 2219, + kX86InstIdPaddb_NameIndex = 2228, + kX86InstIdPaddd_NameIndex = 2234, + kX86InstIdPaddq_NameIndex = 2240, + kX86InstIdPaddsb_NameIndex = 2246, + kX86InstIdPaddsw_NameIndex = 2253, + kX86InstIdPaddusb_NameIndex = 2260, + kX86InstIdPaddusw_NameIndex = 2268, + kX86InstIdPaddw_NameIndex = 2276, + kX86InstIdPalignr_NameIndex = 2282, + kX86InstIdPand_NameIndex = 2290, + kX86InstIdPandn_NameIndex = 2295, + kX86InstIdPause_NameIndex = 2301, + kX86InstIdPavgb_NameIndex = 2307, + kX86InstIdPavgw_NameIndex = 2313, + kX86InstIdPblendvb_NameIndex = 2319, + kX86InstIdPblendw_NameIndex = 2328, + kX86InstIdPclmulqdq_NameIndex = 2336, + kX86InstIdPcmpeqb_NameIndex = 2346, + kX86InstIdPcmpeqd_NameIndex = 2354, + kX86InstIdPcmpeqq_NameIndex = 2362, + kX86InstIdPcmpeqw_NameIndex = 2370, + kX86InstIdPcmpestri_NameIndex = 2378, + kX86InstIdPcmpestrm_NameIndex = 2388, + kX86InstIdPcmpgtb_NameIndex = 2398, + kX86InstIdPcmpgtd_NameIndex = 2406, + kX86InstIdPcmpgtq_NameIndex = 2414, + kX86InstIdPcmpgtw_NameIndex = 2422, + kX86InstIdPcmpistri_NameIndex = 2430, + kX86InstIdPcmpistrm_NameIndex = 2440, + kX86InstIdPdep_NameIndex = 2450, + kX86InstIdPext_NameIndex = 2455, + kX86InstIdPextrb_NameIndex = 2460, + kX86InstIdPextrd_NameIndex = 2467, + kX86InstIdPextrq_NameIndex = 2474, + kX86InstIdPextrw_NameIndex = 2481, + kX86InstIdPf2id_NameIndex = 2488, + kX86InstIdPf2iw_NameIndex = 2494, + kX86InstIdPfacc_NameIndex = 2500, + kX86InstIdPfadd_NameIndex = 2506, + kX86InstIdPfcmpeq_NameIndex = 2512, + kX86InstIdPfcmpge_NameIndex = 2520, + kX86InstIdPfcmpgt_NameIndex = 2528, + kX86InstIdPfmax_NameIndex = 2536, + kX86InstIdPfmin_NameIndex = 2542, + kX86InstIdPfmul_NameIndex = 2548, + kX86InstIdPfnacc_NameIndex = 2554, + kX86InstIdPfpnacc_NameIndex = 2561, + kX86InstIdPfrcp_NameIndex = 2569, + kX86InstIdPfrcpit1_NameIndex = 2575, + kX86InstIdPfrcpit2_NameIndex = 2584, + kX86InstIdPfrsqit1_NameIndex = 2593, + kX86InstIdPfrsqrt_NameIndex = 2602, + kX86InstIdPfsub_NameIndex = 2610, + kX86InstIdPfsubr_NameIndex = 2616, + kX86InstIdPhaddd_NameIndex = 2623, + kX86InstIdPhaddsw_NameIndex = 2630, + kX86InstIdPhaddw_NameIndex = 2638, + kX86InstIdPhminposuw_NameIndex = 2645, + kX86InstIdPhsubd_NameIndex = 2656, + kX86InstIdPhsubsw_NameIndex = 2663, + kX86InstIdPhsubw_NameIndex = 2671, + kX86InstIdPi2fd_NameIndex = 2678, + kX86InstIdPi2fw_NameIndex = 2684, + kX86InstIdPinsrb_NameIndex = 2690, + kX86InstIdPinsrd_NameIndex = 2697, + kX86InstIdPinsrq_NameIndex = 2704, + kX86InstIdPinsrw_NameIndex = 2711, + kX86InstIdPmaddubsw_NameIndex = 2718, + kX86InstIdPmaddwd_NameIndex = 2728, + kX86InstIdPmaxsb_NameIndex = 2736, + kX86InstIdPmaxsd_NameIndex = 2743, + kX86InstIdPmaxsw_NameIndex = 2750, + kX86InstIdPmaxub_NameIndex = 2757, + kX86InstIdPmaxud_NameIndex = 2764, + kX86InstIdPmaxuw_NameIndex = 2771, + kX86InstIdPminsb_NameIndex = 2778, + kX86InstIdPminsd_NameIndex = 2785, + kX86InstIdPminsw_NameIndex = 2792, + kX86InstIdPminub_NameIndex = 2799, + kX86InstIdPminud_NameIndex = 2806, + kX86InstIdPminuw_NameIndex = 2813, + kX86InstIdPmovmskb_NameIndex = 2820, + kX86InstIdPmovsxbd_NameIndex = 2829, + kX86InstIdPmovsxbq_NameIndex = 2838, + kX86InstIdPmovsxbw_NameIndex = 2847, + kX86InstIdPmovsxdq_NameIndex = 2856, + kX86InstIdPmovsxwd_NameIndex = 2865, + kX86InstIdPmovsxwq_NameIndex = 2874, + kX86InstIdPmovzxbd_NameIndex = 2883, + kX86InstIdPmovzxbq_NameIndex = 2892, + kX86InstIdPmovzxbw_NameIndex = 2901, + kX86InstIdPmovzxdq_NameIndex = 2910, + kX86InstIdPmovzxwd_NameIndex = 2919, + kX86InstIdPmovzxwq_NameIndex = 2928, + kX86InstIdPmuldq_NameIndex = 2937, + kX86InstIdPmulhrsw_NameIndex = 2944, + kX86InstIdPmulhuw_NameIndex = 2953, + kX86InstIdPmulhw_NameIndex = 2961, + kX86InstIdPmulld_NameIndex = 2968, + kX86InstIdPmullw_NameIndex = 2975, + kX86InstIdPmuludq_NameIndex = 2982, + kX86InstIdPop_NameIndex = 2990, + kX86InstIdPopa_NameIndex = 2994, + kX86InstIdPopcnt_NameIndex = 2999, + kX86InstIdPopf_NameIndex = 3006, + kX86InstIdPor_NameIndex = 3011, + kX86InstIdPrefetch_NameIndex = 3015, + kX86InstIdPrefetch3dNow_NameIndex = 3024, + kX86InstIdPrefetchw3dNow_NameIndex = 3039, + kX86InstIdPsadbw_NameIndex = 3055, + kX86InstIdPshufb_NameIndex = 3062, + kX86InstIdPshufd_NameIndex = 3069, + kX86InstIdPshufhw_NameIndex = 3076, + kX86InstIdPshuflw_NameIndex = 3084, + kX86InstIdPshufw_NameIndex = 3092, + kX86InstIdPsignb_NameIndex = 3099, + kX86InstIdPsignd_NameIndex = 3106, + kX86InstIdPsignw_NameIndex = 3113, + kX86InstIdPslld_NameIndex = 3120, + kX86InstIdPslldq_NameIndex = 3126, + kX86InstIdPsllq_NameIndex = 3133, + kX86InstIdPsllw_NameIndex = 3139, + kX86InstIdPsrad_NameIndex = 3145, + kX86InstIdPsraw_NameIndex = 3151, + kX86InstIdPsrld_NameIndex = 3157, + kX86InstIdPsrldq_NameIndex = 3163, + kX86InstIdPsrlq_NameIndex = 3170, + kX86InstIdPsrlw_NameIndex = 3176, + kX86InstIdPsubb_NameIndex = 3182, + kX86InstIdPsubd_NameIndex = 3188, + kX86InstIdPsubq_NameIndex = 3194, + kX86InstIdPsubsb_NameIndex = 3200, + kX86InstIdPsubsw_NameIndex = 3207, + kX86InstIdPsubusb_NameIndex = 3214, + kX86InstIdPsubusw_NameIndex = 3222, + kX86InstIdPsubw_NameIndex = 3230, + kX86InstIdPswapd_NameIndex = 3236, + kX86InstIdPtest_NameIndex = 3243, + kX86InstIdPunpckhbw_NameIndex = 3249, + kX86InstIdPunpckhdq_NameIndex = 3259, + kX86InstIdPunpckhqdq_NameIndex = 3269, + kX86InstIdPunpckhwd_NameIndex = 3280, + kX86InstIdPunpcklbw_NameIndex = 3290, + kX86InstIdPunpckldq_NameIndex = 3300, + kX86InstIdPunpcklqdq_NameIndex = 3310, + kX86InstIdPunpcklwd_NameIndex = 3321, + kX86InstIdPush_NameIndex = 3331, + kX86InstIdPusha_NameIndex = 3336, + kX86InstIdPushf_NameIndex = 3342, + kX86InstIdPxor_NameIndex = 3348, + kX86InstIdRcl_NameIndex = 3353, + kX86InstIdRcpps_NameIndex = 3357, + kX86InstIdRcpss_NameIndex = 3363, + kX86InstIdRcr_NameIndex = 3369, + kX86InstIdRdfsbase_NameIndex = 3373, + kX86InstIdRdgsbase_NameIndex = 3382, + kX86InstIdRdrand_NameIndex = 3391, + kX86InstIdRdtsc_NameIndex = 3398, + kX86InstIdRdtscp_NameIndex = 3404, + kX86InstIdRepLodsB_NameIndex = 3411, + kX86InstIdRepLodsD_NameIndex = 3422, + kX86InstIdRepLodsQ_NameIndex = 3433, + kX86InstIdRepLodsW_NameIndex = 3444, + kX86InstIdRepMovsB_NameIndex = 3455, + kX86InstIdRepMovsD_NameIndex = 3466, + kX86InstIdRepMovsQ_NameIndex = 3477, + kX86InstIdRepMovsW_NameIndex = 3488, + kX86InstIdRepStosB_NameIndex = 3499, + kX86InstIdRepStosD_NameIndex = 3510, + kX86InstIdRepStosQ_NameIndex = 3521, + kX86InstIdRepStosW_NameIndex = 3532, + kX86InstIdRepeCmpsB_NameIndex = 3543, + kX86InstIdRepeCmpsD_NameIndex = 3555, + kX86InstIdRepeCmpsQ_NameIndex = 3567, + kX86InstIdRepeCmpsW_NameIndex = 3579, + kX86InstIdRepeScasB_NameIndex = 3591, + kX86InstIdRepeScasD_NameIndex = 3603, + kX86InstIdRepeScasQ_NameIndex = 3615, + kX86InstIdRepeScasW_NameIndex = 3627, + kX86InstIdRepneCmpsB_NameIndex = 3639, + kX86InstIdRepneCmpsD_NameIndex = 3652, + kX86InstIdRepneCmpsQ_NameIndex = 3665, + kX86InstIdRepneCmpsW_NameIndex = 3678, + kX86InstIdRepneScasB_NameIndex = 3691, + kX86InstIdRepneScasD_NameIndex = 3704, + kX86InstIdRepneScasQ_NameIndex = 3717, + kX86InstIdRepneScasW_NameIndex = 3730, + kX86InstIdRet_NameIndex = 3743, + kX86InstIdRol_NameIndex = 3747, + kX86InstIdRor_NameIndex = 3751, + kX86InstIdRorx_NameIndex = 3755, + kX86InstIdRoundpd_NameIndex = 3760, + kX86InstIdRoundps_NameIndex = 3768, + kX86InstIdRoundsd_NameIndex = 3776, + kX86InstIdRoundss_NameIndex = 3784, + kX86InstIdRsqrtps_NameIndex = 3792, + kX86InstIdRsqrtss_NameIndex = 3800, + kX86InstIdSahf_NameIndex = 3808, + kX86InstIdSal_NameIndex = 3813, + kX86InstIdSar_NameIndex = 3817, + kX86InstIdSarx_NameIndex = 3821, + kX86InstIdSbb_NameIndex = 3826, + kX86InstIdScasB_NameIndex = 3830, + kX86InstIdScasD_NameIndex = 3837, + kX86InstIdScasQ_NameIndex = 3844, + kX86InstIdScasW_NameIndex = 3851, + kX86InstIdSeta_NameIndex = 3858, + kX86InstIdSetae_NameIndex = 3863, + kX86InstIdSetb_NameIndex = 3869, + kX86InstIdSetbe_NameIndex = 3874, + kX86InstIdSetc_NameIndex = 3880, + kX86InstIdSete_NameIndex = 3885, + kX86InstIdSetg_NameIndex = 3890, + kX86InstIdSetge_NameIndex = 3895, + kX86InstIdSetl_NameIndex = 3901, + kX86InstIdSetle_NameIndex = 3906, + kX86InstIdSetna_NameIndex = 3912, + kX86InstIdSetnae_NameIndex = 3918, + kX86InstIdSetnb_NameIndex = 3925, + kX86InstIdSetnbe_NameIndex = 3931, + kX86InstIdSetnc_NameIndex = 3938, + kX86InstIdSetne_NameIndex = 3944, + kX86InstIdSetng_NameIndex = 3950, + kX86InstIdSetnge_NameIndex = 3956, + kX86InstIdSetnl_NameIndex = 3963, + kX86InstIdSetnle_NameIndex = 3969, + kX86InstIdSetno_NameIndex = 3976, + kX86InstIdSetnp_NameIndex = 3982, + kX86InstIdSetns_NameIndex = 3988, + kX86InstIdSetnz_NameIndex = 3994, + kX86InstIdSeto_NameIndex = 4000, + kX86InstIdSetp_NameIndex = 4005, + kX86InstIdSetpe_NameIndex = 4010, + kX86InstIdSetpo_NameIndex = 4016, + kX86InstIdSets_NameIndex = 4022, + kX86InstIdSetz_NameIndex = 4027, + kX86InstIdSfence_NameIndex = 4032, + kX86InstIdShl_NameIndex = 4039, + kX86InstIdShld_NameIndex = 4043, + kX86InstIdShlx_NameIndex = 4048, + kX86InstIdShr_NameIndex = 4053, + kX86InstIdShrd_NameIndex = 4057, + kX86InstIdShrx_NameIndex = 4062, + kX86InstIdShufpd_NameIndex = 4067, + kX86InstIdShufps_NameIndex = 4074, + kX86InstIdSqrtpd_NameIndex = 4081, + kX86InstIdSqrtps_NameIndex = 4088, + kX86InstIdSqrtsd_NameIndex = 4095, + kX86InstIdSqrtss_NameIndex = 4102, + kX86InstIdStc_NameIndex = 4109, + kX86InstIdStd_NameIndex = 4113, + kX86InstIdStmxcsr_NameIndex = 4117, + kX86InstIdStosB_NameIndex = 4125, + kX86InstIdStosD_NameIndex = 4132, + kX86InstIdStosQ_NameIndex = 4139, + kX86InstIdStosW_NameIndex = 4146, + kX86InstIdSub_NameIndex = 4153, + kX86InstIdSubpd_NameIndex = 4157, + kX86InstIdSubps_NameIndex = 4163, + kX86InstIdSubsd_NameIndex = 4169, + kX86InstIdSubss_NameIndex = 4175, + kX86InstIdTest_NameIndex = 4181, + kX86InstIdTzcnt_NameIndex = 4186, + kX86InstIdUcomisd_NameIndex = 4192, + kX86InstIdUcomiss_NameIndex = 4200, + kX86InstIdUd2_NameIndex = 4208, + kX86InstIdUnpckhpd_NameIndex = 4212, + kX86InstIdUnpckhps_NameIndex = 4221, + kX86InstIdUnpcklpd_NameIndex = 4230, + kX86InstIdUnpcklps_NameIndex = 4239, + kX86InstIdVaddpd_NameIndex = 4248, + kX86InstIdVaddps_NameIndex = 4255, + kX86InstIdVaddsd_NameIndex = 4262, + kX86InstIdVaddss_NameIndex = 4269, + kX86InstIdVaddsubpd_NameIndex = 4276, + kX86InstIdVaddsubps_NameIndex = 4286, + kX86InstIdVaesdec_NameIndex = 4296, + kX86InstIdVaesdeclast_NameIndex = 4304, + kX86InstIdVaesenc_NameIndex = 4316, + kX86InstIdVaesenclast_NameIndex = 4324, + kX86InstIdVaesimc_NameIndex = 4336, + kX86InstIdVaeskeygenassist_NameIndex = 4344, + kX86InstIdVandnpd_NameIndex = 4361, + kX86InstIdVandnps_NameIndex = 4369, + kX86InstIdVandpd_NameIndex = 4377, + kX86InstIdVandps_NameIndex = 4384, + kX86InstIdVblendpd_NameIndex = 4391, + kX86InstIdVblendps_NameIndex = 4400, + kX86InstIdVblendvpd_NameIndex = 4409, + kX86InstIdVblendvps_NameIndex = 4419, + kX86InstIdVbroadcastf128_NameIndex = 4429, + kX86InstIdVbroadcasti128_NameIndex = 4444, + kX86InstIdVbroadcastsd_NameIndex = 4459, + kX86InstIdVbroadcastss_NameIndex = 4472, + kX86InstIdVcmppd_NameIndex = 4485, + kX86InstIdVcmpps_NameIndex = 4492, + kX86InstIdVcmpsd_NameIndex = 4499, + kX86InstIdVcmpss_NameIndex = 4506, + kX86InstIdVcomisd_NameIndex = 4513, + kX86InstIdVcomiss_NameIndex = 4521, + kX86InstIdVcvtdq2pd_NameIndex = 4529, + kX86InstIdVcvtdq2ps_NameIndex = 4539, + kX86InstIdVcvtpd2dq_NameIndex = 4549, + kX86InstIdVcvtpd2ps_NameIndex = 4559, + kX86InstIdVcvtph2ps_NameIndex = 4569, + kX86InstIdVcvtps2dq_NameIndex = 4579, + kX86InstIdVcvtps2pd_NameIndex = 4589, + kX86InstIdVcvtps2ph_NameIndex = 4599, + kX86InstIdVcvtsd2si_NameIndex = 4609, + kX86InstIdVcvtsd2ss_NameIndex = 4619, + kX86InstIdVcvtsi2sd_NameIndex = 4629, + kX86InstIdVcvtsi2ss_NameIndex = 4639, + kX86InstIdVcvtss2sd_NameIndex = 4649, + kX86InstIdVcvtss2si_NameIndex = 4659, + kX86InstIdVcvttpd2dq_NameIndex = 4669, + kX86InstIdVcvttps2dq_NameIndex = 4680, + kX86InstIdVcvttsd2si_NameIndex = 4691, + kX86InstIdVcvttss2si_NameIndex = 4702, + kX86InstIdVdivpd_NameIndex = 4713, + kX86InstIdVdivps_NameIndex = 4720, + kX86InstIdVdivsd_NameIndex = 4727, + kX86InstIdVdivss_NameIndex = 4734, + kX86InstIdVdppd_NameIndex = 4741, + kX86InstIdVdpps_NameIndex = 4747, + kX86InstIdVextractf128_NameIndex = 4753, + kX86InstIdVextracti128_NameIndex = 4766, + kX86InstIdVextractps_NameIndex = 4779, + kX86InstIdVfmadd132pd_NameIndex = 4790, + kX86InstIdVfmadd132ps_NameIndex = 4802, + kX86InstIdVfmadd132sd_NameIndex = 4814, + kX86InstIdVfmadd132ss_NameIndex = 4826, + kX86InstIdVfmadd213pd_NameIndex = 4838, + kX86InstIdVfmadd213ps_NameIndex = 4850, + kX86InstIdVfmadd213sd_NameIndex = 4862, + kX86InstIdVfmadd213ss_NameIndex = 4874, + kX86InstIdVfmadd231pd_NameIndex = 4886, + kX86InstIdVfmadd231ps_NameIndex = 4898, + kX86InstIdVfmadd231sd_NameIndex = 4910, + kX86InstIdVfmadd231ss_NameIndex = 4922, + kX86InstIdVfmaddpd_NameIndex = 4934, + kX86InstIdVfmaddps_NameIndex = 4943, + kX86InstIdVfmaddsd_NameIndex = 4952, + kX86InstIdVfmaddss_NameIndex = 4961, + kX86InstIdVfmaddsub132pd_NameIndex = 4970, + kX86InstIdVfmaddsub132ps_NameIndex = 4985, + kX86InstIdVfmaddsub213pd_NameIndex = 5000, + kX86InstIdVfmaddsub213ps_NameIndex = 5015, + kX86InstIdVfmaddsub231pd_NameIndex = 5030, + kX86InstIdVfmaddsub231ps_NameIndex = 5045, + kX86InstIdVfmaddsubpd_NameIndex = 5060, + kX86InstIdVfmaddsubps_NameIndex = 5072, + kX86InstIdVfmsub132pd_NameIndex = 5084, + kX86InstIdVfmsub132ps_NameIndex = 5096, + kX86InstIdVfmsub132sd_NameIndex = 5108, + kX86InstIdVfmsub132ss_NameIndex = 5120, + kX86InstIdVfmsub213pd_NameIndex = 5132, + kX86InstIdVfmsub213ps_NameIndex = 5144, + kX86InstIdVfmsub213sd_NameIndex = 5156, + kX86InstIdVfmsub213ss_NameIndex = 5168, + kX86InstIdVfmsub231pd_NameIndex = 5180, + kX86InstIdVfmsub231ps_NameIndex = 5192, + kX86InstIdVfmsub231sd_NameIndex = 5204, + kX86InstIdVfmsub231ss_NameIndex = 5216, + kX86InstIdVfmsubadd132pd_NameIndex = 5228, + kX86InstIdVfmsubadd132ps_NameIndex = 5243, + kX86InstIdVfmsubadd213pd_NameIndex = 5258, + kX86InstIdVfmsubadd213ps_NameIndex = 5273, + kX86InstIdVfmsubadd231pd_NameIndex = 5288, + kX86InstIdVfmsubadd231ps_NameIndex = 5303, + kX86InstIdVfmsubaddpd_NameIndex = 5318, + kX86InstIdVfmsubaddps_NameIndex = 5330, + kX86InstIdVfmsubpd_NameIndex = 5342, + kX86InstIdVfmsubps_NameIndex = 5351, + kX86InstIdVfmsubsd_NameIndex = 5360, + kX86InstIdVfmsubss_NameIndex = 5369, + kX86InstIdVfnmadd132pd_NameIndex = 5378, + kX86InstIdVfnmadd132ps_NameIndex = 5391, + kX86InstIdVfnmadd132sd_NameIndex = 5404, + kX86InstIdVfnmadd132ss_NameIndex = 5417, + kX86InstIdVfnmadd213pd_NameIndex = 5430, + kX86InstIdVfnmadd213ps_NameIndex = 5443, + kX86InstIdVfnmadd213sd_NameIndex = 5456, + kX86InstIdVfnmadd213ss_NameIndex = 5469, + kX86InstIdVfnmadd231pd_NameIndex = 5482, + kX86InstIdVfnmadd231ps_NameIndex = 5495, + kX86InstIdVfnmadd231sd_NameIndex = 5508, + kX86InstIdVfnmadd231ss_NameIndex = 5521, + kX86InstIdVfnmaddpd_NameIndex = 5534, + kX86InstIdVfnmaddps_NameIndex = 5544, + kX86InstIdVfnmaddsd_NameIndex = 5554, + kX86InstIdVfnmaddss_NameIndex = 5564, + kX86InstIdVfnmsub132pd_NameIndex = 5574, + kX86InstIdVfnmsub132ps_NameIndex = 5587, + kX86InstIdVfnmsub132sd_NameIndex = 5600, + kX86InstIdVfnmsub132ss_NameIndex = 5613, + kX86InstIdVfnmsub213pd_NameIndex = 5626, + kX86InstIdVfnmsub213ps_NameIndex = 5639, + kX86InstIdVfnmsub213sd_NameIndex = 5652, + kX86InstIdVfnmsub213ss_NameIndex = 5665, + kX86InstIdVfnmsub231pd_NameIndex = 5678, + kX86InstIdVfnmsub231ps_NameIndex = 5691, + kX86InstIdVfnmsub231sd_NameIndex = 5704, + kX86InstIdVfnmsub231ss_NameIndex = 5717, + kX86InstIdVfnmsubpd_NameIndex = 5730, + kX86InstIdVfnmsubps_NameIndex = 5740, + kX86InstIdVfnmsubsd_NameIndex = 5750, + kX86InstIdVfnmsubss_NameIndex = 5760, + kX86InstIdVfrczpd_NameIndex = 5770, + kX86InstIdVfrczps_NameIndex = 5778, + kX86InstIdVfrczsd_NameIndex = 5786, + kX86InstIdVfrczss_NameIndex = 5794, + kX86InstIdVgatherdpd_NameIndex = 5802, + kX86InstIdVgatherdps_NameIndex = 5813, + kX86InstIdVgatherqpd_NameIndex = 5824, + kX86InstIdVgatherqps_NameIndex = 5835, + kX86InstIdVhaddpd_NameIndex = 5846, + kX86InstIdVhaddps_NameIndex = 5854, + kX86InstIdVhsubpd_NameIndex = 5862, + kX86InstIdVhsubps_NameIndex = 5870, + kX86InstIdVinsertf128_NameIndex = 5878, + kX86InstIdVinserti128_NameIndex = 5890, + kX86InstIdVinsertps_NameIndex = 5902, + kX86InstIdVlddqu_NameIndex = 5912, + kX86InstIdVldmxcsr_NameIndex = 5919, + kX86InstIdVmaskmovdqu_NameIndex = 5928, + kX86InstIdVmaskmovpd_NameIndex = 5940, + kX86InstIdVmaskmovps_NameIndex = 5951, + kX86InstIdVmaxpd_NameIndex = 5962, + kX86InstIdVmaxps_NameIndex = 5969, + kX86InstIdVmaxsd_NameIndex = 5976, + kX86InstIdVmaxss_NameIndex = 5983, + kX86InstIdVminpd_NameIndex = 5990, + kX86InstIdVminps_NameIndex = 5997, + kX86InstIdVminsd_NameIndex = 6004, + kX86InstIdVminss_NameIndex = 6011, + kX86InstIdVmovapd_NameIndex = 6018, + kX86InstIdVmovaps_NameIndex = 6026, + kX86InstIdVmovd_NameIndex = 6034, + kX86InstIdVmovddup_NameIndex = 6040, + kX86InstIdVmovdqa_NameIndex = 6049, + kX86InstIdVmovdqu_NameIndex = 6057, + kX86InstIdVmovhlps_NameIndex = 6065, + kX86InstIdVmovhpd_NameIndex = 6074, + kX86InstIdVmovhps_NameIndex = 6082, + kX86InstIdVmovlhps_NameIndex = 6090, + kX86InstIdVmovlpd_NameIndex = 6099, + kX86InstIdVmovlps_NameIndex = 6107, + kX86InstIdVmovmskpd_NameIndex = 6115, + kX86InstIdVmovmskps_NameIndex = 6125, + kX86InstIdVmovntdq_NameIndex = 6135, + kX86InstIdVmovntdqa_NameIndex = 6144, + kX86InstIdVmovntpd_NameIndex = 6154, + kX86InstIdVmovntps_NameIndex = 6163, + kX86InstIdVmovq_NameIndex = 6172, + kX86InstIdVmovsd_NameIndex = 6178, + kX86InstIdVmovshdup_NameIndex = 6185, + kX86InstIdVmovsldup_NameIndex = 6195, + kX86InstIdVmovss_NameIndex = 6205, + kX86InstIdVmovupd_NameIndex = 6212, + kX86InstIdVmovups_NameIndex = 6220, + kX86InstIdVmpsadbw_NameIndex = 6228, + kX86InstIdVmulpd_NameIndex = 6237, + kX86InstIdVmulps_NameIndex = 6244, + kX86InstIdVmulsd_NameIndex = 6251, + kX86InstIdVmulss_NameIndex = 6258, + kX86InstIdVorpd_NameIndex = 6265, + kX86InstIdVorps_NameIndex = 6271, + kX86InstIdVpabsb_NameIndex = 6277, + kX86InstIdVpabsd_NameIndex = 6284, + kX86InstIdVpabsw_NameIndex = 6291, + kX86InstIdVpackssdw_NameIndex = 6298, + kX86InstIdVpacksswb_NameIndex = 6308, + kX86InstIdVpackusdw_NameIndex = 6318, + kX86InstIdVpackuswb_NameIndex = 6328, + kX86InstIdVpaddb_NameIndex = 6338, + kX86InstIdVpaddd_NameIndex = 6345, + kX86InstIdVpaddq_NameIndex = 6352, + kX86InstIdVpaddsb_NameIndex = 6359, + kX86InstIdVpaddsw_NameIndex = 6367, + kX86InstIdVpaddusb_NameIndex = 6375, + kX86InstIdVpaddusw_NameIndex = 6384, + kX86InstIdVpaddw_NameIndex = 6393, + kX86InstIdVpalignr_NameIndex = 6400, + kX86InstIdVpand_NameIndex = 6409, + kX86InstIdVpandn_NameIndex = 6415, + kX86InstIdVpavgb_NameIndex = 6422, + kX86InstIdVpavgw_NameIndex = 6429, + kX86InstIdVpblendd_NameIndex = 6436, + kX86InstIdVpblendvb_NameIndex = 6445, + kX86InstIdVpblendw_NameIndex = 6455, + kX86InstIdVpbroadcastb_NameIndex = 6464, + kX86InstIdVpbroadcastd_NameIndex = 6477, + kX86InstIdVpbroadcastq_NameIndex = 6490, + kX86InstIdVpbroadcastw_NameIndex = 6503, + kX86InstIdVpclmulqdq_NameIndex = 6516, + kX86InstIdVpcmov_NameIndex = 6527, + kX86InstIdVpcmpeqb_NameIndex = 6534, + kX86InstIdVpcmpeqd_NameIndex = 6543, + kX86InstIdVpcmpeqq_NameIndex = 6552, + kX86InstIdVpcmpeqw_NameIndex = 6561, + kX86InstIdVpcmpestri_NameIndex = 6570, + kX86InstIdVpcmpestrm_NameIndex = 6581, + kX86InstIdVpcmpgtb_NameIndex = 6592, + kX86InstIdVpcmpgtd_NameIndex = 6601, + kX86InstIdVpcmpgtq_NameIndex = 6610, + kX86InstIdVpcmpgtw_NameIndex = 6619, + kX86InstIdVpcmpistri_NameIndex = 6628, + kX86InstIdVpcmpistrm_NameIndex = 6639, + kX86InstIdVpcomb_NameIndex = 6650, + kX86InstIdVpcomd_NameIndex = 6657, + kX86InstIdVpcomq_NameIndex = 6664, + kX86InstIdVpcomub_NameIndex = 6671, + kX86InstIdVpcomud_NameIndex = 6679, + kX86InstIdVpcomuq_NameIndex = 6687, + kX86InstIdVpcomuw_NameIndex = 6695, + kX86InstIdVpcomw_NameIndex = 6703, + kX86InstIdVperm2f128_NameIndex = 6710, + kX86InstIdVperm2i128_NameIndex = 6721, + kX86InstIdVpermd_NameIndex = 6732, + kX86InstIdVpermil2pd_NameIndex = 6739, + kX86InstIdVpermil2ps_NameIndex = 6750, + kX86InstIdVpermilpd_NameIndex = 6761, + kX86InstIdVpermilps_NameIndex = 6771, + kX86InstIdVpermpd_NameIndex = 6781, + kX86InstIdVpermps_NameIndex = 6789, + kX86InstIdVpermq_NameIndex = 6797, + kX86InstIdVpextrb_NameIndex = 6804, + kX86InstIdVpextrd_NameIndex = 6812, + kX86InstIdVpextrq_NameIndex = 6820, + kX86InstIdVpextrw_NameIndex = 6828, + kX86InstIdVpgatherdd_NameIndex = 6836, + kX86InstIdVpgatherdq_NameIndex = 6847, + kX86InstIdVpgatherqd_NameIndex = 6858, + kX86InstIdVpgatherqq_NameIndex = 6869, + kX86InstIdVphaddbd_NameIndex = 6880, + kX86InstIdVphaddbq_NameIndex = 6889, + kX86InstIdVphaddbw_NameIndex = 6898, + kX86InstIdVphaddd_NameIndex = 6907, + kX86InstIdVphadddq_NameIndex = 6915, + kX86InstIdVphaddsw_NameIndex = 6924, + kX86InstIdVphaddubd_NameIndex = 6933, + kX86InstIdVphaddubq_NameIndex = 6943, + kX86InstIdVphaddubw_NameIndex = 6953, + kX86InstIdVphaddudq_NameIndex = 6963, + kX86InstIdVphadduwd_NameIndex = 6973, + kX86InstIdVphadduwq_NameIndex = 6983, + kX86InstIdVphaddw_NameIndex = 6993, + kX86InstIdVphaddwd_NameIndex = 7001, + kX86InstIdVphaddwq_NameIndex = 7010, + kX86InstIdVphminposuw_NameIndex = 7019, + kX86InstIdVphsubbw_NameIndex = 7031, + kX86InstIdVphsubd_NameIndex = 7040, + kX86InstIdVphsubdq_NameIndex = 7048, + kX86InstIdVphsubsw_NameIndex = 7057, + kX86InstIdVphsubw_NameIndex = 7066, + kX86InstIdVphsubwd_NameIndex = 7074, + kX86InstIdVpinsrb_NameIndex = 7083, + kX86InstIdVpinsrd_NameIndex = 7091, + kX86InstIdVpinsrq_NameIndex = 7099, + kX86InstIdVpinsrw_NameIndex = 7107, + kX86InstIdVpmacsdd_NameIndex = 7115, + kX86InstIdVpmacsdqh_NameIndex = 7124, + kX86InstIdVpmacsdql_NameIndex = 7134, + kX86InstIdVpmacssdd_NameIndex = 7144, + kX86InstIdVpmacssdqh_NameIndex = 7154, + kX86InstIdVpmacssdql_NameIndex = 7165, + kX86InstIdVpmacsswd_NameIndex = 7176, + kX86InstIdVpmacssww_NameIndex = 7186, + kX86InstIdVpmacswd_NameIndex = 7196, + kX86InstIdVpmacsww_NameIndex = 7205, + kX86InstIdVpmadcsswd_NameIndex = 7214, + kX86InstIdVpmadcswd_NameIndex = 7225, + kX86InstIdVpmaddubsw_NameIndex = 7235, + kX86InstIdVpmaddwd_NameIndex = 7246, + kX86InstIdVpmaskmovd_NameIndex = 7255, + kX86InstIdVpmaskmovq_NameIndex = 7266, + kX86InstIdVpmaxsb_NameIndex = 7277, + kX86InstIdVpmaxsd_NameIndex = 7285, + kX86InstIdVpmaxsw_NameIndex = 7293, + kX86InstIdVpmaxub_NameIndex = 7301, + kX86InstIdVpmaxud_NameIndex = 7309, + kX86InstIdVpmaxuw_NameIndex = 7317, + kX86InstIdVpminsb_NameIndex = 7325, + kX86InstIdVpminsd_NameIndex = 7333, + kX86InstIdVpminsw_NameIndex = 7341, + kX86InstIdVpminub_NameIndex = 7349, + kX86InstIdVpminud_NameIndex = 7357, + kX86InstIdVpminuw_NameIndex = 7365, + kX86InstIdVpmovmskb_NameIndex = 7373, + kX86InstIdVpmovsxbd_NameIndex = 7383, + kX86InstIdVpmovsxbq_NameIndex = 7393, + kX86InstIdVpmovsxbw_NameIndex = 7403, + kX86InstIdVpmovsxdq_NameIndex = 7413, + kX86InstIdVpmovsxwd_NameIndex = 7423, + kX86InstIdVpmovsxwq_NameIndex = 7433, + kX86InstIdVpmovzxbd_NameIndex = 7443, + kX86InstIdVpmovzxbq_NameIndex = 7453, + kX86InstIdVpmovzxbw_NameIndex = 7463, + kX86InstIdVpmovzxdq_NameIndex = 7473, + kX86InstIdVpmovzxwd_NameIndex = 7483, + kX86InstIdVpmovzxwq_NameIndex = 7493, + kX86InstIdVpmuldq_NameIndex = 7503, + kX86InstIdVpmulhrsw_NameIndex = 7511, + kX86InstIdVpmulhuw_NameIndex = 7521, + kX86InstIdVpmulhw_NameIndex = 7530, + kX86InstIdVpmulld_NameIndex = 7538, + kX86InstIdVpmullw_NameIndex = 7546, + kX86InstIdVpmuludq_NameIndex = 7554, + kX86InstIdVpor_NameIndex = 7563, + kX86InstIdVpperm_NameIndex = 7568, + kX86InstIdVprotb_NameIndex = 7575, + kX86InstIdVprotd_NameIndex = 7582, + kX86InstIdVprotq_NameIndex = 7589, + kX86InstIdVprotw_NameIndex = 7596, + kX86InstIdVpsadbw_NameIndex = 7603, + kX86InstIdVpshab_NameIndex = 7611, + kX86InstIdVpshad_NameIndex = 7618, + kX86InstIdVpshaq_NameIndex = 7625, + kX86InstIdVpshaw_NameIndex = 7632, + kX86InstIdVpshlb_NameIndex = 7639, + kX86InstIdVpshld_NameIndex = 7646, + kX86InstIdVpshlq_NameIndex = 7653, + kX86InstIdVpshlw_NameIndex = 7660, + kX86InstIdVpshufb_NameIndex = 7667, + kX86InstIdVpshufd_NameIndex = 7675, + kX86InstIdVpshufhw_NameIndex = 7683, + kX86InstIdVpshuflw_NameIndex = 7692, + kX86InstIdVpsignb_NameIndex = 7701, + kX86InstIdVpsignd_NameIndex = 7709, + kX86InstIdVpsignw_NameIndex = 7717, + kX86InstIdVpslld_NameIndex = 7725, + kX86InstIdVpslldq_NameIndex = 7732, + kX86InstIdVpsllq_NameIndex = 7740, + kX86InstIdVpsllvd_NameIndex = 7747, + kX86InstIdVpsllvq_NameIndex = 7755, + kX86InstIdVpsllw_NameIndex = 7763, + kX86InstIdVpsrad_NameIndex = 7770, + kX86InstIdVpsravd_NameIndex = 7777, + kX86InstIdVpsraw_NameIndex = 7785, + kX86InstIdVpsrld_NameIndex = 7792, + kX86InstIdVpsrldq_NameIndex = 7799, + kX86InstIdVpsrlq_NameIndex = 7807, + kX86InstIdVpsrlvd_NameIndex = 7814, + kX86InstIdVpsrlvq_NameIndex = 7822, + kX86InstIdVpsrlw_NameIndex = 7830, + kX86InstIdVpsubb_NameIndex = 7837, + kX86InstIdVpsubd_NameIndex = 7844, + kX86InstIdVpsubq_NameIndex = 7851, + kX86InstIdVpsubsb_NameIndex = 7858, + kX86InstIdVpsubsw_NameIndex = 7866, + kX86InstIdVpsubusb_NameIndex = 7874, + kX86InstIdVpsubusw_NameIndex = 7883, + kX86InstIdVpsubw_NameIndex = 7892, + kX86InstIdVptest_NameIndex = 7899, + kX86InstIdVpunpckhbw_NameIndex = 7906, + kX86InstIdVpunpckhdq_NameIndex = 7917, + kX86InstIdVpunpckhqdq_NameIndex = 7928, + kX86InstIdVpunpckhwd_NameIndex = 7940, + kX86InstIdVpunpcklbw_NameIndex = 7951, + kX86InstIdVpunpckldq_NameIndex = 7962, + kX86InstIdVpunpcklqdq_NameIndex = 7973, + kX86InstIdVpunpcklwd_NameIndex = 7985, + kX86InstIdVpxor_NameIndex = 7996, + kX86InstIdVrcpps_NameIndex = 8002, + kX86InstIdVrcpss_NameIndex = 8009, + kX86InstIdVroundpd_NameIndex = 8016, + kX86InstIdVroundps_NameIndex = 8025, + kX86InstIdVroundsd_NameIndex = 8034, + kX86InstIdVroundss_NameIndex = 8043, + kX86InstIdVrsqrtps_NameIndex = 8052, + kX86InstIdVrsqrtss_NameIndex = 8061, + kX86InstIdVshufpd_NameIndex = 8070, + kX86InstIdVshufps_NameIndex = 8078, + kX86InstIdVsqrtpd_NameIndex = 8086, + kX86InstIdVsqrtps_NameIndex = 8094, + kX86InstIdVsqrtsd_NameIndex = 8102, + kX86InstIdVsqrtss_NameIndex = 8110, + kX86InstIdVstmxcsr_NameIndex = 8118, + kX86InstIdVsubpd_NameIndex = 8127, + kX86InstIdVsubps_NameIndex = 8134, + kX86InstIdVsubsd_NameIndex = 8141, + kX86InstIdVsubss_NameIndex = 8148, + kX86InstIdVtestpd_NameIndex = 8155, + kX86InstIdVtestps_NameIndex = 8163, + kX86InstIdVucomisd_NameIndex = 8171, + kX86InstIdVucomiss_NameIndex = 8180, + kX86InstIdVunpckhpd_NameIndex = 8189, + kX86InstIdVunpckhps_NameIndex = 8199, + kX86InstIdVunpcklpd_NameIndex = 8209, + kX86InstIdVunpcklps_NameIndex = 8219, + kX86InstIdVxorpd_NameIndex = 8229, + kX86InstIdVxorps_NameIndex = 8236, + kX86InstIdVzeroall_NameIndex = 8243, + kX86InstIdVzeroupper_NameIndex = 8252, + kX86InstIdWrfsbase_NameIndex = 8263, + kX86InstIdWrgsbase_NameIndex = 8272, + kX86InstIdXadd_NameIndex = 8281, + kX86InstIdXchg_NameIndex = 8286, + kX86InstIdXor_NameIndex = 8291, + kX86InstIdXorpd_NameIndex = 8295, + kX86InstIdXorps_NameIndex = 8301 }; -// ${kInstData:End} -#endif // !ASMJIT_DISABLE_INST_NAMES +#endif // !ASMJIT_DISABLE_NAMES -#if !defined(ASMJIT_DISABLE_INST_NAMES) -# define INST_NAME_INDEX(_Code_) _Code_##_NameIndex -#else -# define INST_NAME_INDEX(_Code_) 0 -#endif - -#define INST(_Code_, _Name_, _Group_, _Flags_, _MoveSize_, _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_, _OpCode0_, _OpCode1_) \ - { INST_NAME_INDEX(_Code_), _Flags_, _Group_, _MoveSize_, { 0, 0 }, { _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_ }, { _OpCode0_, _OpCode1_ } } - -#define G(_Group_) kInstGroup##_Group_ -#define F(_Flags_) kInstFlag##_Flags_ -#define O(_Op_) kInstOp##_Op_ - -#define U 0 -#define L kInstOpCode_L_True - -#define O_000000(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_000F00(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_000F01(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_0F01 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_000F0F(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_000F38(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_000F3A(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_660000(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_660F00(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_660F38(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_660F3A(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_9B0000(_OpCode_, _R_) (kInstOpCode_PP_9B | kInstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F20000(_OpCode_, _R_) (kInstOpCode_PP_F2 | kInstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F20F00(_OpCode_, _R_) (kInstOpCode_PP_F2 | kInstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F20F38(_OpCode_, _R_) (kInstOpCode_PP_F2 | kInstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F20F3A(_OpCode_, _R_) (kInstOpCode_PP_F2 | kInstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F30000(_OpCode_, _R_) (kInstOpCode_PP_F3 | kInstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F30F00(_OpCode_, _R_) (kInstOpCode_PP_F3 | kInstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F30F38(_OpCode_, _R_) (kInstOpCode_PP_F3 | kInstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_F30F3A(_OpCode_, _R_) (kInstOpCode_PP_F3 | kInstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) - -#define O_00_M03(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_00_M08(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_00_M09(_OpCode_, _R_) (kInstOpCode_PP_00 | kInstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) - -#define O_66_M03(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_66_M08(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_66_M09(_OpCode_, _R_) (kInstOpCode_PP_66 | kInstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) - -#define O_00_X(_OpCode_, _R_) (kInstOpCode_PP_00 | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) -#define O_9B_X(_OpCode_, _R_) (kInstOpCode_PP_9B | (0x##_OpCode_) | ((_R_) << kInstOpCode_O_Shift)) - -const InstInfo _instInfo[] = { - // Inst-Code | Inst-Name | Inst-Group | Inst-Flags | M | Op-Flags[0] | Op-Flags[1] | Op-Flags[2] | Op-Flags[2] | Op[0] | Op[1] | - INST(kInstNone , "" , G(None) , F(None) , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), - INST(kInstAdc , "adc" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(10,2) , U ), - INST(kInstAdd , "add" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(00,0) , U ), - INST(kInstAddpd , "addpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(58,U) , U ), - INST(kInstAddps , "addps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(58,U) , U ), - INST(kInstAddsd , "addsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(58,U) , U ), - INST(kInstAddss , "addss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(58,U) , U ), - INST(kInstAddsubpd , "addsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(D0,U) , U ), - INST(kInstAddsubps , "addsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(D0,U) , U ), - INST(kInstAesdec , "aesdec" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DE,U) , U ), - INST(kInstAesdeclast , "aesdeclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DF,U) , U ), - INST(kInstAesenc , "aesenc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DC,U) , U ), - INST(kInstAesenclast , "aesenclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DD,U) , U ), - INST(kInstAesimc , "aesimc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DB,U) , U ), - INST(kInstAeskeygenassist , "aeskeygenassist" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(DF,U) , U ), - INST(kInstAnd , "and" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(20,4) , U ), - INST(kInstAndn , "andn" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , O_000F38(F2,U) , U ), - INST(kInstAndnpd , "andnpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(55,U) , U ), - INST(kInstAndnps , "andnps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(55,U) , U ), - INST(kInstAndpd , "andpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(54,U) , U ), - INST(kInstAndps , "andps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(54,U) , U ), - INST(kInstBextr , "bextr" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , O_000F38(F7,U) , U ), - INST(kInstBlendpd , "blendpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(0D,U) , U ), - INST(kInstBlendps , "blendps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(0C,U) , U ), - INST(kInstBlendvpd , "blendvpd" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(15,U) , U ), - INST(kInstBlendvps , "blendvps" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(14,U) , U ), - INST(kInstBlsi , "blsi" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , O_000F38(F3,3) , U ), - INST(kInstBlsmsk , "blsmsk" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , O_000F38(F3,2) , U ), - INST(kInstBlsr , "blsr" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , O_000F38(F3,1) , U ), - INST(kInstBsf , "bsf" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(BC,U) , U ), - INST(kInstBsr , "bsr" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(BD,U) , U ), - INST(kInstBswap , "bswap" , G(X86BSwap) , F(None) , 0 , O(Gqd) , U , U , U , O_000F00(C8,U) , U ), - INST(kInstBt , "bt" , G(X86BTest) , F(Test) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , O_000F00(A3,U) , O_000F00(BA,4) ), - INST(kInstBtc , "btc" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , O_000F00(BB,U) , O_000F00(BA,7) ), - INST(kInstBtr , "btr" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , O_000F00(B3,U) , O_000F00(BA,6) ), - INST(kInstBts , "bts" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , O_000F00(AB,U) , O_000F00(BA,5) ), - INST(kInstBzhi , "bzhi" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , O_000F38(F5,U) , U ), - INST(kInstCall , "call" , G(X86Call) , F(Flow) , 0 , O(GqdMem)|O(Imm)|O(Label), U , U , U , O_000000(FF,2) , O_000000(E8,U) ), - INST(kInstCbw , "cbw" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_660000(98,U) , U ), - INST(kInstCdq , "cdq" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(99,U) , U ), - INST(kInstCdqe , "cdqe" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , O_000000(98,U) , U ), - INST(kInstClc , "clc" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(F8,U) , U ), - INST(kInstCld , "cld" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(FC,U) , U ), - INST(kInstClflush , "clflush" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(AE,7) , U ), - INST(kInstCmc , "cmc" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(F5,U) , U ), - INST(kInstCmova , "cmova" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(47,U) , U ), - INST(kInstCmovae , "cmovae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(43,U) , U ), - INST(kInstCmovb , "cmovb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(42,U) , U ), - INST(kInstCmovbe , "cmovbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(46,U) , U ), - INST(kInstCmovc , "cmovc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(42,U) , U ), - INST(kInstCmove , "cmove" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(44,U) , U ), - INST(kInstCmovg , "cmovg" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4F,U) , U ), - INST(kInstCmovge , "cmovge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4D,U) , U ), - INST(kInstCmovl , "cmovl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4C,U) , U ), - INST(kInstCmovle , "cmovle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4E,U) , U ), - INST(kInstCmovna , "cmovna" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(46,U) , U ), - INST(kInstCmovnae , "cmovnae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(42,U) , U ), - INST(kInstCmovnb , "cmovnb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(43,U) , U ), - INST(kInstCmovnbe , "cmovnbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(47,U) , U ), - INST(kInstCmovnc , "cmovnc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(43,U) , U ), - INST(kInstCmovne , "cmovne" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(45,U) , U ), - INST(kInstCmovng , "cmovng" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4E,U) , U ), - INST(kInstCmovnge , "cmovnge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4C,U) , U ), - INST(kInstCmovnl , "cmovnl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4D,U) , U ), - INST(kInstCmovnle , "cmovnle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4F,U) , U ), - INST(kInstCmovno , "cmovno" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(41,U) , U ), - INST(kInstCmovnp , "cmovnp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4B,U) , U ), - INST(kInstCmovns , "cmovns" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(49,U) , U ), - INST(kInstCmovnz , "cmovnz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(45,U) , U ), - INST(kInstCmovo , "cmovo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(40,U) , U ), - INST(kInstCmovp , "cmovp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4A,U) , U ), - INST(kInstCmovpe , "cmovpe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4A,U) , U ), - INST(kInstCmovpo , "cmovpo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(4B,U) , U ), - INST(kInstCmovs , "cmovs" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(48,U) , U ), - INST(kInstCmovz , "cmovz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_000F00(44,U) , U ), - INST(kInstCmp , "cmp" , G(X86Arith) , F(Test) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(38,7) , U ), - INST(kInstCmppd , "cmppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F00(C2,U) , U ), - INST(kInstCmpps , "cmpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_000F00(C2,U) , U ), - INST(kInstCmpsd , "cmpsd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_F20F00(C2,U) , U ), - INST(kInstCmpss , "cmpss" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_F30F00(C2,U) , U ), - INST(kInstCmpxchg , "cmpxchg" , G(X86RmReg) , F(Lock)|F(Special) , 0 , U , U , U , U , O_000F00(B0,U) , U ), - INST(kInstCmpxchg16b , "cmpxchg16b" , G(X86M) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , O_000F00(C7,1) , U ), - INST(kInstCmpxchg8b , "cmpxchg8b" , G(X86M) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_000F00(C7,1) , U ), - INST(kInstComisd , "comisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(2F,U) , U ), - INST(kInstComiss , "comiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(2F,U) , U ), - INST(kInstCpuid , "cpuid" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F00(A2,U) , U ), - INST(kInstCqo , "cqo" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , O_000000(99,U) , U ), - INST(kInstCrc32 , "crc32" , G(ExtCrc) , F(None) , 0 , O(Gqd) , O(GqdwbMem) , U , U , O_F20F38(F0,U) , U ), - INST(kInstCvtdq2pd , "cvtdq2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F30F00(E6,U) , U ), - INST(kInstCvtdq2ps , "cvtdq2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_000F00(5B,U) , U ), - INST(kInstCvtpd2dq , "cvtpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F20F00(E6,U) , U ), - INST(kInstCvtpd2pi , "cvtpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , O_660F00(2D,U) , U ), - INST(kInstCvtpd2ps , "cvtpd2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F00(5A,U) , U ), - INST(kInstCvtpi2pd , "cvtpi2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(MmMem) , U , U , O_660F00(2A,U) , U ), - INST(kInstCvtpi2ps , "cvtpi2ps" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(MmMem) , U , U , O_000F00(2A,U) , U ), - INST(kInstCvtps2dq , "cvtps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F00(5B,U) , U ), - INST(kInstCvtps2pd , "cvtps2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_000F00(5A,U) , U ), - INST(kInstCvtps2pi , "cvtps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , O_000F00(2D,U) , U ), - INST(kInstCvtsd2si , "cvtsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , O_F20F00(2D,U) , U ), - INST(kInstCvtsd2ss , "cvtsd2ss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5A,U) , U ), - INST(kInstCvtsi2sd , "cvtsi2sd" , G(ExtRm_Q) , F(Move) , 8 , O(Xmm) , O(GqdMem) , U , U , O_F20F00(2A,U) , U ), - INST(kInstCvtsi2ss , "cvtsi2ss" , G(ExtRm_Q) , F(Move) , 4 , O(Xmm) , O(GqdMem) , U , U , O_F30F00(2A,U) , U ), - INST(kInstCvtss2sd , "cvtss2sd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5A,U) , U ), - INST(kInstCvtss2si , "cvtss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , O_F30F00(2D,U) , U ), - INST(kInstCvttpd2dq , "cvttpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F00(E6,U) , U ), - INST(kInstCvttpd2pi , "cvttpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , O_660F00(2C,U) , U ), - INST(kInstCvttps2dq , "cvttps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F30F00(5B,U) , U ), - INST(kInstCvttps2pi , "cvttps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , O_000F00(2C,U) , U ), - INST(kInstCvttsd2si , "cvttsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , O_F20F00(2C,U) , U ), - INST(kInstCvttss2si , "cvttss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , O_F30F00(2C,U) , U ), - INST(kInstCwd , "cwd" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_660000(99,U) , U ), - INST(kInstCwde , "cwde" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(98,U) , U ), - INST(kInstDaa , "daa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(27,U) , U ), - INST(kInstDas , "das" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(2F,U) , U ), - INST(kInstDec , "dec" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , O_000000(FE,1) , O_000000(48,U) ), - INST(kInstDiv , "div" , G(X86Rm_B) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(F6,6) , U ), - INST(kInstDivpd , "divpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(5E,U) , U ), - INST(kInstDivps , "divps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(5E,U) , U ), - INST(kInstDivsd , "divsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5E,U) , U ), - INST(kInstDivss , "divss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5E,U) , U ), - INST(kInstDppd , "dppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(41,U) , U ), - INST(kInstDpps , "dpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(40,U) , U ), - INST(kInstEmms , "emms" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000F00(77,U) , U ), - INST(kInstEnter , "enter" , G(X86Enter) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(C8,U) , U ), - INST(kInstExtractps , "extractps" , G(ExtExtract) , F(Move) , 8 , O(Gqd)|O(Mem) , O(Xmm) , U , U , O_660F3A(17,U) , O_660F3A(17,U) ), - INST(kInstF2xm1 , "f2xm1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F0,U) , U ), - INST(kInstFabs , "fabs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E1,U) , U ), - INST(kInstFadd , "fadd" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(C0C0,0) , U ), - INST(kInstFaddp , "faddp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEC0,U) , U ), - INST(kInstFbld , "fbld" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(DF,4) , U ), - INST(kInstFbstp , "fbstp" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(DF,6) , U ), - INST(kInstFchs , "fchs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E0,U) , U ), - INST(kInstFclex , "fclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_9B_X(DBE2,U) , U ), - INST(kInstFcmovb , "fcmovb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DAC0,U) , U ), - INST(kInstFcmovbe , "fcmovbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DAD0,U) , U ), - INST(kInstFcmove , "fcmove" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DAC8,U) , U ), - INST(kInstFcmovnb , "fcmovnb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBC0,U) , U ), - INST(kInstFcmovnbe , "fcmovnbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBD0,U) , U ), - INST(kInstFcmovne , "fcmovne" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBC8,U) , U ), - INST(kInstFcmovnu , "fcmovnu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBD8,U) , U ), - INST(kInstFcmovu , "fcmovu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DAD8,U) , U ), - INST(kInstFcom , "fcom" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , O_00_X(D0D0,2) , U ), - INST(kInstFcomi , "fcomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBF0,U) , U ), - INST(kInstFcomip , "fcomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DFF0,U) , U ), - INST(kInstFcomp , "fcomp" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , O_00_X(D8D8,3) , U ), - INST(kInstFcompp , "fcompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(DED9,U) , U ), - INST(kInstFcos , "fcos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FF,U) , U ), - INST(kInstFdecstp , "fdecstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F6,U) , U ), - INST(kInstFdiv , "fdiv" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(F0F8,6) , U ), - INST(kInstFdivp , "fdivp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEF8,U) , U ), - INST(kInstFdivr , "fdivr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(F8F0,7) , U ), - INST(kInstFdivrp , "fdivrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEF0,U) , U ), - INST(kInstFemms , "femms" , G(X86Op) , F(Fp) , 0 , U , U , U , U , O_000F00(0E,U) , U ), - INST(kInstFfree , "ffree" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DDC0,U) , U ), - INST(kInstFiadd , "fiadd" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,0) , U ), - INST(kInstFicom , "ficom" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,2) , U ), - INST(kInstFicomp , "ficomp" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,3) , U ), - INST(kInstFidiv , "fidiv" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,6) , U ), - INST(kInstFidivr , "fidivr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,7) , U ), - INST(kInstFild , "fild" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , O_000000(DB,0) , O_000000(DF,5) ), - INST(kInstFimul , "fimul" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,1) , U ), - INST(kInstFincstp , "fincstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F7,U) , U ), - INST(kInstFinit , "finit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_9B_X(DBE3,U) , U ), - INST(kInstFist , "fist" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DB,2) , U ), - INST(kInstFistp , "fistp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , O_000000(DB,3) , O_000000(DF,7) ), - INST(kInstFisttp , "fisttp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , O_000000(DB,1) , O_000000(DD,1) ), - INST(kInstFisub , "fisub" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,4) , U ), - INST(kInstFisubr , "fisubr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , O_000000(DA,5) , U ), - INST(kInstFld , "fld" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , O_000000(D9,0) , O_000000(DB,5) ), - INST(kInstFld1 , "fld1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E8,U) , U ), - INST(kInstFldcw , "fldcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(D9,5) , U ), - INST(kInstFldenv , "fldenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(D9,4) , U ), - INST(kInstFldl2e , "fldl2e" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9EA,U) , U ), - INST(kInstFldl2t , "fldl2t" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E9,U) , U ), - INST(kInstFldlg2 , "fldlg2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9EC,U) , U ), - INST(kInstFldln2 , "fldln2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9ED,U) , U ), - INST(kInstFldpi , "fldpi" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9EB,U) , U ), - INST(kInstFldz , "fldz" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9EE,U) , U ), - INST(kInstFmul , "fmul" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(C8C8,1) , U ), - INST(kInstFmulp , "fmulp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEC8,U) , U ), - INST(kInstFnclex , "fnclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(DBE2,U) , U ), - INST(kInstFninit , "fninit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(DBE3,U) , U ), - INST(kInstFnop , "fnop" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9D0,U) , U ), - INST(kInstFnsave , "fnsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(DD,6) , U ), - INST(kInstFnstcw , "fnstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(D9,7) , U ), - INST(kInstFnstenv , "fnstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(D9,6) , U ), - INST(kInstFnstsw , "fnstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(DD,7) , O_00_X(DFE0,U) ), - INST(kInstFpatan , "fpatan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F3,U) , U ), - INST(kInstFprem , "fprem" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F8,U) , U ), - INST(kInstFprem1 , "fprem1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F5,U) , U ), - INST(kInstFptan , "fptan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F2,U) , U ), - INST(kInstFrndint , "frndint" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FC,U) , U ), - INST(kInstFrstor , "frstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000000(DD,4) , U ), - INST(kInstFsave , "fsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_9B0000(DD,6) , U ), - INST(kInstFscale , "fscale" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FD,U) , U ), - INST(kInstFsin , "fsin" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FE,U) , U ), - INST(kInstFsincos , "fsincos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FB,U) , U ), - INST(kInstFsqrt , "fsqrt" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9FA,U) , U ), - INST(kInstFst , "fst" , G(FpuFldFst) , F(Fp)|F(Mem4_8) , 0 , O(Mem) , U , U , U , O_000000(D9,2) , U ), - INST(kInstFstcw , "fstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_9B0000(D9,7) , U ), - INST(kInstFstenv , "fstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_9B0000(D9,6) , U ), - INST(kInstFstp , "fstp" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , O_000000(D9,3) , O_000000(DB,7) ), - INST(kInstFstsw , "fstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , O_9B0000(DD,7) , O_9B_X(DFE0,U) ), - INST(kInstFsub , "fsub" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(E0E8,4) , U ), - INST(kInstFsubp , "fsubp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEE8,U) , U ), - INST(kInstFsubr , "fsubr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , O_00_X(E8E0,5) , U ), - INST(kInstFsubrp , "fsubrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DEE0,U) , U ), - INST(kInstFtst , "ftst" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E4,U) , U ), - INST(kInstFucom , "fucom" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DDE0,U) , U ), - INST(kInstFucomi , "fucomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DBE8,U) , U ), - INST(kInstFucomip , "fucomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DFE8,U) , U ), - INST(kInstFucomp , "fucomp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(DDE8,U) , U ), - INST(kInstFucompp , "fucompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(DAE9,U) , U ), - INST(kInstFwait , "fwait" , G(X86Op) , F(Fp) , 0 , U , U , U , U , O_000000(DB,U) , U ), - INST(kInstFxam , "fxam" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9E5,U) , U ), - INST(kInstFxch , "fxch" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , O_00_X(D9C8,U) , U ), - INST(kInstFxrstor , "fxrstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000F00(AE,1) , U ), - INST(kInstFxsave , "fxsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , O_000F00(AE,0) , U ), - INST(kInstFxtract , "fxtract" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F4,U) , U ), - INST(kInstFyl2x , "fyl2x" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F1,U) , U ), - INST(kInstFyl2xp1 , "fyl2xp1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , O_00_X(D9F9,U) , U ), - INST(kInstHaddpd , "haddpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(7C,U) , U ), - INST(kInstHaddps , "haddps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(7C,U) , U ), - INST(kInstHsubpd , "hsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(7D,U) , U ), - INST(kInstHsubps , "hsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(7D,U) , U ), - INST(kInstIdiv , "idiv" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , O_000000(F6,7) , U ), - INST(kInstImul , "imul" , G(X86Imul) , F(None)|F(Special) , 0 , 0 , 0 , U , U , U , U ), - INST(kInstInc , "inc" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , O_000000(FE,0) , O_000000(40,U) ), - INST(kInstInsertps , "insertps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(21,U) , U ), - INST(kInstInt , "int" , G(X86Int) , F(None) , 0 , U , U , U , U , O_000000(CC,U) , U ), - INST(kInstJa , "ja" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(77,U) , U ), - INST(kInstJae , "jae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(73,U) , U ), - INST(kInstJb , "jb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(72,U) , U ), - INST(kInstJbe , "jbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(76,U) , U ), - INST(kInstJc , "jc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(72,U) , U ), - INST(kInstJe , "je" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(74,U) , U ), - INST(kInstJg , "jg" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7F,U) , U ), - INST(kInstJge , "jge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7D,U) , U ), - INST(kInstJl , "jl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7C,U) , U ), - INST(kInstJle , "jle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7E,U) , U ), - INST(kInstJna , "jna" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(76,U) , U ), - INST(kInstJnae , "jnae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(72,U) , U ), - INST(kInstJnb , "jnb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(73,U) , U ), - INST(kInstJnbe , "jnbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(77,U) , U ), - INST(kInstJnc , "jnc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(73,U) , U ), - INST(kInstJne , "jne" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(75,U) , U ), - INST(kInstJng , "jng" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7E,U) , U ), - INST(kInstJnge , "jnge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7C,U) , U ), - INST(kInstJnl , "jnl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7D,U) , U ), - INST(kInstJnle , "jnle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7F,U) , U ), - INST(kInstJno , "jno" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(71,U) , U ), - INST(kInstJnp , "jnp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7B,U) , U ), - INST(kInstJns , "jns" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(79,U) , U ), - INST(kInstJnz , "jnz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(75,U) , U ), - INST(kInstJo , "jo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(70,U) , U ), - INST(kInstJp , "jp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7A,U) , U ), - INST(kInstJpe , "jpe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7A,U) , U ), - INST(kInstJpo , "jpo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(7B,U) , U ), - INST(kInstJs , "js" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(78,U) , U ), - INST(kInstJz , "jz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , O_000000(74,U) , U ), - INST(kInstJecxz , "jecxz" , G(X86Jecxz) , F(Flow)|F(Special) , 0 , O(Gqdw) , O(Label) , U , U , O_000000(E3,U) , U ), - INST(kInstJmp , "jmp" , G(X86Jmp) , F(Flow) , 0 , O(Imm)|O(Label) , U , U , U , O_000000(FF,4) , O_000000(E9,U) ), - INST(kInstLahf , "lahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(9F,U) , U ), - INST(kInstLddqu , "lddqu" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , O_F20F00(F0,U) , U ), - INST(kInstLdmxcsr , "ldmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(AE,2) , U ), - INST(kInstLea , "lea" , G(X86Lea) , F(Move) , 0 , O(Gqd) , O(Mem) , U , U , O_000000(8D,U) , U ), - INST(kInstLeave , "leave" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(C9,U) , U ), - INST(kInstLfence , "lfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , O_000F00(AE,5) , U ), - INST(kInstLzcnt , "lzcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_F30F00(BD,U) , U ), - INST(kInstMaskmovdqu , "maskmovdqu" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(Xmm) , U , U , O_660F00(57,U) , U ), - INST(kInstMaskmovq , "maskmovq" , G(ExtRm) , F(None)|F(Special) , 0 , O(Mm) , O(Mm) , U , U , O_000F00(F7,U) , U ), - INST(kInstMaxpd , "maxpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(5F,U) , U ), - INST(kInstMaxps , "maxps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(5F,U) , U ), - INST(kInstMaxsd , "maxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5F,U) , U ), - INST(kInstMaxss , "maxss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5F,U) , U ), - INST(kInstMfence , "mfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , O_000F00(AE,6) , U ), - INST(kInstMinpd , "minpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(5D,U) , U ), - INST(kInstMinps , "minps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(5D,U) , U ), - INST(kInstMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5D,U) , U ), - INST(kInstMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5D,U) , U ), - INST(kInstMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F01(C8,U) , U ), - INST(kInstMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U , U ), - INST(kInstMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , O_000000(A0,U) , O_000000(A2,U) ), - INST(kInstMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_660F00(28,U) , O_660F00(29,U) ), - INST(kInstMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_000F00(28,U) , O_000F00(29,U) ), - INST(kInstMovbe , "movbe" , G(ExtMovBe) , F(Move) , 0 , O(GqdwMem) , O(GqdwMem) , U , U , O_000F38(F0,U) , O_000F38(F1,U) ), - INST(kInstMovd , "movd" , G(ExtMovD) , F(Move) , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , O_000F00(6E,U) , O_000F00(7E,U) ), - INST(kInstMovddup , "movddup" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F20F00(12,U) , U ), - INST(kInstMovdq2q , "movdq2q" , G(ExtMov) , F(Move) , 8 , O(Mm) , O(Xmm) , U , U , O_F20F00(D6,U) , U ), - INST(kInstMovdqa , "movdqa" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_660F00(6F,U) , O_660F00(7F,U) ), - INST(kInstMovdqu , "movdqu" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_F30F00(6F,U) , O_F30F00(7F,U) ), - INST(kInstMovhlps , "movhlps" , G(ExtMov) , F(Move) , 8 , O(Xmm) , O(Xmm) , U , U , O_000F00(12,U) , U ), - INST(kInstMovhpd , "movhpd" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , O_660F00(16,U) , O_660F00(17,U) ), - INST(kInstMovhps , "movhps" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , O_000F00(16,U) , O_000F00(17,U) ), - INST(kInstMovlhps , "movlhps" , G(ExtMov) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , O_000F00(16,U) , U ), - INST(kInstMovlpd , "movlpd" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , O_660F00(12,U) , O_660F00(13,U) ), - INST(kInstMovlps , "movlps" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , O_000F00(12,U) , O_000F00(13,U) ), - INST(kInstMovmskpd , "movmskpd" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , O_660F00(50,U) , U ), - INST(kInstMovmskps , "movmskps" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , O_000F00(50,U) , U ), - INST(kInstMovntdq , "movntdq" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , U , O_660F00(E7,U) ), - INST(kInstMovntdqa , "movntdqa" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , O_660F38(2A,U) , U ), - INST(kInstMovnti , "movnti" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Gqd) , U , U , U , O_000F00(C3,U) ), - INST(kInstMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , U , O_660F00(2B,U) ), - INST(kInstMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , U , O_000F00(2B,U) ), - INST(kInstMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , U , O_000F00(E7,U) ), - INST(kInstMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U , U ), - INST(kInstMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , O_F30F00(D6,U) , U ), - INST(kInstMovsd , "movsd" , G(ExtMov) , F(Move)|F(ZeroIfMem) , 8 , O(XmmMem) , O(XmmMem) , U , U , O_F20F00(10,U) , O_F20F00(11,U) ), - INST(kInstMovshdup , "movshdup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F30F00(16,U) , U ), - INST(kInstMovsldup , "movsldup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_F30F00(12,U) , U ), - INST(kInstMovss , "movss" , G(ExtMov) , F(Move)|F(ZeroIfMem) , 4 , O(XmmMem) , O(XmmMem) , U , U , O_F30F00(10,U) , O_F30F00(11,U) ), - INST(kInstMovsx , "movsx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , O_000F00(BE,U) , U ), - INST(kInstMovsxd , "movsxd" , G(X86MovSxd) , F(Move) , 0 , O(Gq) , O(GdMem) , U , U , O_000000(63,U) , U ), - INST(kInstMovupd , "movupd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_660F00(10,U) , O_660F00(11,U) ), - INST(kInstMovups , "movups" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_000F00(10,U) , O_000F00(11,U) ), - INST(kInstMovzx , "movzx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , O_000F00(B6,U) , U ), - INST(kInstMpsadbw , "mpsadbw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(42,U) , U ), - INST(kInstMul , "mul" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , O_000000(F6,4) , U ), - INST(kInstMulpd , "mulpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(59,U) , U ), - INST(kInstMulps , "mulps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(59,U) , U ), - INST(kInstMulsd , "mulsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(59,U) , U ), - INST(kInstMulss , "mulss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(59,U) , U ), - INST(kInstMulx , "mulx" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , O_F20F38(F6,U) , U ), - INST(kInstMwait , "mwait" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F01(C9,U) , U ), - INST(kInstNeg , "neg" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , O_000000(F6,3) , U ), - INST(kInstNop , "nop" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(90,U) , U ), - INST(kInstNot , "not" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , O_000000(F6,2) , U ), - INST(kInstOr , "or" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(08,1) , U ), - INST(kInstOrpd , "orpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(56,U) , U ), - INST(kInstOrps , "orps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(56,U) , U ), - INST(kInstPabsb , "pabsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(1C,U) , U ), - INST(kInstPabsd , "pabsd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(1E,U) , U ), - INST(kInstPabsw , "pabsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(1D,U) , U ), - INST(kInstPackssdw , "packssdw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(6B,U) , U ), - INST(kInstPacksswb , "packsswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(63,U) , U ), - INST(kInstPackusdw , "packusdw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(2B,U) , U ), - INST(kInstPackuswb , "packuswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(67,U) , U ), - INST(kInstPaddb , "paddb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(FC,U) , U ), - INST(kInstPaddd , "paddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(FE,U) , U ), - INST(kInstPaddq , "paddq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(D4,U) , U ), - INST(kInstPaddsb , "paddsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(EC,U) , U ), - INST(kInstPaddsw , "paddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(ED,U) , U ), - INST(kInstPaddusb , "paddusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DC,U) , U ), - INST(kInstPaddusw , "paddusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DD,U) , U ), - INST(kInstPaddw , "paddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(FD,U) , U ), - INST(kInstPalignr , "palignr" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , O_000F3A(0F,U) , U ), - INST(kInstPand , "pand" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DB,U) , U ), - INST(kInstPandn , "pandn" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DF,U) , U ), - INST(kInstPause , "pause" , G(X86Op) , F(None) , 0 , U , U , U , U , O_F30000(90,U) , U ), - INST(kInstPavgb , "pavgb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E0,U) , U ), - INST(kInstPavgw , "pavgw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E3,U) , U ), - INST(kInstPblendvb , "pblendvb" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(10,U) , U ), - INST(kInstPblendw , "pblendw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(0E,U) , U ), - INST(kInstPclmulqdq , "pclmulqdq" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(44,U) , U ), - INST(kInstPcmpeqb , "pcmpeqb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(74,U) , U ), - INST(kInstPcmpeqd , "pcmpeqd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(76,U) , U ), - INST(kInstPcmpeqq , "pcmpeqq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(29,U) , U ), - INST(kInstPcmpeqw , "pcmpeqw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(75,U) , U ), - INST(kInstPcmpestri , "pcmpestri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(61,U) , U ), - INST(kInstPcmpestrm , "pcmpestrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(60,U) , U ), - INST(kInstPcmpgtb , "pcmpgtb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(64,U) , U ), - INST(kInstPcmpgtd , "pcmpgtd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(66,U) , U ), - INST(kInstPcmpgtq , "pcmpgtq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(37,U) , U ), - INST(kInstPcmpgtw , "pcmpgtw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(65,U) , U ), - INST(kInstPcmpistri , "pcmpistri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(63,U) , U ), - INST(kInstPcmpistrm , "pcmpistrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(62,U) , U ), - INST(kInstPdep , "pdep" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , O_F20F38(F5,U) , U ), - INST(kInstPext , "pext" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , O_F30F38(F5,U) , U ), - INST(kInstPextrb , "pextrb" , G(ExtExtract) , F(Move) , 8 , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , O_000F3A(14,U) , O_000F3A(14,U) ), - INST(kInstPextrd , "pextrd" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(Xmm) , U , U , O_000F3A(16,U) , O_000F3A(16,U) ), - INST(kInstPextrq , "pextrq" , G(ExtExtract) , F(Move) |F(W), 8 , O(GqdMem) , O(Xmm) , U , U , O_000F3A(16,U) , O_000F3A(16,U) ), - INST(kInstPextrw , "pextrw" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(MmXmm) , U , U , O_000F00(C5,U) , O_000F3A(15,U) ), - INST(kInstPf2id , "pf2id" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(1D,U) , U ), - INST(kInstPf2iw , "pf2iw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(1C,U) , U ), - INST(kInstPfacc , "pfacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(AE,U) , U ), - INST(kInstPfadd , "pfadd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(9E,U) , U ), - INST(kInstPfcmpeq , "pfcmpeq" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(B0,U) , U ), - INST(kInstPfcmpge , "pfcmpge" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(90,U) , U ), - INST(kInstPfcmpgt , "pfcmpgt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(A0,U) , U ), - INST(kInstPfmax , "pfmax" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(A4,U) , U ), - INST(kInstPfmin , "pfmin" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(94,U) , U ), - INST(kInstPfmul , "pfmul" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(B4,U) , U ), - INST(kInstPfnacc , "pfnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(8A,U) , U ), - INST(kInstPfpnacc , "pfpnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(8E,U) , U ), - INST(kInstPfrcp , "pfrcp" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(96,U) , U ), - INST(kInstPfrcpit1 , "pfrcpit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(A6,U) , U ), - INST(kInstPfrcpit2 , "pfrcpit2" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(B6,U) , U ), - INST(kInstPfrsqit1 , "pfrsqit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(A7,U) , U ), - INST(kInstPfrsqrt , "pfrsqrt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(97,U) , U ), - INST(kInstPfsub , "pfsub" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(9A,U) , U ), - INST(kInstPfsubr , "pfsubr" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(AA,U) , U ), - INST(kInstPhaddd , "phaddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(02,U) , U ), - INST(kInstPhaddsw , "phaddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(03,U) , U ), - INST(kInstPhaddw , "phaddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(01,U) , U ), - INST(kInstPhminposuw , "phminposuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(41,U) , U ), - INST(kInstPhsubd , "phsubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(06,U) , U ), - INST(kInstPhsubsw , "phsubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(07,U) , U ), - INST(kInstPhsubw , "phsubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(05,U) , U ), - INST(kInstPi2fd , "pi2fd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(0D,U) , U ), - INST(kInstPi2fw , "pi2fw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(0C,U) , U ), - INST(kInstPinsrb , "pinsrb" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , O_660F3A(20,U) , U ), - INST(kInstPinsrd , "pinsrd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , O_660F3A(22,U) , U ), - INST(kInstPinsrq , "pinsrq" , G(ExtRmi) , F(None) |F(W), 0 , O(Xmm) , O(GqMem) , O(Imm) , U , O_660F3A(22,U) , U ), - INST(kInstPinsrw , "pinsrw" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , O_000F00(C4,U) , U ), - INST(kInstPmaddubsw , "pmaddubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(04,U) , U ), - INST(kInstPmaddwd , "pmaddwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(F5,U) , U ), - INST(kInstPmaxsb , "pmaxsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3C,U) , U ), - INST(kInstPmaxsd , "pmaxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3D,U) , U ), - INST(kInstPmaxsw , "pmaxsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(EE,U) , U ), - INST(kInstPmaxub , "pmaxub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DE,U) , U ), - INST(kInstPmaxud , "pmaxud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3F,U) , U ), - INST(kInstPmaxuw , "pmaxuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3E,U) , U ), - INST(kInstPminsb , "pminsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(38,U) , U ), - INST(kInstPminsd , "pminsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(39,U) , U ), - INST(kInstPminsw , "pminsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(EA,U) , U ), - INST(kInstPminub , "pminub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(DA,U) , U ), - INST(kInstPminud , "pminud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3B,U) , U ), - INST(kInstPminuw , "pminuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(3A,U) , U ), - INST(kInstPmovmskb , "pmovmskb" , G(ExtRm_PQ) , F(Move) , 8 , O(Gqd) , O(MmXmm) , U , U , O_000F00(D7,U) , U ), - INST(kInstPmovsxbd , "pmovsxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(21,U) , U ), - INST(kInstPmovsxbq , "pmovsxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(22,U) , U ), - INST(kInstPmovsxbw , "pmovsxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(20,U) , U ), - INST(kInstPmovsxdq , "pmovsxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(25,U) , U ), - INST(kInstPmovsxwd , "pmovsxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(23,U) , U ), - INST(kInstPmovsxwq , "pmovsxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(24,U) , U ), - INST(kInstPmovzxbd , "pmovzxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(31,U) , U ), - INST(kInstPmovzxbq , "pmovzxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(32,U) , U ), - INST(kInstPmovzxbw , "pmovzxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(30,U) , U ), - INST(kInstPmovzxdq , "pmovzxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(35,U) , U ), - INST(kInstPmovzxwd , "pmovzxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(33,U) , U ), - INST(kInstPmovzxwq , "pmovzxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F38(34,U) , U ), - INST(kInstPmuldq , "pmuldq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(28,U) , U ), - INST(kInstPmulhrsw , "pmulhrsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(0B,U) , U ), - INST(kInstPmulhuw , "pmulhuw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E4,U) , U ), - INST(kInstPmulhw , "pmulhw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E5,U) , U ), - INST(kInstPmulld , "pmulld" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(40,U) , U ), - INST(kInstPmullw , "pmullw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(D5,U) , U ), - INST(kInstPmuludq , "pmuludq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(F4,U) , U ), - INST(kInstPop , "pop" , G(X86Pop) , F(None)|F(Special) , 0 , 0 , U , U , U , O_000000(8F,0) , O_000000(58,U) ), - INST(kInstPopa , "popa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(61,U) , U ), - INST(kInstPopcnt , "popcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_F30F00(B8,U) , U ), - INST(kInstPopf , "popf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(9D,U) , U ), - INST(kInstPor , "por" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(EB,U) , U ), - INST(kInstPrefetch , "prefetch" , G(ExtPrefetch) , F(None) , 0 , O(Mem) , O(Imm) , U , U , O_000F00(18,U) , U ), - INST(kInstPrefetch3dNow , "prefetch_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(0D,0) , U ), - INST(kInstPrefetchw3dNow , "prefetchw_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(0D,1) , U ), - INST(kInstPsadbw , "psadbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(F6,U) , U ), - INST(kInstPshufb , "pshufb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(00,U) , U ), - INST(kInstPshufd , "pshufd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F00(70,U) , U ), - INST(kInstPshufhw , "pshufhw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , O_F30F00(70,U) , U ), - INST(kInstPshuflw , "pshuflw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , O_F20F00(70,U) , U ), - INST(kInstPshufw , "pshufw" , G(ExtRmi_P) , F(Move) , 8 , O(Mm) , O(MmMem) , O(Imm) , U , O_000F00(70,U) , U ), - INST(kInstPsignb , "psignb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(08,U) , U ), - INST(kInstPsignd , "psignd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(0A,U) , U ), - INST(kInstPsignw , "psignw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F38(09,U) , U ), - INST(kInstPslld , "pslld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(F2,U) , O_000F00(72,6) ), - INST(kInstPslldq , "pslldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , U , O_660F00(73,7) ), - INST(kInstPsllq , "psllq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(F3,U) , O_000F00(73,6) ), - INST(kInstPsllw , "psllw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(F1,U) , O_000F00(71,6) ), - INST(kInstPsrad , "psrad" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(E2,U) , O_000F00(72,4) ), - INST(kInstPsraw , "psraw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(E1,U) , O_000F00(71,4) ), - INST(kInstPsrld , "psrld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(D2,U) , O_000F00(72,2) ), - INST(kInstPsrldq , "psrldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , U , O_660F00(73,3) ), - INST(kInstPsrlq , "psrlq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(D3,U) , O_000F00(73,2) ), - INST(kInstPsrlw , "psrlw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , O_000F00(D1,U) , O_000F00(71,2) ), - INST(kInstPsubb , "psubb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(F8,U) , U ), - INST(kInstPsubd , "psubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(FA,U) , U ), - INST(kInstPsubq , "psubq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(FB,U) , U ), - INST(kInstPsubsb , "psubsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E8,U) , U ), - INST(kInstPsubsw , "psubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(E9,U) , U ), - INST(kInstPsubusb , "psubusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(D8,U) , U ), - INST(kInstPsubusw , "psubusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(D9,U) , U ), - INST(kInstPsubw , "psubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(F9,U) , U ), - INST(kInstPswapd , "pswapd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , O_000F0F(BB,U) , U ), - INST(kInstPtest , "ptest" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(17,U) , U ), - INST(kInstPunpckhbw , "punpckhbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(68,U) , U ), - INST(kInstPunpckhdq , "punpckhdq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(6A,U) , U ), - INST(kInstPunpckhqdq , "punpckhqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(6D,U) , U ), - INST(kInstPunpckhwd , "punpckhwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(69,U) , U ), - INST(kInstPunpcklbw , "punpcklbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(60,U) , U ), - INST(kInstPunpckldq , "punpckldq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(62,U) , U ), - INST(kInstPunpcklqdq , "punpcklqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(6C,U) , U ), - INST(kInstPunpcklwd , "punpcklwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(61,U) , U ), - INST(kInstPush , "push" , G(X86Push) , F(None)|F(Special) , 0 , 0 , U , U , U , O_000000(FF,6) , O_000000(50,U) ), - INST(kInstPusha , "pusha" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(60,U) , U ), - INST(kInstPushf , "pushf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(9C,U) , U ), - INST(kInstPxor , "pxor" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , O_000F00(EF,U) , U ), - INST(kInstRcl , "rcl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,2) , U ), - INST(kInstRcpps , "rcpps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_000F00(53,U) , U ), - INST(kInstRcpss , "rcpss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(53,U) , U ), - INST(kInstRcr , "rcr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,3) , U ), - INST(kInstRdfsbase , "rdfsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , O_F30F00(AE,0) , U ), - INST(kInstRdgsbase , "rdgsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , O_F30F00(AE,1) , U ), - INST(kInstRdrand , "rdrand" , G(X86Rm) , F(Move) , 8 , O(Gqdw) , U , U , U , O_000F00(C7,6) , U ), - INST(kInstRdtsc , "rdtsc" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F00(31,U) , U ), - INST(kInstRdtscp , "rdtscp" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F01(F9,U) , U ), - INST(kInstRepLodsb , "rep lodsb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_000000(AC,1) , U ), - INST(kInstRepLodsd , "rep lodsd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_000000(AD,1) , U ), - INST(kInstRepLodsq , "rep lodsq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , O_000000(AD,1) , U ), - INST(kInstRepLodsw , "rep lodsw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_660000(AD,1) , U ), - INST(kInstRepMovsb , "rep movsb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A4,1) , U ), - INST(kInstRepMovsd , "rep movsd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A5,1) , U ), - INST(kInstRepMovsq , "rep movsq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , O_000000(A5,1) , U ), - INST(kInstRepMovsw , "rep movsw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_660000(A5,1) , U ), - INST(kInstRepStosb , "rep stosb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_000000(AA,1) , U ), - INST(kInstRepStosd , "rep stosd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_000000(AB,1) , U ), - INST(kInstRepStosq , "rep stosq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , O_000000(AB,1) , U ), - INST(kInstRepStosw , "rep stosw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , O_660000(AB,1) , U ), - INST(kInstRepeCmpsb , "repe cmpsb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A6,1) , U ), - INST(kInstRepeCmpsd , "repe cmpsd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A7,1) , U ), - INST(kInstRepeCmpsq , "repe cmpsq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , O_000000(A7,1) , U ), - INST(kInstRepeCmpsw , "repe cmpsw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_660000(A7,1) , U ), - INST(kInstRepeScasb , "repe scasb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(AE,1) , U ), - INST(kInstRepeScasd , "repe scasd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(AF,1) , U ), - INST(kInstRepeScasq , "repe scasq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , O_000000(AF,1) , U ), - INST(kInstRepeScasw , "repe scasw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_660000(AF,1) , U ), - INST(kInstRepneCmpsb , "repne cmpsb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A6,0) , U ), - INST(kInstRepneCmpsd , "repne cmpsd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(A7,0) , U ), - INST(kInstRepneCmpsq , "repne cmpsq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , O_000000(A7,0) , U ), - INST(kInstRepneCmpsw , "repne cmpsw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_660000(A7,0) , U ), - INST(kInstRepneScasb , "repne scasb" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(AE,0) , U ), - INST(kInstRepneScasd , "repne scasd" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_000000(AF,0) , U ), - INST(kInstRepneScasq , "repne scasq" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , O_000000(AF,0) , U ), - INST(kInstRepneScasw , "repne scasw" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , O_660000(AF,0) , U ), - INST(kInstRet , "ret" , G(X86Ret) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(C2,U) , U ), - INST(kInstRol , "rol" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,0) , U ), - INST(kInstRor , "ror" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,1) , U ), - INST(kInstRorx , "rorx" , G(AvxRmi) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , O_F20F3A(F0,U) , U ), - INST(kInstRoundpd , "roundpd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(09,U) , U ), - INST(kInstRoundps , "roundps" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(08,U) , U ), - INST(kInstRoundsd , "roundsd" , G(ExtRmi) , F(Move) , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(0B,U) , U ), - INST(kInstRoundss , "roundss" , G(ExtRmi) , F(Move) , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(0A,U) , U ), - INST(kInstRsqrtps , "rsqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_000F00(52,U) , U ), - INST(kInstRsqrtss , "rsqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(52,U) , U ), - INST(kInstSahf , "sahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000000(9E,U) , U ), - INST(kInstSal , "sal" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,4) , U ), - INST(kInstSar , "sar" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,7) , U ), - INST(kInstSarx , "sarx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , O_F30F38(F7,U) , U ), - INST(kInstSbb , "sbb" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(18,3) , U ), - INST(kInstSeta , "seta" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(97,U) , U ), - INST(kInstSetae , "setae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(93,U) , U ), - INST(kInstSetb , "setb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(92,U) , U ), - INST(kInstSetbe , "setbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(96,U) , U ), - INST(kInstSetc , "setc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(92,U) , U ), - INST(kInstSete , "sete" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(94,U) , U ), - INST(kInstSetg , "setg" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9F,U) , U ), - INST(kInstSetge , "setge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9D,U) , U ), - INST(kInstSetl , "setl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9C,U) , U ), - INST(kInstSetle , "setle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9E,U) , U ), - INST(kInstSetna , "setna" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(96,U) , U ), - INST(kInstSetnae , "setnae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(92,U) , U ), - INST(kInstSetnb , "setnb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(93,U) , U ), - INST(kInstSetnbe , "setnbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(97,U) , U ), - INST(kInstSetnc , "setnc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(93,U) , U ), - INST(kInstSetne , "setne" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(95,U) , U ), - INST(kInstSetng , "setng" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9E,U) , U ), - INST(kInstSetnge , "setnge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9C,U) , U ), - INST(kInstSetnl , "setnl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9D,U) , U ), - INST(kInstSetnle , "setnle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9F,U) , U ), - INST(kInstSetno , "setno" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(91,U) , U ), - INST(kInstSetnp , "setnp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9B,U) , U ), - INST(kInstSetns , "setns" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(99,U) , U ), - INST(kInstSetnz , "setnz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(95,U) , U ), - INST(kInstSeto , "seto" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(90,U) , U ), - INST(kInstSetp , "setp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9A,U) , U ), - INST(kInstSetpe , "setpe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9A,U) , U ), - INST(kInstSetpo , "setpo" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(9B,U) , U ), - INST(kInstSets , "sets" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(98,U) , U ), - INST(kInstSetz , "setz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , O_000F00(94,U) , U ), - INST(kInstSfence , "sfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , O_000F00(AE,7) , U ), - INST(kInstShl , "shl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,4) , U ), - INST(kInstShld , "shld" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb) , U , U , O_000F00(A4,U) , U ), - INST(kInstShlx , "shlx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , O_660F38(F7,U) , U ), - INST(kInstShr , "shr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , O_000000(D0,5) , U ), - INST(kInstShrd , "shrd" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , O_000F00(AC,U) , U ), - INST(kInstShrx , "shrx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , O_F20F38(F7,U) , U ), - INST(kInstShufpd , "shufpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F00(C6,U) , U ), - INST(kInstShufps , "shufps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_000F00(C6,U) , U ), - INST(kInstSqrtpd , "sqrtpd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_660F00(51,U) , U ), - INST(kInstSqrtps , "sqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , O_000F00(51,U) , U ), - INST(kInstSqrtsd , "sqrtsd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(51,U) , U ), - INST(kInstSqrtss , "sqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(51,U) , U ), - INST(kInstStc , "stc" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(F9,U) , U ), - INST(kInstStd , "std" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000000(FD,U) , U ), - INST(kInstStmxcsr , "stmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(AE,3) , U ), - INST(kInstSub , "sub" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(28,5) , U ), - INST(kInstSubpd , "subpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(5C,U) , U ), - INST(kInstSubps , "subps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(5C,U) , U ), - INST(kInstSubsd , "subsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5C,U) , U ), - INST(kInstSubss , "subss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5C,U) , U ), - INST(kInstTest , "test" , G(X86Test) , F(Test) , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , O_000000(84,U) , O_000000(F6,U) ), - INST(kInstTzcnt , "tzcnt" , G(X86RegRm) , F(Move) , 0 , O(Gqdw) , O(GqdwMem) , U , U , O_F30F00(BC,U) , U ), - INST(kInstUcomisd , "ucomisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(2E,U) , U ), - INST(kInstUcomiss , "ucomiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(2E,U) , U ), - INST(kInstUd2 , "ud2" , G(X86Op) , F(None) , 0 , U , U , U , U , O_000F00(0B,U) , U ), - INST(kInstUnpckhpd , "unpckhpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(15,U) , U ), - INST(kInstUnpckhps , "unpckhps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(15,U) , U ), - INST(kInstUnpcklpd , "unpcklpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(14,U) , U ), - INST(kInstUnpcklps , "unpcklps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(14,U) , U ), - INST(kInstVaddpd , "vaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(58,U) , U ), - INST(kInstVaddps , "vaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(58,U) , U ), - INST(kInstVaddsd , "vaddsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(58,U) , U ), - INST(kInstVaddss , "vaddss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F30F00(58,U) , U ), - INST(kInstVaddsubpd , "vaddsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(D0,U) , U ), - INST(kInstVaddsubps , "vaddsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(D0,U) , U ), - INST(kInstVaesdec , "vaesdec" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(DE,U) , U ), - INST(kInstVaesdeclast , "vaesdeclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(DF,U) , U ), - INST(kInstVaesenc , "vaesenc" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(DC,U) , U ), - INST(kInstVaesenclast , "vaesenclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(DD,U) , U ), - INST(kInstVaesimc , "vaesimc" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(DB,U) , U ), - INST(kInstVaeskeygenassist , "vaeskeygenassist" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(DF,U) , U ), - INST(kInstVandnpd , "vandnpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(55,U) , U ), - INST(kInstVandnps , "vandnps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(55,U) , U ), - INST(kInstVandpd , "vandpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(54,U) , U ), - INST(kInstVandps , "vandps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(54,U) , U ), - INST(kInstVblendpd , "vblendpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(0D,U) , U ), - INST(kInstVblendps , "vblendps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(0C,U) , U ), - INST(kInstVblendvpd , "vblendvpd" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , O_660F3A(4B,U) , U ), - INST(kInstVblendvps , "vblendvps" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , O_660F3A(4A,U) , U ), - INST(kInstVbroadcastf128 , "vbroadcastf128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , O_660F38(1A,U)|L, U ), - INST(kInstVbroadcasti128 , "vbroadcasti128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , O_660F38(5A,U)|L, U ), - INST(kInstVbroadcastsd , "vbroadcastsd" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , O_660F38(19,U)|L, U ), - INST(kInstVbroadcastss , "vbroadcastss" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , O_660F38(18,U) , U ), - INST(kInstVcmppd , "vcmppd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F00(C2,U) , U ), - INST(kInstVcmpps , "vcmpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_000F00(C2,U) , U ), - INST(kInstVcmpsd , "vcmpsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_F20F00(C2,U) , U ), - INST(kInstVcmpss , "vcmpss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_F30F00(C2,U) , U ), - INST(kInstVcomisd , "vcomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(2F,U) , U ), - INST(kInstVcomiss , "vcomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(2F,U) , U ), - INST(kInstVcvtdq2pd , "vcvtdq2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_F30F00(E6,U) , U ), - INST(kInstVcvtdq2ps , "vcvtdq2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_000F00(5B,U) , U ), - INST(kInstVcvtpd2dq , "vcvtpd2dq" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , O_F20F00(E6,U) , U ), - INST(kInstVcvtpd2ps , "vcvtpd2ps" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , O_660F00(5A,U) , U ), - INST(kInstVcvtph2ps , "vcvtph2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_660F38(13,U) , U ), - INST(kInstVcvtps2dq , "vcvtps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F00(5B,U) , U ), - INST(kInstVcvtps2pd , "vcvtps2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_000F00(5A,U) , U ), - INST(kInstVcvtps2ph , "vcvtps2ph" , G(AvxMri_P) , F(None) , 0 , O(XmmMem) , O(XmmYmm) , O(Imm) , U , O_660F3A(1D,U) , U ), - INST(kInstVcvtsd2si , "vcvtsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , O_F20F00(2D,U) , U ), - INST(kInstVcvtsd2ss , "vcvtsd2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F20F00(5A,U) , U ), - INST(kInstVcvtsi2sd , "vcvtsi2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , O_F20F00(2A,U) , U ), - INST(kInstVcvtsi2ss , "vcvtsi2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , O_F30F00(2A,U) , U ), - INST(kInstVcvtss2sd , "vcvtss2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(5A,U) , U ), - INST(kInstVcvtss2si , "vcvtss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , O_F20F00(2D,U) , U ), - INST(kInstVcvttpd2dq , "vcvttpd2dq" , G(AvxRm_P) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , O_660F00(E6,U) , U ), - INST(kInstVcvttps2dq , "vcvttps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_F30F00(5B,U) , U ), - INST(kInstVcvttsd2si , "vcvttsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , O_F20F00(2C,U) , U ), - INST(kInstVcvttss2si , "vcvttss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , O_F30F00(2C,U) , U ), - INST(kInstVdivpd , "vdivpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(5E,U) , U ), - INST(kInstVdivps , "vdivps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(5E,U) , U ), - INST(kInstVdivsd , "vdivsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F20F00(5E,U) , U ), - INST(kInstVdivss , "vdivss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(5E,U) , U ), - INST(kInstVdppd , "vdppd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_660F3A(41,U) , U ), - INST(kInstVdpps , "vdpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(40,U) , U ), - INST(kInstVextractf128 , "vextractf128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , O_660F3A(19,U)|L, U ), - INST(kInstVextracti128 , "vextracti128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , O_660F3A(39,U)|L, U ), - INST(kInstVextractps , "vextractps" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , O_660F3A(17,U) , U ), - INST(kInstVfmadd132pd , "vfmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(98,U) , U ), - INST(kInstVfmadd132ps , "vfmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(98,U) , U ), - INST(kInstVfmadd132sd , "vfmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(99,U) , U ), - INST(kInstVfmadd132ss , "vfmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(99,U) , U ), - INST(kInstVfmadd213pd , "vfmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A8,U) , U ), - INST(kInstVfmadd213ps , "vfmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A8,U) , U ), - INST(kInstVfmadd213sd , "vfmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(A9,U) , U ), - INST(kInstVfmadd213ss , "vfmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(A9,U) , U ), - INST(kInstVfmadd231pd , "vfmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B8,U) , U ), - INST(kInstVfmadd231ps , "vfmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B8,U) , U ), - INST(kInstVfmadd231sd , "vfmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(B9,U) , U ), - INST(kInstVfmadd231ss , "vfmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(B9,U) , U ), - INST(kInstVfmaddpd , "vfmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(69,U) , U ), - INST(kInstVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(68,U) , U ), - INST(kInstVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6B,U) , U ), - INST(kInstVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6A,U) , U ), - INST(kInstVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(96,U) , U ), - INST(kInstVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(96,U) , U ), - INST(kInstVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A6,U) , U ), - INST(kInstVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A6,U) , U ), - INST(kInstVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B6,U) , U ), - INST(kInstVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B6,U) , U ), - INST(kInstVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5D,U) , U ), - INST(kInstVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5C,U) , U ), - INST(kInstVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9A,U) , U ), - INST(kInstVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9A,U) , U ), - INST(kInstVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9B,U) , U ), - INST(kInstVfmsub132ss , "vfmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9B,U) , U ), - INST(kInstVfmsub213pd , "vfmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AA,U) , U ), - INST(kInstVfmsub213ps , "vfmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AA,U) , U ), - INST(kInstVfmsub213sd , "vfmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AB,U) , U ), - INST(kInstVfmsub213ss , "vfmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AB,U) , U ), - INST(kInstVfmsub231pd , "vfmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BA,U) , U ), - INST(kInstVfmsub231ps , "vfmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BA,U) , U ), - INST(kInstVfmsub231sd , "vfmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BB,U) , U ), - INST(kInstVfmsub231ss , "vfmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BB,U) , U ), - INST(kInstVfmsubadd132pd , "vfmsubadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(97,U) , U ), - INST(kInstVfmsubadd132ps , "vfmsubadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(97,U) , U ), - INST(kInstVfmsubadd213pd , "vfmsubadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A7,U) , U ), - INST(kInstVfmsubadd213ps , "vfmsubadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A7,U) , U ), - INST(kInstVfmsubadd231pd , "vfmsubadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B7,U) , U ), - INST(kInstVfmsubadd231ps , "vfmsubadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B7,U) , U ), - INST(kInstVfmsubaddpd , "vfmsubaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5F,U) , U ), - INST(kInstVfmsubaddps , "vfmsubaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5E,U) , U ), - INST(kInstVfmsubpd , "vfmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(6D,U) , U ), - INST(kInstVfmsubps , "vfmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(6C,U) , U ), - INST(kInstVfmsubsd , "vfmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6F,U) , U ), - INST(kInstVfmsubss , "vfmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6E,U) , U ), - INST(kInstVfnmadd132pd , "vfnmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9C,U) , U ), - INST(kInstVfnmadd132ps , "vfnmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9C,U) , U ), - INST(kInstVfnmadd132sd , "vfnmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9D,U) , U ), - INST(kInstVfnmadd132ss , "vfnmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9D,U) , U ), - INST(kInstVfnmadd213pd , "vfnmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AC,U) , U ), - INST(kInstVfnmadd213ps , "vfnmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AC,U) , U ), - INST(kInstVfnmadd213sd , "vfnmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AD,U) , U ), - INST(kInstVfnmadd213ss , "vfnmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AD,U) , U ), - INST(kInstVfnmadd231pd , "vfnmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BC,U) , U ), - INST(kInstVfnmadd231ps , "vfnmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BC,U) , U ), - INST(kInstVfnmadd231sd , "vfnmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BC,U) , U ), - INST(kInstVfnmadd231ss , "vfnmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BC,U) , U ), - INST(kInstVfnmaddpd , "vfnmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(79,U) , U ), - INST(kInstVfnmaddps , "vfnmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(78,U) , U ), - INST(kInstVfnmaddsd , "vfnmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(7B,U) , U ), - INST(kInstVfnmaddss , "vfnmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(7A,U) , U ), - INST(kInstVfnmsub132pd , "vfnmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9E,U) , U ), - INST(kInstVfnmsub132ps , "vfnmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9E,U) , U ), - INST(kInstVfnmsub132sd , "vfnmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9F,U) , U ), - INST(kInstVfnmsub132ss , "vfnmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9F,U) , U ), - INST(kInstVfnmsub213pd , "vfnmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AE,U) , U ), - INST(kInstVfnmsub213ps , "vfnmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(AE,U) , U ), - INST(kInstVfnmsub213sd , "vfnmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AF,U) , U ), - INST(kInstVfnmsub213ss , "vfnmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(AF,U) , U ), - INST(kInstVfnmsub231pd , "vfnmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BE,U) , U ), - INST(kInstVfnmsub231ps , "vfnmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(BE,U) , U ), - INST(kInstVfnmsub231sd , "vfnmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BF,U) , U ), - INST(kInstVfnmsub231ss , "vfnmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(BF,U) , U ), - INST(kInstVfnmsubpd , "vfnmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(7D,U) , U ), - INST(kInstVfnmsubps , "vfnmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(7C,U) , U ), - INST(kInstVfnmsubsd , "vfnmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(7F,U) , U ), - INST(kInstVfnmsubss , "vfnmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(7E,U) , U ), - INST(kInstVfrczpd , "vfrczpd" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_00_M09(81,U) , U ), - INST(kInstVfrczps , "vfrczps" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_00_M09(80,U) , U ), - INST(kInstVfrczsd , "vfrczsd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(83,U) , U ), - INST(kInstVfrczss , "vfrczss" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(82,U) , U ), - INST(kInstVgatherdpd , "vgatherdpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(92,U) , U ), - INST(kInstVgatherdps , "vgatherdps" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(92,U) , U ), - INST(kInstVgatherqpd , "vgatherqpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(93,U) , U ), - INST(kInstVgatherqps , "vgatherqps" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , O_660F38(93,U) , U ), - INST(kInstVhaddpd , "vhaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(7C,U) , U ), - INST(kInstVhaddps , "vhaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(7C,U) , U ), - INST(kInstVhsubpd , "vhsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(7D,U) , U ), - INST(kInstVhsubps , "vhsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(7D,U) , U ), - INST(kInstVinsertf128 , "vinsertf128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , O_660F3A(18,U)|L, U ), - INST(kInstVinserti128 , "vinserti128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , O_660F3A(38,U)|L, U ), - INST(kInstVinsertps , "vinsertps" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_660F3A(21,U) , U ), - INST(kInstVlddqu , "vlddqu" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , O_F20F00(F0,U) , U ), - INST(kInstVldmxcsr , "vldmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(AE,2) , U ), - INST(kInstVmaskmovdqu , "vmaskmovdqu" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , O_660F00(F7,U) , U ), - INST(kInstVmaskmovpd , "vmaskmovpd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(2D,U) , O_660F38(2F,U) ), - INST(kInstVmaskmovps , "vmaskmovps" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(2C,U) , O_660F38(2E,U) ), - INST(kInstVmaxpd , "vmaxpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(5F,U) , U ), - INST(kInstVmaxps , "vmaxps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(5F,U) , U ), - INST(kInstVmaxsd , "vmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(5F,U) , U ), - INST(kInstVmaxss , "vmaxss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F30F00(5F,U) , U ), - INST(kInstVminpd , "vminpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(5D,U) , U ), - INST(kInstVminps , "vminps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(5D,U) , U ), - INST(kInstVminsd , "vminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(5D,U) , U ), - INST(kInstVminss , "vminss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F30F00(5D,U) , U ), - INST(kInstVmovapd , "vmovapd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_660F00(28,U) , O_660F00(29,U) ), - INST(kInstVmovaps , "vmovaps" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_000F00(28,U) , O_000F00(29,U) ), - INST(kInstVmovd , "vmovd" , G(AvxRmMr) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , O_660F00(6E,U) , O_660F00(7E,U) ), - INST(kInstVmovddup , "vmovddup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_F20F00(12,U) , U ), - INST(kInstVmovdqa , "vmovdqa" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_660F00(6F,U) , O_660F00(7F,U) ), - INST(kInstVmovdqu , "vmovdqu" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_F30F00(6F,U) , O_F30F00(7F,U) ), - INST(kInstVmovhlps , "vmovhlps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , O_000F00(12,U) , U ), - INST(kInstVmovhpd , "vmovhpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , O_660F00(16,U) , O_660F00(17,U) ), - INST(kInstVmovhps , "vmovhps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , O_000F00(16,U) , O_000F00(17,U) ), - INST(kInstVmovlhps , "vmovlhps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , O_000F00(16,U) , U ), - INST(kInstVmovlpd , "vmovlpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , O_660F00(12,U) , O_660F00(13,U) ), - INST(kInstVmovlps , "vmovlps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , O_000F00(12,U) , O_000F00(13,U) ), - INST(kInstVmovmskpd , "vmovmskpd" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , O_660F00(50,U) , U ), - INST(kInstVmovmskps , "vmovmskps" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , O_000F00(50,U) , U ), - INST(kInstVmovntdq , "vmovntdq" , G(AvxMr) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , O_660F00(E7,U) , U ), - INST(kInstVmovntdqa , "vmovntdqa" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , O_660F38(2A,U) , U ), - INST(kInstVmovntpd , "vmovntpd" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , O_660F00(2B,U) , U ), - INST(kInstVmovntps , "vmovntps" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , O_000F00(2B,U) , U ), - INST(kInstVmovq , "vmovq" , G(AvxRmMr) , F(None) |F(W), 0 , O(XmmMem) , O(XmmMem) , U , U , O_660F00(6E,U) , O_660F00(7E,U) ), - INST(kInstVmovsd , "vmovsd" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , O_F20F00(10,U) , O_F20F00(11,U) ), - INST(kInstVmovshdup , "vmovshdup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_F30F00(16,U) , U ), - INST(kInstVmovsldup , "vmovsldup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_F30F00(12,U) , U ), - INST(kInstVmovss , "vmovss" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , O_F30F00(10,U) , O_F30F00(11,U) ), - INST(kInstVmovupd , "vmovupd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_660F00(10,U) , O_660F00(11,U) ), - INST(kInstVmovups , "vmovups" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , O_000F00(10,U) , O_000F00(11,U) ), - INST(kInstVmpsadbw , "vmpsadbw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(42,U) , U ), - INST(kInstVmulpd , "vmulpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(59,U) , U ), - INST(kInstVmulps , "vmulps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(59,U) , U ), - INST(kInstVmulsd , "vmulsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F20F00(59,U) , U ), - INST(kInstVmulss , "vmulss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_F30F00(59,U) , U ), - INST(kInstVorpd , "vorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(56,U) , U ), - INST(kInstVorps , "vorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(56,U) , U ), - INST(kInstVpabsb , "vpabsb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(1C,U) , U ), - INST(kInstVpabsd , "vpabsd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(1E,U) , U ), - INST(kInstVpabsw , "vpabsw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(1D,U) , U ), - INST(kInstVpackssdw , "vpackssdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(6B,U) , U ), - INST(kInstVpacksswb , "vpacksswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(63,U) , U ), - INST(kInstVpackusdw , "vpackusdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(2B,U) , U ), - INST(kInstVpackuswb , "vpackuswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(67,U) , U ), - INST(kInstVpaddb , "vpaddb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(FC,U) , U ), - INST(kInstVpaddd , "vpaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(FE,U) , U ), - INST(kInstVpaddq , "vpaddq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(D4,U) , U ), - INST(kInstVpaddsb , "vpaddsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(EC,U) , U ), - INST(kInstVpaddsw , "vpaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(ED,U) , U ), - INST(kInstVpaddusb , "vpaddusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DC,U) , U ), - INST(kInstVpaddusw , "vpaddusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DD,U) , U ), - INST(kInstVpaddw , "vpaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(FD,U) , U ), - INST(kInstVpalignr , "vpalignr" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(0F,U) , U ), - INST(kInstVpand , "vpand" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DB,U) , U ), - INST(kInstVpandn , "vpandn" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DF,U) , U ), - INST(kInstVpavgb , "vpavgb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E0,U) , U ), - INST(kInstVpavgw , "vpavgw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E3,U) , U ), - INST(kInstVpblendd , "vpblendd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(02,U) , U ), - INST(kInstVpblendvb , "vpblendvb" , G(AvxRvmr) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , O_660F3A(4C,U) , U ), - INST(kInstVpblendw , "vpblendw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F3A(0E,U) , U ), - INST(kInstVpbroadcastb , "vpbroadcastb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_660F38(78,U) , U ), - INST(kInstVpbroadcastd , "vpbroadcastd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_660F38(58,U) , U ), - INST(kInstVpbroadcastq , "vpbroadcastq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_660F38(59,U) , U ), - INST(kInstVpbroadcastw , "vpbroadcastw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , O_660F38(79,U) , U ), - INST(kInstVpclmulqdq , "vpclmulqdq" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_660F3A(44,U) , U ), - INST(kInstVpcmov , "vpcmov" , G(XopRvrmRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_00_M08(A2,U) , U ), - INST(kInstVpcmpeqb , "vpcmpeqb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(74,U) , U ), - INST(kInstVpcmpeqd , "vpcmpeqd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(76,U) , U ), - INST(kInstVpcmpeqq , "vpcmpeqq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(29,U) , U ), - INST(kInstVpcmpeqw , "vpcmpeqw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(75,U) , U ), - INST(kInstVpcmpestri , "vpcmpestri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(61,U) , U ), - INST(kInstVpcmpestrm , "vpcmpestrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(60,U) , U ), - INST(kInstVpcmpgtb , "vpcmpgtb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(64,U) , U ), - INST(kInstVpcmpgtd , "vpcmpgtd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(66,U) , U ), - INST(kInstVpcmpgtq , "vpcmpgtq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(37,U) , U ), - INST(kInstVpcmpgtw , "vpcmpgtw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(65,U) , U ), - INST(kInstVpcmpistri , "vpcmpistri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(63,U) , U ), - INST(kInstVpcmpistrm , "vpcmpistrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , O_660F3A(62,U) , U ), - INST(kInstVpcomb , "vpcomb" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(CC,U) , U ), - INST(kInstVpcomd , "vpcomd" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(CE,U) , U ), - INST(kInstVpcomq , "vpcomq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(CF,U) , U ), - INST(kInstVpcomub , "vpcomub" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(EC,U) , U ), - INST(kInstVpcomud , "vpcomud" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(EE,U) , U ), - INST(kInstVpcomuq , "vpcomuq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(EF,U) , U ), - INST(kInstVpcomuw , "vpcomuw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(ED,U) , U ), - INST(kInstVpcomw , "vpcomw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_00_M08(CD,U) , U ), - INST(kInstVperm2f128 , "vperm2f128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , O_660F3A(06,U)|L, U ), - INST(kInstVperm2i128 , "vperm2i128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , O_660F3A(46,U)|L, U ), - INST(kInstVpermd , "vpermd" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , O_660F38(36,U)|L, U ), - INST(kInstVpermil2pd , "vpermil2pd" , G(AvxRvrmRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_66_M03(49,U) , U ), - INST(kInstVpermil2ps , "vpermil2ps" , G(AvxRvrmRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_66_M03(48,U) , U ), - INST(kInstVpermilpd , "vpermilpd" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F38(0D,U) , O_660F3A(05,U) ), - INST(kInstVpermilps , "vpermilps" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F38(0C,U) , O_660F3A(04,U) ), - INST(kInstVpermpd , "vpermpd" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , O_660F3A(01,U)|L, U ), - INST(kInstVpermps , "vpermps" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , O_660F38(16,U)|L, U ), - INST(kInstVpermq , "vpermq" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , O_660F3A(00,U)|L, U ), - INST(kInstVpextrb , "vpextrb" , G(AvxMri) , F(None) , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , O_660F3A(14,U) , U ), - INST(kInstVpextrd , "vpextrd" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , O_660F3A(16,U) , U ), - INST(kInstVpextrq , "vpextrq" , G(AvxMri) , F(None) |F(W), 0 , O(GqMem) , O(Xmm) , O(Imm) , U , O_660F3A(16,U) , U ), - INST(kInstVpextrw , "vpextrw" , G(AvxMri) , F(None) , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , O_660F3A(15,U) , U ), - INST(kInstVpgatherdd , "vpgatherdd" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(90,U) , U ), - INST(kInstVpgatherdq , "vpgatherdq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(90,U) , U ), - INST(kInstVpgatherqd , "vpgatherqd" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , O_660F38(91,U) , U ), - INST(kInstVpgatherqq , "vpgatherqq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , O_660F38(91,U) , U ), - INST(kInstVphaddbd , "vphaddbd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C2,U) , U ), - INST(kInstVphaddbq , "vphaddbq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C3,U) , U ), - INST(kInstVphaddbw , "vphaddbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C1,U) , U ), - INST(kInstVphaddd , "vphaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(02,U) , U ), - INST(kInstVphadddq , "vphadddq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(CB,U) , U ), - INST(kInstVphaddsw , "vphaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(03,U) , U ), - INST(kInstVphaddubd , "vphaddubd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(D2,U) , U ), - INST(kInstVphaddubq , "vphaddubq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(D3,U) , U ), - INST(kInstVphaddubw , "vphaddubw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(D1,U) , U ), - INST(kInstVphaddudq , "vphaddudq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(DB,U) , U ), - INST(kInstVphadduwd , "vphadduwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(D6,U) , U ), - INST(kInstVphadduwq , "vphadduwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(D7,U) , U ), - INST(kInstVphaddw , "vphaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(01,U) , U ), - INST(kInstVphaddwd , "vphaddwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C6,U) , U ), - INST(kInstVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C7,U) , U ), - INST(kInstVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(41,U) , U ), - INST(kInstVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E1,U) , U ), - INST(kInstVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(06,U) , U ), - INST(kInstVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E3,U) , U ), - INST(kInstVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(07,U) , U ), - INST(kInstVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(05,U) , U ), - INST(kInstVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E2,U) , U ), - INST(kInstVpinsrb , "vpinsrb" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , O_660F3A(20,U) , U ), - INST(kInstVpinsrd , "vpinsrd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , O_660F3A(22,U) , U ), - INST(kInstVpinsrq , "vpinsrq" , G(AvxRvmi) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , O_660F3A(22,U) , U ), - INST(kInstVpinsrw , "vpinsrw" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , O_660F00(C4,U) , U ), - INST(kInstVpmacsdd , "vpmacsdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(9E,U) , U ), - INST(kInstVpmacsdqh , "vpmacsdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(9F,U) , U ), - INST(kInstVpmacsdql , "vpmacsdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(97,U) , U ), - INST(kInstVpmacssdd , "vpmacssdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(8E,U) , U ), - INST(kInstVpmacssdqh , "vpmacssdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(8F,U) , U ), - INST(kInstVpmacssdql , "vpmacssdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(87,U) , U ), - INST(kInstVpmacsswd , "vpmacsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(86,U) , U ), - INST(kInstVpmacssww , "vpmacssww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(85,U) , U ), - INST(kInstVpmacswd , "vpmacswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(96,U) , U ), - INST(kInstVpmacsww , "vpmacsww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(95,U) , U ), - INST(kInstVpmadcsswd , "vpmadcsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(A6,U) , U ), - INST(kInstVpmadcswd , "vpmadcswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , O_00_M08(B6,U) , U ), - INST(kInstVpmaddubsw , "vpmaddubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(04,U) , U ), - INST(kInstVpmaddwd , "vpmaddwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(F5,U) , U ), - INST(kInstVpmaskmovd , "vpmaskmovd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(8C,U) , O_660F38(8E,U) ), - INST(kInstVpmaskmovq , "vpmaskmovq" , G(AvxRvmMvr_P) , F(None) |F(W), 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(8C,U) , O_660F38(8E,U) ), - INST(kInstVpmaxsb , "vpmaxsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3C,U) , U ), - INST(kInstVpmaxsd , "vpmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3D,U) , U ), - INST(kInstVpmaxsw , "vpmaxsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(EE,U) , U ), - INST(kInstVpmaxub , "vpmaxub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DE,U) , U ), - INST(kInstVpmaxud , "vpmaxud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3F,U) , U ), - INST(kInstVpmaxuw , "vpmaxuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3E,U) , U ), - INST(kInstVpminsb , "vpminsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(38,U) , U ), - INST(kInstVpminsd , "vpminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(39,U) , U ), - INST(kInstVpminsw , "vpminsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(EA,U) , U ), - INST(kInstVpminub , "vpminub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(DA,U) , U ), - INST(kInstVpminud , "vpminud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3B,U) , U ), - INST(kInstVpminuw , "vpminuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(3A,U) , U ), - INST(kInstVpmovmskb , "vpmovmskb" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , O_660F00(D7,U) , U ), - INST(kInstVpmovsxbd , "vpmovsxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(21,U) , U ), - INST(kInstVpmovsxbq , "vpmovsxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(22,U) , U ), - INST(kInstVpmovsxbw , "vpmovsxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(20,U) , U ), - INST(kInstVpmovsxdq , "vpmovsxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(25,U) , U ), - INST(kInstVpmovsxwd , "vpmovsxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(23,U) , U ), - INST(kInstVpmovsxwq , "vpmovsxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(24,U) , U ), - INST(kInstVpmovzxbd , "vpmovzxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(31,U) , U ), - INST(kInstVpmovzxbq , "vpmovzxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(32,U) , U ), - INST(kInstVpmovzxbw , "vpmovzxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(30,U) , U ), - INST(kInstVpmovzxdq , "vpmovzxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(35,U) , U ), - INST(kInstVpmovzxwd , "vpmovzxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(33,U) , U ), - INST(kInstVpmovzxwq , "vpmovzxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(34,U) , U ), - INST(kInstVpmuldq , "vpmuldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(28,U) , U ), - INST(kInstVpmulhrsw , "vpmulhrsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(0B,U) , U ), - INST(kInstVpmulhuw , "vpmulhuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E4,U) , U ), - INST(kInstVpmulhw , "vpmulhw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E5,U) , U ), - INST(kInstVpmulld , "vpmulld" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(40,U) , U ), - INST(kInstVpmullw , "vpmullw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(D5,U) , U ), - INST(kInstVpmuludq , "vpmuludq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(F4,U) , U ), - INST(kInstVpor , "vpor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(EB,U) , U ), - INST(kInstVpperm , "vpperm" , G(XopRvrmRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_00_M08(A3,U) , U ), - INST(kInstVprotb , "vprotb" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , O_00_M09(90,U) , O_00_M08(C0,U) ), - INST(kInstVprotd , "vprotd" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , O_00_M09(92,U) , O_00_M08(C2,U) ), - INST(kInstVprotq , "vprotq" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , O_00_M09(93,U) , O_00_M08(C3,U) ), - INST(kInstVprotw , "vprotw" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , O_00_M09(91,U) , O_00_M08(C1,U) ), - INST(kInstVpsadbw , "vpsadbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(F6,U) , U ), - INST(kInstVpshab , "vpshab" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(98,U) , U ), - INST(kInstVpshad , "vpshad" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(9A,U) , U ), - INST(kInstVpshaq , "vpshaq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(9B,U) , U ), - INST(kInstVpshaw , "vpshaw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(99,U) , U ), - INST(kInstVpshlb , "vpshlb" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(94,U) , U ), - INST(kInstVpshld , "vpshld" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(96,U) , U ), - INST(kInstVpshlq , "vpshlq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(97,U) , U ), - INST(kInstVpshlw , "vpshlw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , O_00_M09(95,U) , U ), - INST(kInstVpshufb , "vpshufb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(00,U) , U ), - INST(kInstVpshufd , "vpshufd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_660F00(70,U) , U ), - INST(kInstVpshufhw , "vpshufhw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_F30F00(70,U) , U ), - INST(kInstVpshuflw , "vpshuflw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_F20F00(70,U) , U ), - INST(kInstVpsignb , "vpsignb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(08,U) , U ), - INST(kInstVpsignd , "vpsignd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(0A,U) , U ), - INST(kInstVpsignw , "vpsignw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(09,U) , U ), - INST(kInstVpslld , "vpslld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(F2,U) , O_660F00(72,6) ), - INST(kInstVpslldq , "vpslldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_660F00(73,7) , U ), - INST(kInstVpsllq , "vpsllq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(F3,U) , O_660F00(73,6) ), - INST(kInstVpsllvd , "vpsllvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(47,U) , U ), - INST(kInstVpsllvq , "vpsllvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(47,U) , U ), - INST(kInstVpsllw , "vpsllw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(F1,U) , O_660F00(71,6) ), - INST(kInstVpsrad , "vpsrad" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(E2,U) , O_660F00(72,4) ), - INST(kInstVpsravd , "vpsravd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(46,U) , U ), - INST(kInstVpsraw , "vpsraw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(E1,U) , O_660F00(71,4) ), - INST(kInstVpsrld , "vpsrld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(D2,U) , O_660F00(72,2) ), - INST(kInstVpsrldq , "vpsrldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_660F00(73,3) , U ), - INST(kInstVpsrlq , "vpsrlq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(D3,U) , O_660F00(73,2) ), - INST(kInstVpsrlvd , "vpsrlvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(45,U) , U ), - INST(kInstVpsrlvq , "vpsrlvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(45,U) , U ), - INST(kInstVpsrlw , "vpsrlw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , O_660F00(D1,U) , O_660F00(71,2) ), - INST(kInstVpsubb , "vpsubb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(F8,U) , U ), - INST(kInstVpsubd , "vpsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(FA,U) , U ), - INST(kInstVpsubq , "vpsubq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(FB,U) , U ), - INST(kInstVpsubsb , "vpsubsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E8,U) , U ), - INST(kInstVpsubsw , "vpsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(E9,U) , U ), - INST(kInstVpsubusb , "vpsubusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(D8,U) , U ), - INST(kInstVpsubusw , "vpsubusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(D9,U) , U ), - INST(kInstVpsubw , "vpsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(F9,U) , U ), - INST(kInstVptest , "vptest" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(17,U) , U ), - INST(kInstVpunpckhbw , "vpunpckhbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(68,U) , U ), - INST(kInstVpunpckhdq , "vpunpckhdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(6A,U) , U ), - INST(kInstVpunpckhqdq , "vpunpckhqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(6D,U) , U ), - INST(kInstVpunpckhwd , "vpunpckhwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(69,U) , U ), - INST(kInstVpunpcklbw , "vpunpcklbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(60,U) , U ), - INST(kInstVpunpckldq , "vpunpckldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(62,U) , U ), - INST(kInstVpunpcklqdq , "vpunpcklqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(6C,U) , U ), - INST(kInstVpunpcklwd , "vpunpcklwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(61,U) , U ), - INST(kInstVpxor , "vpxor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(EF,U) , U ), - INST(kInstVrcpps , "vrcpps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_000F00(53,U) , U ), - INST(kInstVrcpss , "vrcpss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(53,U) , U ), - INST(kInstVroundpd , "vroundpd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_660F3A(09,U) , U ), - INST(kInstVroundps , "vroundps" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , O_660F3A(08,U) , U ), - INST(kInstVroundsd , "vroundsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_660F3A(0B,U) , U ), - INST(kInstVroundss , "vroundss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , O_660F3A(0A,U) , U ), - INST(kInstVrsqrtps , "vrsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_000F00(52,U) , U ), - INST(kInstVrsqrtss , "vrsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(52,U) , U ), - INST(kInstVshufpd , "vshufpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_660F00(C6,U) , U ), - INST(kInstVshufps , "vshufps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , O_000F00(C6,U) , U ), - INST(kInstVsqrtpd , "vsqrtpd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F00(51,U) , U ), - INST(kInstVsqrtps , "vsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_000F00(51,U) , U ), - INST(kInstVsqrtsd , "vsqrtsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F20F00(51,U) , U ), - INST(kInstVsqrtss , "vsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(51,U) , U ), - INST(kInstVstmxcsr , "vstmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , O_000F00(AE,3) , U ), - INST(kInstVsubpd , "vsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(5C,U) , U ), - INST(kInstVsubps , "vsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(5C,U) , U ), - INST(kInstVsubsd , "vsubsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F20F00(5C,U) , U ), - INST(kInstVsubss , "vsubss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_F30F00(5C,U) , U ), - INST(kInstVtestpd , "vtestpd" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(0F,U) , U ), - INST(kInstVtestps , "vtestps" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , O_660F38(0E,U) , U ), - INST(kInstVucomisd , "vucomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(2E,U) , U ), - INST(kInstVucomiss , "vucomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(2E,U) , U ), - INST(kInstVunpckhpd , "vunpckhpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(15,U) , U ), - INST(kInstVunpckhps , "vunpckhps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(15,U) , U ), - INST(kInstVunpcklpd , "vunpcklpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(14,U) , U ), - INST(kInstVunpcklps , "vunpcklps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(14,U) , U ), - INST(kInstVxorpd , "vxorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F00(57,U) , U ), - INST(kInstVxorps , "vxorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_000F00(57,U) , U ), - INST(kInstVzeroall , "vzeroall" , G(AvxOp) , F(None) , 0 , U , U , U , U , O_000F00(77,U)|L, U ), - INST(kInstVzeroupper , "vzeroupper" , G(AvxOp) , F(None) , 0 , U , U , U , U , O_000F00(77,U) , U ), - INST(kInstWrfsbase , "wrfsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , O_F30F00(AE,2) , U ), - INST(kInstWrgsbase , "wrgsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , O_F30F00(AE,3) , U ), - INST(kInstXadd , "xadd" , G(X86Xadd) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , O_000F00(C0,U) , U ), - INST(kInstXchg , "xchg" , G(X86Xchg) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , O_000000(86,U) , U ), - INST(kInstXor , "xor" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , O_000000(30,6) , U ), - INST(kInstXorpd , "xorpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F00(57,U) , U ), - INST(kInstXorps , "xorps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_000F00(57,U) , U ) +// Automatically generated, do not edit. +const X86InstExtendedInfo _x86InstExtendedInfo[] = { + { G(None) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Arith) , 0 , 0x20, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86Arith) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, + { G(AvxRmv) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxVm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x00, 0x3F, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86BSwap) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Test) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,4) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,7) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,6) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,5) }, + { G(X86Call) , 0 , 0x00, 0x00, F(Flow) , { O(GqdMem)|O(Imm)|O(Label), U , U , U , U }, O_000000(E8,U) }, + { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x20, F(None) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x40, F(None) , { U , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x20, 0x20, F(None) , { U , U , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x24, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x20, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x04, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x07, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x03, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x01, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x10, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x02, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86Arith) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86RmReg) , 0 , 0x00, 0x3F, F(Lock)|F(Special) , { U , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x3F, F(Test) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtCrc) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdwbMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, + { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, + { G(ExtRm_Q) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(X86Op) , 0 , 0x28, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(48,U) }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Enter) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GqdMem) , O(Xmm) , U , U , U }, O_660F3A(17,U) }, + { G(FpuOp) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, + { G(FpuArith) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(FpMem) , O(Fp) , U , U , U }, U }, + { G(FpuRDef) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x20, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x24, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x04, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x10, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuCom) , 0 , 0x00, 0x00, F(Fp) , { O(Fp)|O(Mem) , O(Fp) , U , U , U }, U }, + { G(FpuR) , 0 , 0x00, 0x3F, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4) , { O(Mem) , U , U , U , U }, U }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,5) }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,7) }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DD,1) }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,5) }, + { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_00_X(DFE0,U) }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(Mem) , U , U , U , U }, U }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,7) }, + { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_9B_X(DFE0,U) }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, + { G(X86Imul) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, + { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(40,U) }, + { G(X86Int) , 0 , 0x00, 0x80, F(None) , { U , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x24, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x20, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x04, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x07, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x03, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x01, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x10, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x02, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jecxz) , 0 , 0x00, 0x00, F(Flow)|F(Special) , { O(Gqdw) , O(Label) , U , U , U }, U }, + { G(X86Jmp) , 0 , 0x00, 0x00, F(Flow) , { O(Imm)|O(Label) , U , U , U , U }, O_000000(E9,U) }, + { G(X86Op) , 0 , 0x3E, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, + { G(X86Lea) , 0 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Mem) , U , U , U }, U }, + { G(ExtFence) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Op) , 1 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 4 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 8 , 0x40, 0x00, F(Move)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 2 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Mm) , O(Mm) , U , U , U }, U }, + { G(X86Mov) , 0 , 0x00, 0x00, F(Move) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86MovPtr) , 0 , 0x00, 0x00, F(Move)|F(Special) , { O(Gqdwb) , O(Imm) , U , U , U }, O_000000(A2,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(29,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(29,U) }, + { G(ExtMovBe) , 0 , 0x00, 0x00, F(Move) , { O(GqdwMem) , O(GqdwMem) , U , U , U }, O_000F38(F1,U) }, + { G(ExtMovD) , 16, 0x00, 0x00, F(Move) , { O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U }, O_000F00(7E,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7F,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(7F,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(17,U) }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(17,U) }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(13,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(13,U) }, + { G(ExtMovNoRexW) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(E7,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Gqd) , U , U , U }, O_000F00(C3,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(2B,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_000F00(2B,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Mm) , U , U , U }, O_000F00(E7,U) }, + { G(ExtMovQ) , 16, 0x00, 0x00, F(Move) , { O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mm) , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F20F00(11,U) }, + { G(ExtMov) , 4 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(11,U) }, + { G(X86MovSxZx) , 0 , 0x00, 0x00, F(Move) , { O(Gqdw) , O(GwbMem) , U , U , U }, U }, + { G(X86MovSxd) , 0 , 0x00, 0x00, F(Move) , { O(Gq) , O(GdMem) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(11,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(11,U) }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, + { G(X86Rm_B) , 0 , 0x00, 0x00, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, + { G(ExtRm_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , U , U , U }, U }, + { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U }, U }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , U }, O_000F3A(14,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) |F(W), { O(GqdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(MmXmm) , U , U , U }, O_000F3A(15,U) }, + { G(3dNow) , 0 , 0x00, 0x00, F(None) , { O(Mm) , O(MmMem) , U , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(GdMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(GqMem) , O(Imm) , U , U }, U }, + { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(GdMem) , O(Imm) , U , U }, U }, + { G(ExtRm_PQ) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(MmXmm) , U , U , U }, U }, + { G(X86Pop) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(58,U) }, + { G(X86Op) , 0 , 0x00, 0xFF, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtPrefetch) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(Imm) , U , U , U }, U }, + { G(ExtRmi) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(ExtRmi_P) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(MmMem) , O(Imm) , U , U }, U }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,6) }, + { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,7) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,6) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,6) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,4) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,4) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,2) }, + { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,3) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,2) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,2) }, + { G(X86Push) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(50,U) }, + { G(X86Op) , 0 , 0xFF, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x20, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(X86Rm) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , U , U , U , U }, U }, + { G(X86Rm) , 8 , 0x00, 0x3F, F(Move) , { O(Gqdw) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Ret) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x00, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x3E, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(AvxRmv) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, + { G(X86Set) , 1 , 0x24, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x20, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x04, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x07, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x03, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x01, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x10, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x02, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb) , U , U , U }, U }, + { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Test) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U }, O_000000(F6,U) }, + { G(X86RegRm) , 0 , 0x00, 0x3F, F(Move) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U }, U }, + { G(AvxRvmr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Mem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxMri_P) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmYmm) , O(Imm) , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Ymm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, + { G(Fma4_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(Fma4) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, + { G(XopRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(XopRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxGather) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, + { G(AvxGather) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, + { G(AvxGatherEx) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Mem) , O(Xmm) , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , U , U , U }, U }, + { G(AvxM) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2F,U) }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2E,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(29,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(29,U) }, + { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(7F,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_F30F00(7F,U) }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(Xmm) , U , U }, U }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(17,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(17,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(13,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(13,U) }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmYmm) , U , U , U }, U }, + { G(AvxMr) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, + { G(AvxMr_P) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, + { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, + { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , O(Xmm) , U , U }, O_F20F00(11,U) }, + { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Xmm) , U , U }, O_F30F00(11,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(11,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(11,U) }, + { G(AvxRvmr) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, + { G(XopRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(XopRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , U , U }, U }, + { G(AvxRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(05,U) }, + { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(04,U) }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Ymm) , O(YmmMem) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwbMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) |F(W), { O(GqMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U }, U }, + { G(XopRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U }, U }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, + { G(XopRvrmRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C0,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C2,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C3,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C1,U) }, + { G(XopRvmRmv) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem) , U , U }, U }, + { G(AvxRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,6) }, + { G(AvxVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,6) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,6) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,4) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,4) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,2) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,2) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,2) }, + { G(AvxRm_P) , 0 , 0x00, 0x3F, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x3F, F(Test) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x3F, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxOp) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Rm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, + { G(X86Xadd) , 0 , 0x00, 0x3F, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, + { G(X86Xchg) , 0 , 0x00, 0x00, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U } }; +// Automatically generated, do not edit. +enum kX86InstData_ExtendedIndex { + kInstIdNone_ExtendedIndex = 0, + kX86InstIdAdc_ExtendedIndex = 1, + kX86InstIdAdd_ExtendedIndex = 2, + kX86InstIdAddpd_ExtendedIndex = 3, + kX86InstIdAddps_ExtendedIndex = 3, + kX86InstIdAddsd_ExtendedIndex = 3, + kX86InstIdAddss_ExtendedIndex = 3, + kX86InstIdAddsubpd_ExtendedIndex = 3, + kX86InstIdAddsubps_ExtendedIndex = 3, + kX86InstIdAesdec_ExtendedIndex = 3, + kX86InstIdAesdeclast_ExtendedIndex = 3, + kX86InstIdAesenc_ExtendedIndex = 3, + kX86InstIdAesenclast_ExtendedIndex = 3, + kX86InstIdAesimc_ExtendedIndex = 3, + kX86InstIdAeskeygenassist_ExtendedIndex = 4, + kX86InstIdAnd_ExtendedIndex = 2, + kX86InstIdAndn_ExtendedIndex = 5, + kX86InstIdAndnpd_ExtendedIndex = 3, + kX86InstIdAndnps_ExtendedIndex = 3, + kX86InstIdAndpd_ExtendedIndex = 3, + kX86InstIdAndps_ExtendedIndex = 3, + kX86InstIdBextr_ExtendedIndex = 6, + kX86InstIdBlendpd_ExtendedIndex = 4, + kX86InstIdBlendps_ExtendedIndex = 4, + kX86InstIdBlendvpd_ExtendedIndex = 7, + kX86InstIdBlendvps_ExtendedIndex = 7, + kX86InstIdBlsi_ExtendedIndex = 8, + kX86InstIdBlsmsk_ExtendedIndex = 8, + kX86InstIdBlsr_ExtendedIndex = 8, + kX86InstIdBsf_ExtendedIndex = 9, + kX86InstIdBsr_ExtendedIndex = 9, + kX86InstIdBswap_ExtendedIndex = 10, + kX86InstIdBt_ExtendedIndex = 11, + kX86InstIdBtc_ExtendedIndex = 12, + kX86InstIdBtr_ExtendedIndex = 13, + kX86InstIdBts_ExtendedIndex = 14, + kX86InstIdBzhi_ExtendedIndex = 6, + kX86InstIdCall_ExtendedIndex = 15, + kX86InstIdCbw_ExtendedIndex = 16, + kX86InstIdCdq_ExtendedIndex = 16, + kX86InstIdCdqe_ExtendedIndex = 17, + kX86InstIdClc_ExtendedIndex = 18, + kX86InstIdCld_ExtendedIndex = 19, + kX86InstIdClflush_ExtendedIndex = 20, + kX86InstIdCmc_ExtendedIndex = 21, + kX86InstIdCmova_ExtendedIndex = 22, + kX86InstIdCmovae_ExtendedIndex = 23, + kX86InstIdCmovb_ExtendedIndex = 23, + kX86InstIdCmovbe_ExtendedIndex = 22, + kX86InstIdCmovc_ExtendedIndex = 23, + kX86InstIdCmove_ExtendedIndex = 24, + kX86InstIdCmovg_ExtendedIndex = 25, + kX86InstIdCmovge_ExtendedIndex = 26, + kX86InstIdCmovl_ExtendedIndex = 26, + kX86InstIdCmovle_ExtendedIndex = 25, + kX86InstIdCmovna_ExtendedIndex = 22, + kX86InstIdCmovnae_ExtendedIndex = 23, + kX86InstIdCmovnb_ExtendedIndex = 23, + kX86InstIdCmovnbe_ExtendedIndex = 22, + kX86InstIdCmovnc_ExtendedIndex = 23, + kX86InstIdCmovne_ExtendedIndex = 24, + kX86InstIdCmovng_ExtendedIndex = 25, + kX86InstIdCmovnge_ExtendedIndex = 26, + kX86InstIdCmovnl_ExtendedIndex = 26, + kX86InstIdCmovnle_ExtendedIndex = 25, + kX86InstIdCmovno_ExtendedIndex = 27, + kX86InstIdCmovnp_ExtendedIndex = 28, + kX86InstIdCmovns_ExtendedIndex = 29, + kX86InstIdCmovnz_ExtendedIndex = 24, + kX86InstIdCmovo_ExtendedIndex = 27, + kX86InstIdCmovp_ExtendedIndex = 28, + kX86InstIdCmovpe_ExtendedIndex = 28, + kX86InstIdCmovpo_ExtendedIndex = 28, + kX86InstIdCmovs_ExtendedIndex = 29, + kX86InstIdCmovz_ExtendedIndex = 24, + kX86InstIdCmp_ExtendedIndex = 30, + kX86InstIdCmppd_ExtendedIndex = 4, + kX86InstIdCmpps_ExtendedIndex = 4, + kX86InstIdCmpsB_ExtendedIndex = 31, + kX86InstIdCmpsD_ExtendedIndex = 31, + kX86InstIdCmpsQ_ExtendedIndex = 32, + kX86InstIdCmpsW_ExtendedIndex = 33, + kX86InstIdCmpsd_ExtendedIndex = 4, + kX86InstIdCmpss_ExtendedIndex = 4, + kX86InstIdCmpxchg_ExtendedIndex = 34, + kX86InstIdCmpxchg16b_ExtendedIndex = 35, + kX86InstIdCmpxchg8b_ExtendedIndex = 36, + kX86InstIdComisd_ExtendedIndex = 37, + kX86InstIdComiss_ExtendedIndex = 37, + kX86InstIdCpuid_ExtendedIndex = 16, + kX86InstIdCqo_ExtendedIndex = 17, + kX86InstIdCrc32_ExtendedIndex = 38, + kX86InstIdCvtdq2pd_ExtendedIndex = 39, + kX86InstIdCvtdq2ps_ExtendedIndex = 39, + kX86InstIdCvtpd2dq_ExtendedIndex = 39, + kX86InstIdCvtpd2pi_ExtendedIndex = 40, + kX86InstIdCvtpd2ps_ExtendedIndex = 39, + kX86InstIdCvtpi2pd_ExtendedIndex = 41, + kX86InstIdCvtpi2ps_ExtendedIndex = 42, + kX86InstIdCvtps2dq_ExtendedIndex = 39, + kX86InstIdCvtps2pd_ExtendedIndex = 39, + kX86InstIdCvtps2pi_ExtendedIndex = 40, + kX86InstIdCvtsd2si_ExtendedIndex = 43, + kX86InstIdCvtsd2ss_ExtendedIndex = 44, + kX86InstIdCvtsi2sd_ExtendedIndex = 45, + kX86InstIdCvtsi2ss_ExtendedIndex = 46, + kX86InstIdCvtss2sd_ExtendedIndex = 47, + kX86InstIdCvtss2si_ExtendedIndex = 43, + kX86InstIdCvttpd2dq_ExtendedIndex = 39, + kX86InstIdCvttpd2pi_ExtendedIndex = 40, + kX86InstIdCvttps2dq_ExtendedIndex = 39, + kX86InstIdCvttps2pi_ExtendedIndex = 40, + kX86InstIdCvttsd2si_ExtendedIndex = 43, + kX86InstIdCvttss2si_ExtendedIndex = 43, + kX86InstIdCwd_ExtendedIndex = 16, + kX86InstIdCwde_ExtendedIndex = 16, + kX86InstIdDaa_ExtendedIndex = 48, + kX86InstIdDas_ExtendedIndex = 48, + kX86InstIdDec_ExtendedIndex = 49, + kX86InstIdDiv_ExtendedIndex = 50, + kX86InstIdDivpd_ExtendedIndex = 3, + kX86InstIdDivps_ExtendedIndex = 3, + kX86InstIdDivsd_ExtendedIndex = 3, + kX86InstIdDivss_ExtendedIndex = 3, + kX86InstIdDppd_ExtendedIndex = 4, + kX86InstIdDpps_ExtendedIndex = 4, + kX86InstIdEmms_ExtendedIndex = 51, + kX86InstIdEnter_ExtendedIndex = 52, + kX86InstIdExtractps_ExtendedIndex = 53, + kX86InstIdF2xm1_ExtendedIndex = 54, + kX86InstIdFabs_ExtendedIndex = 54, + kX86InstIdFadd_ExtendedIndex = 55, + kX86InstIdFaddp_ExtendedIndex = 56, + kX86InstIdFbld_ExtendedIndex = 57, + kX86InstIdFbstp_ExtendedIndex = 57, + kX86InstIdFchs_ExtendedIndex = 54, + kX86InstIdFclex_ExtendedIndex = 54, + kX86InstIdFcmovb_ExtendedIndex = 58, + kX86InstIdFcmovbe_ExtendedIndex = 59, + kX86InstIdFcmove_ExtendedIndex = 60, + kX86InstIdFcmovnb_ExtendedIndex = 58, + kX86InstIdFcmovnbe_ExtendedIndex = 59, + kX86InstIdFcmovne_ExtendedIndex = 60, + kX86InstIdFcmovnu_ExtendedIndex = 61, + kX86InstIdFcmovu_ExtendedIndex = 61, + kX86InstIdFcom_ExtendedIndex = 62, + kX86InstIdFcomi_ExtendedIndex = 63, + kX86InstIdFcomip_ExtendedIndex = 63, + kX86InstIdFcomp_ExtendedIndex = 62, + kX86InstIdFcompp_ExtendedIndex = 54, + kX86InstIdFcos_ExtendedIndex = 54, + kX86InstIdFdecstp_ExtendedIndex = 54, + kX86InstIdFdiv_ExtendedIndex = 55, + kX86InstIdFdivp_ExtendedIndex = 56, + kX86InstIdFdivr_ExtendedIndex = 55, + kX86InstIdFdivrp_ExtendedIndex = 56, + kX86InstIdFemms_ExtendedIndex = 64, + kX86InstIdFfree_ExtendedIndex = 65, + kX86InstIdFiadd_ExtendedIndex = 66, + kX86InstIdFicom_ExtendedIndex = 66, + kX86InstIdFicomp_ExtendedIndex = 66, + kX86InstIdFidiv_ExtendedIndex = 66, + kX86InstIdFidivr_ExtendedIndex = 66, + kX86InstIdFild_ExtendedIndex = 67, + kX86InstIdFimul_ExtendedIndex = 66, + kX86InstIdFincstp_ExtendedIndex = 54, + kX86InstIdFinit_ExtendedIndex = 54, + kX86InstIdFist_ExtendedIndex = 66, + kX86InstIdFistp_ExtendedIndex = 68, + kX86InstIdFisttp_ExtendedIndex = 69, + kX86InstIdFisub_ExtendedIndex = 66, + kX86InstIdFisubr_ExtendedIndex = 66, + kX86InstIdFld_ExtendedIndex = 70, + kX86InstIdFld1_ExtendedIndex = 54, + kX86InstIdFldcw_ExtendedIndex = 57, + kX86InstIdFldenv_ExtendedIndex = 57, + kX86InstIdFldl2e_ExtendedIndex = 54, + kX86InstIdFldl2t_ExtendedIndex = 54, + kX86InstIdFldlg2_ExtendedIndex = 54, + kX86InstIdFldln2_ExtendedIndex = 54, + kX86InstIdFldpi_ExtendedIndex = 54, + kX86InstIdFldz_ExtendedIndex = 54, + kX86InstIdFmul_ExtendedIndex = 55, + kX86InstIdFmulp_ExtendedIndex = 56, + kX86InstIdFnclex_ExtendedIndex = 54, + kX86InstIdFninit_ExtendedIndex = 54, + kX86InstIdFnop_ExtendedIndex = 54, + kX86InstIdFnsave_ExtendedIndex = 57, + kX86InstIdFnstcw_ExtendedIndex = 57, + kX86InstIdFnstenv_ExtendedIndex = 57, + kX86InstIdFnstsw_ExtendedIndex = 71, + kX86InstIdFpatan_ExtendedIndex = 54, + kX86InstIdFprem_ExtendedIndex = 54, + kX86InstIdFprem1_ExtendedIndex = 54, + kX86InstIdFptan_ExtendedIndex = 54, + kX86InstIdFrndint_ExtendedIndex = 54, + kX86InstIdFrstor_ExtendedIndex = 57, + kX86InstIdFsave_ExtendedIndex = 57, + kX86InstIdFscale_ExtendedIndex = 54, + kX86InstIdFsin_ExtendedIndex = 54, + kX86InstIdFsincos_ExtendedIndex = 54, + kX86InstIdFsqrt_ExtendedIndex = 54, + kX86InstIdFst_ExtendedIndex = 72, + kX86InstIdFstcw_ExtendedIndex = 57, + kX86InstIdFstenv_ExtendedIndex = 57, + kX86InstIdFstp_ExtendedIndex = 73, + kX86InstIdFstsw_ExtendedIndex = 74, + kX86InstIdFsub_ExtendedIndex = 55, + kX86InstIdFsubp_ExtendedIndex = 56, + kX86InstIdFsubr_ExtendedIndex = 55, + kX86InstIdFsubrp_ExtendedIndex = 56, + kX86InstIdFtst_ExtendedIndex = 54, + kX86InstIdFucom_ExtendedIndex = 56, + kX86InstIdFucomi_ExtendedIndex = 63, + kX86InstIdFucomip_ExtendedIndex = 63, + kX86InstIdFucomp_ExtendedIndex = 56, + kX86InstIdFucompp_ExtendedIndex = 54, + kX86InstIdFwait_ExtendedIndex = 64, + kX86InstIdFxam_ExtendedIndex = 54, + kX86InstIdFxch_ExtendedIndex = 65, + kX86InstIdFxrstor_ExtendedIndex = 57, + kX86InstIdFxsave_ExtendedIndex = 57, + kX86InstIdFxtract_ExtendedIndex = 54, + kX86InstIdFyl2x_ExtendedIndex = 54, + kX86InstIdFyl2xp1_ExtendedIndex = 54, + kX86InstIdHaddpd_ExtendedIndex = 3, + kX86InstIdHaddps_ExtendedIndex = 3, + kX86InstIdHsubpd_ExtendedIndex = 3, + kX86InstIdHsubps_ExtendedIndex = 3, + kX86InstIdIdiv_ExtendedIndex = 75, + kX86InstIdImul_ExtendedIndex = 76, + kX86InstIdInc_ExtendedIndex = 77, + kX86InstIdInsertps_ExtendedIndex = 4, + kX86InstIdInt_ExtendedIndex = 78, + kX86InstIdJa_ExtendedIndex = 79, + kX86InstIdJae_ExtendedIndex = 80, + kX86InstIdJb_ExtendedIndex = 80, + kX86InstIdJbe_ExtendedIndex = 79, + kX86InstIdJc_ExtendedIndex = 80, + kX86InstIdJe_ExtendedIndex = 81, + kX86InstIdJg_ExtendedIndex = 82, + kX86InstIdJge_ExtendedIndex = 83, + kX86InstIdJl_ExtendedIndex = 83, + kX86InstIdJle_ExtendedIndex = 82, + kX86InstIdJna_ExtendedIndex = 79, + kX86InstIdJnae_ExtendedIndex = 80, + kX86InstIdJnb_ExtendedIndex = 80, + kX86InstIdJnbe_ExtendedIndex = 79, + kX86InstIdJnc_ExtendedIndex = 80, + kX86InstIdJne_ExtendedIndex = 81, + kX86InstIdJng_ExtendedIndex = 82, + kX86InstIdJnge_ExtendedIndex = 83, + kX86InstIdJnl_ExtendedIndex = 83, + kX86InstIdJnle_ExtendedIndex = 82, + kX86InstIdJno_ExtendedIndex = 84, + kX86InstIdJnp_ExtendedIndex = 85, + kX86InstIdJns_ExtendedIndex = 86, + kX86InstIdJnz_ExtendedIndex = 81, + kX86InstIdJo_ExtendedIndex = 84, + kX86InstIdJp_ExtendedIndex = 85, + kX86InstIdJpe_ExtendedIndex = 85, + kX86InstIdJpo_ExtendedIndex = 85, + kX86InstIdJs_ExtendedIndex = 86, + kX86InstIdJz_ExtendedIndex = 81, + kX86InstIdJecxz_ExtendedIndex = 87, + kX86InstIdJmp_ExtendedIndex = 88, + kX86InstIdLahf_ExtendedIndex = 89, + kX86InstIdLddqu_ExtendedIndex = 90, + kX86InstIdLdmxcsr_ExtendedIndex = 20, + kX86InstIdLea_ExtendedIndex = 91, + kX86InstIdLeave_ExtendedIndex = 16, + kX86InstIdLfence_ExtendedIndex = 92, + kX86InstIdLodsB_ExtendedIndex = 93, + kX86InstIdLodsD_ExtendedIndex = 94, + kX86InstIdLodsQ_ExtendedIndex = 95, + kX86InstIdLodsW_ExtendedIndex = 96, + kX86InstIdLzcnt_ExtendedIndex = 9, + kX86InstIdMaskmovdqu_ExtendedIndex = 97, + kX86InstIdMaskmovq_ExtendedIndex = 98, + kX86InstIdMaxpd_ExtendedIndex = 3, + kX86InstIdMaxps_ExtendedIndex = 3, + kX86InstIdMaxsd_ExtendedIndex = 3, + kX86InstIdMaxss_ExtendedIndex = 3, + kX86InstIdMfence_ExtendedIndex = 92, + kX86InstIdMinpd_ExtendedIndex = 3, + kX86InstIdMinps_ExtendedIndex = 3, + kX86InstIdMinsd_ExtendedIndex = 3, + kX86InstIdMinss_ExtendedIndex = 3, + kX86InstIdMonitor_ExtendedIndex = 16, + kX86InstIdMov_ExtendedIndex = 99, + kX86InstIdMovPtr_ExtendedIndex = 100, + kX86InstIdMovapd_ExtendedIndex = 101, + kX86InstIdMovaps_ExtendedIndex = 102, + kX86InstIdMovbe_ExtendedIndex = 103, + kX86InstIdMovd_ExtendedIndex = 104, + kX86InstIdMovddup_ExtendedIndex = 105, + kX86InstIdMovdq2q_ExtendedIndex = 106, + kX86InstIdMovdqa_ExtendedIndex = 107, + kX86InstIdMovdqu_ExtendedIndex = 108, + kX86InstIdMovhlps_ExtendedIndex = 109, + kX86InstIdMovhpd_ExtendedIndex = 110, + kX86InstIdMovhps_ExtendedIndex = 111, + kX86InstIdMovlhps_ExtendedIndex = 112, + kX86InstIdMovlpd_ExtendedIndex = 113, + kX86InstIdMovlps_ExtendedIndex = 114, + kX86InstIdMovmskpd_ExtendedIndex = 115, + kX86InstIdMovmskps_ExtendedIndex = 115, + kX86InstIdMovntdq_ExtendedIndex = 116, + kX86InstIdMovntdqa_ExtendedIndex = 117, + kX86InstIdMovnti_ExtendedIndex = 118, + kX86InstIdMovntpd_ExtendedIndex = 119, + kX86InstIdMovntps_ExtendedIndex = 120, + kX86InstIdMovntq_ExtendedIndex = 121, + kX86InstIdMovq_ExtendedIndex = 122, + kX86InstIdMovq2dq_ExtendedIndex = 123, + kX86InstIdMovsB_ExtendedIndex = 16, + kX86InstIdMovsD_ExtendedIndex = 124, + kX86InstIdMovsQ_ExtendedIndex = 17, + kX86InstIdMovsW_ExtendedIndex = 125, + kX86InstIdMovsd_ExtendedIndex = 126, + kX86InstIdMovshdup_ExtendedIndex = 39, + kX86InstIdMovsldup_ExtendedIndex = 39, + kX86InstIdMovss_ExtendedIndex = 127, + kX86InstIdMovsx_ExtendedIndex = 128, + kX86InstIdMovsxd_ExtendedIndex = 129, + kX86InstIdMovupd_ExtendedIndex = 130, + kX86InstIdMovups_ExtendedIndex = 131, + kX86InstIdMovzx_ExtendedIndex = 128, + kX86InstIdMpsadbw_ExtendedIndex = 4, + kX86InstIdMul_ExtendedIndex = 75, + kX86InstIdMulpd_ExtendedIndex = 3, + kX86InstIdMulps_ExtendedIndex = 3, + kX86InstIdMulsd_ExtendedIndex = 3, + kX86InstIdMulss_ExtendedIndex = 3, + kX86InstIdMulx_ExtendedIndex = 132, + kX86InstIdMwait_ExtendedIndex = 16, + kX86InstIdNeg_ExtendedIndex = 133, + kX86InstIdNop_ExtendedIndex = 51, + kX86InstIdNot_ExtendedIndex = 134, + kX86InstIdOr_ExtendedIndex = 2, + kX86InstIdOrpd_ExtendedIndex = 3, + kX86InstIdOrps_ExtendedIndex = 3, + kX86InstIdPabsb_ExtendedIndex = 135, + kX86InstIdPabsd_ExtendedIndex = 135, + kX86InstIdPabsw_ExtendedIndex = 135, + kX86InstIdPackssdw_ExtendedIndex = 135, + kX86InstIdPacksswb_ExtendedIndex = 135, + kX86InstIdPackusdw_ExtendedIndex = 3, + kX86InstIdPackuswb_ExtendedIndex = 135, + kX86InstIdPaddb_ExtendedIndex = 135, + kX86InstIdPaddd_ExtendedIndex = 135, + kX86InstIdPaddq_ExtendedIndex = 135, + kX86InstIdPaddsb_ExtendedIndex = 135, + kX86InstIdPaddsw_ExtendedIndex = 135, + kX86InstIdPaddusb_ExtendedIndex = 135, + kX86InstIdPaddusw_ExtendedIndex = 135, + kX86InstIdPaddw_ExtendedIndex = 135, + kX86InstIdPalignr_ExtendedIndex = 136, + kX86InstIdPand_ExtendedIndex = 135, + kX86InstIdPandn_ExtendedIndex = 135, + kX86InstIdPause_ExtendedIndex = 51, + kX86InstIdPavgb_ExtendedIndex = 135, + kX86InstIdPavgw_ExtendedIndex = 135, + kX86InstIdPblendvb_ExtendedIndex = 7, + kX86InstIdPblendw_ExtendedIndex = 4, + kX86InstIdPclmulqdq_ExtendedIndex = 4, + kX86InstIdPcmpeqb_ExtendedIndex = 135, + kX86InstIdPcmpeqd_ExtendedIndex = 135, + kX86InstIdPcmpeqq_ExtendedIndex = 3, + kX86InstIdPcmpeqw_ExtendedIndex = 135, + kX86InstIdPcmpestri_ExtendedIndex = 4, + kX86InstIdPcmpestrm_ExtendedIndex = 4, + kX86InstIdPcmpgtb_ExtendedIndex = 135, + kX86InstIdPcmpgtd_ExtendedIndex = 135, + kX86InstIdPcmpgtq_ExtendedIndex = 3, + kX86InstIdPcmpgtw_ExtendedIndex = 135, + kX86InstIdPcmpistri_ExtendedIndex = 4, + kX86InstIdPcmpistrm_ExtendedIndex = 4, + kX86InstIdPdep_ExtendedIndex = 132, + kX86InstIdPext_ExtendedIndex = 132, + kX86InstIdPextrb_ExtendedIndex = 137, + kX86InstIdPextrd_ExtendedIndex = 138, + kX86InstIdPextrq_ExtendedIndex = 139, + kX86InstIdPextrw_ExtendedIndex = 140, + kX86InstIdPf2id_ExtendedIndex = 141, + kX86InstIdPf2iw_ExtendedIndex = 141, + kX86InstIdPfacc_ExtendedIndex = 141, + kX86InstIdPfadd_ExtendedIndex = 141, + kX86InstIdPfcmpeq_ExtendedIndex = 141, + kX86InstIdPfcmpge_ExtendedIndex = 141, + kX86InstIdPfcmpgt_ExtendedIndex = 141, + kX86InstIdPfmax_ExtendedIndex = 141, + kX86InstIdPfmin_ExtendedIndex = 141, + kX86InstIdPfmul_ExtendedIndex = 141, + kX86InstIdPfnacc_ExtendedIndex = 141, + kX86InstIdPfpnacc_ExtendedIndex = 141, + kX86InstIdPfrcp_ExtendedIndex = 141, + kX86InstIdPfrcpit1_ExtendedIndex = 141, + kX86InstIdPfrcpit2_ExtendedIndex = 141, + kX86InstIdPfrsqit1_ExtendedIndex = 141, + kX86InstIdPfrsqrt_ExtendedIndex = 141, + kX86InstIdPfsub_ExtendedIndex = 141, + kX86InstIdPfsubr_ExtendedIndex = 141, + kX86InstIdPhaddd_ExtendedIndex = 135, + kX86InstIdPhaddsw_ExtendedIndex = 135, + kX86InstIdPhaddw_ExtendedIndex = 135, + kX86InstIdPhminposuw_ExtendedIndex = 3, + kX86InstIdPhsubd_ExtendedIndex = 135, + kX86InstIdPhsubsw_ExtendedIndex = 135, + kX86InstIdPhsubw_ExtendedIndex = 135, + kX86InstIdPi2fd_ExtendedIndex = 141, + kX86InstIdPi2fw_ExtendedIndex = 141, + kX86InstIdPinsrb_ExtendedIndex = 142, + kX86InstIdPinsrd_ExtendedIndex = 142, + kX86InstIdPinsrq_ExtendedIndex = 143, + kX86InstIdPinsrw_ExtendedIndex = 144, + kX86InstIdPmaddubsw_ExtendedIndex = 135, + kX86InstIdPmaddwd_ExtendedIndex = 135, + kX86InstIdPmaxsb_ExtendedIndex = 3, + kX86InstIdPmaxsd_ExtendedIndex = 3, + kX86InstIdPmaxsw_ExtendedIndex = 135, + kX86InstIdPmaxub_ExtendedIndex = 135, + kX86InstIdPmaxud_ExtendedIndex = 3, + kX86InstIdPmaxuw_ExtendedIndex = 3, + kX86InstIdPminsb_ExtendedIndex = 3, + kX86InstIdPminsd_ExtendedIndex = 3, + kX86InstIdPminsw_ExtendedIndex = 135, + kX86InstIdPminub_ExtendedIndex = 135, + kX86InstIdPminud_ExtendedIndex = 3, + kX86InstIdPminuw_ExtendedIndex = 3, + kX86InstIdPmovmskb_ExtendedIndex = 145, + kX86InstIdPmovsxbd_ExtendedIndex = 39, + kX86InstIdPmovsxbq_ExtendedIndex = 39, + kX86InstIdPmovsxbw_ExtendedIndex = 39, + kX86InstIdPmovsxdq_ExtendedIndex = 39, + kX86InstIdPmovsxwd_ExtendedIndex = 39, + kX86InstIdPmovsxwq_ExtendedIndex = 39, + kX86InstIdPmovzxbd_ExtendedIndex = 39, + kX86InstIdPmovzxbq_ExtendedIndex = 39, + kX86InstIdPmovzxbw_ExtendedIndex = 39, + kX86InstIdPmovzxdq_ExtendedIndex = 39, + kX86InstIdPmovzxwd_ExtendedIndex = 39, + kX86InstIdPmovzxwq_ExtendedIndex = 39, + kX86InstIdPmuldq_ExtendedIndex = 3, + kX86InstIdPmulhrsw_ExtendedIndex = 135, + kX86InstIdPmulhuw_ExtendedIndex = 135, + kX86InstIdPmulhw_ExtendedIndex = 135, + kX86InstIdPmulld_ExtendedIndex = 3, + kX86InstIdPmullw_ExtendedIndex = 135, + kX86InstIdPmuludq_ExtendedIndex = 135, + kX86InstIdPop_ExtendedIndex = 146, + kX86InstIdPopa_ExtendedIndex = 16, + kX86InstIdPopcnt_ExtendedIndex = 9, + kX86InstIdPopf_ExtendedIndex = 147, + kX86InstIdPor_ExtendedIndex = 135, + kX86InstIdPrefetch_ExtendedIndex = 148, + kX86InstIdPrefetch3dNow_ExtendedIndex = 20, + kX86InstIdPrefetchw3dNow_ExtendedIndex = 20, + kX86InstIdPsadbw_ExtendedIndex = 135, + kX86InstIdPshufb_ExtendedIndex = 135, + kX86InstIdPshufd_ExtendedIndex = 149, + kX86InstIdPshufhw_ExtendedIndex = 149, + kX86InstIdPshuflw_ExtendedIndex = 149, + kX86InstIdPshufw_ExtendedIndex = 150, + kX86InstIdPsignb_ExtendedIndex = 135, + kX86InstIdPsignd_ExtendedIndex = 135, + kX86InstIdPsignw_ExtendedIndex = 135, + kX86InstIdPslld_ExtendedIndex = 151, + kX86InstIdPslldq_ExtendedIndex = 152, + kX86InstIdPsllq_ExtendedIndex = 153, + kX86InstIdPsllw_ExtendedIndex = 154, + kX86InstIdPsrad_ExtendedIndex = 155, + kX86InstIdPsraw_ExtendedIndex = 156, + kX86InstIdPsrld_ExtendedIndex = 157, + kX86InstIdPsrldq_ExtendedIndex = 158, + kX86InstIdPsrlq_ExtendedIndex = 159, + kX86InstIdPsrlw_ExtendedIndex = 160, + kX86InstIdPsubb_ExtendedIndex = 135, + kX86InstIdPsubd_ExtendedIndex = 135, + kX86InstIdPsubq_ExtendedIndex = 135, + kX86InstIdPsubsb_ExtendedIndex = 135, + kX86InstIdPsubsw_ExtendedIndex = 135, + kX86InstIdPsubusb_ExtendedIndex = 135, + kX86InstIdPsubusw_ExtendedIndex = 135, + kX86InstIdPsubw_ExtendedIndex = 135, + kX86InstIdPswapd_ExtendedIndex = 141, + kX86InstIdPtest_ExtendedIndex = 37, + kX86InstIdPunpckhbw_ExtendedIndex = 135, + kX86InstIdPunpckhdq_ExtendedIndex = 135, + kX86InstIdPunpckhqdq_ExtendedIndex = 3, + kX86InstIdPunpckhwd_ExtendedIndex = 135, + kX86InstIdPunpcklbw_ExtendedIndex = 135, + kX86InstIdPunpckldq_ExtendedIndex = 135, + kX86InstIdPunpcklqdq_ExtendedIndex = 3, + kX86InstIdPunpcklwd_ExtendedIndex = 135, + kX86InstIdPush_ExtendedIndex = 161, + kX86InstIdPusha_ExtendedIndex = 16, + kX86InstIdPushf_ExtendedIndex = 162, + kX86InstIdPxor_ExtendedIndex = 135, + kX86InstIdRcl_ExtendedIndex = 163, + kX86InstIdRcpps_ExtendedIndex = 39, + kX86InstIdRcpss_ExtendedIndex = 44, + kX86InstIdRcr_ExtendedIndex = 163, + kX86InstIdRdfsbase_ExtendedIndex = 164, + kX86InstIdRdgsbase_ExtendedIndex = 164, + kX86InstIdRdrand_ExtendedIndex = 165, + kX86InstIdRdtsc_ExtendedIndex = 16, + kX86InstIdRdtscp_ExtendedIndex = 16, + kX86InstIdRepLodsB_ExtendedIndex = 166, + kX86InstIdRepLodsD_ExtendedIndex = 166, + kX86InstIdRepLodsQ_ExtendedIndex = 167, + kX86InstIdRepLodsW_ExtendedIndex = 166, + kX86InstIdRepMovsB_ExtendedIndex = 168, + kX86InstIdRepMovsD_ExtendedIndex = 168, + kX86InstIdRepMovsQ_ExtendedIndex = 169, + kX86InstIdRepMovsW_ExtendedIndex = 168, + kX86InstIdRepStosB_ExtendedIndex = 166, + kX86InstIdRepStosD_ExtendedIndex = 166, + kX86InstIdRepStosQ_ExtendedIndex = 167, + kX86InstIdRepStosW_ExtendedIndex = 166, + kX86InstIdRepeCmpsB_ExtendedIndex = 170, + kX86InstIdRepeCmpsD_ExtendedIndex = 170, + kX86InstIdRepeCmpsQ_ExtendedIndex = 171, + kX86InstIdRepeCmpsW_ExtendedIndex = 170, + kX86InstIdRepeScasB_ExtendedIndex = 170, + kX86InstIdRepeScasD_ExtendedIndex = 170, + kX86InstIdRepeScasQ_ExtendedIndex = 171, + kX86InstIdRepeScasW_ExtendedIndex = 170, + kX86InstIdRepneCmpsB_ExtendedIndex = 170, + kX86InstIdRepneCmpsD_ExtendedIndex = 170, + kX86InstIdRepneCmpsQ_ExtendedIndex = 171, + kX86InstIdRepneCmpsW_ExtendedIndex = 170, + kX86InstIdRepneScasB_ExtendedIndex = 170, + kX86InstIdRepneScasD_ExtendedIndex = 170, + kX86InstIdRepneScasQ_ExtendedIndex = 171, + kX86InstIdRepneScasW_ExtendedIndex = 170, + kX86InstIdRet_ExtendedIndex = 172, + kX86InstIdRol_ExtendedIndex = 173, + kX86InstIdRor_ExtendedIndex = 173, + kX86InstIdRorx_ExtendedIndex = 174, + kX86InstIdRoundpd_ExtendedIndex = 149, + kX86InstIdRoundps_ExtendedIndex = 149, + kX86InstIdRoundsd_ExtendedIndex = 175, + kX86InstIdRoundss_ExtendedIndex = 176, + kX86InstIdRsqrtps_ExtendedIndex = 39, + kX86InstIdRsqrtss_ExtendedIndex = 44, + kX86InstIdSahf_ExtendedIndex = 177, + kX86InstIdSal_ExtendedIndex = 178, + kX86InstIdSar_ExtendedIndex = 178, + kX86InstIdSarx_ExtendedIndex = 179, + kX86InstIdSbb_ExtendedIndex = 1, + kX86InstIdScasB_ExtendedIndex = 31, + kX86InstIdScasD_ExtendedIndex = 31, + kX86InstIdScasQ_ExtendedIndex = 32, + kX86InstIdScasW_ExtendedIndex = 33, + kX86InstIdSeta_ExtendedIndex = 180, + kX86InstIdSetae_ExtendedIndex = 181, + kX86InstIdSetb_ExtendedIndex = 181, + kX86InstIdSetbe_ExtendedIndex = 180, + kX86InstIdSetc_ExtendedIndex = 181, + kX86InstIdSete_ExtendedIndex = 182, + kX86InstIdSetg_ExtendedIndex = 183, + kX86InstIdSetge_ExtendedIndex = 184, + kX86InstIdSetl_ExtendedIndex = 184, + kX86InstIdSetle_ExtendedIndex = 183, + kX86InstIdSetna_ExtendedIndex = 180, + kX86InstIdSetnae_ExtendedIndex = 181, + kX86InstIdSetnb_ExtendedIndex = 181, + kX86InstIdSetnbe_ExtendedIndex = 180, + kX86InstIdSetnc_ExtendedIndex = 181, + kX86InstIdSetne_ExtendedIndex = 182, + kX86InstIdSetng_ExtendedIndex = 183, + kX86InstIdSetnge_ExtendedIndex = 184, + kX86InstIdSetnl_ExtendedIndex = 184, + kX86InstIdSetnle_ExtendedIndex = 183, + kX86InstIdSetno_ExtendedIndex = 185, + kX86InstIdSetnp_ExtendedIndex = 186, + kX86InstIdSetns_ExtendedIndex = 187, + kX86InstIdSetnz_ExtendedIndex = 182, + kX86InstIdSeto_ExtendedIndex = 185, + kX86InstIdSetp_ExtendedIndex = 186, + kX86InstIdSetpe_ExtendedIndex = 186, + kX86InstIdSetpo_ExtendedIndex = 186, + kX86InstIdSets_ExtendedIndex = 187, + kX86InstIdSetz_ExtendedIndex = 182, + kX86InstIdSfence_ExtendedIndex = 92, + kX86InstIdShl_ExtendedIndex = 178, + kX86InstIdShld_ExtendedIndex = 188, + kX86InstIdShlx_ExtendedIndex = 179, + kX86InstIdShr_ExtendedIndex = 178, + kX86InstIdShrd_ExtendedIndex = 189, + kX86InstIdShrx_ExtendedIndex = 179, + kX86InstIdShufpd_ExtendedIndex = 4, + kX86InstIdShufps_ExtendedIndex = 4, + kX86InstIdSqrtpd_ExtendedIndex = 39, + kX86InstIdSqrtps_ExtendedIndex = 39, + kX86InstIdSqrtsd_ExtendedIndex = 47, + kX86InstIdSqrtss_ExtendedIndex = 44, + kX86InstIdStc_ExtendedIndex = 18, + kX86InstIdStd_ExtendedIndex = 19, + kX86InstIdStmxcsr_ExtendedIndex = 20, + kX86InstIdStosB_ExtendedIndex = 190, + kX86InstIdStosD_ExtendedIndex = 190, + kX86InstIdStosQ_ExtendedIndex = 191, + kX86InstIdStosW_ExtendedIndex = 192, + kX86InstIdSub_ExtendedIndex = 2, + kX86InstIdSubpd_ExtendedIndex = 3, + kX86InstIdSubps_ExtendedIndex = 3, + kX86InstIdSubsd_ExtendedIndex = 3, + kX86InstIdSubss_ExtendedIndex = 3, + kX86InstIdTest_ExtendedIndex = 193, + kX86InstIdTzcnt_ExtendedIndex = 194, + kX86InstIdUcomisd_ExtendedIndex = 37, + kX86InstIdUcomiss_ExtendedIndex = 37, + kX86InstIdUd2_ExtendedIndex = 51, + kX86InstIdUnpckhpd_ExtendedIndex = 3, + kX86InstIdUnpckhps_ExtendedIndex = 3, + kX86InstIdUnpcklpd_ExtendedIndex = 3, + kX86InstIdUnpcklps_ExtendedIndex = 3, + kX86InstIdVaddpd_ExtendedIndex = 195, + kX86InstIdVaddps_ExtendedIndex = 195, + kX86InstIdVaddsd_ExtendedIndex = 195, + kX86InstIdVaddss_ExtendedIndex = 195, + kX86InstIdVaddsubpd_ExtendedIndex = 195, + kX86InstIdVaddsubps_ExtendedIndex = 195, + kX86InstIdVaesdec_ExtendedIndex = 196, + kX86InstIdVaesdeclast_ExtendedIndex = 196, + kX86InstIdVaesenc_ExtendedIndex = 196, + kX86InstIdVaesenclast_ExtendedIndex = 196, + kX86InstIdVaesimc_ExtendedIndex = 197, + kX86InstIdVaeskeygenassist_ExtendedIndex = 198, + kX86InstIdVandnpd_ExtendedIndex = 195, + kX86InstIdVandnps_ExtendedIndex = 195, + kX86InstIdVandpd_ExtendedIndex = 195, + kX86InstIdVandps_ExtendedIndex = 195, + kX86InstIdVblendpd_ExtendedIndex = 199, + kX86InstIdVblendps_ExtendedIndex = 199, + kX86InstIdVblendvpd_ExtendedIndex = 200, + kX86InstIdVblendvps_ExtendedIndex = 200, + kX86InstIdVbroadcastf128_ExtendedIndex = 201, + kX86InstIdVbroadcasti128_ExtendedIndex = 201, + kX86InstIdVbroadcastsd_ExtendedIndex = 202, + kX86InstIdVbroadcastss_ExtendedIndex = 202, + kX86InstIdVcmppd_ExtendedIndex = 199, + kX86InstIdVcmpps_ExtendedIndex = 199, + kX86InstIdVcmpsd_ExtendedIndex = 203, + kX86InstIdVcmpss_ExtendedIndex = 203, + kX86InstIdVcomisd_ExtendedIndex = 197, + kX86InstIdVcomiss_ExtendedIndex = 197, + kX86InstIdVcvtdq2pd_ExtendedIndex = 204, + kX86InstIdVcvtdq2ps_ExtendedIndex = 205, + kX86InstIdVcvtpd2dq_ExtendedIndex = 206, + kX86InstIdVcvtpd2ps_ExtendedIndex = 206, + kX86InstIdVcvtph2ps_ExtendedIndex = 204, + kX86InstIdVcvtps2dq_ExtendedIndex = 205, + kX86InstIdVcvtps2pd_ExtendedIndex = 204, + kX86InstIdVcvtps2ph_ExtendedIndex = 207, + kX86InstIdVcvtsd2si_ExtendedIndex = 208, + kX86InstIdVcvtsd2ss_ExtendedIndex = 196, + kX86InstIdVcvtsi2sd_ExtendedIndex = 209, + kX86InstIdVcvtsi2ss_ExtendedIndex = 209, + kX86InstIdVcvtss2sd_ExtendedIndex = 196, + kX86InstIdVcvtss2si_ExtendedIndex = 208, + kX86InstIdVcvttpd2dq_ExtendedIndex = 210, + kX86InstIdVcvttps2dq_ExtendedIndex = 205, + kX86InstIdVcvttsd2si_ExtendedIndex = 208, + kX86InstIdVcvttss2si_ExtendedIndex = 208, + kX86InstIdVdivpd_ExtendedIndex = 195, + kX86InstIdVdivps_ExtendedIndex = 195, + kX86InstIdVdivsd_ExtendedIndex = 196, + kX86InstIdVdivss_ExtendedIndex = 196, + kX86InstIdVdppd_ExtendedIndex = 203, + kX86InstIdVdpps_ExtendedIndex = 199, + kX86InstIdVextractf128_ExtendedIndex = 211, + kX86InstIdVextracti128_ExtendedIndex = 211, + kX86InstIdVextractps_ExtendedIndex = 212, + kX86InstIdVfmadd132pd_ExtendedIndex = 213, + kX86InstIdVfmadd132ps_ExtendedIndex = 195, + kX86InstIdVfmadd132sd_ExtendedIndex = 214, + kX86InstIdVfmadd132ss_ExtendedIndex = 196, + kX86InstIdVfmadd213pd_ExtendedIndex = 213, + kX86InstIdVfmadd213ps_ExtendedIndex = 195, + kX86InstIdVfmadd213sd_ExtendedIndex = 214, + kX86InstIdVfmadd213ss_ExtendedIndex = 196, + kX86InstIdVfmadd231pd_ExtendedIndex = 213, + kX86InstIdVfmadd231ps_ExtendedIndex = 195, + kX86InstIdVfmadd231sd_ExtendedIndex = 214, + kX86InstIdVfmadd231ss_ExtendedIndex = 196, + kX86InstIdVfmaddpd_ExtendedIndex = 215, + kX86InstIdVfmaddps_ExtendedIndex = 215, + kX86InstIdVfmaddsd_ExtendedIndex = 216, + kX86InstIdVfmaddss_ExtendedIndex = 216, + kX86InstIdVfmaddsub132pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub132ps_ExtendedIndex = 195, + kX86InstIdVfmaddsub213pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub213ps_ExtendedIndex = 195, + kX86InstIdVfmaddsub231pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub231ps_ExtendedIndex = 195, + kX86InstIdVfmaddsubpd_ExtendedIndex = 215, + kX86InstIdVfmaddsubps_ExtendedIndex = 215, + kX86InstIdVfmsub132pd_ExtendedIndex = 213, + kX86InstIdVfmsub132ps_ExtendedIndex = 195, + kX86InstIdVfmsub132sd_ExtendedIndex = 214, + kX86InstIdVfmsub132ss_ExtendedIndex = 196, + kX86InstIdVfmsub213pd_ExtendedIndex = 213, + kX86InstIdVfmsub213ps_ExtendedIndex = 195, + kX86InstIdVfmsub213sd_ExtendedIndex = 214, + kX86InstIdVfmsub213ss_ExtendedIndex = 196, + kX86InstIdVfmsub231pd_ExtendedIndex = 213, + kX86InstIdVfmsub231ps_ExtendedIndex = 195, + kX86InstIdVfmsub231sd_ExtendedIndex = 214, + kX86InstIdVfmsub231ss_ExtendedIndex = 196, + kX86InstIdVfmsubadd132pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd132ps_ExtendedIndex = 195, + kX86InstIdVfmsubadd213pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd213ps_ExtendedIndex = 195, + kX86InstIdVfmsubadd231pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd231ps_ExtendedIndex = 195, + kX86InstIdVfmsubaddpd_ExtendedIndex = 215, + kX86InstIdVfmsubaddps_ExtendedIndex = 215, + kX86InstIdVfmsubpd_ExtendedIndex = 215, + kX86InstIdVfmsubps_ExtendedIndex = 215, + kX86InstIdVfmsubsd_ExtendedIndex = 216, + kX86InstIdVfmsubss_ExtendedIndex = 216, + kX86InstIdVfnmadd132pd_ExtendedIndex = 213, + kX86InstIdVfnmadd132ps_ExtendedIndex = 195, + kX86InstIdVfnmadd132sd_ExtendedIndex = 214, + kX86InstIdVfnmadd132ss_ExtendedIndex = 196, + kX86InstIdVfnmadd213pd_ExtendedIndex = 213, + kX86InstIdVfnmadd213ps_ExtendedIndex = 195, + kX86InstIdVfnmadd213sd_ExtendedIndex = 214, + kX86InstIdVfnmadd213ss_ExtendedIndex = 196, + kX86InstIdVfnmadd231pd_ExtendedIndex = 213, + kX86InstIdVfnmadd231ps_ExtendedIndex = 195, + kX86InstIdVfnmadd231sd_ExtendedIndex = 214, + kX86InstIdVfnmadd231ss_ExtendedIndex = 196, + kX86InstIdVfnmaddpd_ExtendedIndex = 215, + kX86InstIdVfnmaddps_ExtendedIndex = 215, + kX86InstIdVfnmaddsd_ExtendedIndex = 216, + kX86InstIdVfnmaddss_ExtendedIndex = 216, + kX86InstIdVfnmsub132pd_ExtendedIndex = 213, + kX86InstIdVfnmsub132ps_ExtendedIndex = 195, + kX86InstIdVfnmsub132sd_ExtendedIndex = 214, + kX86InstIdVfnmsub132ss_ExtendedIndex = 196, + kX86InstIdVfnmsub213pd_ExtendedIndex = 213, + kX86InstIdVfnmsub213ps_ExtendedIndex = 195, + kX86InstIdVfnmsub213sd_ExtendedIndex = 214, + kX86InstIdVfnmsub213ss_ExtendedIndex = 196, + kX86InstIdVfnmsub231pd_ExtendedIndex = 213, + kX86InstIdVfnmsub231ps_ExtendedIndex = 195, + kX86InstIdVfnmsub231sd_ExtendedIndex = 214, + kX86InstIdVfnmsub231ss_ExtendedIndex = 196, + kX86InstIdVfnmsubpd_ExtendedIndex = 215, + kX86InstIdVfnmsubps_ExtendedIndex = 215, + kX86InstIdVfnmsubsd_ExtendedIndex = 216, + kX86InstIdVfnmsubss_ExtendedIndex = 216, + kX86InstIdVfrczpd_ExtendedIndex = 217, + kX86InstIdVfrczps_ExtendedIndex = 217, + kX86InstIdVfrczsd_ExtendedIndex = 218, + kX86InstIdVfrczss_ExtendedIndex = 218, + kX86InstIdVgatherdpd_ExtendedIndex = 219, + kX86InstIdVgatherdps_ExtendedIndex = 220, + kX86InstIdVgatherqpd_ExtendedIndex = 219, + kX86InstIdVgatherqps_ExtendedIndex = 221, + kX86InstIdVhaddpd_ExtendedIndex = 195, + kX86InstIdVhaddps_ExtendedIndex = 195, + kX86InstIdVhsubpd_ExtendedIndex = 195, + kX86InstIdVhsubps_ExtendedIndex = 195, + kX86InstIdVinsertf128_ExtendedIndex = 222, + kX86InstIdVinserti128_ExtendedIndex = 222, + kX86InstIdVinsertps_ExtendedIndex = 203, + kX86InstIdVlddqu_ExtendedIndex = 223, + kX86InstIdVldmxcsr_ExtendedIndex = 224, + kX86InstIdVmaskmovdqu_ExtendedIndex = 225, + kX86InstIdVmaskmovpd_ExtendedIndex = 226, + kX86InstIdVmaskmovps_ExtendedIndex = 227, + kX86InstIdVmaxpd_ExtendedIndex = 195, + kX86InstIdVmaxps_ExtendedIndex = 195, + kX86InstIdVmaxsd_ExtendedIndex = 195, + kX86InstIdVmaxss_ExtendedIndex = 195, + kX86InstIdVminpd_ExtendedIndex = 195, + kX86InstIdVminps_ExtendedIndex = 195, + kX86InstIdVminsd_ExtendedIndex = 195, + kX86InstIdVminss_ExtendedIndex = 195, + kX86InstIdVmovapd_ExtendedIndex = 228, + kX86InstIdVmovaps_ExtendedIndex = 229, + kX86InstIdVmovd_ExtendedIndex = 230, + kX86InstIdVmovddup_ExtendedIndex = 205, + kX86InstIdVmovdqa_ExtendedIndex = 231, + kX86InstIdVmovdqu_ExtendedIndex = 232, + kX86InstIdVmovhlps_ExtendedIndex = 233, + kX86InstIdVmovhpd_ExtendedIndex = 234, + kX86InstIdVmovhps_ExtendedIndex = 235, + kX86InstIdVmovlhps_ExtendedIndex = 233, + kX86InstIdVmovlpd_ExtendedIndex = 236, + kX86InstIdVmovlps_ExtendedIndex = 237, + kX86InstIdVmovmskpd_ExtendedIndex = 238, + kX86InstIdVmovmskps_ExtendedIndex = 238, + kX86InstIdVmovntdq_ExtendedIndex = 239, + kX86InstIdVmovntdqa_ExtendedIndex = 223, + kX86InstIdVmovntpd_ExtendedIndex = 240, + kX86InstIdVmovntps_ExtendedIndex = 240, + kX86InstIdVmovq_ExtendedIndex = 241, + kX86InstIdVmovsd_ExtendedIndex = 242, + kX86InstIdVmovshdup_ExtendedIndex = 205, + kX86InstIdVmovsldup_ExtendedIndex = 205, + kX86InstIdVmovss_ExtendedIndex = 243, + kX86InstIdVmovupd_ExtendedIndex = 244, + kX86InstIdVmovups_ExtendedIndex = 245, + kX86InstIdVmpsadbw_ExtendedIndex = 199, + kX86InstIdVmulpd_ExtendedIndex = 195, + kX86InstIdVmulps_ExtendedIndex = 195, + kX86InstIdVmulsd_ExtendedIndex = 195, + kX86InstIdVmulss_ExtendedIndex = 195, + kX86InstIdVorpd_ExtendedIndex = 195, + kX86InstIdVorps_ExtendedIndex = 195, + kX86InstIdVpabsb_ExtendedIndex = 205, + kX86InstIdVpabsd_ExtendedIndex = 205, + kX86InstIdVpabsw_ExtendedIndex = 205, + kX86InstIdVpackssdw_ExtendedIndex = 195, + kX86InstIdVpacksswb_ExtendedIndex = 195, + kX86InstIdVpackusdw_ExtendedIndex = 195, + kX86InstIdVpackuswb_ExtendedIndex = 195, + kX86InstIdVpaddb_ExtendedIndex = 195, + kX86InstIdVpaddd_ExtendedIndex = 195, + kX86InstIdVpaddq_ExtendedIndex = 195, + kX86InstIdVpaddsb_ExtendedIndex = 195, + kX86InstIdVpaddsw_ExtendedIndex = 195, + kX86InstIdVpaddusb_ExtendedIndex = 195, + kX86InstIdVpaddusw_ExtendedIndex = 195, + kX86InstIdVpaddw_ExtendedIndex = 195, + kX86InstIdVpalignr_ExtendedIndex = 199, + kX86InstIdVpand_ExtendedIndex = 195, + kX86InstIdVpandn_ExtendedIndex = 195, + kX86InstIdVpavgb_ExtendedIndex = 195, + kX86InstIdVpavgw_ExtendedIndex = 195, + kX86InstIdVpblendd_ExtendedIndex = 199, + kX86InstIdVpblendvb_ExtendedIndex = 246, + kX86InstIdVpblendw_ExtendedIndex = 199, + kX86InstIdVpbroadcastb_ExtendedIndex = 204, + kX86InstIdVpbroadcastd_ExtendedIndex = 204, + kX86InstIdVpbroadcastq_ExtendedIndex = 204, + kX86InstIdVpbroadcastw_ExtendedIndex = 204, + kX86InstIdVpclmulqdq_ExtendedIndex = 203, + kX86InstIdVpcmov_ExtendedIndex = 247, + kX86InstIdVpcmpeqb_ExtendedIndex = 195, + kX86InstIdVpcmpeqd_ExtendedIndex = 195, + kX86InstIdVpcmpeqq_ExtendedIndex = 195, + kX86InstIdVpcmpeqw_ExtendedIndex = 195, + kX86InstIdVpcmpestri_ExtendedIndex = 198, + kX86InstIdVpcmpestrm_ExtendedIndex = 198, + kX86InstIdVpcmpgtb_ExtendedIndex = 195, + kX86InstIdVpcmpgtd_ExtendedIndex = 195, + kX86InstIdVpcmpgtq_ExtendedIndex = 195, + kX86InstIdVpcmpgtw_ExtendedIndex = 195, + kX86InstIdVpcmpistri_ExtendedIndex = 198, + kX86InstIdVpcmpistrm_ExtendedIndex = 198, + kX86InstIdVpcomb_ExtendedIndex = 248, + kX86InstIdVpcomd_ExtendedIndex = 248, + kX86InstIdVpcomq_ExtendedIndex = 248, + kX86InstIdVpcomub_ExtendedIndex = 248, + kX86InstIdVpcomud_ExtendedIndex = 248, + kX86InstIdVpcomuq_ExtendedIndex = 248, + kX86InstIdVpcomuw_ExtendedIndex = 248, + kX86InstIdVpcomw_ExtendedIndex = 248, + kX86InstIdVperm2f128_ExtendedIndex = 249, + kX86InstIdVperm2i128_ExtendedIndex = 249, + kX86InstIdVpermd_ExtendedIndex = 250, + kX86InstIdVpermil2pd_ExtendedIndex = 251, + kX86InstIdVpermil2ps_ExtendedIndex = 251, + kX86InstIdVpermilpd_ExtendedIndex = 252, + kX86InstIdVpermilps_ExtendedIndex = 253, + kX86InstIdVpermpd_ExtendedIndex = 254, + kX86InstIdVpermps_ExtendedIndex = 250, + kX86InstIdVpermq_ExtendedIndex = 254, + kX86InstIdVpextrb_ExtendedIndex = 255, + kX86InstIdVpextrd_ExtendedIndex = 212, + kX86InstIdVpextrq_ExtendedIndex = 256, + kX86InstIdVpextrw_ExtendedIndex = 257, + kX86InstIdVpgatherdd_ExtendedIndex = 220, + kX86InstIdVpgatherdq_ExtendedIndex = 219, + kX86InstIdVpgatherqd_ExtendedIndex = 221, + kX86InstIdVpgatherqq_ExtendedIndex = 219, + kX86InstIdVphaddbd_ExtendedIndex = 218, + kX86InstIdVphaddbq_ExtendedIndex = 218, + kX86InstIdVphaddbw_ExtendedIndex = 218, + kX86InstIdVphaddd_ExtendedIndex = 195, + kX86InstIdVphadddq_ExtendedIndex = 218, + kX86InstIdVphaddsw_ExtendedIndex = 195, + kX86InstIdVphaddubd_ExtendedIndex = 218, + kX86InstIdVphaddubq_ExtendedIndex = 218, + kX86InstIdVphaddubw_ExtendedIndex = 218, + kX86InstIdVphaddudq_ExtendedIndex = 218, + kX86InstIdVphadduwd_ExtendedIndex = 218, + kX86InstIdVphadduwq_ExtendedIndex = 218, + kX86InstIdVphaddw_ExtendedIndex = 195, + kX86InstIdVphaddwd_ExtendedIndex = 218, + kX86InstIdVphaddwq_ExtendedIndex = 218, + kX86InstIdVphminposuw_ExtendedIndex = 197, + kX86InstIdVphsubbw_ExtendedIndex = 218, + kX86InstIdVphsubd_ExtendedIndex = 195, + kX86InstIdVphsubdq_ExtendedIndex = 218, + kX86InstIdVphsubsw_ExtendedIndex = 195, + kX86InstIdVphsubw_ExtendedIndex = 195, + kX86InstIdVphsubwd_ExtendedIndex = 218, + kX86InstIdVpinsrb_ExtendedIndex = 258, + kX86InstIdVpinsrd_ExtendedIndex = 259, + kX86InstIdVpinsrq_ExtendedIndex = 260, + kX86InstIdVpinsrw_ExtendedIndex = 261, + kX86InstIdVpmacsdd_ExtendedIndex = 262, + kX86InstIdVpmacsdqh_ExtendedIndex = 262, + kX86InstIdVpmacsdql_ExtendedIndex = 262, + kX86InstIdVpmacssdd_ExtendedIndex = 262, + kX86InstIdVpmacssdqh_ExtendedIndex = 262, + kX86InstIdVpmacssdql_ExtendedIndex = 262, + kX86InstIdVpmacsswd_ExtendedIndex = 262, + kX86InstIdVpmacssww_ExtendedIndex = 262, + kX86InstIdVpmacswd_ExtendedIndex = 262, + kX86InstIdVpmacsww_ExtendedIndex = 262, + kX86InstIdVpmadcsswd_ExtendedIndex = 262, + kX86InstIdVpmadcswd_ExtendedIndex = 262, + kX86InstIdVpmaddubsw_ExtendedIndex = 195, + kX86InstIdVpmaddwd_ExtendedIndex = 195, + kX86InstIdVpmaskmovd_ExtendedIndex = 263, + kX86InstIdVpmaskmovq_ExtendedIndex = 264, + kX86InstIdVpmaxsb_ExtendedIndex = 195, + kX86InstIdVpmaxsd_ExtendedIndex = 195, + kX86InstIdVpmaxsw_ExtendedIndex = 195, + kX86InstIdVpmaxub_ExtendedIndex = 195, + kX86InstIdVpmaxud_ExtendedIndex = 195, + kX86InstIdVpmaxuw_ExtendedIndex = 195, + kX86InstIdVpminsb_ExtendedIndex = 195, + kX86InstIdVpminsd_ExtendedIndex = 195, + kX86InstIdVpminsw_ExtendedIndex = 195, + kX86InstIdVpminub_ExtendedIndex = 195, + kX86InstIdVpminud_ExtendedIndex = 195, + kX86InstIdVpminuw_ExtendedIndex = 195, + kX86InstIdVpmovmskb_ExtendedIndex = 238, + kX86InstIdVpmovsxbd_ExtendedIndex = 205, + kX86InstIdVpmovsxbq_ExtendedIndex = 205, + kX86InstIdVpmovsxbw_ExtendedIndex = 205, + kX86InstIdVpmovsxdq_ExtendedIndex = 205, + kX86InstIdVpmovsxwd_ExtendedIndex = 205, + kX86InstIdVpmovsxwq_ExtendedIndex = 205, + kX86InstIdVpmovzxbd_ExtendedIndex = 205, + kX86InstIdVpmovzxbq_ExtendedIndex = 205, + kX86InstIdVpmovzxbw_ExtendedIndex = 205, + kX86InstIdVpmovzxdq_ExtendedIndex = 205, + kX86InstIdVpmovzxwd_ExtendedIndex = 205, + kX86InstIdVpmovzxwq_ExtendedIndex = 205, + kX86InstIdVpmuldq_ExtendedIndex = 195, + kX86InstIdVpmulhrsw_ExtendedIndex = 195, + kX86InstIdVpmulhuw_ExtendedIndex = 195, + kX86InstIdVpmulhw_ExtendedIndex = 195, + kX86InstIdVpmulld_ExtendedIndex = 195, + kX86InstIdVpmullw_ExtendedIndex = 195, + kX86InstIdVpmuludq_ExtendedIndex = 195, + kX86InstIdVpor_ExtendedIndex = 195, + kX86InstIdVpperm_ExtendedIndex = 265, + kX86InstIdVprotb_ExtendedIndex = 266, + kX86InstIdVprotd_ExtendedIndex = 267, + kX86InstIdVprotq_ExtendedIndex = 268, + kX86InstIdVprotw_ExtendedIndex = 269, + kX86InstIdVpsadbw_ExtendedIndex = 195, + kX86InstIdVpshab_ExtendedIndex = 270, + kX86InstIdVpshad_ExtendedIndex = 270, + kX86InstIdVpshaq_ExtendedIndex = 270, + kX86InstIdVpshaw_ExtendedIndex = 270, + kX86InstIdVpshlb_ExtendedIndex = 270, + kX86InstIdVpshld_ExtendedIndex = 270, + kX86InstIdVpshlq_ExtendedIndex = 270, + kX86InstIdVpshlw_ExtendedIndex = 270, + kX86InstIdVpshufb_ExtendedIndex = 195, + kX86InstIdVpshufd_ExtendedIndex = 271, + kX86InstIdVpshufhw_ExtendedIndex = 271, + kX86InstIdVpshuflw_ExtendedIndex = 271, + kX86InstIdVpsignb_ExtendedIndex = 195, + kX86InstIdVpsignd_ExtendedIndex = 195, + kX86InstIdVpsignw_ExtendedIndex = 195, + kX86InstIdVpslld_ExtendedIndex = 272, + kX86InstIdVpslldq_ExtendedIndex = 273, + kX86InstIdVpsllq_ExtendedIndex = 274, + kX86InstIdVpsllvd_ExtendedIndex = 195, + kX86InstIdVpsllvq_ExtendedIndex = 213, + kX86InstIdVpsllw_ExtendedIndex = 275, + kX86InstIdVpsrad_ExtendedIndex = 276, + kX86InstIdVpsravd_ExtendedIndex = 195, + kX86InstIdVpsraw_ExtendedIndex = 277, + kX86InstIdVpsrld_ExtendedIndex = 278, + kX86InstIdVpsrldq_ExtendedIndex = 273, + kX86InstIdVpsrlq_ExtendedIndex = 279, + kX86InstIdVpsrlvd_ExtendedIndex = 195, + kX86InstIdVpsrlvq_ExtendedIndex = 213, + kX86InstIdVpsrlw_ExtendedIndex = 280, + kX86InstIdVpsubb_ExtendedIndex = 195, + kX86InstIdVpsubd_ExtendedIndex = 195, + kX86InstIdVpsubq_ExtendedIndex = 195, + kX86InstIdVpsubsb_ExtendedIndex = 195, + kX86InstIdVpsubsw_ExtendedIndex = 195, + kX86InstIdVpsubusb_ExtendedIndex = 195, + kX86InstIdVpsubusw_ExtendedIndex = 195, + kX86InstIdVpsubw_ExtendedIndex = 195, + kX86InstIdVptest_ExtendedIndex = 281, + kX86InstIdVpunpckhbw_ExtendedIndex = 195, + kX86InstIdVpunpckhdq_ExtendedIndex = 195, + kX86InstIdVpunpckhqdq_ExtendedIndex = 195, + kX86InstIdVpunpckhwd_ExtendedIndex = 195, + kX86InstIdVpunpcklbw_ExtendedIndex = 195, + kX86InstIdVpunpckldq_ExtendedIndex = 195, + kX86InstIdVpunpcklqdq_ExtendedIndex = 195, + kX86InstIdVpunpcklwd_ExtendedIndex = 195, + kX86InstIdVpxor_ExtendedIndex = 195, + kX86InstIdVrcpps_ExtendedIndex = 205, + kX86InstIdVrcpss_ExtendedIndex = 196, + kX86InstIdVroundpd_ExtendedIndex = 271, + kX86InstIdVroundps_ExtendedIndex = 271, + kX86InstIdVroundsd_ExtendedIndex = 203, + kX86InstIdVroundss_ExtendedIndex = 203, + kX86InstIdVrsqrtps_ExtendedIndex = 205, + kX86InstIdVrsqrtss_ExtendedIndex = 196, + kX86InstIdVshufpd_ExtendedIndex = 199, + kX86InstIdVshufps_ExtendedIndex = 199, + kX86InstIdVsqrtpd_ExtendedIndex = 205, + kX86InstIdVsqrtps_ExtendedIndex = 205, + kX86InstIdVsqrtsd_ExtendedIndex = 196, + kX86InstIdVsqrtss_ExtendedIndex = 196, + kX86InstIdVstmxcsr_ExtendedIndex = 224, + kX86InstIdVsubpd_ExtendedIndex = 195, + kX86InstIdVsubps_ExtendedIndex = 195, + kX86InstIdVsubsd_ExtendedIndex = 196, + kX86InstIdVsubss_ExtendedIndex = 196, + kX86InstIdVtestpd_ExtendedIndex = 282, + kX86InstIdVtestps_ExtendedIndex = 282, + kX86InstIdVucomisd_ExtendedIndex = 283, + kX86InstIdVucomiss_ExtendedIndex = 283, + kX86InstIdVunpckhpd_ExtendedIndex = 195, + kX86InstIdVunpckhps_ExtendedIndex = 195, + kX86InstIdVunpcklpd_ExtendedIndex = 195, + kX86InstIdVunpcklps_ExtendedIndex = 195, + kX86InstIdVxorpd_ExtendedIndex = 195, + kX86InstIdVxorps_ExtendedIndex = 195, + kX86InstIdVzeroall_ExtendedIndex = 284, + kX86InstIdVzeroupper_ExtendedIndex = 284, + kX86InstIdWrfsbase_ExtendedIndex = 285, + kX86InstIdWrgsbase_ExtendedIndex = 285, + kX86InstIdXadd_ExtendedIndex = 286, + kX86InstIdXchg_ExtendedIndex = 287, + kX86InstIdXor_ExtendedIndex = 2, + kX86InstIdXorpd_ExtendedIndex = 3, + kX86InstIdXorps_ExtendedIndex = 3 +}; +// ${X86InstData:End} + +// Instruction data. +// +// Please rerun tools/src-gendefs.js (by using node.js) to regenerate instruction +// names and extended info tables. +const X86InstInfo _x86InstInfo[] = { + // Inst-Code | Inst-Name | Inst-Group | Inst-Flags | M | Op-Flags[0] | Op-Flags[1] | Op-Flags[2] | Op-Flags[2] | E-OSZAPCDX | OpCode[0] | OpCode[1] | + INST(kInstIdNone , "" , G(None) , F(None) , 0 , U , U , U , U , E(________) , U , U ), + INST(kX86InstIdAdc , "adc" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(10,2) , U ), + INST(kX86InstIdAdd , "add" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(00,0) , U ), + INST(kX86InstIdAddpd , "addpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(58,U) , U ), + INST(kX86InstIdAddps , "addps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(58,U) , U ), + INST(kX86InstIdAddsd , "addsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(58,U) , U ), + INST(kX86InstIdAddss , "addss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(58,U) , U ), + INST(kX86InstIdAddsubpd , "addsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(D0,U) , U ), + INST(kX86InstIdAddsubps , "addsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(D0,U) , U ), + INST(kX86InstIdAesdec , "aesdec" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DE,U) , U ), + INST(kX86InstIdAesdeclast , "aesdeclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DF,U) , U ), + INST(kX86InstIdAesenc , "aesenc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DC,U) , U ), + INST(kX86InstIdAesenclast , "aesenclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DD,U) , U ), + INST(kX86InstIdAesimc , "aesimc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), + INST(kX86InstIdAeskeygenassist , "aeskeygenassist" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), + INST(kX86InstIdAnd , "and" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(20,4) , U ), + INST(kX86InstIdAndn , "andn" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(WWWUUW__) , O_000F38(F2,U) , U ), + INST(kX86InstIdAndnpd , "andnpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(55,U) , U ), + INST(kX86InstIdAndnps , "andnps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(55,U) , U ), + INST(kX86InstIdAndpd , "andpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(54,U) , U ), + INST(kX86InstIdAndps , "andps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(54,U) , U ), + INST(kX86InstIdBextr , "bextr" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WUWUUW__) , O_000F38(F7,U) , U ), + INST(kX86InstIdBlendpd , "blendpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0D,U) , U ), + INST(kX86InstIdBlendps , "blendps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0C,U) , U ), + INST(kX86InstIdBlendvpd , "blendvpd" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(15,U) , U ), + INST(kX86InstIdBlendvps , "blendvps" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(14,U) , U ), + INST(kX86InstIdBlsi , "blsi" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,3) , U ), + INST(kX86InstIdBlsmsk , "blsmsk" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,2) , U ), + INST(kX86InstIdBlsr , "blsr" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,1) , U ), + INST(kX86InstIdBsf , "bsf" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BC,U) , U ), + INST(kX86InstIdBsr , "bsr" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BD,U) , U ), + INST(kX86InstIdBswap , "bswap" , G(X86BSwap) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_000F00(C8,U) , U ), + INST(kX86InstIdBt , "bt" , G(X86BTest) , F(Test) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(A3,U) , O_000F00(BA,4) ), + INST(kX86InstIdBtc , "btc" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(BB,U) , O_000F00(BA,7) ), + INST(kX86InstIdBtr , "btr" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(B3,U) , O_000F00(BA,6) ), + INST(kX86InstIdBts , "bts" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(AB,U) , O_000F00(BA,5) ), + INST(kX86InstIdBzhi , "bzhi" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WWWUUW__) , O_000F38(F5,U) , U ), + INST(kX86InstIdCall , "call" , G(X86Call) , F(Flow) , 0 , O(GqdMem)|O(Imm)|O(Label), U , U , U , E(________) , O_000000(FF,2) , O_000000(E8,U) ), + INST(kX86InstIdCbw , "cbw" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(98,U) , U ), + INST(kX86InstIdCdq , "cdq" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), + INST(kX86InstIdCdqe , "cdqe" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), + INST(kX86InstIdClc , "clc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F8,U) , U ), + INST(kX86InstIdCld , "cld" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FC,U) , U ), + INST(kX86InstIdClflush , "clflush" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,7) , U ), + INST(kX86InstIdCmc , "cmc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____X__) , O_000000(F5,U) , U ), + INST(kX86InstIdCmova , "cmova" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), + INST(kX86InstIdCmovae , "cmovae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovb , "cmovb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmovbe , "cmovbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), + INST(kX86InstIdCmovc , "cmovc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmove , "cmove" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), + INST(kX86InstIdCmovg , "cmovg" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), + INST(kX86InstIdCmovge , "cmovge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), + INST(kX86InstIdCmovl , "cmovl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), + INST(kX86InstIdCmovle , "cmovle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), + INST(kX86InstIdCmovna , "cmovna" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), + INST(kX86InstIdCmovnae , "cmovnae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmovnb , "cmovnb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovnbe , "cmovnbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), + INST(kX86InstIdCmovnc , "cmovnc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovne , "cmovne" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), + INST(kX86InstIdCmovng , "cmovng" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), + INST(kX86InstIdCmovnge , "cmovnge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), + INST(kX86InstIdCmovnl , "cmovnl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), + INST(kX86InstIdCmovnle , "cmovnle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), + INST(kX86InstIdCmovno , "cmovno" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(41,U) , U ), + INST(kX86InstIdCmovnp , "cmovnp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), + INST(kX86InstIdCmovns , "cmovns" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(49,U) , U ), + INST(kX86InstIdCmovnz , "cmovnz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), + INST(kX86InstIdCmovo , "cmovo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(40,U) , U ), + INST(kX86InstIdCmovp , "cmovp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), + INST(kX86InstIdCmovpe , "cmovpe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), + INST(kX86InstIdCmovpo , "cmovpo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), + INST(kX86InstIdCmovs , "cmovs" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(48,U) , U ), + INST(kX86InstIdCmovz , "cmovz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), + INST(kX86InstIdCmp , "cmp" , G(X86Arith) , F(Test) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(38,7) , U ), + INST(kX86InstIdCmppd , "cmppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C2,U) , U ), + INST(kX86InstIdCmpps , "cmpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C2,U) , U ), + INST(kX86InstIdCmpsB , "cmps_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A6,U) , U ), + INST(kX86InstIdCmpsD , "cmps_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsQ , "cmps_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsW , "cmps_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsd , "cmpsd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(C2,U) , U ), + INST(kX86InstIdCmpss , "cmpss" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(C2,U) , U ), + INST(kX86InstIdCmpxchg , "cmpxchg" , G(X86RmReg) , F(Lock)|F(Special) , 0 , U , U , U , U , E(WWWWWW__) , O_000F00(B0,U) , U ), + INST(kX86InstIdCmpxchg16b , "cmpxchg16b" , G(X86M) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), + INST(kX86InstIdCmpxchg8b , "cmpxchg8b" , G(X86M) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), + INST(kX86InstIdComisd , "comisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2F,U) , U ), + INST(kX86InstIdComiss , "comiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2F,U) , U ), + INST(kX86InstIdCpuid , "cpuid" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(A2,U) , U ), + INST(kX86InstIdCqo , "cqo" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), + INST(kX86InstIdCrc32 , "crc32" , G(ExtCrc) , F(None) , 0 , O(Gqd) , O(GqdwbMem) , U , U , E(________) , O_F20F38(F0,U) , U ), + INST(kX86InstIdCvtdq2pd , "cvtdq2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), + INST(kX86InstIdCvtdq2ps , "cvtdq2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), + INST(kX86InstIdCvtpd2dq , "cvtpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), + INST(kX86InstIdCvtpd2pi , "cvtpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2D,U) , U ), + INST(kX86InstIdCvtpd2ps , "cvtpd2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), + INST(kX86InstIdCvtpi2pd , "cvtpi2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(MmMem) , U , U , E(________) , O_660F00(2A,U) , U ), + INST(kX86InstIdCvtpi2ps , "cvtpi2ps" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(MmMem) , U , U , E(________) , O_000F00(2A,U) , U ), + INST(kX86InstIdCvtps2dq , "cvtps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), + INST(kX86InstIdCvtps2pd , "cvtps2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), + INST(kX86InstIdCvtps2pi , "cvtps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2D,U) , U ), + INST(kX86InstIdCvtsd2si , "cvtsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdCvtsd2ss , "cvtsd2ss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5A,U) , U ), + INST(kX86InstIdCvtsi2sd , "cvtsi2sd" , G(ExtRm_Q) , F(Move) , 8 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F20F00(2A,U) , U ), + INST(kX86InstIdCvtsi2ss , "cvtsi2ss" , G(ExtRm_Q) , F(Move) , 4 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F30F00(2A,U) , U ), + INST(kX86InstIdCvtss2sd , "cvtss2sd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5A,U) , U ), + INST(kX86InstIdCvtss2si , "cvtss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2D,U) , U ), + INST(kX86InstIdCvttpd2dq , "cvttpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), + INST(kX86InstIdCvttpd2pi , "cvttpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2C,U) , U ), + INST(kX86InstIdCvttps2dq , "cvttps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), + INST(kX86InstIdCvttps2pi , "cvttps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2C,U) , U ), + INST(kX86InstIdCvttsd2si , "cvttsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), + INST(kX86InstIdCvttss2si , "cvttss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), + INST(kX86InstIdCwd , "cwd" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(99,U) , U ), + INST(kX86InstIdCwde , "cwde" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), + INST(kX86InstIdDaa , "daa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(27,U) , U ), + INST(kX86InstIdDas , "das" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(2F,U) , U ), + INST(kX86InstIdDec , "dec" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,1) , O_000000(48,U) ), + INST(kX86InstIdDiv , "div" , G(X86Rm_B) , F(None)|F(Special) , 0 , U , U , U , U , E(UUUUUU__) , O_000000(F6,6) , U ), + INST(kX86InstIdDivpd , "divpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5E,U) , U ), + INST(kX86InstIdDivps , "divps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5E,U) , U ), + INST(kX86InstIdDivsd , "divsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5E,U) , U ), + INST(kX86InstIdDivss , "divss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5E,U) , U ), + INST(kX86InstIdDppd , "dppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(41,U) , U ), + INST(kX86InstIdDpps , "dpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(40,U) , U ), + INST(kX86InstIdEmms , "emms" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), + INST(kX86InstIdEnter , "enter" , G(X86Enter) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C8,U) , U ), + INST(kX86InstIdExtractps , "extractps" , G(ExtExtract) , F(Move) , 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_660F3A(17,U) , O_660F3A(17,U) ), + INST(kX86InstIdF2xm1 , "f2xm1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F0,U) , U ), + INST(kX86InstIdFabs , "fabs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E1,U) , U ), + INST(kX86InstIdFadd , "fadd" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C0C0,0) , U ), + INST(kX86InstIdFaddp , "faddp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC0,U) , U ), + INST(kX86InstIdFbld , "fbld" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,4) , U ), + INST(kX86InstIdFbstp , "fbstp" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,6) , U ), + INST(kX86InstIdFchs , "fchs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E0,U) , U ), + INST(kX86InstIdFclex , "fclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE2,U) , U ), + INST(kX86InstIdFcmovb , "fcmovb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DAC0,U) , U ), + INST(kX86InstIdFcmovbe , "fcmovbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DAD0,U) , U ), + INST(kX86InstIdFcmove , "fcmove" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DAC8,U) , U ), + INST(kX86InstIdFcmovnb , "fcmovnb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DBC0,U) , U ), + INST(kX86InstIdFcmovnbe , "fcmovnbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DBD0,U) , U ), + INST(kX86InstIdFcmovne , "fcmovne" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DBC8,U) , U ), + INST(kX86InstIdFcmovnu , "fcmovnu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DBD8,U) , U ), + INST(kX86InstIdFcmovu , "fcmovu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DAD8,U) , U ), + INST(kX86InstIdFcom , "fcom" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D0D0,2) , U ), + INST(kX86InstIdFcomi , "fcomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBF0,U) , U ), + INST(kX86InstIdFcomip , "fcomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFF0,U) , U ), + INST(kX86InstIdFcomp , "fcomp" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D8D8,3) , U ), + INST(kX86InstIdFcompp , "fcompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DED9,U) , U ), + INST(kX86InstIdFcos , "fcos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FF,U) , U ), + INST(kX86InstIdFdecstp , "fdecstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F6,U) , U ), + INST(kX86InstIdFdiv , "fdiv" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F0F8,6) , U ), + INST(kX86InstIdFdivp , "fdivp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF8,U) , U ), + INST(kX86InstIdFdivr , "fdivr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F8F0,7) , U ), + INST(kX86InstIdFdivrp , "fdivrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF0,U) , U ), + INST(kX86InstIdFemms , "femms" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000F00(0E,U) , U ), + INST(kX86InstIdFfree , "ffree" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDC0,U) , U ), + INST(kX86InstIdFiadd , "fiadd" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,0) , U ), + INST(kX86InstIdFicom , "ficom" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,2) , U ), + INST(kX86InstIdFicomp , "ficomp" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,3) , U ), + INST(kX86InstIdFidiv , "fidiv" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,6) , U ), + INST(kX86InstIdFidivr , "fidivr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,7) , U ), + INST(kX86InstIdFild , "fild" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,0) , O_000000(DF,5) ), + INST(kX86InstIdFimul , "fimul" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,1) , U ), + INST(kX86InstIdFincstp , "fincstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F7,U) , U ), + INST(kX86InstIdFinit , "finit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE3,U) , U ), + INST(kX86InstIdFist , "fist" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,2) , U ), + INST(kX86InstIdFistp , "fistp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,3) , O_000000(DF,7) ), + INST(kX86InstIdFisttp , "fisttp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,1) , O_000000(DD,1) ), + INST(kX86InstIdFisub , "fisub" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,4) , U ), + INST(kX86InstIdFisubr , "fisubr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,5) , U ), + INST(kX86InstIdFld , "fld" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,0) , O_000000(DB,5) ), + INST(kX86InstIdFld1 , "fld1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E8,U) , U ), + INST(kX86InstIdFldcw , "fldcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,5) , U ), + INST(kX86InstIdFldenv , "fldenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,4) , U ), + INST(kX86InstIdFldl2e , "fldl2e" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EA,U) , U ), + INST(kX86InstIdFldl2t , "fldl2t" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E9,U) , U ), + INST(kX86InstIdFldlg2 , "fldlg2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EC,U) , U ), + INST(kX86InstIdFldln2 , "fldln2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9ED,U) , U ), + INST(kX86InstIdFldpi , "fldpi" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EB,U) , U ), + INST(kX86InstIdFldz , "fldz" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EE,U) , U ), + INST(kX86InstIdFmul , "fmul" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C8C8,1) , U ), + INST(kX86InstIdFmulp , "fmulp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC8,U) , U ), + INST(kX86InstIdFnclex , "fnclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE2,U) , U ), + INST(kX86InstIdFninit , "fninit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE3,U) , U ), + INST(kX86InstIdFnop , "fnop" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9D0,U) , U ), + INST(kX86InstIdFnsave , "fnsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,6) , U ), + INST(kX86InstIdFnstcw , "fnstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,7) , U ), + INST(kX86InstIdFnstenv , "fnstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,6) , U ), + INST(kX86InstIdFnstsw , "fnstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,7) , O_00_X(DFE0,U) ), + INST(kX86InstIdFpatan , "fpatan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F3,U) , U ), + INST(kX86InstIdFprem , "fprem" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F8,U) , U ), + INST(kX86InstIdFprem1 , "fprem1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F5,U) , U ), + INST(kX86InstIdFptan , "fptan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F2,U) , U ), + INST(kX86InstIdFrndint , "frndint" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FC,U) , U ), + INST(kX86InstIdFrstor , "frstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,4) , U ), + INST(kX86InstIdFsave , "fsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,6) , U ), + INST(kX86InstIdFscale , "fscale" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FD,U) , U ), + INST(kX86InstIdFsin , "fsin" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FE,U) , U ), + INST(kX86InstIdFsincos , "fsincos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FB,U) , U ), + INST(kX86InstIdFsqrt , "fsqrt" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FA,U) , U ), + INST(kX86InstIdFst , "fst" , G(FpuFldFst) , F(Fp)|F(Mem4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,2) , U ), + INST(kX86InstIdFstcw , "fstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,7) , U ), + INST(kX86InstIdFstenv , "fstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,6) , U ), + INST(kX86InstIdFstp , "fstp" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,3) , O_000000(DB,7) ), + INST(kX86InstIdFstsw , "fstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,7) , O_9B_X(DFE0,U) ), + INST(kX86InstIdFsub , "fsub" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E0E8,4) , U ), + INST(kX86InstIdFsubp , "fsubp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE8,U) , U ), + INST(kX86InstIdFsubr , "fsubr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E8E0,5) , U ), + INST(kX86InstIdFsubrp , "fsubrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE0,U) , U ), + INST(kX86InstIdFtst , "ftst" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E4,U) , U ), + INST(kX86InstIdFucom , "fucom" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE0,U) , U ), + INST(kX86InstIdFucomi , "fucomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBE8,U) , U ), + INST(kX86InstIdFucomip , "fucomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFE8,U) , U ), + INST(kX86InstIdFucomp , "fucomp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE8,U) , U ), + INST(kX86InstIdFucompp , "fucompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DAE9,U) , U ), + INST(kX86InstIdFwait , "fwait" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000000(DB,U) , U ), + INST(kX86InstIdFxam , "fxam" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E5,U) , U ), + INST(kX86InstIdFxch , "fxch" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(D9C8,U) , U ), + INST(kX86InstIdFxrstor , "fxrstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,1) , U ), + INST(kX86InstIdFxsave , "fxsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,0) , U ), + INST(kX86InstIdFxtract , "fxtract" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F4,U) , U ), + INST(kX86InstIdFyl2x , "fyl2x" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F1,U) , U ), + INST(kX86InstIdFyl2xp1 , "fyl2xp1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F9,U) , U ), + INST(kX86InstIdHaddpd , "haddpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7C,U) , U ), + INST(kX86InstIdHaddps , "haddps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7C,U) , U ), + INST(kX86InstIdHsubpd , "hsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7D,U) , U ), + INST(kX86InstIdHsubps , "hsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7D,U) , U ), + INST(kX86InstIdIdiv , "idiv" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(UUUUUU__) , O_000000(F6,7) , U ), + INST(kX86InstIdImul , "imul" , G(X86Imul) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , U , U ), + INST(kX86InstIdInc , "inc" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,0) , O_000000(40,U) ), + INST(kX86InstIdInsertps , "insertps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(21,U) , U ), + INST(kX86InstIdInt , "int" , G(X86Int) , F(None) , 0 , U , U , U , U , E(_______W) , O_000000(CC,U) , U ), + INST(kX86InstIdJa , "ja" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), + INST(kX86InstIdJae , "jae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJb , "jb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJbe , "jbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), + INST(kX86InstIdJc , "jc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJe , "je" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), + INST(kX86InstIdJg , "jg" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), + INST(kX86InstIdJge , "jge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), + INST(kX86InstIdJl , "jl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), + INST(kX86InstIdJle , "jle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), + INST(kX86InstIdJna , "jna" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), + INST(kX86InstIdJnae , "jnae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJnb , "jnb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJnbe , "jnbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), + INST(kX86InstIdJnc , "jnc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJne , "jne" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), + INST(kX86InstIdJng , "jng" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), + INST(kX86InstIdJnge , "jnge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), + INST(kX86InstIdJnl , "jnl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), + INST(kX86InstIdJnle , "jnle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), + INST(kX86InstIdJno , "jno" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(71,U) , U ), + INST(kX86InstIdJnp , "jnp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), + INST(kX86InstIdJns , "jns" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(79,U) , U ), + INST(kX86InstIdJnz , "jnz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), + INST(kX86InstIdJo , "jo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(70,U) , U ), + INST(kX86InstIdJp , "jp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), + INST(kX86InstIdJpe , "jpe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), + INST(kX86InstIdJpo , "jpo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), + INST(kX86InstIdJs , "js" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(78,U) , U ), + INST(kX86InstIdJz , "jz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), + INST(kX86InstIdJecxz , "jecxz" , G(X86Jecxz) , F(Flow)|F(Special) , 0 , O(Gqdw) , O(Label) , U , U , E(________) , O_000000(E3,U) , U ), + INST(kX86InstIdJmp , "jmp" , G(X86Jmp) , F(Flow) , 0 , O(Imm)|O(Label) , U , U , U , E(________) , O_000000(FF,4) , O_000000(E9,U) ), + INST(kX86InstIdLahf , "lahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_RRRRR__) , O_000000(9F,U) , U ), + INST(kX86InstIdLddqu , "lddqu" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), + INST(kX86InstIdLdmxcsr , "ldmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), + INST(kX86InstIdLea , "lea" , G(X86Lea) , F(Move) , 0 , O(Gqd) , O(Mem) , U , U , E(________) , O_000000(8D,U) , U ), + INST(kX86InstIdLeave , "leave" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C9,U) , U ), + INST(kX86InstIdLfence , "lfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,5) , U ), + INST(kX86InstIdLodsB , "lods_b" , G(X86Op) , F(Move)|F(Special) , 1 , U , U , U , U , E(______R_) , O_000000(AC,U) , U ), + INST(kX86InstIdLodsD , "lods_d" , G(X86Op) , F(Move)|F(Special) , 4 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLodsQ , "lods_q" , G(X86Op) , F(Move)|F(Special)|F(W), 8 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLodsW , "lods_w" , G(X86Op_66H) , F(Move)|F(Special) , 2 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLzcnt , "lzcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BD,U) , U ), + INST(kX86InstIdMaskmovdqu , "maskmovdqu" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdMaskmovq , "maskmovq" , G(ExtRm) , F(None)|F(Special) , 0 , O(Mm) , O(Mm) , U , U , E(________) , O_000F00(F7,U) , U ), + INST(kX86InstIdMaxpd , "maxpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5F,U) , U ), + INST(kX86InstIdMaxps , "maxps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5F,U) , U ), + INST(kX86InstIdMaxsd , "maxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5F,U) , U ), + INST(kX86InstIdMaxss , "maxss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5F,U) , U ), + INST(kX86InstIdMfence , "mfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,6) , U ), + INST(kX86InstIdMinpd , "minpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5D,U) , U ), + INST(kX86InstIdMinps , "minps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5D,U) , U ), + INST(kX86InstIdMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5D,U) , U ), + INST(kX86InstIdMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5D,U) , U ), + INST(kX86InstIdMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C8,U) , U ), + INST(kX86InstIdMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(________) , U , U ), + INST(kX86InstIdMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , E(________) , O_000000(A0,U) , O_000000(A2,U) ), + INST(kX86InstIdMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), + INST(kX86InstIdMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), + INST(kX86InstIdMovbe , "movbe" , G(ExtMovBe) , F(Move) , 0 , O(GqdwMem) , O(GqdwMem) , U , U , E(________) , O_000F38(F0,U) , O_000F38(F1,U) ), + INST(kX86InstIdMovd , "movd" , G(ExtMovD) , F(Move) , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , E(________) , O_000F00(6E,U) , O_000F00(7E,U) ), + INST(kX86InstIdMovddup , "movddup" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), + INST(kX86InstIdMovdq2q , "movdq2q" , G(ExtMov) , F(Move) , 8 , O(Mm) , O(Xmm) , U , U , E(________) , O_F20F00(D6,U) , U ), + INST(kX86InstIdMovdqa , "movdqa" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), + INST(kX86InstIdMovdqu , "movdqu" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), + INST(kX86InstIdMovhlps , "movhlps" , G(ExtMov) , F(Move) , 8 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(12,U) , U ), + INST(kX86InstIdMovhpd , "movhpd" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), + INST(kX86InstIdMovhps , "movhps" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), + INST(kX86InstIdMovlhps , "movlhps" , G(ExtMov) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(16,U) , U ), + INST(kX86InstIdMovlpd , "movlpd" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), + INST(kX86InstIdMovlps , "movlps" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), + INST(kX86InstIdMovmskpd , "movmskpd" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_660F00(50,U) , U ), + INST(kX86InstIdMovmskps , "movmskps" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_000F00(50,U) , U ), + INST(kX86InstIdMovntdq , "movntdq" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(E7,U) ), + INST(kX86InstIdMovntdqa , "movntdqa" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), + INST(kX86InstIdMovnti , "movnti" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Gqd) , U , U , E(________) , U , O_000F00(C3,U) ), + INST(kX86InstIdMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(2B,U) ), + INST(kX86InstIdMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_000F00(2B,U) ), + INST(kX86InstIdMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , E(________) , U , O_000F00(E7,U) ), + INST(kX86InstIdMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , E(________) , U , U ), + INST(kX86InstIdMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , E(________) , O_F30F00(D6,U) , U ), + INST(kX86InstIdMovsB , "movs_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A4,U) , U ), + INST(kX86InstIdMovsD , "movs_d" , G(X86Op) , F(Move)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsQ , "movs_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsW , "movs_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsd , "movsd" , G(ExtMov) , F(Move) |F(Z), 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), + INST(kX86InstIdMovshdup , "movshdup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), + INST(kX86InstIdMovsldup , "movsldup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), + INST(kX86InstIdMovss , "movss" , G(ExtMov) , F(Move) |F(Z), 4 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), + INST(kX86InstIdMovsx , "movsx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(BE,U) , U ), + INST(kX86InstIdMovsxd , "movsxd" , G(X86MovSxd) , F(Move) , 0 , O(Gq) , O(GdMem) , U , U , E(________) , O_000000(63,U) , U ), + INST(kX86InstIdMovupd , "movupd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), + INST(kX86InstIdMovups , "movups" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), + INST(kX86InstIdMovzx , "movzx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(B6,U) , U ), + INST(kX86InstIdMpsadbw , "mpsadbw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(42,U) , U ), + INST(kX86InstIdMul , "mul" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , O_000000(F6,4) , U ), + INST(kX86InstIdMulpd , "mulpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(59,U) , U ), + INST(kX86InstIdMulps , "mulps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(59,U) , U ), + INST(kX86InstIdMulsd , "mulsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(59,U) , U ), + INST(kX86InstIdMulss , "mulss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(59,U) , U ), + INST(kX86InstIdMulx , "mulx" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F6,U) , U ), + INST(kX86InstIdMwait , "mwait" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C9,U) , U ), + INST(kX86InstIdNeg , "neg" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWWW__) , O_000000(F6,3) , U ), + INST(kX86InstIdNop , "nop" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000000(90,U) , U ), + INST(kX86InstIdNot , "not" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(________) , O_000000(F6,2) , U ), + INST(kX86InstIdOr , "or" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(08,1) , U ), + INST(kX86InstIdOrpd , "orpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(56,U) , U ), + INST(kX86InstIdOrps , "orps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(56,U) , U ), + INST(kX86InstIdPabsb , "pabsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1C,U) , U ), + INST(kX86InstIdPabsd , "pabsd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1E,U) , U ), + INST(kX86InstIdPabsw , "pabsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1D,U) , U ), + INST(kX86InstIdPackssdw , "packssdw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6B,U) , U ), + INST(kX86InstIdPacksswb , "packsswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(63,U) , U ), + INST(kX86InstIdPackusdw , "packusdw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(2B,U) , U ), + INST(kX86InstIdPackuswb , "packuswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(67,U) , U ), + INST(kX86InstIdPaddb , "paddb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FC,U) , U ), + INST(kX86InstIdPaddd , "paddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FE,U) , U ), + INST(kX86InstIdPaddq , "paddq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D4,U) , U ), + INST(kX86InstIdPaddsb , "paddsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EC,U) , U ), + INST(kX86InstIdPaddsw , "paddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(ED,U) , U ), + INST(kX86InstIdPaddusb , "paddusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DC,U) , U ), + INST(kX86InstIdPaddusw , "paddusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DD,U) , U ), + INST(kX86InstIdPaddw , "paddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FD,U) , U ), + INST(kX86InstIdPalignr , "palignr" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , E(________) , O_000F3A(0F,U) , U ), + INST(kX86InstIdPand , "pand" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DB,U) , U ), + INST(kX86InstIdPandn , "pandn" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DF,U) , U ), + INST(kX86InstIdPause , "pause" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_F30000(90,U) , U ), + INST(kX86InstIdPavgb , "pavgb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E0,U) , U ), + INST(kX86InstIdPavgw , "pavgw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E3,U) , U ), + INST(kX86InstIdPblendvb , "pblendvb" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(10,U) , U ), + INST(kX86InstIdPblendw , "pblendw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0E,U) , U ), + INST(kX86InstIdPclmulqdq , "pclmulqdq" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(44,U) , U ), + INST(kX86InstIdPcmpeqb , "pcmpeqb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(74,U) , U ), + INST(kX86InstIdPcmpeqd , "pcmpeqd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(76,U) , U ), + INST(kX86InstIdPcmpeqq , "pcmpeqq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(29,U) , U ), + INST(kX86InstIdPcmpeqw , "pcmpeqw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(75,U) , U ), + INST(kX86InstIdPcmpestri , "pcmpestri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), + INST(kX86InstIdPcmpestrm , "pcmpestrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), + INST(kX86InstIdPcmpgtb , "pcmpgtb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(64,U) , U ), + INST(kX86InstIdPcmpgtd , "pcmpgtd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(66,U) , U ), + INST(kX86InstIdPcmpgtq , "pcmpgtq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(37,U) , U ), + INST(kX86InstIdPcmpgtw , "pcmpgtw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(65,U) , U ), + INST(kX86InstIdPcmpistri , "pcmpistri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), + INST(kX86InstIdPcmpistrm , "pcmpistrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), + INST(kX86InstIdPdep , "pdep" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F5,U) , U ), + INST(kX86InstIdPext , "pext" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F30F38(F5,U) , U ), + INST(kX86InstIdPextrb , "pextrb" , G(ExtExtract) , F(Move) , 8 , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , E(________) , O_000F3A(14,U) , O_000F3A(14,U) ), + INST(kX86InstIdPextrd , "pextrd" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), + INST(kX86InstIdPextrq , "pextrq" , G(ExtExtract) , F(Move) |F(W), 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), + INST(kX86InstIdPextrw , "pextrw" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(MmXmm) , U , U , E(________) , O_000F00(C5,U) , O_000F3A(15,U) ), + INST(kX86InstIdPf2id , "pf2id" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1D,U) , U ), + INST(kX86InstIdPf2iw , "pf2iw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1C,U) , U ), + INST(kX86InstIdPfacc , "pfacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AE,U) , U ), + INST(kX86InstIdPfadd , "pfadd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9E,U) , U ), + INST(kX86InstIdPfcmpeq , "pfcmpeq" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B0,U) , U ), + INST(kX86InstIdPfcmpge , "pfcmpge" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(90,U) , U ), + INST(kX86InstIdPfcmpgt , "pfcmpgt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A0,U) , U ), + INST(kX86InstIdPfmax , "pfmax" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A4,U) , U ), + INST(kX86InstIdPfmin , "pfmin" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(94,U) , U ), + INST(kX86InstIdPfmul , "pfmul" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B4,U) , U ), + INST(kX86InstIdPfnacc , "pfnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8A,U) , U ), + INST(kX86InstIdPfpnacc , "pfpnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8E,U) , U ), + INST(kX86InstIdPfrcp , "pfrcp" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(96,U) , U ), + INST(kX86InstIdPfrcpit1 , "pfrcpit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A6,U) , U ), + INST(kX86InstIdPfrcpit2 , "pfrcpit2" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B6,U) , U ), + INST(kX86InstIdPfrsqit1 , "pfrsqit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A7,U) , U ), + INST(kX86InstIdPfrsqrt , "pfrsqrt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(97,U) , U ), + INST(kX86InstIdPfsub , "pfsub" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9A,U) , U ), + INST(kX86InstIdPfsubr , "pfsubr" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AA,U) , U ), + INST(kX86InstIdPhaddd , "phaddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(02,U) , U ), + INST(kX86InstIdPhaddsw , "phaddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(03,U) , U ), + INST(kX86InstIdPhaddw , "phaddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(01,U) , U ), + INST(kX86InstIdPhminposuw , "phminposuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), + INST(kX86InstIdPhsubd , "phsubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(06,U) , U ), + INST(kX86InstIdPhsubsw , "phsubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(07,U) , U ), + INST(kX86InstIdPhsubw , "phsubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(05,U) , U ), + INST(kX86InstIdPi2fd , "pi2fd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0D,U) , U ), + INST(kX86InstIdPi2fw , "pi2fw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0C,U) , U ), + INST(kX86InstIdPinsrb , "pinsrb" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(20,U) , U ), + INST(kX86InstIdPinsrd , "pinsrd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdPinsrq , "pinsrq" , G(ExtRmi) , F(None) |F(W), 0 , O(Xmm) , O(GqMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdPinsrw , "pinsrw" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , E(________) , O_000F00(C4,U) , U ), + INST(kX86InstIdPmaddubsw , "pmaddubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(04,U) , U ), + INST(kX86InstIdPmaddwd , "pmaddwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F5,U) , U ), + INST(kX86InstIdPmaxsb , "pmaxsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3C,U) , U ), + INST(kX86InstIdPmaxsd , "pmaxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3D,U) , U ), + INST(kX86InstIdPmaxsw , "pmaxsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EE,U) , U ), + INST(kX86InstIdPmaxub , "pmaxub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DE,U) , U ), + INST(kX86InstIdPmaxud , "pmaxud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3F,U) , U ), + INST(kX86InstIdPmaxuw , "pmaxuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3E,U) , U ), + INST(kX86InstIdPminsb , "pminsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(38,U) , U ), + INST(kX86InstIdPminsd , "pminsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(39,U) , U ), + INST(kX86InstIdPminsw , "pminsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EA,U) , U ), + INST(kX86InstIdPminub , "pminub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DA,U) , U ), + INST(kX86InstIdPminud , "pminud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3B,U) , U ), + INST(kX86InstIdPminuw , "pminuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3A,U) , U ), + INST(kX86InstIdPmovmskb , "pmovmskb" , G(ExtRm_PQ) , F(Move) , 8 , O(Gqd) , O(MmXmm) , U , U , E(________) , O_000F00(D7,U) , U ), + INST(kX86InstIdPmovsxbd , "pmovsxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(21,U) , U ), + INST(kX86InstIdPmovsxbq , "pmovsxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(22,U) , U ), + INST(kX86InstIdPmovsxbw , "pmovsxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(20,U) , U ), + INST(kX86InstIdPmovsxdq , "pmovsxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(25,U) , U ), + INST(kX86InstIdPmovsxwd , "pmovsxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(23,U) , U ), + INST(kX86InstIdPmovsxwq , "pmovsxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(24,U) , U ), + INST(kX86InstIdPmovzxbd , "pmovzxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(31,U) , U ), + INST(kX86InstIdPmovzxbq , "pmovzxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(32,U) , U ), + INST(kX86InstIdPmovzxbw , "pmovzxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(30,U) , U ), + INST(kX86InstIdPmovzxdq , "pmovzxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(35,U) , U ), + INST(kX86InstIdPmovzxwd , "pmovzxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(33,U) , U ), + INST(kX86InstIdPmovzxwq , "pmovzxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(34,U) , U ), + INST(kX86InstIdPmuldq , "pmuldq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(28,U) , U ), + INST(kX86InstIdPmulhrsw , "pmulhrsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0B,U) , U ), + INST(kX86InstIdPmulhuw , "pmulhuw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E4,U) , U ), + INST(kX86InstIdPmulhw , "pmulhw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E5,U) , U ), + INST(kX86InstIdPmulld , "pmulld" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(40,U) , U ), + INST(kX86InstIdPmullw , "pmullw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D5,U) , U ), + INST(kX86InstIdPmuludq , "pmuludq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F4,U) , U ), + INST(kX86InstIdPop , "pop" , G(X86Pop) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(8F,0) , O_000000(58,U) ), + INST(kX86InstIdPopa , "popa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(61,U) , U ), + INST(kX86InstIdPopcnt , "popcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(WWWWWW__) , O_F30F00(B8,U) , U ), + INST(kX86InstIdPopf , "popf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWWW) , O_000000(9D,U) , U ), + INST(kX86InstIdPor , "por" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EB,U) , U ), + INST(kX86InstIdPrefetch , "prefetch" , G(ExtPrefetch) , F(None) , 0 , O(Mem) , O(Imm) , U , U , E(________) , O_000F00(18,U) , U ), + INST(kX86InstIdPrefetch3dNow , "prefetch_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,0) , U ), + INST(kX86InstIdPrefetchw3dNow , "prefetchw_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,1) , U ), + INST(kX86InstIdPsadbw , "psadbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F6,U) , U ), + INST(kX86InstIdPshufb , "pshufb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(00,U) , U ), + INST(kX86InstIdPshufd , "pshufd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), + INST(kX86InstIdPshufhw , "pshufhw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), + INST(kX86InstIdPshuflw , "pshuflw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), + INST(kX86InstIdPshufw , "pshufw" , G(ExtRmi_P) , F(Move) , 8 , O(Mm) , O(MmMem) , O(Imm) , U , E(________) , O_000F00(70,U) , U ), + INST(kX86InstIdPsignb , "psignb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(08,U) , U ), + INST(kX86InstIdPsignd , "psignd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0A,U) , U ), + INST(kX86InstIdPsignw , "psignw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(09,U) , U ), + INST(kX86InstIdPslld , "pslld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F2,U) , O_000F00(72,6) ), + INST(kX86InstIdPslldq , "pslldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,7) ), + INST(kX86InstIdPsllq , "psllq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F3,U) , O_000F00(73,6) ), + INST(kX86InstIdPsllw , "psllw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F1,U) , O_000F00(71,6) ), + INST(kX86InstIdPsrad , "psrad" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E2,U) , O_000F00(72,4) ), + INST(kX86InstIdPsraw , "psraw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E1,U) , O_000F00(71,4) ), + INST(kX86InstIdPsrld , "psrld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D2,U) , O_000F00(72,2) ), + INST(kX86InstIdPsrldq , "psrldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,3) ), + INST(kX86InstIdPsrlq , "psrlq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D3,U) , O_000F00(73,2) ), + INST(kX86InstIdPsrlw , "psrlw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D1,U) , O_000F00(71,2) ), + INST(kX86InstIdPsubb , "psubb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F8,U) , U ), + INST(kX86InstIdPsubd , "psubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FA,U) , U ), + INST(kX86InstIdPsubq , "psubq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FB,U) , U ), + INST(kX86InstIdPsubsb , "psubsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E8,U) , U ), + INST(kX86InstIdPsubsw , "psubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E9,U) , U ), + INST(kX86InstIdPsubusb , "psubusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D8,U) , U ), + INST(kX86InstIdPsubusw , "psubusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D9,U) , U ), + INST(kX86InstIdPsubw , "psubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F9,U) , U ), + INST(kX86InstIdPswapd , "pswapd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(BB,U) , U ), + INST(kX86InstIdPtest , "ptest" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), + INST(kX86InstIdPunpckhbw , "punpckhbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(68,U) , U ), + INST(kX86InstIdPunpckhdq , "punpckhdq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6A,U) , U ), + INST(kX86InstIdPunpckhqdq , "punpckhqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6D,U) , U ), + INST(kX86InstIdPunpckhwd , "punpckhwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(69,U) , U ), + INST(kX86InstIdPunpcklbw , "punpcklbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(60,U) , U ), + INST(kX86InstIdPunpckldq , "punpckldq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(62,U) , U ), + INST(kX86InstIdPunpcklqdq , "punpcklqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6C,U) , U ), + INST(kX86InstIdPunpcklwd , "punpcklwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(61,U) , U ), + INST(kX86InstIdPush , "push" , G(X86Push) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(FF,6) , O_000000(50,U) ), + INST(kX86InstIdPusha , "pusha" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(60,U) , U ), + INST(kX86InstIdPushf , "pushf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(RRRRRRRR) , O_000000(9C,U) , U ), + INST(kX86InstIdPxor , "pxor" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EF,U) , U ), + INST(kX86InstIdRcl , "rcl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,2) , U ), + INST(kX86InstIdRcpps , "rcpps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(53,U) , U ), + INST(kX86InstIdRcpss , "rcpss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(53,U) , U ), + INST(kX86InstIdRcr , "rcr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,3) , U ), + INST(kX86InstIdRdfsbase , "rdfsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,0) , U ), + INST(kX86InstIdRdgsbase , "rdgsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,1) , U ), + INST(kX86InstIdRdrand , "rdrand" , G(X86Rm) , F(Move) , 8 , O(Gqdw) , U , U , U , E(WWWWWW__) , O_000F00(C7,6) , U ), + INST(kX86InstIdRdtsc , "rdtsc" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(31,U) , U ), + INST(kX86InstIdRdtscp , "rdtscp" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(F9,U) , U ), + INST(kX86InstIdRepLodsB , "rep lods_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AC,1) , U ), + INST(kX86InstIdRepLodsD , "rep lods_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), + INST(kX86InstIdRepLodsQ , "rep lods_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), + INST(kX86InstIdRepLodsW , "rep lods_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AD,1) , U ), + INST(kX86InstIdRepMovsB , "rep movs_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A4,1) , U ), + INST(kX86InstIdRepMovsD , "rep movs_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), + INST(kX86InstIdRepMovsQ , "rep movs_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), + INST(kX86InstIdRepMovsW , "rep movs_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_660000(A5,1) , U ), + INST(kX86InstIdRepStosB , "rep stos_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AA,1) , U ), + INST(kX86InstIdRepStosD , "rep stos_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), + INST(kX86InstIdRepStosQ , "rep stos_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), + INST(kX86InstIdRepStosW , "rep stos_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AB,1) , U ), + INST(kX86InstIdRepeCmpsB , "repe cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,1) , U ), + INST(kX86InstIdRepeCmpsD , "repe cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), + INST(kX86InstIdRepeCmpsQ , "repe cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), + INST(kX86InstIdRepeCmpsW , "repe cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,1) , U ), + INST(kX86InstIdRepeScasB , "repe scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,1) , U ), + INST(kX86InstIdRepeScasD , "repe scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), + INST(kX86InstIdRepeScasQ , "repe scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), + INST(kX86InstIdRepeScasW , "repe scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,1) , U ), + INST(kX86InstIdRepneCmpsB , "repne cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,0) , U ), + INST(kX86InstIdRepneCmpsD , "repne cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), + INST(kX86InstIdRepneCmpsQ , "repne cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), + INST(kX86InstIdRepneCmpsW , "repne cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,0) , U ), + INST(kX86InstIdRepneScasB , "repne scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,0) , U ), + INST(kX86InstIdRepneScasD , "repne scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), + INST(kX86InstIdRepneScasQ , "repne scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), + INST(kX86InstIdRepneScasW , "repne scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,0) , U ), + INST(kX86InstIdRet , "ret" , G(X86Ret) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C2,U) , U ), + INST(kX86InstIdRol , "rol" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,0) , U ), + INST(kX86InstIdRor , "ror" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,1) , U ), + INST(kX86InstIdRorx , "rorx" , G(AvxRmi) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , E(________) , O_F20F3A(F0,U) , U ), + INST(kX86InstIdRoundpd , "roundpd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), + INST(kX86InstIdRoundps , "roundps" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), + INST(kX86InstIdRoundsd , "roundsd" , G(ExtRmi) , F(Move) , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0B,U) , U ), + INST(kX86InstIdRoundss , "roundss" , G(ExtRmi) , F(Move) , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0A,U) , U ), + INST(kX86InstIdRsqrtps , "rsqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(52,U) , U ), + INST(kX86InstIdRsqrtss , "rsqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(52,U) , U ), + INST(kX86InstIdSahf , "sahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_WWWWW__) , O_000000(9E,U) , U ), + INST(kX86InstIdSal , "sal" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), + INST(kX86InstIdSar , "sar" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,7) , U ), + INST(kX86InstIdSarx , "sarx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F30F38(F7,U) , U ), + INST(kX86InstIdSbb , "sbb" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(18,3) , U ), + INST(kX86InstIdScasB , "scas_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AE,U) , U ), + INST(kX86InstIdScasD , "scas_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdScasQ , "scas_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdScasW , "scas_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdSeta , "seta" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), + INST(kX86InstIdSetae , "setae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetb , "setb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSetbe , "setbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), + INST(kX86InstIdSetc , "setc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSete , "sete" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), + INST(kX86InstIdSetg , "setg" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), + INST(kX86InstIdSetge , "setge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), + INST(kX86InstIdSetl , "setl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), + INST(kX86InstIdSetle , "setle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), + INST(kX86InstIdSetna , "setna" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), + INST(kX86InstIdSetnae , "setnae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSetnb , "setnb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetnbe , "setnbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), + INST(kX86InstIdSetnc , "setnc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetne , "setne" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), + INST(kX86InstIdSetng , "setng" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), + INST(kX86InstIdSetnge , "setnge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), + INST(kX86InstIdSetnl , "setnl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), + INST(kX86InstIdSetnle , "setnle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), + INST(kX86InstIdSetno , "setno" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(91,U) , U ), + INST(kX86InstIdSetnp , "setnp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), + INST(kX86InstIdSetns , "setns" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(99,U) , U ), + INST(kX86InstIdSetnz , "setnz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), + INST(kX86InstIdSeto , "seto" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(90,U) , U ), + INST(kX86InstIdSetp , "setp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), + INST(kX86InstIdSetpe , "setpe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), + INST(kX86InstIdSetpo , "setpo" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), + INST(kX86InstIdSets , "sets" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(98,U) , U ), + INST(kX86InstIdSetz , "setz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), + INST(kX86InstIdSfence , "sfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,7) , U ), + INST(kX86InstIdShl , "shl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), + INST(kX86InstIdShld , "shld" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb) , U , U , E(UWWUWW__) , O_000F00(A4,U) , U ), + INST(kX86InstIdShlx , "shlx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_660F38(F7,U) , U ), + INST(kX86InstIdShr , "shr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,5) , U ), + INST(kX86InstIdShrd , "shrd" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(UWWUWW__) , O_000F00(AC,U) , U ), + INST(kX86InstIdShrx , "shrx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F20F38(F7,U) , U ), + INST(kX86InstIdShufpd , "shufpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C6,U) , U ), + INST(kX86InstIdShufps , "shufps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C6,U) , U ), + INST(kX86InstIdSqrtpd , "sqrtpd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(51,U) , U ), + INST(kX86InstIdSqrtps , "sqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(51,U) , U ), + INST(kX86InstIdSqrtsd , "sqrtsd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(51,U) , U ), + INST(kX86InstIdSqrtss , "sqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(51,U) , U ), + INST(kX86InstIdStc , "stc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F9,U) , U ), + INST(kX86InstIdStd , "std" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FD,U) , U ), + INST(kX86InstIdStmxcsr , "stmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), + INST(kX86InstIdStosB , "stos_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AA,U) , U ), + INST(kX86InstIdStosD , "stos_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdStosQ , "stos_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdStosW , "stos_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdSub , "sub" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(28,5) , U ), + INST(kX86InstIdSubpd , "subpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5C,U) , U ), + INST(kX86InstIdSubps , "subps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5C,U) , U ), + INST(kX86InstIdSubsd , "subsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5C,U) , U ), + INST(kX86InstIdSubss , "subss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5C,U) , U ), + INST(kX86InstIdTest , "test" , G(X86Test) , F(Test) , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(84,U) , O_000000(F6,U) ), + INST(kX86InstIdTzcnt , "tzcnt" , G(X86RegRm) , F(Move) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BC,U) , U ), + INST(kX86InstIdUcomisd , "ucomisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), + INST(kX86InstIdUcomiss , "ucomiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), + INST(kX86InstIdUd2 , "ud2" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(0B,U) , U ), + INST(kX86InstIdUnpckhpd , "unpckhpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(15,U) , U ), + INST(kX86InstIdUnpckhps , "unpckhps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(15,U) , U ), + INST(kX86InstIdUnpcklpd , "unpcklpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(14,U) , U ), + INST(kX86InstIdUnpcklps , "unpcklps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(14,U) , U ), + INST(kX86InstIdVaddpd , "vaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(58,U) , U ), + INST(kX86InstIdVaddps , "vaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(58,U) , U ), + INST(kX86InstIdVaddsd , "vaddsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(58,U) , U ), + INST(kX86InstIdVaddss , "vaddss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(58,U) , U ), + INST(kX86InstIdVaddsubpd , "vaddsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D0,U) , U ), + INST(kX86InstIdVaddsubps , "vaddsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(D0,U) , U ), + INST(kX86InstIdVaesdec , "vaesdec" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DE,U) , U ), + INST(kX86InstIdVaesdeclast , "vaesdeclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DF,U) , U ), + INST(kX86InstIdVaesenc , "vaesenc" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DC,U) , U ), + INST(kX86InstIdVaesenclast , "vaesenclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DD,U) , U ), + INST(kX86InstIdVaesimc , "vaesimc" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), + INST(kX86InstIdVaeskeygenassist , "vaeskeygenassist" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), + INST(kX86InstIdVandnpd , "vandnpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(55,U) , U ), + INST(kX86InstIdVandnps , "vandnps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(55,U) , U ), + INST(kX86InstIdVandpd , "vandpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(54,U) , U ), + INST(kX86InstIdVandps , "vandps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(54,U) , U ), + INST(kX86InstIdVblendpd , "vblendpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0D,U) , U ), + INST(kX86InstIdVblendps , "vblendps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0C,U) , U ), + INST(kX86InstIdVblendvpd , "vblendvpd" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4B,U) , U ), + INST(kX86InstIdVblendvps , "vblendvps" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4A,U) , U ), + INST(kX86InstIdVbroadcastf128 , "vbroadcastf128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(1A,U)|L, U ), + INST(kX86InstIdVbroadcasti128 , "vbroadcasti128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(5A,U)|L, U ), + INST(kX86InstIdVbroadcastsd , "vbroadcastsd" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(19,U)|L, U ), + INST(kX86InstIdVbroadcastss , "vbroadcastss" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(18,U) , U ), + INST(kX86InstIdVcmppd , "vcmppd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C2,U) , U ), + INST(kX86InstIdVcmpps , "vcmpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C2,U) , U ), + INST(kX86InstIdVcmpsd , "vcmpsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F20F00(C2,U) , U ), + INST(kX86InstIdVcmpss , "vcmpss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F30F00(C2,U) , U ), + INST(kX86InstIdVcomisd , "vcomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(2F,U) , U ), + INST(kX86InstIdVcomiss , "vcomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(2F,U) , U ), + INST(kX86InstIdVcvtdq2pd , "vcvtdq2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), + INST(kX86InstIdVcvtdq2ps , "vcvtdq2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), + INST(kX86InstIdVcvtpd2dq , "vcvtpd2dq" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), + INST(kX86InstIdVcvtpd2ps , "vcvtpd2ps" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), + INST(kX86InstIdVcvtph2ps , "vcvtph2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(13,U) , U ), + INST(kX86InstIdVcvtps2dq , "vcvtps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), + INST(kX86InstIdVcvtps2pd , "vcvtps2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), + INST(kX86InstIdVcvtps2ph , "vcvtps2ph" , G(AvxMri_P) , F(None) , 0 , O(XmmMem) , O(XmmYmm) , O(Imm) , U , E(________) , O_660F3A(1D,U) , U ), + INST(kX86InstIdVcvtsd2si , "vcvtsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdVcvtsd2ss , "vcvtsd2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5A,U) , U ), + INST(kX86InstIdVcvtsi2sd , "vcvtsi2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F20F00(2A,U) , U ), + INST(kX86InstIdVcvtsi2ss , "vcvtsi2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F30F00(2A,U) , U ), + INST(kX86InstIdVcvtss2sd , "vcvtss2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5A,U) , U ), + INST(kX86InstIdVcvtss2si , "vcvtss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdVcvttpd2dq , "vcvttpd2dq" , G(AvxRm_P) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), + INST(kX86InstIdVcvttps2dq , "vcvttps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), + INST(kX86InstIdVcvttsd2si , "vcvttsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), + INST(kX86InstIdVcvttss2si , "vcvttss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), + INST(kX86InstIdVdivpd , "vdivpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5E,U) , U ), + INST(kX86InstIdVdivps , "vdivps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5E,U) , U ), + INST(kX86InstIdVdivsd , "vdivsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5E,U) , U ), + INST(kX86InstIdVdivss , "vdivss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5E,U) , U ), + INST(kX86InstIdVdppd , "vdppd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(41,U) , U ), + INST(kX86InstIdVdpps , "vdpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(40,U) , U ), + INST(kX86InstIdVextractf128 , "vextractf128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(19,U)|L, U ), + INST(kX86InstIdVextracti128 , "vextracti128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(39,U)|L, U ), + INST(kX86InstIdVextractps , "vextractps" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(17,U) , U ), + INST(kX86InstIdVfmadd132pd , "vfmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), + INST(kX86InstIdVfmadd132ps , "vfmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), + INST(kX86InstIdVfmadd132sd , "vfmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), + INST(kX86InstIdVfmadd132ss , "vfmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), + INST(kX86InstIdVfmadd213pd , "vfmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), + INST(kX86InstIdVfmadd213ps , "vfmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), + INST(kX86InstIdVfmadd213sd , "vfmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), + INST(kX86InstIdVfmadd213ss , "vfmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), + INST(kX86InstIdVfmadd231pd , "vfmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), + INST(kX86InstIdVfmadd231ps , "vfmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), + INST(kX86InstIdVfmadd231sd , "vfmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), + INST(kX86InstIdVfmadd231ss , "vfmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), + INST(kX86InstIdVfmaddpd , "vfmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(69,U) , U ), + INST(kX86InstIdVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(68,U) , U ), + INST(kX86InstIdVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6B,U) , U ), + INST(kX86InstIdVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6A,U) , U ), + INST(kX86InstIdVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), + INST(kX86InstIdVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), + INST(kX86InstIdVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), + INST(kX86InstIdVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), + INST(kX86InstIdVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), + INST(kX86InstIdVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), + INST(kX86InstIdVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5D,U) , U ), + INST(kX86InstIdVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5C,U) , U ), + INST(kX86InstIdVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), + INST(kX86InstIdVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), + INST(kX86InstIdVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), + INST(kX86InstIdVfmsub132ss , "vfmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), + INST(kX86InstIdVfmsub213pd , "vfmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), + INST(kX86InstIdVfmsub213ps , "vfmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), + INST(kX86InstIdVfmsub213sd , "vfmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), + INST(kX86InstIdVfmsub213ss , "vfmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), + INST(kX86InstIdVfmsub231pd , "vfmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), + INST(kX86InstIdVfmsub231ps , "vfmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), + INST(kX86InstIdVfmsub231sd , "vfmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), + INST(kX86InstIdVfmsub231ss , "vfmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), + INST(kX86InstIdVfmsubadd132pd , "vfmsubadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), + INST(kX86InstIdVfmsubadd132ps , "vfmsubadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), + INST(kX86InstIdVfmsubadd213pd , "vfmsubadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), + INST(kX86InstIdVfmsubadd213ps , "vfmsubadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), + INST(kX86InstIdVfmsubadd231pd , "vfmsubadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), + INST(kX86InstIdVfmsubadd231ps , "vfmsubadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), + INST(kX86InstIdVfmsubaddpd , "vfmsubaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5F,U) , U ), + INST(kX86InstIdVfmsubaddps , "vfmsubaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5E,U) , U ), + INST(kX86InstIdVfmsubpd , "vfmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6D,U) , U ), + INST(kX86InstIdVfmsubps , "vfmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6C,U) , U ), + INST(kX86InstIdVfmsubsd , "vfmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6F,U) , U ), + INST(kX86InstIdVfmsubss , "vfmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6E,U) , U ), + INST(kX86InstIdVfnmadd132pd , "vfnmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), + INST(kX86InstIdVfnmadd132ps , "vfnmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), + INST(kX86InstIdVfnmadd132sd , "vfnmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), + INST(kX86InstIdVfnmadd132ss , "vfnmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), + INST(kX86InstIdVfnmadd213pd , "vfnmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), + INST(kX86InstIdVfnmadd213ps , "vfnmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), + INST(kX86InstIdVfnmadd213sd , "vfnmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), + INST(kX86InstIdVfnmadd213ss , "vfnmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), + INST(kX86InstIdVfnmadd231pd , "vfnmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231ps , "vfnmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231sd , "vfnmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231ss , "vfnmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmaddpd , "vfnmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(79,U) , U ), + INST(kX86InstIdVfnmaddps , "vfnmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(78,U) , U ), + INST(kX86InstIdVfnmaddsd , "vfnmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7B,U) , U ), + INST(kX86InstIdVfnmaddss , "vfnmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7A,U) , U ), + INST(kX86InstIdVfnmsub132pd , "vfnmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), + INST(kX86InstIdVfnmsub132ps , "vfnmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), + INST(kX86InstIdVfnmsub132sd , "vfnmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), + INST(kX86InstIdVfnmsub132ss , "vfnmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), + INST(kX86InstIdVfnmsub213pd , "vfnmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), + INST(kX86InstIdVfnmsub213ps , "vfnmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), + INST(kX86InstIdVfnmsub213sd , "vfnmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), + INST(kX86InstIdVfnmsub213ss , "vfnmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), + INST(kX86InstIdVfnmsub231pd , "vfnmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), + INST(kX86InstIdVfnmsub231ps , "vfnmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), + INST(kX86InstIdVfnmsub231sd , "vfnmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), + INST(kX86InstIdVfnmsub231ss , "vfnmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), + INST(kX86InstIdVfnmsubpd , "vfnmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7D,U) , U ), + INST(kX86InstIdVfnmsubps , "vfnmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7C,U) , U ), + INST(kX86InstIdVfnmsubsd , "vfnmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7F,U) , U ), + INST(kX86InstIdVfnmsubss , "vfnmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7E,U) , U ), + INST(kX86InstIdVfrczpd , "vfrczpd" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(81,U) , U ), + INST(kX86InstIdVfrczps , "vfrczps" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(80,U) , U ), + INST(kX86InstIdVfrczsd , "vfrczsd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(83,U) , U ), + INST(kX86InstIdVfrczss , "vfrczss" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(82,U) , U ), + INST(kX86InstIdVgatherdpd , "vgatherdpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), + INST(kX86InstIdVgatherdps , "vgatherdps" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), + INST(kX86InstIdVgatherqpd , "vgatherqpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(93,U) , U ), + INST(kX86InstIdVgatherqps , "vgatherqps" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(93,U) , U ), + INST(kX86InstIdVhaddpd , "vhaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7C,U) , U ), + INST(kX86InstIdVhaddps , "vhaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7C,U) , U ), + INST(kX86InstIdVhsubpd , "vhsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7D,U) , U ), + INST(kX86InstIdVhsubps , "vhsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7D,U) , U ), + INST(kX86InstIdVinsertf128 , "vinsertf128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(18,U)|L, U ), + INST(kX86InstIdVinserti128 , "vinserti128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(38,U)|L, U ), + INST(kX86InstIdVinsertps , "vinsertps" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(21,U) , U ), + INST(kX86InstIdVlddqu , "vlddqu" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), + INST(kX86InstIdVldmxcsr , "vldmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), + INST(kX86InstIdVmaskmovdqu , "vmaskmovdqu" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(F7,U) , U ), + INST(kX86InstIdVmaskmovpd , "vmaskmovpd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2D,U) , O_660F38(2F,U) ), + INST(kX86InstIdVmaskmovps , "vmaskmovps" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2C,U) , O_660F38(2E,U) ), + INST(kX86InstIdVmaxpd , "vmaxpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5F,U) , U ), + INST(kX86InstIdVmaxps , "vmaxps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5F,U) , U ), + INST(kX86InstIdVmaxsd , "vmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5F,U) , U ), + INST(kX86InstIdVmaxss , "vmaxss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5F,U) , U ), + INST(kX86InstIdVminpd , "vminpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5D,U) , U ), + INST(kX86InstIdVminps , "vminps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5D,U) , U ), + INST(kX86InstIdVminsd , "vminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5D,U) , U ), + INST(kX86InstIdVminss , "vminss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5D,U) , U ), + INST(kX86InstIdVmovapd , "vmovapd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), + INST(kX86InstIdVmovaps , "vmovaps" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), + INST(kX86InstIdVmovd , "vmovd" , G(AvxRmMr) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), + INST(kX86InstIdVmovddup , "vmovddup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), + INST(kX86InstIdVmovdqa , "vmovdqa" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), + INST(kX86InstIdVmovdqu , "vmovdqu" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), + INST(kX86InstIdVmovhlps , "vmovhlps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(12,U) , U ), + INST(kX86InstIdVmovhpd , "vmovhpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), + INST(kX86InstIdVmovhps , "vmovhps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), + INST(kX86InstIdVmovlhps , "vmovlhps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(16,U) , U ), + INST(kX86InstIdVmovlpd , "vmovlpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), + INST(kX86InstIdVmovlps , "vmovlps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), + INST(kX86InstIdVmovmskpd , "vmovmskpd" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(50,U) , U ), + INST(kX86InstIdVmovmskps , "vmovmskps" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_000F00(50,U) , U ), + INST(kX86InstIdVmovntdq , "vmovntdq" , G(AvxMr) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(E7,U) , U ), + INST(kX86InstIdVmovntdqa , "vmovntdqa" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), + INST(kX86InstIdVmovntpd , "vmovntpd" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(2B,U) , U ), + INST(kX86InstIdVmovntps , "vmovntps" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_000F00(2B,U) , U ), + INST(kX86InstIdVmovq , "vmovq" , G(AvxRmMr) , F(None) |F(W), 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), + INST(kX86InstIdVmovsd , "vmovsd" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), + INST(kX86InstIdVmovshdup , "vmovshdup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), + INST(kX86InstIdVmovsldup , "vmovsldup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), + INST(kX86InstIdVmovss , "vmovss" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), + INST(kX86InstIdVmovupd , "vmovupd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), + INST(kX86InstIdVmovups , "vmovups" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), + INST(kX86InstIdVmpsadbw , "vmpsadbw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(42,U) , U ), + INST(kX86InstIdVmulpd , "vmulpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(59,U) , U ), + INST(kX86InstIdVmulps , "vmulps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(59,U) , U ), + INST(kX86InstIdVmulsd , "vmulsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(59,U) , U ), + INST(kX86InstIdVmulss , "vmulss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(59,U) , U ), + INST(kX86InstIdVorpd , "vorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(56,U) , U ), + INST(kX86InstIdVorps , "vorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(56,U) , U ), + INST(kX86InstIdVpabsb , "vpabsb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1C,U) , U ), + INST(kX86InstIdVpabsd , "vpabsd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1E,U) , U ), + INST(kX86InstIdVpabsw , "vpabsw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1D,U) , U ), + INST(kX86InstIdVpackssdw , "vpackssdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6B,U) , U ), + INST(kX86InstIdVpacksswb , "vpacksswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(63,U) , U ), + INST(kX86InstIdVpackusdw , "vpackusdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2B,U) , U ), + INST(kX86InstIdVpackuswb , "vpackuswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(67,U) , U ), + INST(kX86InstIdVpaddb , "vpaddb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FC,U) , U ), + INST(kX86InstIdVpaddd , "vpaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FE,U) , U ), + INST(kX86InstIdVpaddq , "vpaddq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D4,U) , U ), + INST(kX86InstIdVpaddsb , "vpaddsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EC,U) , U ), + INST(kX86InstIdVpaddsw , "vpaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(ED,U) , U ), + INST(kX86InstIdVpaddusb , "vpaddusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DC,U) , U ), + INST(kX86InstIdVpaddusw , "vpaddusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DD,U) , U ), + INST(kX86InstIdVpaddw , "vpaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FD,U) , U ), + INST(kX86InstIdVpalignr , "vpalignr" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0F,U) , U ), + INST(kX86InstIdVpand , "vpand" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DB,U) , U ), + INST(kX86InstIdVpandn , "vpandn" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DF,U) , U ), + INST(kX86InstIdVpavgb , "vpavgb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E0,U) , U ), + INST(kX86InstIdVpavgw , "vpavgw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E3,U) , U ), + INST(kX86InstIdVpblendd , "vpblendd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(02,U) , U ), + INST(kX86InstIdVpblendvb , "vpblendvb" , G(AvxRvmr) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4C,U) , U ), + INST(kX86InstIdVpblendw , "vpblendw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0E,U) , U ), + INST(kX86InstIdVpbroadcastb , "vpbroadcastb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(78,U) , U ), + INST(kX86InstIdVpbroadcastd , "vpbroadcastd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(58,U) , U ), + INST(kX86InstIdVpbroadcastq , "vpbroadcastq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(59,U) , U ), + INST(kX86InstIdVpbroadcastw , "vpbroadcastw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(79,U) , U ), + INST(kX86InstIdVpclmulqdq , "vpclmulqdq" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(44,U) , U ), + INST(kX86InstIdVpcmov , "vpcmov" , G(XopRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_00_M08(A2,U) , U ), + INST(kX86InstIdVpcmpeqb , "vpcmpeqb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(74,U) , U ), + INST(kX86InstIdVpcmpeqd , "vpcmpeqd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(76,U) , U ), + INST(kX86InstIdVpcmpeqq , "vpcmpeqq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(29,U) , U ), + INST(kX86InstIdVpcmpeqw , "vpcmpeqw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(75,U) , U ), + INST(kX86InstIdVpcmpestri , "vpcmpestri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), + INST(kX86InstIdVpcmpestrm , "vpcmpestrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), + INST(kX86InstIdVpcmpgtb , "vpcmpgtb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(64,U) , U ), + INST(kX86InstIdVpcmpgtd , "vpcmpgtd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(66,U) , U ), + INST(kX86InstIdVpcmpgtq , "vpcmpgtq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(37,U) , U ), + INST(kX86InstIdVpcmpgtw , "vpcmpgtw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(65,U) , U ), + INST(kX86InstIdVpcmpistri , "vpcmpistri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), + INST(kX86InstIdVpcmpistrm , "vpcmpistrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), + INST(kX86InstIdVpcomb , "vpcomb" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CC,U) , U ), + INST(kX86InstIdVpcomd , "vpcomd" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CE,U) , U ), + INST(kX86InstIdVpcomq , "vpcomq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CF,U) , U ), + INST(kX86InstIdVpcomub , "vpcomub" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EC,U) , U ), + INST(kX86InstIdVpcomud , "vpcomud" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EE,U) , U ), + INST(kX86InstIdVpcomuq , "vpcomuq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EF,U) , U ), + INST(kX86InstIdVpcomuw , "vpcomuw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(ED,U) , U ), + INST(kX86InstIdVpcomw , "vpcomw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CD,U) , U ), + INST(kX86InstIdVperm2f128 , "vperm2f128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(06,U)|L, U ), + INST(kX86InstIdVperm2i128 , "vperm2i128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(46,U)|L, U ), + INST(kX86InstIdVpermd , "vpermd" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(36,U)|L, U ), + INST(kX86InstIdVpermil2pd , "vpermil2pd" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(49,U) , U ), + INST(kX86InstIdVpermil2ps , "vpermil2ps" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(48,U) , U ), + INST(kX86InstIdVpermilpd , "vpermilpd" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0D,U) , O_660F3A(05,U) ), + INST(kX86InstIdVpermilps , "vpermilps" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0C,U) , O_660F3A(04,U) ), + INST(kX86InstIdVpermpd , "vpermpd" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(01,U)|L, U ), + INST(kX86InstIdVpermps , "vpermps" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(16,U)|L, U ), + INST(kX86InstIdVpermq , "vpermq" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(00,U)|L, U ), + INST(kX86InstIdVpextrb , "vpextrb" , G(AvxMri) , F(None) , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(14,U) , U ), + INST(kX86InstIdVpextrd , "vpextrd" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), + INST(kX86InstIdVpextrq , "vpextrq" , G(AvxMri) , F(None) |F(W), 0 , O(GqMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), + INST(kX86InstIdVpextrw , "vpextrw" , G(AvxMri) , F(None) , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(15,U) , U ), + INST(kX86InstIdVpgatherdd , "vpgatherdd" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), + INST(kX86InstIdVpgatherdq , "vpgatherdq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), + INST(kX86InstIdVpgatherqd , "vpgatherqd" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(91,U) , U ), + INST(kX86InstIdVpgatherqq , "vpgatherqq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(91,U) , U ), + INST(kX86InstIdVphaddbd , "vphaddbd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C2,U) , U ), + INST(kX86InstIdVphaddbq , "vphaddbq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C3,U) , U ), + INST(kX86InstIdVphaddbw , "vphaddbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C1,U) , U ), + INST(kX86InstIdVphaddd , "vphaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(02,U) , U ), + INST(kX86InstIdVphadddq , "vphadddq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(CB,U) , U ), + INST(kX86InstIdVphaddsw , "vphaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(03,U) , U ), + INST(kX86InstIdVphaddubd , "vphaddubd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D2,U) , U ), + INST(kX86InstIdVphaddubq , "vphaddubq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D3,U) , U ), + INST(kX86InstIdVphaddubw , "vphaddubw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D1,U) , U ), + INST(kX86InstIdVphaddudq , "vphaddudq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(DB,U) , U ), + INST(kX86InstIdVphadduwd , "vphadduwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D6,U) , U ), + INST(kX86InstIdVphadduwq , "vphadduwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D7,U) , U ), + INST(kX86InstIdVphaddw , "vphaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(01,U) , U ), + INST(kX86InstIdVphaddwd , "vphaddwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C6,U) , U ), + INST(kX86InstIdVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C7,U) , U ), + INST(kX86InstIdVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), + INST(kX86InstIdVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E1,U) , U ), + INST(kX86InstIdVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(06,U) , U ), + INST(kX86InstIdVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E3,U) , U ), + INST(kX86InstIdVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(07,U) , U ), + INST(kX86InstIdVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(05,U) , U ), + INST(kX86InstIdVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E2,U) , U ), + INST(kX86InstIdVpinsrb , "vpinsrb" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , E(________) , O_660F3A(20,U) , U ), + INST(kX86InstIdVpinsrd , "vpinsrd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdVpinsrq , "vpinsrq" , G(AvxRvmi) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdVpinsrw , "vpinsrw" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , E(________) , O_660F00(C4,U) , U ), + INST(kX86InstIdVpmacsdd , "vpmacsdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9E,U) , U ), + INST(kX86InstIdVpmacsdqh , "vpmacsdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9F,U) , U ), + INST(kX86InstIdVpmacsdql , "vpmacsdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(97,U) , U ), + INST(kX86InstIdVpmacssdd , "vpmacssdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8E,U) , U ), + INST(kX86InstIdVpmacssdqh , "vpmacssdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8F,U) , U ), + INST(kX86InstIdVpmacssdql , "vpmacssdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(87,U) , U ), + INST(kX86InstIdVpmacsswd , "vpmacsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(86,U) , U ), + INST(kX86InstIdVpmacssww , "vpmacssww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(85,U) , U ), + INST(kX86InstIdVpmacswd , "vpmacswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(96,U) , U ), + INST(kX86InstIdVpmacsww , "vpmacsww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(95,U) , U ), + INST(kX86InstIdVpmadcsswd , "vpmadcsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(A6,U) , U ), + INST(kX86InstIdVpmadcswd , "vpmadcswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(B6,U) , U ), + INST(kX86InstIdVpmaddubsw , "vpmaddubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(04,U) , U ), + INST(kX86InstIdVpmaddwd , "vpmaddwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F5,U) , U ), + INST(kX86InstIdVpmaskmovd , "vpmaskmovd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), + INST(kX86InstIdVpmaskmovq , "vpmaskmovq" , G(AvxRvmMvr_P) , F(None) |F(W), 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), + INST(kX86InstIdVpmaxsb , "vpmaxsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3C,U) , U ), + INST(kX86InstIdVpmaxsd , "vpmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3D,U) , U ), + INST(kX86InstIdVpmaxsw , "vpmaxsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EE,U) , U ), + INST(kX86InstIdVpmaxub , "vpmaxub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DE,U) , U ), + INST(kX86InstIdVpmaxud , "vpmaxud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3F,U) , U ), + INST(kX86InstIdVpmaxuw , "vpmaxuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3E,U) , U ), + INST(kX86InstIdVpminsb , "vpminsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(38,U) , U ), + INST(kX86InstIdVpminsd , "vpminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(39,U) , U ), + INST(kX86InstIdVpminsw , "vpminsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EA,U) , U ), + INST(kX86InstIdVpminub , "vpminub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DA,U) , U ), + INST(kX86InstIdVpminud , "vpminud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3B,U) , U ), + INST(kX86InstIdVpminuw , "vpminuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3A,U) , U ), + INST(kX86InstIdVpmovmskb , "vpmovmskb" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(D7,U) , U ), + INST(kX86InstIdVpmovsxbd , "vpmovsxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(21,U) , U ), + INST(kX86InstIdVpmovsxbq , "vpmovsxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(22,U) , U ), + INST(kX86InstIdVpmovsxbw , "vpmovsxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(20,U) , U ), + INST(kX86InstIdVpmovsxdq , "vpmovsxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(25,U) , U ), + INST(kX86InstIdVpmovsxwd , "vpmovsxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(23,U) , U ), + INST(kX86InstIdVpmovsxwq , "vpmovsxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(24,U) , U ), + INST(kX86InstIdVpmovzxbd , "vpmovzxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(31,U) , U ), + INST(kX86InstIdVpmovzxbq , "vpmovzxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(32,U) , U ), + INST(kX86InstIdVpmovzxbw , "vpmovzxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(30,U) , U ), + INST(kX86InstIdVpmovzxdq , "vpmovzxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(35,U) , U ), + INST(kX86InstIdVpmovzxwd , "vpmovzxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(33,U) , U ), + INST(kX86InstIdVpmovzxwq , "vpmovzxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(34,U) , U ), + INST(kX86InstIdVpmuldq , "vpmuldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(28,U) , U ), + INST(kX86InstIdVpmulhrsw , "vpmulhrsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0B,U) , U ), + INST(kX86InstIdVpmulhuw , "vpmulhuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E4,U) , U ), + INST(kX86InstIdVpmulhw , "vpmulhw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E5,U) , U ), + INST(kX86InstIdVpmulld , "vpmulld" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(40,U) , U ), + INST(kX86InstIdVpmullw , "vpmullw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D5,U) , U ), + INST(kX86InstIdVpmuludq , "vpmuludq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F4,U) , U ), + INST(kX86InstIdVpor , "vpor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EB,U) , U ), + INST(kX86InstIdVpperm , "vpperm" , G(XopRvrmRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_00_M08(A3,U) , U ), + INST(kX86InstIdVprotb , "vprotb" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(90,U) , O_00_M08(C0,U) ), + INST(kX86InstIdVprotd , "vprotd" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(92,U) , O_00_M08(C2,U) ), + INST(kX86InstIdVprotq , "vprotq" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(93,U) , O_00_M08(C3,U) ), + INST(kX86InstIdVprotw , "vprotw" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(91,U) , O_00_M08(C1,U) ), + INST(kX86InstIdVpsadbw , "vpsadbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F6,U) , U ), + INST(kX86InstIdVpshab , "vpshab" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(98,U) , U ), + INST(kX86InstIdVpshad , "vpshad" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9A,U) , U ), + INST(kX86InstIdVpshaq , "vpshaq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9B,U) , U ), + INST(kX86InstIdVpshaw , "vpshaw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(99,U) , U ), + INST(kX86InstIdVpshlb , "vpshlb" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(94,U) , U ), + INST(kX86InstIdVpshld , "vpshld" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(96,U) , U ), + INST(kX86InstIdVpshlq , "vpshlq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(97,U) , U ), + INST(kX86InstIdVpshlw , "vpshlw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(95,U) , U ), + INST(kX86InstIdVpshufb , "vpshufb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(00,U) , U ), + INST(kX86InstIdVpshufd , "vpshufd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), + INST(kX86InstIdVpshufhw , "vpshufhw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), + INST(kX86InstIdVpshuflw , "vpshuflw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), + INST(kX86InstIdVpsignb , "vpsignb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(08,U) , U ), + INST(kX86InstIdVpsignd , "vpsignd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0A,U) , U ), + INST(kX86InstIdVpsignw , "vpsignw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(09,U) , U ), + INST(kX86InstIdVpslld , "vpslld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F2,U) , O_660F00(72,6) ), + INST(kX86InstIdVpslldq , "vpslldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,7) , U ), + INST(kX86InstIdVpsllq , "vpsllq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F3,U) , O_660F00(73,6) ), + INST(kX86InstIdVpsllvd , "vpsllvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), + INST(kX86InstIdVpsllvq , "vpsllvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), + INST(kX86InstIdVpsllw , "vpsllw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F1,U) , O_660F00(71,6) ), + INST(kX86InstIdVpsrad , "vpsrad" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E2,U) , O_660F00(72,4) ), + INST(kX86InstIdVpsravd , "vpsravd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(46,U) , U ), + INST(kX86InstIdVpsraw , "vpsraw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E1,U) , O_660F00(71,4) ), + INST(kX86InstIdVpsrld , "vpsrld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D2,U) , O_660F00(72,2) ), + INST(kX86InstIdVpsrldq , "vpsrldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,3) , U ), + INST(kX86InstIdVpsrlq , "vpsrlq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D3,U) , O_660F00(73,2) ), + INST(kX86InstIdVpsrlvd , "vpsrlvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), + INST(kX86InstIdVpsrlvq , "vpsrlvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), + INST(kX86InstIdVpsrlw , "vpsrlw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D1,U) , O_660F00(71,2) ), + INST(kX86InstIdVpsubb , "vpsubb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F8,U) , U ), + INST(kX86InstIdVpsubd , "vpsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FA,U) , U ), + INST(kX86InstIdVpsubq , "vpsubq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FB,U) , U ), + INST(kX86InstIdVpsubsb , "vpsubsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E8,U) , U ), + INST(kX86InstIdVpsubsw , "vpsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E9,U) , U ), + INST(kX86InstIdVpsubusb , "vpsubusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D8,U) , U ), + INST(kX86InstIdVpsubusw , "vpsubusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D9,U) , U ), + INST(kX86InstIdVpsubw , "vpsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F9,U) , U ), + INST(kX86InstIdVptest , "vptest" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), + INST(kX86InstIdVpunpckhbw , "vpunpckhbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(68,U) , U ), + INST(kX86InstIdVpunpckhdq , "vpunpckhdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6A,U) , U ), + INST(kX86InstIdVpunpckhqdq , "vpunpckhqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6D,U) , U ), + INST(kX86InstIdVpunpckhwd , "vpunpckhwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(69,U) , U ), + INST(kX86InstIdVpunpcklbw , "vpunpcklbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(60,U) , U ), + INST(kX86InstIdVpunpckldq , "vpunpckldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(62,U) , U ), + INST(kX86InstIdVpunpcklqdq , "vpunpcklqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6C,U) , U ), + INST(kX86InstIdVpunpcklwd , "vpunpcklwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(61,U) , U ), + INST(kX86InstIdVpxor , "vpxor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EF,U) , U ), + INST(kX86InstIdVrcpps , "vrcpps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(53,U) , U ), + INST(kX86InstIdVrcpss , "vrcpss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(53,U) , U ), + INST(kX86InstIdVroundpd , "vroundpd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), + INST(kX86InstIdVroundps , "vroundps" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), + INST(kX86InstIdVroundsd , "vroundsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0B,U) , U ), + INST(kX86InstIdVroundss , "vroundss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0A,U) , U ), + INST(kX86InstIdVrsqrtps , "vrsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(52,U) , U ), + INST(kX86InstIdVrsqrtss , "vrsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(52,U) , U ), + INST(kX86InstIdVshufpd , "vshufpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C6,U) , U ), + INST(kX86InstIdVshufps , "vshufps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C6,U) , U ), + INST(kX86InstIdVsqrtpd , "vsqrtpd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(51,U) , U ), + INST(kX86InstIdVsqrtps , "vsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(51,U) , U ), + INST(kX86InstIdVsqrtsd , "vsqrtsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(51,U) , U ), + INST(kX86InstIdVsqrtss , "vsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(51,U) , U ), + INST(kX86InstIdVstmxcsr , "vstmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), + INST(kX86InstIdVsubpd , "vsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5C,U) , U ), + INST(kX86InstIdVsubps , "vsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5C,U) , U ), + INST(kX86InstIdVsubsd , "vsubsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5C,U) , U ), + INST(kX86InstIdVsubss , "vsubss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5C,U) , U ), + INST(kX86InstIdVtestpd , "vtestpd" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0F,U) , U ), + INST(kX86InstIdVtestps , "vtestps" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0E,U) , U ), + INST(kX86InstIdVucomisd , "vucomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), + INST(kX86InstIdVucomiss , "vucomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), + INST(kX86InstIdVunpckhpd , "vunpckhpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(15,U) , U ), + INST(kX86InstIdVunpckhps , "vunpckhps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(15,U) , U ), + INST(kX86InstIdVunpcklpd , "vunpcklpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(14,U) , U ), + INST(kX86InstIdVunpcklps , "vunpcklps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(14,U) , U ), + INST(kX86InstIdVxorpd , "vxorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdVxorps , "vxorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(57,U) , U ), + INST(kX86InstIdVzeroall , "vzeroall" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U)|L, U ), + INST(kX86InstIdVzeroupper , "vzeroupper" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), + INST(kX86InstIdWrfsbase , "wrfsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,2) , U ), + INST(kX86InstIdWrgsbase , "wrgsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,3) , U ), + INST(kX86InstIdXadd , "xadd" , G(X86Xadd) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(WWWWWW__) , O_000F00(C0,U) , U ), + INST(kX86InstIdXchg , "xchg" , G(X86Xchg) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(________) , O_000000(86,U) , U ), + INST(kX86InstIdXor , "xor" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(30,6) , U ), + INST(kX86InstIdXorpd , "xorpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdXorps , "xorps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(57,U) , U ) +}; + +#undef INST + #undef O_00_X #undef O_9B_X @@ -3245,22 +4663,80 @@ const InstInfo _instInfo[] = { #undef L #undef U +#undef E #undef O #undef F #undef G -#undef INST - // ============================================================================ -// [asmjit::x86x64::X86Util] +// [asmjit::X86Cond] // ============================================================================ -#if !defined(ASMJIT_DISABLE_INST_NAMES) +#define CC_TO_INST(_Inst_) { \ + _Inst_##o, \ + _Inst_##no, \ + _Inst_##b, \ + _Inst_##ae, \ + _Inst_##e, \ + _Inst_##ne, \ + _Inst_##be, \ + _Inst_##a, \ + _Inst_##s, \ + _Inst_##ns, \ + _Inst_##pe, \ + _Inst_##po, \ + _Inst_##l, \ + _Inst_##ge, \ + _Inst_##le, \ + _Inst_##g, \ + \ + kInstIdNone, \ + kInstIdNone, \ + kInstIdNone, \ + kInstIdNone \ +} + +const uint32_t _x86ReverseCond[20] = { + /* kX86CondO -> */ kX86CondO, + /* kX86CondNO -> */ kX86CondNO, + /* kX86CondB -> */ kX86CondA, + /* kX86CondAE -> */ kX86CondBE, + /* kX86CondE -> */ kX86CondE, + /* kX86CondNE -> */ kX86CondNE, + /* kX86CondBE -> */ kX86CondAE, + /* kX86CondA -> */ kX86CondB, + /* kX86CondS -> */ kX86CondS, + /* kX86CondNS -> */ kX86CondNS, + /* kX86CondPE -> */ kX86CondPE, + /* kX86CondPO -> */ kX86CondPO, + /* kX86CondL -> */ kX86CondG, + /* kX86CondGE -> */ kX86CondLE, + /* kX86CondLE -> */ kX86CondGE, + /* kX86CondG -> */ kX86CondL, + + /* kX86CondFpuUnordered -> */ kX86CondFpuUnordered, + /* kX86CondFpuNotUnordered -> */ kX86CondFpuNotUnordered, + + 0x12, + 0x13 +}; + +const uint32_t _x86CondToCmovcc[20] = CC_TO_INST(kX86InstIdCmov); +const uint32_t _x86CondToJcc [20] = CC_TO_INST(kX86InstIdJ ); +const uint32_t _x86CondToSetcc [20] = CC_TO_INST(kX86InstIdSet ); + +#undef CC_TO_INST + +// ============================================================================ +// [asmjit::X86Util] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) // Compare two instruction names. // -// `a` is null terminated instruction name from `_instName[]` table. +// `a` is null terminated instruction name from `_x86InstName[]` table. // `b` is non-null terminated instruction name passed to `getInstIdByName()`. -static ASMJIT_INLINE int X86InstUtil_cmpName(const char* a, const char* b, size_t len) { +static ASMJIT_INLINE int X86Util_cmpInstName(const char* a, const char* b, size_t len) { for (size_t i = 0; i < len; i++) { int c = static_cast(static_cast(a[i])) - static_cast(static_cast(b[i])) ; @@ -3271,51 +4747,51 @@ static ASMJIT_INLINE int X86InstUtil_cmpName(const char* a, const char* b, size_ return static_cast(a[len]); } -uint32_t X86InstUtil::getInstIdByName(const char* name, size_t len) { +uint32_t X86Util::getInstIdByName(const char* name, size_t len) { if (name == NULL) - return kInstNone; + return kInstIdNone; if (len == kInvalidIndex) len = ::strlen(name); if (len == 0) - return kInstNone; + return kInstIdNone; - uint32_t prefix = name[0] - kInstAlphaIndexFirst; - if (prefix > kInstAlphaIndexLast - kInstAlphaIndexFirst) - return kInstNone; + uint32_t prefix = name[0] - kX86InstAlphaIndexFirst; + if (prefix > kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst) + return kInstIdNone; - uint32_t index = _instAlphaIndex[prefix]; - if (index == kInstAlphaIndexInvalid) - return kInstNone; + uint32_t index = _x86InstAlphaIndex[prefix]; + if (index == kX86InstAlphaIndexInvalid) + return kInstIdNone; - const InstInfo* base = _instInfo + index; - const InstInfo* end = _instInfo + _kInstCount; + const X86InstInfo* base = _x86InstInfo + index; + const X86InstInfo* end = _x86InstInfo + _kX86InstIdCount; // Handle instructions starting with 'j' specially. `jcc` instruction breaks // the sorting, because of the suffixes (it's considered as one instruction), // so basically `jecxz` and `jmp` are stored after all `jcc` instructions. - bool linearSearch = prefix == ('j' - kInstAlphaIndexFirst); + bool linearSearch = prefix == ('j' - kX86InstAlphaIndexFirst); - while (++prefix <= kInstAlphaIndexLast - kInstAlphaIndexFirst) { - index = _instAlphaIndex[prefix]; - if (index == kInstAlphaIndexInvalid) + while (++prefix <= kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst) { + index = _x86InstAlphaIndex[prefix]; + if (index == kX86InstAlphaIndexInvalid) continue; - end = _instInfo + index; + end = _x86InstInfo + index; break; } if (linearSearch) { while (base != end) { - if (X86InstUtil_cmpName(base->getName(), name, len) == 0) - return static_cast((size_t)(base - _instInfo)); + if (X86Util_cmpInstName(base->getInstName(), name, len) == 0) + return static_cast((size_t)(base - _x86InstInfo)); base++; } } else { for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) { - const InstInfo* cur = base + (lim >> 1); - int result = X86InstUtil_cmpName(cur->getName(), name, len); + const X86InstInfo* cur = base + (lim >> 1); + int result = X86Util_cmpInstName(cur->getInstName(), name, len); if (result < 0) { base = cur + 1; @@ -3326,48 +4802,48 @@ uint32_t X86InstUtil::getInstIdByName(const char* name, size_t len) { if (result > 0) continue; - return static_cast((size_t)(cur - _instInfo)); + return static_cast((size_t)(cur - _x86InstInfo)); } } - return kInstNone; + return kInstIdNone; } -#endif // ASMJIT_DISABLE_INST_NAMES +#endif // ASMJIT_DISABLE_NAMES // ============================================================================ -// [asmjit::x86x64::X86Util - Test] +// [asmjit::X86Util - Test] // ============================================================================ -#if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_INST_NAMES) +#if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_NAMES) UNIT(x86_inst_name) { // All known instructions should be matched. - for (uint32_t a = 0; a < _kInstCount; a++) { - uint32_t b = X86InstUtil::getInstIdByName(_instInfo[a].getName()); + for (uint32_t a = 0; a < _kX86InstIdCount; a++) { + uint32_t b = X86Util::getInstIdByName(_x86InstInfo[a].getInstName()); EXPECT(a == b, "Should match existing instruction \"%s\" {id:%u} != \"%s\" {id:%u}.", - _instInfo[a].getName(), a, - _instInfo[b].getName(), b); + _x86InstInfo[a].getInstName(), a, + _x86InstInfo[b].getInstName(), b); } - // Everything else should return kInstNone - EXPECT(X86InstUtil::getInstIdByName(NULL) == kInstNone, - "Should return kInstNone for NULL input."); + // Everything else should return kInstIdNone + EXPECT(X86Util::getInstIdByName(NULL) == kInstIdNone, + "Should return kInstIdNone for NULL input."); - EXPECT(X86InstUtil::getInstIdByName("") == kInstNone, - "Should return kInstNone for empty string."); + EXPECT(X86Util::getInstIdByName("") == kInstIdNone, + "Should return kInstIdNone for empty string."); - EXPECT(X86InstUtil::getInstIdByName("_") == kInstNone, - "Should return kInstNone for unknown instruction."); + EXPECT(X86Util::getInstIdByName("_") == kInstIdNone, + "Should return kInstIdNone for unknown instruction."); - EXPECT(X86InstUtil::getInstIdByName("123xyz") == kInstNone, - "Should return kInstNone for unknown instruction."); + EXPECT(X86Util::getInstIdByName("123xyz") == kInstIdNone, + "Should return kInstIdNone for unknown instruction."); } -#endif // ASMJIT_TEST && !ASMJIT_DISABLE_INST_NAMES +#endif // ASMJIT_TEST && !ASMJIT_DISABLE_NAMES -} // x86x64 namespace } // asmjit namespace +// [Api-End] #include "../apiend.h" // [Guard] diff --git a/src/asmjit/x86/x86inst.h b/src/asmjit/x86/x86inst.h index 91b3c92..7112881 100644 --- a/src/asmjit/x86/x86inst.h +++ b/src/asmjit/x86/x86inst.h @@ -20,1093 +20,1138 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { // ============================================================================ // [Forward Declarations] // ============================================================================ -struct InstInfo; +struct X86InstInfo; +struct X86InstExtendedInfo; -//! \addtogroup asmjit_x86x64_inst +//! \addtogroup asmjit_x86_inst //! \{ // ============================================================================ -// [asmjit::x86x64::Inst/Cond - Globals] +// [asmjit::X86Inst/X86Cond - Globals] // ============================================================================ -#if !defined(ASMJIT_DISABLE_INST_NAMES) +#if !defined(ASMJIT_DISABLE_NAMES) //! \internal //! -//! X86/X64 instructions' names. -ASMJIT_VAR const char _instName[]; -#endif // !ASMJIT_DISABLE_INST_NAMES +//! 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 InstInfo _instInfo[]; +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::x86x64::kInstCode] +// [asmjit::kX86InstId] // ============================================================================ //! X86/X64 instruction codes. //! //! Note that these instruction codes are AsmJit specific. Each instruction has //! a unique ID that is used as an index to AsmJit instruction table. -ASMJIT_ENUM(kInstCode) { - kInstAdc = 1, // X86/X64 - kInstAdd, // X86/X64 - kInstAddpd, // SSE2 - kInstAddps, // SSE - kInstAddsd, // SSE2 - kInstAddss, // SSE - kInstAddsubpd, // SSE3 - kInstAddsubps, // SSE3 - kInstAesdec, // AESNI - kInstAesdeclast, // AESNI - kInstAesenc, // AESNI - kInstAesenclast, // AESNI - kInstAesimc, // AESNI - kInstAeskeygenassist, // AESNI - kInstAnd, // X86/X64 - kInstAndn, // BMI - kInstAndnpd, // SSE2 - kInstAndnps, // SSE - kInstAndpd, // SSE2 - kInstAndps, // SSE - kInstBextr, // BMI - kInstBlendpd, // SSE4.1 - kInstBlendps, // SSE4.1 - kInstBlendvpd, // SSE4.1 - kInstBlendvps, // SSE4.1 - kInstBlsi, // BMI - kInstBlsmsk, // BMI - kInstBlsr, // BMI - kInstBsf, // X86/X64 - kInstBsr, // X86/X64 - kInstBswap, // X86/X64 (i486) - kInstBt, // X86/X64 - kInstBtc, // X86/X64 - kInstBtr, // X86/X64 - kInstBts, // X86/X64 - kInstBzhi, // BMI2 - kInstCall, // X86/X64 - kInstCbw, // X86/X64 - kInstCdq, // X86/X64 - kInstCdqe, // X64 only - kInstClc, // X86/X64 - kInstCld, // X86/X64 - kInstClflush, // SSE2 - kInstCmc, // X86/X64 - kInstCmova, // X86/X64 (cmovcc) (i586) - kInstCmovae, // X86/X64 (cmovcc) (i586) - kInstCmovb, // X86/X64 (cmovcc) (i586) - kInstCmovbe, // X86/X64 (cmovcc) (i586) - kInstCmovc, // X86/X64 (cmovcc) (i586) - kInstCmove, // X86/X64 (cmovcc) (i586) - kInstCmovg, // X86/X64 (cmovcc) (i586) - kInstCmovge, // X86/X64 (cmovcc) (i586) - kInstCmovl, // X86/X64 (cmovcc) (i586) - kInstCmovle, // X86/X64 (cmovcc) (i586) - kInstCmovna, // X86/X64 (cmovcc) (i586) - kInstCmovnae, // X86/X64 (cmovcc) (i586) - kInstCmovnb, // X86/X64 (cmovcc) (i586) - kInstCmovnbe, // X86/X64 (cmovcc) (i586) - kInstCmovnc, // X86/X64 (cmovcc) (i586) - kInstCmovne, // X86/X64 (cmovcc) (i586) - kInstCmovng, // X86/X64 (cmovcc) (i586) - kInstCmovnge, // X86/X64 (cmovcc) (i586) - kInstCmovnl, // X86/X64 (cmovcc) (i586) - kInstCmovnle, // X86/X64 (cmovcc) (i586) - kInstCmovno, // X86/X64 (cmovcc) (i586) - kInstCmovnp, // X86/X64 (cmovcc) (i586) - kInstCmovns, // X86/X64 (cmovcc) (i586) - kInstCmovnz, // X86/X64 (cmovcc) (i586) - kInstCmovo, // X86/X64 (cmovcc) (i586) - kInstCmovp, // X86/X64 (cmovcc) (i586) - kInstCmovpe, // X86/X64 (cmovcc) (i586) - kInstCmovpo, // X86/X64 (cmovcc) (i586) - kInstCmovs, // X86/X64 (cmovcc) (i586) - kInstCmovz, // X86/X64 (cmovcc) (i586) - kInstCmp, // X86/X64 - kInstCmppd, // SSE2 - kInstCmpps, // SSE - kInstCmpsd, // SSE2 - kInstCmpss, // SSE - kInstCmpxchg, // X86/X64 (i486) - kInstCmpxchg16b, // X64 only - kInstCmpxchg8b, // X86/X64 (i586) - kInstComisd, // SSE2 - kInstComiss, // SSE - kInstCpuid, // X86/X64 (i486) - kInstCqo, // X64 only - kInstCrc32, // SSE4.2 - kInstCvtdq2pd, // SSE2 - kInstCvtdq2ps, // SSE2 - kInstCvtpd2dq, // SSE2 - kInstCvtpd2pi, // SSE2 - kInstCvtpd2ps, // SSE2 - kInstCvtpi2pd, // SSE2 - kInstCvtpi2ps, // SSE - kInstCvtps2dq, // SSE2 - kInstCvtps2pd, // SSE2 - kInstCvtps2pi, // SSE - kInstCvtsd2si, // SSE2 - kInstCvtsd2ss, // SSE2 - kInstCvtsi2sd, // SSE2 - kInstCvtsi2ss, // SSE - kInstCvtss2sd, // SSE2 - kInstCvtss2si, // SSE - kInstCvttpd2dq, // SSE2 - kInstCvttpd2pi, // SSE2 - kInstCvttps2dq, // SSE2 - kInstCvttps2pi, // SSE - kInstCvttsd2si, // SSE2 - kInstCvttss2si, // SSE - kInstCwd, // X86/X64 - kInstCwde, // X86/X64 - kInstDaa, // X86 only - kInstDas, // X86 only - kInstDec, // X86/X64 - kInstDiv, // X86/X64 - kInstDivpd, // SSE2 - kInstDivps, // SSE - kInstDivsd, // SSE2 - kInstDivss, // SSE - kInstDppd, // SSE4.1 - kInstDpps, // SSE4.1 - kInstEmms, // MMX - kInstEnter, // X86/X64 - kInstExtractps, // SSE4.1 - kInstF2xm1, // FPU - kInstFabs, // FPU - kInstFadd, // FPU - kInstFaddp, // FPU - kInstFbld, // FPU - kInstFbstp, // FPU - kInstFchs, // FPU - kInstFclex, // FPU - kInstFcmovb, // FPU - kInstFcmovbe, // FPU - kInstFcmove, // FPU - kInstFcmovnb, // FPU - kInstFcmovnbe, // FPU - kInstFcmovne, // FPU - kInstFcmovnu, // FPU - kInstFcmovu, // FPU - kInstFcom, // FPU - kInstFcomi, // FPU - kInstFcomip, // FPU - kInstFcomp, // FPU - kInstFcompp, // FPU - kInstFcos, // FPU - kInstFdecstp, // FPU - kInstFdiv, // FPU - kInstFdivp, // FPU - kInstFdivr, // FPU - kInstFdivrp, // FPU - kInstFemms, // 3dNow! - kInstFfree, // FPU - kInstFiadd, // FPU - kInstFicom, // FPU - kInstFicomp, // FPU - kInstFidiv, // FPU - kInstFidivr, // FPU - kInstFild, // FPU - kInstFimul, // FPU - kInstFincstp, // FPU - kInstFinit, // FPU - kInstFist, // FPU - kInstFistp, // FPU - kInstFisttp, // SSE3 - kInstFisub, // FPU - kInstFisubr, // FPU - kInstFld, // FPU - kInstFld1, // FPU - kInstFldcw, // FPU - kInstFldenv, // FPU - kInstFldl2e, // FPU - kInstFldl2t, // FPU - kInstFldlg2, // FPU - kInstFldln2, // FPU - kInstFldpi, // FPU - kInstFldz, // FPU - kInstFmul, // FPU - kInstFmulp, // FPU - kInstFnclex, // FPU - kInstFninit, // FPU - kInstFnop, // FPU - kInstFnsave, // FPU - kInstFnstcw, // FPU - kInstFnstenv, // FPU - kInstFnstsw, // FPU - kInstFpatan, // FPU - kInstFprem, // FPU - kInstFprem1, // FPU - kInstFptan, // FPU - kInstFrndint, // FPU - kInstFrstor, // FPU - kInstFsave, // FPU - kInstFscale, // FPU - kInstFsin, // FPU - kInstFsincos, // FPU - kInstFsqrt, // FPU - kInstFst, // FPU - kInstFstcw, // FPU - kInstFstenv, // FPU - kInstFstp, // FPU - kInstFstsw, // FPU - kInstFsub, // FPU - kInstFsubp, // FPU - kInstFsubr, // FPU - kInstFsubrp, // FPU - kInstFtst, // FPU - kInstFucom, // FPU - kInstFucomi, // FPU - kInstFucomip, // FPU - kInstFucomp, // FPU - kInstFucompp, // FPU - kInstFwait, // FPU - kInstFxam, // FPU - kInstFxch, // FPU - kInstFxrstor, // FPU - kInstFxsave, // FPU - kInstFxtract, // FPU - kInstFyl2x, // FPU - kInstFyl2xp1, // FPU - kInstHaddpd, // SSE3 - kInstHaddps, // SSE3 - kInstHsubpd, // SSE3 - kInstHsubps, // SSE3 - kInstIdiv, // X86/X64 - kInstImul, // X86/X64 - kInstInc, // X86/X64 - kInstInsertps, // SSE4.1 - kInstInt, // X86/X64 - kInstJa, // X86/X64 (jcc) - kInstJae, // X86/X64 (jcc) - kInstJb, // X86/X64 (jcc) - kInstJbe, // X86/X64 (jcc) - kInstJc, // X86/X64 (jcc) - kInstJe, // X86/X64 (jcc) - kInstJg, // X86/X64 (jcc) - kInstJge, // X86/X64 (jcc) - kInstJl, // X86/X64 (jcc) - kInstJle, // X86/X64 (jcc) - kInstJna, // X86/X64 (jcc) - kInstJnae, // X86/X64 (jcc) - kInstJnb, // X86/X64 (jcc) - kInstJnbe, // X86/X64 (jcc) - kInstJnc, // X86/X64 (jcc) - kInstJne, // X86/X64 (jcc) - kInstJng, // X86/X64 (jcc) - kInstJnge, // X86/X64 (jcc) - kInstJnl, // X86/X64 (jcc) - kInstJnle, // X86/X64 (jcc) - kInstJno, // X86/X64 (jcc) - kInstJnp, // X86/X64 (jcc) - kInstJns, // X86/X64 (jcc) - kInstJnz, // X86/X64 (jcc) - kInstJo, // X86/X64 (jcc) - kInstJp, // X86/X64 (jcc) - kInstJpe, // X86/X64 (jcc) - kInstJpo, // X86/X64 (jcc) - kInstJs, // X86/X64 (jcc) - kInstJz, // X86/X64 (jcc) - kInstJecxz, // X86/X64 (jcxz/jecxz/jrcxz) - kInstJmp, // X86/X64 (jmp) - kInstLahf, // X86/X64 (CPUID NEEDED) - kInstLddqu, // SSE3 - kInstLdmxcsr, // SSE - kInstLea, // X86/X64 - kInstLeave, // X86/X64 - kInstLfence, // SSE2 - kInstLzcnt, // LZCNT - kInstMaskmovdqu, // SSE2 - kInstMaskmovq, // MMX-Ext - kInstMaxpd, // SSE2 - kInstMaxps, // SSE - kInstMaxsd, // SSE2 - kInstMaxss, // SSE - kInstMfence, // SSE2 - kInstMinpd, // SSE2 - kInstMinps, // SSE - kInstMinsd, // SSE2 - kInstMinss, // SSE - kInstMonitor, // SSE3 - kInstMov, // X86/X64 - kInstMovPtr, // X86/X64 - kInstMovapd, // SSE2 - kInstMovaps, // SSE - kInstMovbe, // SSE3 - Intel-Atom - kInstMovd, // MMX/SSE2 - kInstMovddup, // SSE3 - kInstMovdq2q, // SSE2 - kInstMovdqa, // SSE2 - kInstMovdqu, // SSE2 - kInstMovhlps, // SSE - kInstMovhpd, // SSE2 - kInstMovhps, // SSE - kInstMovlhps, // SSE - kInstMovlpd, // SSE2 - kInstMovlps, // SSE - kInstMovmskpd, // SSE2 - kInstMovmskps, // SSE2 - kInstMovntdq, // SSE2 - kInstMovntdqa, // SSE4.1 - kInstMovnti, // SSE2 - kInstMovntpd, // SSE2 - kInstMovntps, // SSE - kInstMovntq, // MMX-Ext - kInstMovq, // MMX/SSE/SSE2 - kInstMovq2dq, // SSE2 - kInstMovsd, // SSE2 - kInstMovshdup, // SSE3 - kInstMovsldup, // SSE3 - kInstMovss, // SSE - kInstMovsx, // X86/X64 - kInstMovsxd, // X86/X64 - kInstMovupd, // SSE2 - kInstMovups, // SSE - kInstMovzx, // X86/X64 - kInstMpsadbw, // SSE4.1 - kInstMul, // X86/X64 - kInstMulpd, // SSE2 - kInstMulps, // SSE - kInstMulsd, // SSE2 - kInstMulss, // SSE - kInstMulx, // BMI2 - kInstMwait, // SSE3 - kInstNeg, // X86/X64 - kInstNop, // X86/X64 - kInstNot, // X86/X64 - kInstOr, // X86/X64 - kInstOrpd, // SSE2 - kInstOrps, // SSE - kInstPabsb, // SSSE3 - kInstPabsd, // SSSE3 - kInstPabsw, // SSSE3 - kInstPackssdw, // MMX/SSE2 - kInstPacksswb, // MMX/SSE2 - kInstPackusdw, // SSE4.1 - kInstPackuswb, // MMX/SSE2 - kInstPaddb, // MMX/SSE2 - kInstPaddd, // MMX/SSE2 - kInstPaddq, // SSE2 - kInstPaddsb, // MMX/SSE2 - kInstPaddsw, // MMX/SSE2 - kInstPaddusb, // MMX/SSE2 - kInstPaddusw, // MMX/SSE2 - kInstPaddw, // MMX/SSE2 - kInstPalignr, // SSSE3 - kInstPand, // MMX/SSE2 - kInstPandn, // MMX/SSE2 - kInstPause, // SSE2. - kInstPavgb, // MMX-Ext - kInstPavgw, // MMX-Ext - kInstPblendvb, // SSE4.1 - kInstPblendw, // SSE4.1 - kInstPclmulqdq, // PCLMULQDQ - kInstPcmpeqb, // MMX/SSE2 - kInstPcmpeqd, // MMX/SSE2 - kInstPcmpeqq, // SSE4.1 - kInstPcmpeqw, // MMX/SSE2 - kInstPcmpestri, // SSE4.2 - kInstPcmpestrm, // SSE4.2 - kInstPcmpgtb, // MMX/SSE2 - kInstPcmpgtd, // MMX/SSE2 - kInstPcmpgtq, // SSE4.2 - kInstPcmpgtw, // MMX/SSE2 - kInstPcmpistri, // SSE4.2 - kInstPcmpistrm, // SSE4.2 - kInstPdep, // BMI2 - kInstPext, // BMI2 - kInstPextrb, // SSE4.1 - kInstPextrd, // SSE4.1 - kInstPextrq, // SSE4.1 - kInstPextrw, // MMX-Ext/SSE2 - kInstPf2id, // 3dNow! - kInstPf2iw, // Enhanced 3dNow! - kInstPfacc, // 3dNow! - kInstPfadd, // 3dNow! - kInstPfcmpeq, // 3dNow! - kInstPfcmpge, // 3dNow! - kInstPfcmpgt, // 3dNow! - kInstPfmax, // 3dNow! - kInstPfmin, // 3dNow! - kInstPfmul, // 3dNow! - kInstPfnacc, // Enhanced 3dNow! - kInstPfpnacc, // Enhanced 3dNow! - kInstPfrcp, // 3dNow! - kInstPfrcpit1, // 3dNow! - kInstPfrcpit2, // 3dNow! - kInstPfrsqit1, // 3dNow! - kInstPfrsqrt, // 3dNow! - kInstPfsub, // 3dNow! - kInstPfsubr, // 3dNow! - kInstPhaddd, // SSSE3 - kInstPhaddsw, // SSSE3 - kInstPhaddw, // SSSE3 - kInstPhminposuw, // SSE4.1 - kInstPhsubd, // SSSE3 - kInstPhsubsw, // SSSE3 - kInstPhsubw, // SSSE3 - kInstPi2fd, // 3dNow! - kInstPi2fw, // Enhanced 3dNow! - kInstPinsrb, // SSE4.1 - kInstPinsrd, // SSE4.1 - kInstPinsrq, // SSE4.1 - kInstPinsrw, // MMX-Ext - kInstPmaddubsw, // SSSE3 - kInstPmaddwd, // MMX/SSE2 - kInstPmaxsb, // SSE4.1 - kInstPmaxsd, // SSE4.1 - kInstPmaxsw, // MMX-Ext - kInstPmaxub, // MMX-Ext - kInstPmaxud, // SSE4.1 - kInstPmaxuw, // SSE4.1 - kInstPminsb, // SSE4.1 - kInstPminsd, // SSE4.1 - kInstPminsw, // MMX-Ext - kInstPminub, // MMX-Ext - kInstPminud, // SSE4.1 - kInstPminuw, // SSE4.1 - kInstPmovmskb, // MMX-Ext - kInstPmovsxbd, // SSE4.1 - kInstPmovsxbq, // SSE4.1 - kInstPmovsxbw, // SSE4.1 - kInstPmovsxdq, // SSE4.1 - kInstPmovsxwd, // SSE4.1 - kInstPmovsxwq, // SSE4.1 - kInstPmovzxbd, // SSE4.1 - kInstPmovzxbq, // SSE4.1 - kInstPmovzxbw, // SSE4.1 - kInstPmovzxdq, // SSE4.1 - kInstPmovzxwd, // SSE4.1 - kInstPmovzxwq, // SSE4.1 - kInstPmuldq, // SSE4.1 - kInstPmulhrsw, // SSSE3 - kInstPmulhuw, // MMX-Ext - kInstPmulhw, // MMX/SSE2 - kInstPmulld, // SSE4.1 - kInstPmullw, // MMX/SSE2 - kInstPmuludq, // SSE2 - kInstPop, // X86/X64 - kInstPopa, // X86 only - kInstPopcnt, // SSE4.2 - kInstPopf, // X86/X64 - kInstPor, // MMX/SSE2 - kInstPrefetch, // MMX-Ext/SSE - kInstPrefetch3dNow, // 3dNow! - kInstPrefetchw3dNow, // 3dNow! - kInstPsadbw, // MMX-Ext - kInstPshufb, // SSSE3 - kInstPshufd, // SSE2 - kInstPshufhw, // SSE2 - kInstPshuflw, // SSE2 - kInstPshufw, // MMX-Ext - kInstPsignb, // SSSE3 - kInstPsignd, // SSSE3 - kInstPsignw, // SSSE3 - kInstPslld, // MMX/SSE2 - kInstPslldq, // SSE2 - kInstPsllq, // MMX/SSE2 - kInstPsllw, // MMX/SSE2 - kInstPsrad, // MMX/SSE2 - kInstPsraw, // MMX/SSE2 - kInstPsrld, // MMX/SSE2 - kInstPsrldq, // SSE2 - kInstPsrlq, // MMX/SSE2 - kInstPsrlw, // MMX/SSE2 - kInstPsubb, // MMX/SSE2 - kInstPsubd, // MMX/SSE2 - kInstPsubq, // SSE2 - kInstPsubsb, // MMX/SSE2 - kInstPsubsw, // MMX/SSE2 - kInstPsubusb, // MMX/SSE2 - kInstPsubusw, // MMX/SSE2 - kInstPsubw, // MMX/SSE2 - kInstPswapd, // Enhanced 3dNow! - kInstPtest, // SSE4.1 - kInstPunpckhbw, // MMX/SSE2 - kInstPunpckhdq, // MMX/SSE2 - kInstPunpckhqdq, // SSE2 - kInstPunpckhwd, // MMX/SSE2 - kInstPunpcklbw, // MMX/SSE2 - kInstPunpckldq, // MMX/SSE2 - kInstPunpcklqdq, // SSE2 - kInstPunpcklwd, // MMX/SSE2 - kInstPush, // X86/X64 - kInstPusha, // X86 only - kInstPushf, // X86/X64 - kInstPxor, // MMX/SSE2 - kInstRcl, // X86/X64 - kInstRcpps, // SSE - kInstRcpss, // SSE - kInstRcr, // X86/X64 - kInstRdfsbase, // FSGSBASE (x64) - kInstRdgsbase, // FSGSBASE (x64) - kInstRdrand, // RDRAND - kInstRdtsc, // X86/X64 - kInstRdtscp, // X86/X64 - kInstRepLodsb, // X86/X64 (REP) - kInstRepLodsd, // X86/X64 (REP) - kInstRepLodsq, // X64 only (REP) - kInstRepLodsw, // X86/X64 (REP) - kInstRepMovsb, // X86/X64 (REP) - kInstRepMovsd, // X86/X64 (REP) - kInstRepMovsq, // X64 only (REP) - kInstRepMovsw, // X86/X64 (REP) - kInstRepStosb, // X86/X64 (REP) - kInstRepStosd, // X86/X64 (REP) - kInstRepStosq, // X64 only (REP) - kInstRepStosw, // X86/X64 (REP) - kInstRepeCmpsb, // X86/X64 (REP) - kInstRepeCmpsd, // X86/X64 (REP) - kInstRepeCmpsq, // X64 only (REP) - kInstRepeCmpsw, // X86/X64 (REP) - kInstRepeScasb, // X86/X64 (REP) - kInstRepeScasd, // X86/X64 (REP) - kInstRepeScasq, // X64 only (REP) - kInstRepeScasw, // X86/X64 (REP) - kInstRepneCmpsb, // X86/X64 (REP) - kInstRepneCmpsd, // X86/X64 (REP) - kInstRepneCmpsq, // X64 only (REP) - kInstRepneCmpsw, // X86/X64 (REP) - kInstRepneScasb, // X86/X64 (REP) - kInstRepneScasd, // X86/X64 (REP) - kInstRepneScasq, // X64 only (REP) - kInstRepneScasw, // X86/X64 (REP) - kInstRet, // X86/X64 - kInstRol, // X86/X64 - kInstRor, // X86/X64 - kInstRorx, // BMI2 - kInstRoundpd, // SSE4.1 - kInstRoundps, // SSE4.1 - kInstRoundsd, // SSE4.1 - kInstRoundss, // SSE4.1 - kInstRsqrtps, // SSE - kInstRsqrtss, // SSE - kInstSahf, // X86/X64 (CPUID NEEDED) - kInstSal, // X86/X64 - kInstSar, // X86/X64 - kInstSarx, // BMI2 - kInstSbb, // X86/X64 - kInstSeta, // X86/X64 (setcc) - kInstSetae, // X86/X64 (setcc) - kInstSetb, // X86/X64 (setcc) - kInstSetbe, // X86/X64 (setcc) - kInstSetc, // X86/X64 (setcc) - kInstSete, // X86/X64 (setcc) - kInstSetg, // X86/X64 (setcc) - kInstSetge, // X86/X64 (setcc) - kInstSetl, // X86/X64 (setcc) - kInstSetle, // X86/X64 (setcc) - kInstSetna, // X86/X64 (setcc) - kInstSetnae, // X86/X64 (setcc) - kInstSetnb, // X86/X64 (setcc) - kInstSetnbe, // X86/X64 (setcc) - kInstSetnc, // X86/X64 (setcc) - kInstSetne, // X86/X64 (setcc) - kInstSetng, // X86/X64 (setcc) - kInstSetnge, // X86/X64 (setcc) - kInstSetnl, // X86/X64 (setcc) - kInstSetnle, // X86/X64 (setcc) - kInstSetno, // X86/X64 (setcc) - kInstSetnp, // X86/X64 (setcc) - kInstSetns, // X86/X64 (setcc) - kInstSetnz, // X86/X64 (setcc) - kInstSeto, // X86/X64 (setcc) - kInstSetp, // X86/X64 (setcc) - kInstSetpe, // X86/X64 (setcc) - kInstSetpo, // X86/X64 (setcc) - kInstSets, // X86/X64 (setcc) - kInstSetz, // X86/X64 (setcc) - kInstSfence, // MMX-Ext/SSE - kInstShl, // X86/X64 - kInstShld, // X86/X64 - kInstShlx, // BMI2 - kInstShr, // X86/X64 - kInstShrd, // X86/X64 - kInstShrx, // BMI2 - kInstShufpd, // SSE2 - kInstShufps, // SSE - kInstSqrtpd, // SSE2 - kInstSqrtps, // SSE - kInstSqrtsd, // SSE2 - kInstSqrtss, // SSE - kInstStc, // X86/X64 - kInstStd, // X86/X64 - kInstStmxcsr, // SSE - kInstSub, // X86/X64 - kInstSubpd, // SSE2 - kInstSubps, // SSE - kInstSubsd, // SSE2 - kInstSubss, // SSE - kInstTest, // X86/X64 - kInstTzcnt, // TZCNT - kInstUcomisd, // SSE2 - kInstUcomiss, // SSE - kInstUd2, // X86/X64 - kInstUnpckhpd, // SSE2 - kInstUnpckhps, // SSE - kInstUnpcklpd, // SSE2 - kInstUnpcklps, // SSE - kInstVaddpd, // AVX - kInstVaddps, // AVX - kInstVaddsd, // AVX - kInstVaddss, // AVX - kInstVaddsubpd, // AVX - kInstVaddsubps, // AVX - kInstVaesdec, // AVX+AESNI - kInstVaesdeclast, // AVX+AESNI - kInstVaesenc, // AVX+AESNI - kInstVaesenclast, // AVX+AESNI - kInstVaesimc, // AVX+AESNI - kInstVaeskeygenassist,// AVX+AESNI - kInstVandnpd, // AVX - kInstVandnps, // AVX - kInstVandpd, // AVX - kInstVandps, // AVX - kInstVblendpd, // AVX - kInstVblendps, // AVX - kInstVblendvpd, // AVX - kInstVblendvps, // AVX - kInstVbroadcastf128, // AVX - kInstVbroadcasti128, // AVX2 - kInstVbroadcastsd, // AVX/AVX2 - kInstVbroadcastss, // AVX/AVX2 - kInstVcmppd, // AVX - kInstVcmpps, // AVX - kInstVcmpsd, // AVX - kInstVcmpss, // AVX - kInstVcomisd, // AVX - kInstVcomiss, // AVX - kInstVcvtdq2pd, // AVX - kInstVcvtdq2ps, // AVX - kInstVcvtpd2dq, // AVX - kInstVcvtpd2ps, // AVX - kInstVcvtph2ps, // F16C - kInstVcvtps2dq, // AVX - kInstVcvtps2pd, // AVX - kInstVcvtps2ph, // F16C - kInstVcvtsd2si, // AVX - kInstVcvtsd2ss, // AVX - kInstVcvtsi2sd, // AVX - kInstVcvtsi2ss, // AVX - kInstVcvtss2sd, // AVX - kInstVcvtss2si, // AVX - kInstVcvttpd2dq, // AVX - kInstVcvttps2dq, // AVX - kInstVcvttsd2si, // AVX - kInstVcvttss2si, // AVX - kInstVdivpd, // AVX - kInstVdivps, // AVX - kInstVdivsd, // AVX - kInstVdivss, // AVX - kInstVdppd, // AVX - kInstVdpps, // AVX - kInstVextractf128, // AVX - kInstVextracti128, // AVX2 - kInstVextractps, // AVX - kInstVfmadd132pd, // FMA3 - kInstVfmadd132ps, // FMA3 - kInstVfmadd132sd, // FMA3 - kInstVfmadd132ss, // FMA3 - kInstVfmadd213pd, // FMA3 - kInstVfmadd213ps, // FMA3 - kInstVfmadd213sd, // FMA3 - kInstVfmadd213ss, // FMA3 - kInstVfmadd231pd, // FMA3 - kInstVfmadd231ps, // FMA3 - kInstVfmadd231sd, // FMA3 - kInstVfmadd231ss, // FMA3 - kInstVfmaddpd, // FMA4 - kInstVfmaddps, // FMA4 - kInstVfmaddsd, // FMA4 - kInstVfmaddss, // FMA4 - kInstVfmaddsub132pd, // FMA3 - kInstVfmaddsub132ps, // FMA3 - kInstVfmaddsub213pd, // FMA3 - kInstVfmaddsub213ps, // FMA3 - kInstVfmaddsub231pd, // FMA3 - kInstVfmaddsub231ps, // FMA3 - kInstVfmaddsubpd, // FMA4 - kInstVfmaddsubps, // FMA4 - kInstVfmsub132pd, // FMA3 - kInstVfmsub132ps, // FMA3 - kInstVfmsub132sd, // FMA3 - kInstVfmsub132ss, // FMA3 - kInstVfmsub213pd, // FMA3 - kInstVfmsub213ps, // FMA3 - kInstVfmsub213sd, // FMA3 - kInstVfmsub213ss, // FMA3 - kInstVfmsub231pd, // FMA3 - kInstVfmsub231ps, // FMA3 - kInstVfmsub231sd, // FMA3 - kInstVfmsub231ss, // FMA3 - kInstVfmsubadd132pd, // FMA3 - kInstVfmsubadd132ps, // FMA3 - kInstVfmsubadd213pd, // FMA3 - kInstVfmsubadd213ps, // FMA3 - kInstVfmsubadd231pd, // FMA3 - kInstVfmsubadd231ps, // FMA3 - kInstVfmsubaddpd, // FMA4 - kInstVfmsubaddps, // FMA4 - kInstVfmsubpd, // FMA4 - kInstVfmsubps, // FMA4 - kInstVfmsubsd, // FMA4 - kInstVfmsubss, // FMA4 - kInstVfnmadd132pd, // FMA3 - kInstVfnmadd132ps, // FMA3 - kInstVfnmadd132sd, // FMA3 - kInstVfnmadd132ss, // FMA3 - kInstVfnmadd213pd, // FMA3 - kInstVfnmadd213ps, // FMA3 - kInstVfnmadd213sd, // FMA3 - kInstVfnmadd213ss, // FMA3 - kInstVfnmadd231pd, // FMA3 - kInstVfnmadd231ps, // FMA3 - kInstVfnmadd231sd, // FMA3 - kInstVfnmadd231ss, // FMA3 - kInstVfnmaddpd, // FMA4 - kInstVfnmaddps, // FMA4 - kInstVfnmaddsd, // FMA4 - kInstVfnmaddss, // FMA4 - kInstVfnmsub132pd, // FMA3 - kInstVfnmsub132ps, // FMA3 - kInstVfnmsub132sd, // FMA3 - kInstVfnmsub132ss, // FMA3 - kInstVfnmsub213pd, // FMA3 - kInstVfnmsub213ps, // FMA3 - kInstVfnmsub213sd, // FMA3 - kInstVfnmsub213ss, // FMA3 - kInstVfnmsub231pd, // FMA3 - kInstVfnmsub231ps, // FMA3 - kInstVfnmsub231sd, // FMA3 - kInstVfnmsub231ss, // FMA3 - kInstVfnmsubpd, // FMA4 - kInstVfnmsubps, // FMA4 - kInstVfnmsubsd, // FMA4 - kInstVfnmsubss, // FMA4 - kInstVfrczpd, // XOP - kInstVfrczps, // XOP - kInstVfrczsd, // XOP - kInstVfrczss, // XOP - kInstVgatherdpd, // AVX2 - kInstVgatherdps, // AVX2 - kInstVgatherqpd, // AVX2 - kInstVgatherqps, // AVX2 - kInstVhaddpd, // AVX - kInstVhaddps, // AVX - kInstVhsubpd, // AVX - kInstVhsubps, // AVX - kInstVinsertf128, // AVX - kInstVinserti128, // AVX2 - kInstVinsertps, // AVX - kInstVlddqu, // AVX - kInstVldmxcsr, // AVX - kInstVmaskmovdqu, // AVX - kInstVmaskmovpd, // AVX - kInstVmaskmovps, // AVX - kInstVmaxpd, // AVX - kInstVmaxps, // AVX - kInstVmaxsd, // AVX - kInstVmaxss, // AVX - kInstVminpd, // AVX - kInstVminps, // AVX - kInstVminsd, // AVX - kInstVminss, // AVX - kInstVmovapd, // AVX - kInstVmovaps, // AVX - kInstVmovd, // AVX - kInstVmovddup, // AVX - kInstVmovdqa, // AVX - kInstVmovdqu, // AVX - kInstVmovhlps, // AVX - kInstVmovhpd, // AVX - kInstVmovhps, // AVX - kInstVmovlhps, // AVX - kInstVmovlpd, // AVX - kInstVmovlps, // AVX - kInstVmovmskpd, // AVX - kInstVmovmskps, // AVX - kInstVmovntdq, // AVX - kInstVmovntdqa, // AVX/AVX2 - kInstVmovntpd, // AVX - kInstVmovntps, // AVX - kInstVmovq, // AVX - kInstVmovsd, // AVX - kInstVmovshdup, // AVX - kInstVmovsldup, // AVX - kInstVmovss, // AVX - kInstVmovupd, // AVX - kInstVmovups, // AVX - kInstVmpsadbw, // AVX/AVX2 - kInstVmulpd, // AVX - kInstVmulps, // AVX - kInstVmulsd, // AVX - kInstVmulss, // AVX - kInstVorpd, // AVX - kInstVorps, // AVX - kInstVpabsb, // AVX2 - kInstVpabsd, // AVX2 - kInstVpabsw, // AVX2 - kInstVpackssdw, // AVX2 - kInstVpacksswb, // AVX2 - kInstVpackusdw, // AVX2 - kInstVpackuswb, // AVX2 - kInstVpaddb, // AVX2 - kInstVpaddd, // AVX2 - kInstVpaddq, // AVX2 - kInstVpaddsb, // AVX2 - kInstVpaddsw, // AVX2 - kInstVpaddusb, // AVX2 - kInstVpaddusw, // AVX2 - kInstVpaddw, // AVX2 - kInstVpalignr, // AVX2 - kInstVpand, // AVX2 - kInstVpandn, // AVX2 - kInstVpavgb, // AVX2 - kInstVpavgw, // AVX2 - kInstVpblendd, // AVX2 - kInstVpblendvb, // AVX2 - kInstVpblendw, // AVX2 - kInstVpbroadcastb, // AVX2 - kInstVpbroadcastd, // AVX2 - kInstVpbroadcastq, // AVX2 - kInstVpbroadcastw, // AVX2 - kInstVpclmulqdq, // AVX+PCLMULQDQ - kInstVpcmov, // XOP - kInstVpcmpeqb, // AVX2 - kInstVpcmpeqd, // AVX2 - kInstVpcmpeqq, // AVX2 - kInstVpcmpeqw, // AVX2 - kInstVpcmpestri, // AVX - kInstVpcmpestrm, // AVX - kInstVpcmpgtb, // AVX2 - kInstVpcmpgtd, // AVX2 - kInstVpcmpgtq, // AVX2 - kInstVpcmpgtw, // AVX2 - kInstVpcmpistri, // AVX - kInstVpcmpistrm, // AVX - kInstVpcomb, // XOP - kInstVpcomd, // XOP - kInstVpcomq, // XOP - kInstVpcomub, // XOP - kInstVpcomud, // XOP - kInstVpcomuq, // XOP - kInstVpcomuw, // XOP - kInstVpcomw, // XOP - kInstVperm2f128, // AVX - kInstVperm2i128, // AVX2 - kInstVpermd, // AVX2 - kInstVpermil2pd, // XOP - kInstVpermil2ps, // XOP - kInstVpermilpd, // AVX - kInstVpermilps, // AVX - kInstVpermpd, // AVX2 - kInstVpermps, // AVX2 - kInstVpermq, // AVX2 - kInstVpextrb, // AVX - kInstVpextrd, // AVX - kInstVpextrq, // AVX (x64 only) - kInstVpextrw, // AVX - kInstVpgatherdd, // AVX2 - kInstVpgatherdq, // AVX2 - kInstVpgatherqd, // AVX2 - kInstVpgatherqq, // AVX2 - kInstVphaddbd, // XOP - kInstVphaddbq, // XOP - kInstVphaddbw, // XOP - kInstVphaddd, // AVX2 - kInstVphadddq, // XOP - kInstVphaddsw, // AVX2 - kInstVphaddubd, // XOP - kInstVphaddubq, // XOP - kInstVphaddubw, // XOP - kInstVphaddudq, // XOP - kInstVphadduwd, // XOP - kInstVphadduwq, // XOP - kInstVphaddw, // AVX2 - kInstVphaddwd, // XOP - kInstVphaddwq, // XOP - kInstVphminposuw, // AVX - kInstVphsubbw, // XOP - kInstVphsubd, // AVX2 - kInstVphsubdq, // XOP - kInstVphsubsw, // AVX2 - kInstVphsubw, // AVX2 - kInstVphsubwd, // XOP - kInstVpinsrb, // AVX - kInstVpinsrd, // AVX - kInstVpinsrq, // AVX (x64 only) - kInstVpinsrw, // AVX - kInstVpmacsdd, // XOP - kInstVpmacsdqh, // XOP - kInstVpmacsdql, // XOP - kInstVpmacssdd, // XOP - kInstVpmacssdqh, // XOP - kInstVpmacssdql, // XOP - kInstVpmacsswd, // XOP - kInstVpmacssww, // XOP - kInstVpmacswd, // XOP - kInstVpmacsww, // XOP - kInstVpmadcsswd, // XOP - kInstVpmadcswd, // XOP - kInstVpmaddubsw, // AVX/AVX2 - kInstVpmaddwd, // AVX/AVX2 - kInstVpmaskmovd, // AVX2 - kInstVpmaskmovq, // AVX2 - kInstVpmaxsb, // AVX/AVX2 - kInstVpmaxsd, // AVX/AVX2 - kInstVpmaxsw, // AVX/AVX2 - kInstVpmaxub, // AVX/AVX2 - kInstVpmaxud, // AVX/AVX2 - kInstVpmaxuw, // AVX/AVX2 - kInstVpminsb, // AVX/AVX2 - kInstVpminsd, // AVX/AVX2 - kInstVpminsw, // AVX/AVX2 - kInstVpminub, // AVX/AVX2 - kInstVpminud, // AVX/AVX2 - kInstVpminuw, // AVX/AVX2 - kInstVpmovmskb, // AVX/AVX2 - kInstVpmovsxbd, // AVX/AVX2 - kInstVpmovsxbq, // AVX/AVX2 - kInstVpmovsxbw, // AVX/AVX2 - kInstVpmovsxdq, // AVX/AVX2 - kInstVpmovsxwd, // AVX/AVX2 - kInstVpmovsxwq, // AVX/AVX2 - kInstVpmovzxbd, // AVX/AVX2 - kInstVpmovzxbq, // AVX/AVX2 - kInstVpmovzxbw, // AVX/AVX2 - kInstVpmovzxdq, // AVX/AVX2 - kInstVpmovzxwd, // AVX/AVX2 - kInstVpmovzxwq, // AVX/AVX2 - kInstVpmuldq, // AVX/AVX2 - kInstVpmulhrsw, // AVX/AVX2 - kInstVpmulhuw, // AVX/AVX2 - kInstVpmulhw, // AVX/AVX2 - kInstVpmulld, // AVX/AVX2 - kInstVpmullw, // AVX/AVX2 - kInstVpmuludq, // AVX/AVX2 - kInstVpor, // AVX/AVX2 - kInstVpperm, // XOP - kInstVprotb, // XOP - kInstVprotd, // XOP - kInstVprotq, // XOP - kInstVprotw, // XOP - kInstVpsadbw, // AVX/AVX2 - kInstVpshab, // XOP - kInstVpshad, // XOP - kInstVpshaq, // XOP - kInstVpshaw, // XOP - kInstVpshlb, // XOP - kInstVpshld, // XOP - kInstVpshlq, // XOP - kInstVpshlw, // XOP - kInstVpshufb, // AVX/AVX2 - kInstVpshufd, // AVX/AVX2 - kInstVpshufhw, // AVX/AVX2 - kInstVpshuflw, // AVX/AVX2 - kInstVpsignb, // AVX/AVX2 - kInstVpsignd, // AVX/AVX2 - kInstVpsignw, // AVX/AVX2 - kInstVpslld, // AVX/AVX2 - kInstVpslldq, // AVX/AVX2 - kInstVpsllq, // AVX/AVX2 - kInstVpsllvd, // AVX2 - kInstVpsllvq, // AVX2 - kInstVpsllw, // AVX/AVX2 - kInstVpsrad, // AVX/AVX2 - kInstVpsravd, // AVX2 - kInstVpsraw, // AVX/AVX2 - kInstVpsrld, // AVX/AVX2 - kInstVpsrldq, // AVX/AVX2 - kInstVpsrlq, // AVX/AVX2 - kInstVpsrlvd, // AVX2 - kInstVpsrlvq, // AVX2 - kInstVpsrlw, // AVX/AVX2 - kInstVpsubb, // AVX/AVX2 - kInstVpsubd, // AVX/AVX2 - kInstVpsubq, // AVX/AVX2 - kInstVpsubsb, // AVX/AVX2 - kInstVpsubsw, // AVX/AVX2 - kInstVpsubusb, // AVX/AVX2 - kInstVpsubusw, // AVX/AVX2 - kInstVpsubw, // AVX/AVX2 - kInstVptest, // AVX - kInstVpunpckhbw, // AVX/AVX2 - kInstVpunpckhdq, // AVX/AVX2 - kInstVpunpckhqdq, // AVX/AVX2 - kInstVpunpckhwd, // AVX/AVX2 - kInstVpunpcklbw, // AVX/AVX2 - kInstVpunpckldq, // AVX/AVX2 - kInstVpunpcklqdq, // AVX/AVX2 - kInstVpunpcklwd, // AVX/AVX2 - kInstVpxor, // AVX/AVX2 - kInstVrcpps, // AVX - kInstVrcpss, // AVX - kInstVroundpd, // AVX - kInstVroundps, // AVX - kInstVroundsd, // AVX - kInstVroundss, // AVX - kInstVrsqrtps, // AVX - kInstVrsqrtss, // AVX - kInstVshufpd, // AVX - kInstVshufps, // AVX - kInstVsqrtpd, // AVX - kInstVsqrtps, // AVX - kInstVsqrtsd, // AVX - kInstVsqrtss, // AVX - kInstVstmxcsr, // AVX - kInstVsubpd, // AVX - kInstVsubps, // AVX - kInstVsubsd, // AVX - kInstVsubss, // AVX - kInstVtestpd, // AVX - kInstVtestps, // AVX - kInstVucomisd, // AVX - kInstVucomiss, // AVX - kInstVunpckhpd, // AVX - kInstVunpckhps, // AVX - kInstVunpcklpd, // AVX - kInstVunpcklps, // AVX - kInstVxorpd, // AVX - kInstVxorps, // AVX - kInstVzeroall, // AVX - kInstVzeroupper, // AVX - kInstWrfsbase, // FSGSBASE (x64) - kInstWrgsbase, // FSGSBASE (x64) - kInstXadd, // X86/X64 (i486) - kInstXchg, // X86/X64 (i386) - kInstXor, // X86/X64 - kInstXorpd, // SSE2 - kInstXorps, // SSE +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) + 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 + 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 + 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 + 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 (i386) + kX86InstIdXor, // X86/X64 + kX86InstIdXorpd, // SSE2 + kX86InstIdXorps, // SSE - _kInstCount, + _kX86InstIdCount, - _kInstCmovcc = kInstCmova, - _kInstJcc = kInstJa, - _kInstSetcc = kInstSeta, + _kX86InstIdCmovcc = kX86InstIdCmova, + _kX86InstIdJcc = kX86InstIdJa, + _kX86InstIdSetcc = kX86InstIdSeta, - _kInstJbegin = kInstJa, - _kInstJend = kInstJmp + _kX86InstIdJbegin = kX86InstIdJa, + _kX86InstIdJend = kX86InstIdJmp }; // ============================================================================ -// [asmjit::x86x64::kInstOptions] +// [asmjit::kX86InstOptions] // ============================================================================ //! X86/X64 instruction emit options, mainly for internal purposes. -ASMJIT_ENUM(kInstOptions) { +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. - kInstOptionLock = 0x10, + kX86InstOptionLock = 0x10, //! Force REX prefix to be emitted. //! @@ -1114,308 +1159,312 @@ ASMJIT_ENUM(kInstOptions) { //! combinations. If you want to access ah, bh, ch or dh registers the REX //! prefix can't be emitted, otherwise illegal instruction error will be //! returned. - kInstOptionRex = 0x40, + kX86InstOptionRex = 0x40, //! Force three-byte VEX prefix to be emitted (instead of more compact //! two-byte VEX prefix). //! //! Ignored if the instruction doesn't use VEX prefix. - kInstOptionVex3 = 0x80 + kX86InstOptionVex3 = 0x80 }; // ============================================================================ -// [asmjit::x86x64::kInstGroup] +// [asmjit::kX86InstGroup] // ============================================================================ //! \internal //! //! X86/X64 instruction groups. //! -//! This group is specific to AsmJit and only used by `x86x64::X86X64Assembler`. -ASMJIT_ENUM(kInstGroup) { +//! This group is specific to AsmJit and only used by `X86Assembler`. +ASMJIT_ENUM(kX86InstGroup) { //! Never used. - kInstGroupNone, + kX86InstGroupNone, - kInstGroupX86Op, - kInstGroupX86Rm, - kInstGroupX86Rm_B, - kInstGroupX86RmReg, - kInstGroupX86RegRm, - kInstGroupX86M, + kX86InstGroupX86Op, + kX86InstGroupX86Op_66H, + kX86InstGroupX86Rm, + kX86InstGroupX86Rm_B, + kX86InstGroupX86RmReg, + kX86InstGroupX86RegRm, + kX86InstGroupX86M, //! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor. - kInstGroupX86Arith, + kX86InstGroupX86Arith, //! Bswap. - kInstGroupX86BSwap, + kX86InstGroupX86BSwap, //! Bt/Btc/Btr/Bts. - kInstGroupX86BTest, + kX86InstGroupX86BTest, //! Call. - kInstGroupX86Call, + kX86InstGroupX86Call, //! Enter. - kInstGroupX86Enter, + kX86InstGroupX86Enter, //! Imul. - kInstGroupX86Imul, + kX86InstGroupX86Imul, //! Inc/Dec. - kInstGroupX86IncDec, + kX86InstGroupX86IncDec, //! Int. - kInstGroupX86Int, + kX86InstGroupX86Int, //! Jcc. - kInstGroupX86Jcc, + kX86InstGroupX86Jcc, //! Jcxz/Jecxz/Jrcxz. - kInstGroupX86Jecxz, + kX86InstGroupX86Jecxz, //! Jmp. - kInstGroupX86Jmp, + kX86InstGroupX86Jmp, //! Lea. - kInstGroupX86Lea, + kX86InstGroupX86Lea, //! Mov. - kInstGroupX86Mov, + kX86InstGroupX86Mov, //! Movsx/Movzx. - kInstGroupX86MovSxZx, + kX86InstGroupX86MovSxZx, //! Movsxd. - kInstGroupX86MovSxd, + kX86InstGroupX86MovSxd, //! Mov having absolute memory operand (x86/x64). - kInstGroupX86MovPtr, + kX86InstGroupX86MovPtr, //! Push. - kInstGroupX86Push, + kX86InstGroupX86Push, //! Pop. - kInstGroupX86Pop, + kX86InstGroupX86Pop, //! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX. - kInstGroupX86Rep, + kX86InstGroupX86Rep, //! Ret. - kInstGroupX86Ret, + kX86InstGroupX86Ret, //! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr. - kInstGroupX86Rot, + kX86InstGroupX86Rot, //! Setcc. - kInstGroupX86Set, + kX86InstGroupX86Set, //! Shld/Rhrd. - kInstGroupX86Shlrd, + kX86InstGroupX86Shlrd, //! Test. - kInstGroupX86Test, + kX86InstGroupX86Test, //! Xadd. - kInstGroupX86Xadd, + kX86InstGroupX86Xadd, //! Xchg. - kInstGroupX86Xchg, + kX86InstGroupX86Xchg, //! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1. - kInstGroupFpuOp, + kX86InstGroupFpuOp, //! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr. - kInstGroupFpuArith, + kX86InstGroupFpuArith, //! Fcom/Fcomp. - kInstGroupFpuCom, + kX86InstGroupFpuCom, //! Fld/Fst/Fstp. - kInstGroupFpuFldFst, + kX86InstGroupFpuFldFst, //! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr. - kInstGroupFpuM, + kX86InstGroupFpuM, //! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch. - kInstGroupFpuR, + kX86InstGroupFpuR, //! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp. - kInstGroupFpuRDef, + kX86InstGroupFpuRDef, //! Fnstsw/Fstsw. - kInstGroupFpuStsw, + kX86InstGroupFpuStsw, //! Mm/Xmm instruction. - kInstGroupExtRm, + kX86InstGroupExtRm, //! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register). - kInstGroupExtRm_P, + kX86InstGroupExtRm_P, //! Mm/Xmm instruction (propagates REX.W if GPQ is used). - kInstGroupExtRm_Q, + kX86InstGroupExtRm_Q, //! Mm/Xmm instruction (propagates 66H and REX.W). - kInstGroupExtRm_PQ, + kX86InstGroupExtRm_PQ, //! Mm/Xmm instruction having Rm/Ri encodings. - kInstGroupExtRmRi, + kX86InstGroupExtRmRi, //! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register). - kInstGroupExtRmRi_P, + kX86InstGroupExtRmRi_P, //! Mm/Xmm instruction having Rmi encoding. - kInstGroupExtRmi, + kX86InstGroupExtRmi, //! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register). - kInstGroupExtRmi_P, + kX86InstGroupExtRmi_P, //! Crc32. - kInstGroupExtCrc, + kX86InstGroupExtCrc, //! Pextrb/Pextrw/Pextrd/Pextrq/Extractps. - kInstGroupExtExtract, + kX86InstGroupExtExtract, //! Lfence/Mfence/Sfence. - kInstGroupExtFence, + kX86InstGroupExtFence, //! Mov Mm/Xmm. //! //! 0x66 prefix must be set manually in opcodes. //! - //! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/Mem format, - //! - Secondary opcode is used for instructions in (X)Mm/Mem <- (X)Mm format. - kInstGroupExtMov, + //! - 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. + kX86InstGroupExtMov, //! Mov Mm/Xmm. - kInstGroupExtMovNoRexW, + kX86InstGroupExtMovNoRexW, //! Movbe. - kInstGroupExtMovBe, + kX86InstGroupExtMovBe, //! Movd. - kInstGroupExtMovD, + kX86InstGroupExtMovD, //! Movq. - kInstGroupExtMovQ, + kX86InstGroupExtMovQ, //! Prefetch. - kInstGroupExtPrefetch, + kX86InstGroupExtPrefetch, //! 3dNow instruction. - kInstGroup3dNow, + kX86InstGroup3dNow, //! AVX instruction without operands. - kInstGroupAvxOp, + kX86InstGroupAvxOp, //! AVX instruction encoded as 'M'. - kInstGroupAvxM, + kX86InstGroupAvxM, //! AVX instruction encoded as 'MR'. - kInstGroupAvxMr, + kX86InstGroupAvxMr, //! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used). - kInstGroupAvxMr_P, + kX86InstGroupAvxMr_P, //! AVX instruction encoded as 'MRI'. - kInstGroupAvxMri, + kX86InstGroupAvxMri, //! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used). - kInstGroupAvxMri_P, + kX86InstGroupAvxMri_P, //! AVX instruction encoded as 'RM'. - kInstGroupAvxRm, + kX86InstGroupAvxRm, //! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used). - kInstGroupAvxRm_P, + kX86InstGroupAvxRm_P, //! AVX instruction encoded as 'RMI'. - kInstGroupAvxRmi, + kX86InstGroupAvxRmi, //! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used). - kInstGroupAvxRmi_P, + kX86InstGroupAvxRmi_P, //! AVX instruction encoded as 'RVM'. - kInstGroupAvxRvm, + kX86InstGroupAvxRvm, //! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvm_P, + kX86InstGroupAvxRvm_P, //! AVX instruction encoded as 'RVMR'. - kInstGroupAvxRvmr, + kX86InstGroupAvxRvmr, //! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvmr_P, + kX86InstGroupAvxRvmr_P, //! AVX instruction encoded as 'RVMI'. - kInstGroupAvxRvmi, + kX86InstGroupAvxRvmi, //! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvmi_P, + kX86InstGroupAvxRvmi_P, //! AVX instruction encoded as 'RMV'. - kInstGroupAvxRmv, + kX86InstGroupAvxRmv, //! AVX instruction encoded as 'RMVI'. - kInstGroupAvxRmvi, + kX86InstGroupAvxRmvi, //! AVX instruction encoded as 'RM' or 'MR'. - kInstGroupAvxRmMr, + kX86InstGroupAvxRmMr, //! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used). - kInstGroupAvxRmMr_P, + kX86InstGroupAvxRmMr_P, //! AVX instruction encoded as 'RVM' or 'RMI'. - kInstGroupAvxRvmRmi, + kX86InstGroupAvxRvmRmi, //! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvmRmi_P, + kX86InstGroupAvxRvmRmi_P, //! AVX instruction encoded as 'RVM' or 'MR'. - kInstGroupAvxRvmMr, + kX86InstGroupAvxRvmMr, //! AVX instruction encoded as 'RVM' or 'MVR'. - kInstGroupAvxRvmMvr, + kX86InstGroupAvxRvmMvr, //! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvmMvr_P, + kX86InstGroupAvxRvmMvr_P, //! AVX instruction encoded as 'RVM' or 'VMI'. - kInstGroupAvxRvmVmi, + kX86InstGroupAvxRvmVmi, //! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvmVmi_P, + kX86InstGroupAvxRvmVmi_P, //! AVX instruction encoded as 'VM'. - kInstGroupAvxVm, + kX86InstGroupAvxVm, //! AVX instruction encoded as 'VMI'. - kInstGroupAvxVmi, + kX86InstGroupAvxVmi, //! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used). - kInstGroupAvxVmi_P, + kX86InstGroupAvxVmi_P, //! AVX instruction encoded as 'RVRM' or 'RVMR'. - kInstGroupAvxRvrmRvmr, + kX86InstGroupAvxRvrmRvmr, //! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). - kInstGroupAvxRvrmRvmr_P, + kX86InstGroupAvxRvrmRvmr_P, //! Vmovss/Vmovsd. - kInstGroupAvxMovSsSd, + kX86InstGroupAvxMovSsSd, //! AVX2 gather family instructions (VSIB). - kInstGroupAvxGather, + kX86InstGroupAvxGather, //! AVX2 gather family instructions (VSIB), differs only in mem operand. - kInstGroupAvxGatherEx, + kX86InstGroupAvxGatherEx, //! FMA4 instruction in form [R, R, R/M, R/M]. - kInstGroupFma4, + kX86InstGroupFma4, //! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used). - kInstGroupFma4_P, + kX86InstGroupFma4_P, //! XOP instruction encoded as 'RM'. - kInstGroupXopRm, + kX86InstGroupXopRm, //! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used). - kInstGroupXopRm_P, + kX86InstGroupXopRm_P, //! XOP instruction encoded as 'RVM' or 'RMV'. - kInstGroupXopRvmRmv, + kX86InstGroupXopRvmRmv, //! XOP instruction encoded as 'RVM' or 'RMI'. - kInstGroupXopRvmRmi, + kX86InstGroupXopRvmRmi, //! XOP instruction encoded as 'RVMR'. - kInstGroupXopRvmr, + kX86InstGroupXopRvmr, //! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). - kInstGroupXopRvmr_P, + kX86InstGroupXopRvmr_P, //! XOP instruction encoded as 'RVMI'. - kInstGroupXopRvmi, + kX86InstGroupXopRvmi, //! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). - kInstGroupXopRvmi_P, + kX86InstGroupXopRvmi_P, //! XOP instruction encoded as 'RVRM' or 'RVMR'. - kInstGroupXopRvrmRvmr, + kX86InstGroupXopRvrmRvmr, //! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). - kInstGroupXopRvrmRvmr_P + kX86InstGroupXopRvrmRvmr_P, + + //! Count of X86 instruction groups. + _kX86InstGroupCount }; // ============================================================================ -// [asmjit::x86x64::kInstOpCode] +// [asmjit::kX86InstOpCode] // ============================================================================ //! \internal //! -//! Instruction OpCode encoding used by asmjit 'InstInfo' table. +//! Instruction OpCode encoding used by asmjit 'X86InstInfo' table. //! //! The schema was inspired by AVX/AVX2 features. -ASMJIT_ENUM(kInstOpCode) { +ASMJIT_ENUM(kX86InstOpCode) { // 'MMMMM' field in AVX/XOP instruction. // 'OpCode' leading bytes in legacy encoding. - kInstOpCode_MM_Shift = 16, - kInstOpCode_MM_Mask = 0x0FU << kInstOpCode_MM_Shift, - kInstOpCode_MM_00 = 0x00U << kInstOpCode_MM_Shift, - kInstOpCode_MM_0F = 0x01U << kInstOpCode_MM_Shift, - kInstOpCode_MM_0F38 = 0x02U << kInstOpCode_MM_Shift, - kInstOpCode_MM_0F3A = 0x03U << kInstOpCode_MM_Shift, - kInstOpCode_MM_0F01 = 0x0FU << kInstOpCode_MM_Shift, // Ext/Not part of AVX. + 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_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // Ext/Not part of AVX. - kInstOpCode_MM_00011 = 0x03U << kInstOpCode_MM_Shift, - kInstOpCode_MM_01000 = 0x08U << kInstOpCode_MM_Shift, - kInstOpCode_MM_01001 = 0x09U << kInstOpCode_MM_Shift, + kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, // 'PP' field in AVX/XOP instruction. // 'Mandatory Prefix' in legacy encoding. - kInstOpCode_PP_Shift = 21, - kInstOpCode_PP_Mask = 0x07U << kInstOpCode_PP_Shift, - kInstOpCode_PP_00 = 0x00U << kInstOpCode_PP_Shift, - kInstOpCode_PP_66 = 0x01U << kInstOpCode_PP_Shift, - kInstOpCode_PP_F3 = 0x02U << kInstOpCode_PP_Shift, - kInstOpCode_PP_F2 = 0x03U << kInstOpCode_PP_Shift, - kInstOpCode_PP_9B = 0x07U << kInstOpCode_PP_Shift, // Ext/Not part of AVX. + kX86InstOpCode_PP_Shift = 21, + 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, // Ext/Not part of AVX. // 'L' field in AVX/XOP instruction. - kInstOpCode_L_Shift = 24, - kInstOpCode_L_Mask = 0x01U << kInstOpCode_L_Shift, - kInstOpCode_L_False = 0x00U << kInstOpCode_L_Shift, - kInstOpCode_L_True = 0x01U << kInstOpCode_L_Shift, + kX86InstOpCode_L_Shift = 24, + kX86InstOpCode_L_Mask = 0x01U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_False = 0x00U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_True = 0x01U << kX86InstOpCode_L_Shift, // 'O' field. - kInstOpCode_O_Shift = 29, - kInstOpCode_O_Mask = 0x07U << kInstOpCode_O_Shift + kX86InstOpCode_O_Shift = 29, + kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift }; // ============================================================================ -// [asmjit::x86x64::kInstFlags] +// [asmjit::kX86InstFlags] // ============================================================================ //! \internal //! //! X86/X64 instruction type flags. -ASMJIT_ENUM(kInstFlags) { +ASMJIT_ENUM(kX86InstFlags) { //! No flags. - kInstFlagNone = 0x0000, + kX86InstFlagNone = 0x0000, //! Instruction is a control-flow instruction. //! //! Control flow instructions are jmp, jcc, call and ret. - kInstFlagFlow = 0x0001, + kX86InstFlagFlow = 0x0001, //! Instruction is a compare/test like instruction. - kInstFlagTest = 0x0002, + kX86InstFlagTest = 0x0002, //! Instruction is a move like instruction. //! @@ -1430,99 +1479,101 @@ ASMJIT_ENUM(kInstFlags) { //! 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. - kInstFlagMove = 0x0004, + kX86InstFlagMove = 0x0004, //! Instruction is an exchange like instruction. //! //! Exchange instruction typically overwrite first and second operand. So //! far only the instructions 'xchg' and 'xadd' are considered. - kInstFlagXchg = 0x0008, + kX86InstFlagXchg = 0x0008, //! Instruction accesses Fp register(s). - kInstFlagFp = 0x0010, + kX86InstFlagFp = 0x0010, //! Instruction can be prefixed by using the LOCK prefix. - kInstFlagLock = 0x0020, + kX86InstFlagLock = 0x0020, - //! Instruction is special, this is for `BaseCompiler`. - kInstFlagSpecial = 0x0040, + //! Instruction is special, this is for `Compiler`. + kX86InstFlagSpecial = 0x0040, //! Instruction always performs memory access. //! - //! This flag is always combined with `kInstFlagSpecial` and signalizes + //! This flag is always combined with `kX86InstFlagSpecial` and signalizes //! that there is an implicit address which is accessed (usually EDI/RDI or //! ESI/EDI). - kInstFlagSpecialMem = 0x0080, + kX86InstFlagSpecialMem = 0x0080, //! Instruction memory operand can refer to 16-bit address (used by FPU). - kInstFlagMem2 = 0x0100, + kX86InstFlagMem2 = 0x0100, //! Instruction memory operand can refer to 32-bit address (used by FPU). - kInstFlagMem4 = 0x0200, + kX86InstFlagMem4 = 0x0200, //! Instruction memory operand can refer to 64-bit address (used by FPU). - kInstFlagMem8 = 0x0400, + kX86InstFlagMem8 = 0x0400, //! Instruction memory operand can refer to 80-bit address (used by FPU). - kInstFlagMem10 = 0x0800, + kX86InstFlagMem10 = 0x0800, //! \internal //! - //! Combination of `kInstFlagMem2` and `kInstFlagMem4`. - kInstFlagMem2_4 = kInstFlagMem2 | kInstFlagMem4, + //! Combination of `kX86InstFlagMem2` and `kX86InstFlagMem4`. + kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4, //! \internal //! - //! Combination of `kInstFlagMem2`, `kInstFlagMem4` and `kInstFlagMem8`. - kInstFlagMem2_4_8 = kInstFlagMem2_4 | kInstFlagMem8, + //! Combination of `kX86InstFlagMem2`, `kX86InstFlagMem4` and `kX86InstFlagMem8`. + kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8, //! \internal //! - //! Combination of `kInstFlagMem4` and `kInstFlagMem8`. - kInstFlagMem4_8 = kInstFlagMem4 | kInstFlagMem8, + //! Combination of `kX86InstFlagMem4` and `kX86InstFlagMem8`. + kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8, //! \internal //! - //! Combination of `kInstFlagMem4`, `kInstFlagMem8` and `kInstFlagMem10`. - kInstFlagMem4_8_10 = kInstFlagMem4_8 | kInstFlagMem10, + //! Combination of `kX86InstFlagMem4`, `kX86InstFlagMem8` and `kX86InstFlagMem10`. + kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10, //! Zeroes the rest of the register if the source operand is memory. - kInstFlagZeroIfMem = 0x1000, + //! + //! Special behavior related to some SIMD load instructions. + kX86InstFlagZ = 0x1000, //! REX.W/VEX.W by default. - kInstFlagW = 0x8000 + kX86InstFlagW = 0x8000 }; // ============================================================================ -// [asmjit::x86x64::kInstOp] +// [asmjit::kX86InstOp] // ============================================================================ //! \internal //! //! X86/X64 instruction operand flags. -ASMJIT_ENUM(kInstOp) { +ASMJIT_ENUM(kX86InstOp) { //! Instruction operand can be 8-bit Gpb register. - kInstOpGb = 0x0001, + kX86InstOpGb = 0x0001, //! Instruction operand can be 16-bit Gpw register. - kInstOpGw = 0x0002, + kX86InstOpGw = 0x0002, //! Instruction operand can be 32-bit Gpd register. - kInstOpGd = 0x0004, + kX86InstOpGd = 0x0004, //! Instruction operand can be 64-bit Gpq register. - kInstOpGq = 0x0008, + kX86InstOpGq = 0x0008, //! Instruction operand can be Fp register. - kInstOpFp = 0x0010, + kX86InstOpFp = 0x0010, //! Instruction operand can be 64-bit Mmx register. - kInstOpMm = 0x0020, + kX86InstOpMm = 0x0020, //! Instruction operand can be 128-bit Xmm register. - kInstOpXmm = 0x0100, + kX86InstOpXmm = 0x0100, //! Instruction operand can be 256-bit Ymm register. - kInstOpYmm = 0x0200, + kX86InstOpYmm = 0x0200, //! Instruction operand can be 512-bit Zmm register. - kInstOpZmm = 0x0400, + kX86InstOpZmm = 0x0400, //! Instruction operand can be memory. - kInstOpMem = 0x2000, + kX86InstOpMem = 0x2000, //! Instruction operand can be immediate. - kInstOpImm = 0x4000, + kX86InstOpImm = 0x4000, //! Instruction operand can be label. - kInstOpLabel = 0x8000, + kX86InstOpLabel = 0x8000, //! \internal //! @@ -1530,201 +1581,477 @@ ASMJIT_ENUM(kInstOp) { //! //! \{ - kInstOpGwb = kInstOpGw | kInstOpGb, - kInstOpGqd = kInstOpGq | kInstOpGd, - kInstOpGqdw = kInstOpGq | kInstOpGd | kInstOpGw, - kInstOpGqdwb = kInstOpGq | kInstOpGd | kInstOpGw | kInstOpGb, + kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb, + kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd, + kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw, + kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb, - kInstOpGbMem = kInstOpGb | kInstOpMem, - kInstOpGwMem = kInstOpGw | kInstOpMem, - kInstOpGdMem = kInstOpGd | kInstOpMem, - kInstOpGqMem = kInstOpGq | kInstOpMem, - kInstOpGwbMem = kInstOpGwb | kInstOpMem, - kInstOpGqdMem = kInstOpGqd | kInstOpMem, - kInstOpGqdwMem = kInstOpGqdw | kInstOpMem, - kInstOpGqdwbMem = kInstOpGqdwb | kInstOpMem, + kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem, + kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem, + kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem, + kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem, + kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem, + kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem, + kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem, + kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem, - kInstOpFpMem = kInstOpFp | kInstOpMem, - kInstOpMmMem = kInstOpMm | kInstOpMem, - kInstOpXmmMem = kInstOpXmm | kInstOpMem, - kInstOpYmmMem = kInstOpYmm | kInstOpMem, + kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem, + kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem, + kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem, + kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem, - kInstOpMmXmm = kInstOpMm | kInstOpXmm, - kInstOpMmXmmMem = kInstOpMmXmm | kInstOpMem, + kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm, + kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem, - kInstOpXmmYmm = kInstOpXmm | kInstOpYmm, - kInstOpXmmYmmMem = kInstOpXmmYmm | kInstOpMem + kX86InstOpXmmYmm = kX86InstOpXmm | kX86InstOpYmm, + kX86InstOpXmmYmmMem = kX86InstOpXmmYmm | kX86InstOpMem //! \} }; // ============================================================================ -// [asmjit::x86x64::kCond] +// [asmjit::kX86Cond] // ============================================================================ //! X86/X64 Condition codes. -ASMJIT_ENUM(kCond) { - kCondA = 0x07, // CF==0 & ZF==0 (unsigned) - kCondAE = 0x03, // CF==0 (unsigned) - kCondB = 0x02, // CF==1 (unsigned) - kCondBE = 0x06, // CF==1 | ZF==1 (unsigned) - kCondC = 0x02, // CF==1 - kCondE = 0x04, // ZF==1 (signed/unsigned) - kCondG = 0x0F, // ZF==0 & SF==OF (signed) - kCondGE = 0x0D, // SF==OF (signed) - kCondL = 0x0C, // SF!=OF (signed) - kCondLE = 0x0E, // ZF==1 | SF!=OF (signed) - kCondNA = 0x06, // CF==1 | ZF==1 (unsigned) - kCondNAE = 0x02, // CF==1 (unsigned) - kCondNB = 0x03, // CF==0 (unsigned) - kCondNBE = 0x07, // CF==0 & ZF==0 (unsigned) - kCondNC = 0x03, // CF==0 - kCondNE = 0x05, // ZF==0 (signed/unsigned) - kCondNG = 0x0E, // ZF==1 | SF!=OF (signed) - kCondNGE = 0x0C, // SF!=OF (signed) - kCondNL = 0x0D, // SF==OF (signed) - kCondNLE = 0x0F, // ZF==0 & SF==OF (signed) - kCondNO = 0x01, // OF==0 - kCondNP = 0x0B, // PF==0 - kCondNS = 0x09, // SF==0 - kCondNZ = 0x05, // ZF==0 - kCondO = 0x00, // OF==1 - kCondP = 0x0A, // PF==1 - kCondPE = 0x0A, // PF==1 - kCondPO = 0x0B, // PF==0 - kCondS = 0x08, // SF==1 - kCondZ = 0x04, // ZF==1 +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. - kCondOverflow = 0x00, - kCondNotOverflow = 0x01, - kCondBelow = 0x02, //!< Unsigned comparison. - kCondAboveEqual = 0x03, //!< Unsigned comparison. - kCondEqual = 0x04, - kCondNotEqual = 0x05, - kCondBelowEqual = 0x06, //!< Unsigned comparison. - kCondAbove = 0x07, //!< Unsigned comparison. - kCondSign = 0x08, - kCondNotSign = 0x09, - kCondParityEven = 0x0A, - kCondParityOdd = 0x0B, - kCondLess = 0x0C, //!< Signed comparison. - kCondGreaterEqual = 0x0D, //!< Signed comparison. - kCondLessEqual = 0x0E, //!< Signed comparison. - kCondGreater = 0x0F, //!< Signed comparison. + kX86CondOverflow = 0x00, + kX86CondNotOverflow = 0x01, + kX86CondBelow = 0x02, //!< Unsigned comparison. + kX86CondAboveEqual = 0x03, //!< Unsigned comparison. + kX86CondEqual = 0x04, + kX86CondNotEqual = 0x05, + kX86CondBelowEqual = 0x06, //!< Unsigned comparison. + kX86CondAbove = 0x07, //!< Unsigned comparison. + kX86CondSign = 0x08, + kX86CondNotSign = 0x09, + kX86CondParityEven = 0x0A, + kX86CondParityOdd = 0x0B, + kX86CondLess = 0x0C, //!< Signed comparison. + kX86CondGreaterEqual = 0x0D, //!< Signed comparison. + kX86CondLessEqual = 0x0E, //!< Signed comparison. + kX86CondGreater = 0x0F, //!< Signed comparison. // Aliases. - kCondZero = 0x04, - kCondNotZero = 0x05, - kCondNegative = 0x08, - kCondPositive = 0x09, + kX86CondZero = 0x04, + kX86CondNotZero = 0x05, + kX86CondNegative = 0x08, + kX86CondPositive = 0x09, // Fpu-only. - kCondFpuUnordered = 0x10, - kCondFpuNotUnordered = 0x11, + kX86CondFpuUnordered = 0x10, + kX86CondFpuNotUnordered = 0x11, //! No condition code. - kCondNone = 0x12 + kX86CondNone = 0x12 }; // ============================================================================ -// [asmjit::x86x64::kPrefetchHint] +// [asmjit::kX86EFlags] // ============================================================================ -//! X86/X64 Prefetch hints. -ASMJIT_ENUM(kPrefetchHint) { - //! Prefetch using NT hint. - kPrefetchNta = 0, - //! Prefetch to L0 cache. - kPrefetchT0 = 1, - //! Prefetch to L1 cache. - kPrefetchT1 = 2, - //! Prefetch to L2 cache. - kPrefetchT2 = 3 +//! 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 the API and +//! definitions are public. +//! +//! \note Flags defined here doesn'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 8-bit integer. +ASMJIT_ENUM(kX86EFlags) { + // -------------------------------------------------------------------------- + // src-gendefs.js relies on the values of these masks, to modify them the + // tool has to be changed as well. + // -------------------------------------------------------------------------- + + //! 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 it. + kX86EFlagX = 0x80 }; // ============================================================================ -// [asmjit::x86x64::kFPSW] +// [asmjit::kX86FpSw] // ============================================================================ //! X86/X64 FPU status Word. -ASMJIT_ENUM(kFPSW) { - kFPSW_Invalid = 0x0001, - kFPSW_Denormalized = 0x0002, - kFPSW_DivByZero = 0x0004, - kFPSW_Overflow = 0x0008, - kFPSW_Underflow = 0x0010, - kFPSW_Precision = 0x0020, - kFPSW_StackFault = 0x0040, - kFPSW_Interrupt = 0x0080, - kFPSW_C0 = 0x0100, - kFPSW_C1 = 0x0200, - kFPSW_C2 = 0x0400, - kFPSW_Top = 0x3800, - kFPSW_C3 = 0x4000, - kFPSW_Busy = 0x8000 +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::x86x64::kFPCW] +// [asmjit::kX86FpCw] // ============================================================================ //! X86/X64 FPU control Word. -ASMJIT_ENUM(kFPCW) { - kFPCW_EM_Mask = 0x003F, // Bits 0-5. - kFPCW_EM_Invalid = 0x0001, - kFPCW_EM_Denormal = 0x0002, - kFPCW_EM_DivByZero = 0x0004, - kFPCW_EM_Overflow = 0x0008, - kFPCW_EM_Underflow = 0x0010, - kFPCW_EM_Inexact = 0x0020, +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, - kFPCW_PC_Mask = 0x0300, // Bits 8-9. - kFPCW_PC_Float = 0x0000, - kFPCW_PC_Reserved = 0x0100, - kFPCW_PC_Double = 0x0200, - kFPCW_PC_Extended = 0x0300, + kX86FpCw_PC_Mask = 0x0300, // Bits 8-9. + kX86FpCw_PC_Float = 0x0000, + kX86FpCw_PC_Reserved = 0x0100, + kX86FpCw_PC_Double = 0x0200, + kX86FpCw_PC_Extended = 0x0300, - kFPCW_RC_Mask = 0x0C00, // Bits 10-11. - kFPCW_RC_Nearest = 0x0000, - kFPCW_RC_Down = 0x0400, - kFPCW_RC_Up = 0x0800, - kFPCW_RC_Truncate = 0x0C00, + kX86FpCw_RC_Mask = 0x0C00, // Bits 10-11. + kX86FpCw_RC_Nearest = 0x0000, + kX86FpCw_RC_Down = 0x0400, + kX86FpCw_RC_Up = 0x0800, + kX86FpCw_RC_Truncate = 0x0C00, - kFPCW_IC_Mask = 0x1000, // Bit 12. - kFPCW_IC_Projective = 0x0000, - kFPCW_IC_Affine = 0x1000 + kX86FpCw_IC_Mask = 0x1000, // Bit 12. + kX86FpCw_IC_Projective = 0x0000, + kX86FpCw_IC_Affine = 0x1000 }; // ============================================================================ -// [asmjit::x86x64::InstInfo] +// [asmjit::kX86Prefetch] // ============================================================================ -//! \internal +//! 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. //! -//! X86/X64 instruction information. -struct InstInfo { +//! 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] + // [Accessors - InstGroup] // -------------------------------------------------------------------------- -#if !defined(ASMJIT_DISABLE_INST_NAMES) - //! Get instruction name string (null terminated). - ASMJIT_INLINE const char* getName() const { - return _instName + static_cast(_nameIndex); + //! Get instruction group, see \ref kX86InstGroup. + ASMJIT_INLINE uint32_t getInstGroup() const { + return _instGroup; } - //! Get instruction name index to `_instName` array. + // -------------------------------------------------------------------------- + // [Accessors - InstFlags] + // -------------------------------------------------------------------------- + + //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { + return (_instFlags & flag) != 0; + } + + //! Get 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 modifies instruction pointer, + //! 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. + ASMJIT_INLINE uint32_t getEFlagsIn() const { + return _eflagsIn; + } + + //! Get EFLAGS that the instruction writes. + ASMJIT_INLINE uint32_t getEFlagsOut() const { + return _eflagsOut; + } + + // -------------------------------------------------------------------------- + // [Accessors - Move-Size] + // -------------------------------------------------------------------------- + + //! Get size of move instruction in bytes. + //! + //! See \ref X86InstInfo::getMoveSize() for more details. + ASMJIT_INLINE uint32_t getMoveSize() const { + return _moveSize; + } + + // -------------------------------------------------------------------------- + // [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 group. + uint8_t _instGroup; + + //! Count of bytes overwritten by a move instruction. + //! + //! Only used with `kX86InstFlagMove` flag. If this value is zero move depends + //! on size of the destination register. + uint8_t _moveSize; + + //! EFlags read by the instruction. + uint8_t _eflagsIn; + //! EFlags modified by the instruction. + uint8_t _eflagsOut; + + //! Instruction flags. + uint16_t _instFlags; + + //! Operands' flags. + uint16_t _opFlags[5]; + + //! 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_INST_NAMES +#endif // !ASMJIT_DISABLE_NAMES - //! Get instruction group, see `kInstGroup`. - ASMJIT_INLINE uint32_t getGroup() const { - return _group; + // -------------------------------------------------------------------------- + // [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 - Group] + // -------------------------------------------------------------------------- + + //! Get instruction group, see \ref kX86InstGroup. + ASMJIT_INLINE uint32_t getInstGroup() const { + return getExtendedInfo().getInstGroup(); + } + + // -------------------------------------------------------------------------- + // [Accessors - 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 - Move-Size] + // -------------------------------------------------------------------------- + //! Get size of move instruction in bytes. //! //! If zero, the size of MOV instruction is determined by the size of the @@ -1733,120 +2060,146 @@ struct InstInfo { //! be overwritten or not. Basically if the move size is equal or greater //! than a variable itself it is considered overwritten. ASMJIT_INLINE uint32_t getMoveSize() const { - return _moveSize; + return getExtendedInfo().getMoveSize(); } - //! Get instruction flags, see `kInstFlags`. - ASMJIT_INLINE uint32_t getFlags() const { - return _flags; + // -------------------------------------------------------------------------- + // [Accessors - Operand-Flags] + // -------------------------------------------------------------------------- + + //! Get flags of operand at index `index`. + ASMJIT_INLINE uint32_t getOperandFlags(uint32_t index) const { + return getExtendedInfo().getOperandFlags(index); } - //! Get whether the instruction is a control-flow intruction. - //! - //! Control flow instruction is instruction that modifies instruction pointer, - //! typically jmp, jcc, call, or ret. - ASMJIT_INLINE bool isFlow() const { - return (_flags & kInstFlagFlow) != 0; + // -------------------------------------------------------------------------- + // [Accessors - OpCode] + // -------------------------------------------------------------------------- + + //! Get the primary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getPrimaryOpCode() const { + return _primaryOpCode; } - //! Get whether the instruction is a compare/test like intruction. - ASMJIT_INLINE bool isTest() const { - return (_flags & kInstFlagTest) != 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 `BaseCompiler` 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 (_flags & kInstFlagMove) != 0; - } - - //! Get whether the instruction is a typical Exchange instruction. - //! - //! Exchange instructios are 'xchg' and 'xadd'. - ASMJIT_INLINE bool isXchg() const { - return (_flags & kInstFlagXchg) != 0; - } - - //! Get whether the instruction accesses Fp register(s). - ASMJIT_INLINE bool isFp() const { - return (_flags & kInstFlagFp) != 0; - } - - //! Get whether the instruction can be prefixed by LOCK prefix. - ASMJIT_INLINE bool isLockable() const { - return (_flags & kInstFlagLock) != 0; - } - - //! Get whether the instruction is special type (this is used by - //! `BaseCompiler` to manage additional variables or functionality). - ASMJIT_INLINE bool isSpecial() const { - return (_flags & kInstFlagSpecial) != 0; - } - - //! Get whether the instruction is special type and it performs - //! memory access. - ASMJIT_INLINE bool isSpecialMem() const { - return (_flags & kInstFlagSpecialMem) != 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 (_flags & kInstFlagZeroIfMem) != 0; + //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getSecondaryOpCode() const { + return getExtendedInfo().getSecondaryOpCode(); } // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- - //! Instruction name index in _instName[] array. + //! Instruction name index in `_x86InstName[]` array. uint16_t _nameIndex; - //! Instruction flags. - uint16_t _flags; - //! Instruction group, used by `BaseAssembler`. - uint8_t _group; - //! Count of bytes overwritten by a move instruction. - //! - //! Only used with `kInstFlagMove` flag. If this value is zero move depends - //! on the destination register size. - uint8_t _moveSize; - //! Reserved for future use. - uint8_t _reserved[2]; - //! Operands' flags. - uint16_t _opFlags[4]; - //! Primary and secondary opcodes. - uint32_t _opCode[2]; + //! Extended information name index in `_x86InstExtendedInfo[]` array. + uint16_t _extendedIndex; + + //! Primary opcode, secondary opcode is stored in `X86InstExtendedInfo` table. + uint32_t _primaryOpCode; }; // ============================================================================ -// [asmjit::x86x64::X86InstUtil] +// [asmjit::X86Util] // ============================================================================ -struct X86InstUtil { -#if !defined(ASMJIT_DISABLE_INST_NAMES) +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 - //! `kInstNone` (zero) is returned. + //! `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_INST_NAMES +#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); + } }; //! \} -} // x64 namespace } // asmjit namespace #undef _OP_ID diff --git a/src/asmjit/x86/x86operand.cpp b/src/asmjit/x86/x86operand.cpp index 76b6bf1..7e300ee 100644 --- a/src/asmjit/x86/x86operand.cpp +++ b/src/asmjit/x86/x86operand.cpp @@ -18,48 +18,14 @@ #include "../apibegin.h" namespace asmjit { -namespace x86x64 { +namespace x86 { // ============================================================================ -// [asmjit::x86x64::Variables] +// [asmjit::X86Mem - abs[]] // ============================================================================ -#define C(_Class_) kRegClass##_Class_ -#define D(_Desc_) kVarDesc##_Desc_ - -const VarInfo _varInfo[] = { - /* 00: kVarTypeInt8 */ { kRegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, - /* 01: kVarTypeUInt8 */ { kRegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, - /* 02: kVarTypeInt16 */ { kRegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, - /* 03: kVarTypeUInt16 */ { kRegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, - /* 04: kVarTypeInt32 */ { kRegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, - /* 05: kVarTypeUInt32 */ { kRegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, - /* 06: kVarTypeInt64 */ { kRegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, - /* 07: kVarTypeUInt64 */ { kRegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, - /* 08: kVarTypeIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. - /* 09: kVarTypeUIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. - /* 10: kVarTypeFp32 */ { kRegTypeFp , 4 , C(Fp) , D(Sp) , "fp" }, - /* 11: kVarTypeFp64 */ { kRegTypeFp , 8 , C(Fp) , D(Dp) , "fp" }, - /* 12: kVarTypeMm */ { kRegTypeMm , 8 , C(Mm) , 0 , "mm" }, - /* 13: kVarTypeXmm */ { kRegTypeXmm , 16, C(Xyz), 0 , "xmm" }, - /* 14: kVarTypeXmmSs */ { kRegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, - /* 15: kVarTypeXmmPs */ { kRegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, - /* 16: kVarTypeXmmSd */ { kRegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, - /* 17: kVarTypeXmmPd */ { kRegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, - /* 18: kVarTypeYmm */ { kRegTypeYmm , 32, C(Xyz), 0 , "ymm" }, - /* 19: kVarTypeYmmPs */ { kRegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, - /* 20: kVarTypeYmmPd */ { kRegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" } -}; - -#undef D -#undef C - -// ============================================================================ -// [asmjit::Mem - abs[]] -// ============================================================================ - -Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) { - Mem m(NoInit); +X86Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) { + X86Mem m(NoInit); m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue); m._vmem.index = kInvalidValue; @@ -68,13 +34,16 @@ Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) { return m; } -Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) { - Mem m(NoInit); - uint32_t flags = shift << kMemShiftIndex; +X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) { + X86Mem m(NoInit); + uint32_t flags = shift << kX86MemShiftIndex; - if (index.isGp()) flags |= Mem::_getGpdFlags(reinterpret_cast(index)); - if (index.isXmm()) flags |= kMemVSibXmm << kMemVSibIndex; - if (index.isYmm()) flags |= kMemVSibYmm << kMemVSibIndex; + if (index.isGp()) + flags |= X86Mem::_getGpdFlags(index); + else if (index.isXmm()) + flags |= kX86MemVSibXmm << kX86MemVSibIndex; + else if (index.isYmm()) + flags |= kX86MemVSibYmm << kX86MemVSibIndex; m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); m._vmem.index = index.getRegIndex(); @@ -83,99 +52,33 @@ Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_ return m; } -Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) { - Mem m(NoInit); - uint32_t flags = shift << kMemShiftIndex; +#if !defined(ASMJIT_DISABLE_COMPILER) +X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) { + X86Mem m(NoInit); + uint32_t flags = shift << kX86MemShiftIndex; - if (index.isGp()) flags |= Mem::_getGpdFlags(reinterpret_cast(index)); - if (index.isXmm()) flags |= kMemVSibXmm << kMemVSibIndex; - if (index.isYmm()) flags |= kMemVSibYmm << kMemVSibIndex; + const Var& index_ = reinterpret_cast(index); + uint32_t indexRegType = index_.getRegType(); + + if (indexRegType <= kX86RegTypeGpq) + flags |= X86Mem::_getGpdFlags(reinterpret_cast(index)); + else if (indexRegType == kX86RegTypeXmm) + flags |= kX86MemVSibXmm << kX86MemVSibIndex; + else if (indexRegType == kX86RegTypeYmm) + flags |= kX86MemVSibYmm << kX86MemVSibIndex; m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); - m._vmem.index = index.getId(); + m._vmem.index = index_.getId(); m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); return m; } - -} // x86x64 namespace -} // asmjit namespace - -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -const uint8_t _varMapping[kVarTypeCount] = { - /* 00: kVarTypeInt8 */ kVarTypeInt8, - /* 01: kVarTypeUInt8 */ kVarTypeUInt8, - /* 02: kVarTypeInt16 */ kVarTypeInt16, - /* 03: kVarTypeUInt16 */ kVarTypeUInt16, - /* 04: kVarTypeInt32 */ kVarTypeInt32, - /* 05: kVarTypeUInt32 */ kVarTypeUInt32, - /* 06: kVarTypeInt64 */ kVarTypeInvalid, // Invalid in 32-bit mode. - /* 07: kVarTypeUInt64 */ kVarTypeInvalid, // Invalid in 32-bit mode. - /* 08: kVarTypeIntPtr */ kVarTypeInt32, // Remapped. - /* 09: kVarTypeUIntPtr */ kVarTypeUInt32, // Remapped. - /* 10: kVarTypeFp32 */ kVarTypeFp32, - /* 11: kVarTypeFp64 */ kVarTypeFp64, - /* 12: kVarTypeMm */ kVarTypeMm, - /* 13: kVarTypeXmm */ kVarTypeXmm, - /* 14: kVarTypeXmmSs */ kVarTypeXmmSs, - /* 15: kVarTypeXmmPs */ kVarTypeXmmPs, - /* 16: kVarTypeXmmSd */ kVarTypeXmmSd, - /* 17: kVarTypeXmmPd */ kVarTypeXmmPd, - /* 18: kVarTypeYmm */ kVarTypeYmm, - /* 19: kVarTypeYmmPs */ kVarTypeYmmPs, - /* 20: kVarTypeYmmPd */ kVarTypeYmmPd -}; +#endif // !ASMJIT_DISABLE_COMPILER } // x86 namespace } // asmjit namespace -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) -namespace asmjit { -namespace x64 { - -const uint8_t _varMapping[kVarTypeCount] = { - /* 00: kVarTypeInt8 */ kVarTypeInt8, - /* 01: kVarTypeUInt8 */ kVarTypeUInt8, - /* 02: kVarTypeInt16 */ kVarTypeInt16, - /* 03: kVarTypeUInt16 */ kVarTypeUInt16, - /* 04: kVarTypeInt32 */ kVarTypeInt32, - /* 05: kVarTypeUInt32 */ kVarTypeUInt32, - /* 06: kVarTypeInt64 */ kVarTypeInt64, - /* 07: kVarTypeUInt64 */ kVarTypeUInt64, - /* 08: kVarTypeIntPtr */ kVarTypeInt64, // Remapped. - /* 09: kVarTypeUIntPtr */ kVarTypeUInt64, // Remapped. - /* 10: kVarTypeFp32 */ kVarTypeFp32, - /* 11: kVarTypeFp64 */ kVarTypeFp64, - /* 12: kVarTypeMm */ kVarTypeMm, - /* 13: kVarTypeXmm */ kVarTypeXmm, - /* 14: kVarTypeXmmSs */ kVarTypeXmmSs, - /* 15: kVarTypeXmmPs */ kVarTypeXmmPs, - /* 16: kVarTypeXmmSd */ kVarTypeXmmSd, - /* 17: kVarTypeXmmPd */ kVarTypeXmmPd, - /* 18: kVarTypeYmm */ kVarTypeYmm, - /* 19: kVarTypeYmmPs */ kVarTypeYmmPs, - /* 20: kVarTypeYmmPd */ kVarTypeYmmPd -}; - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - +// [Api-End] #include "../apiend.h" // [Guard] diff --git a/src/asmjit/x86/x86operand.h b/src/asmjit/x86/x86operand.h index 1ab4306..f40ab12 100644 --- a/src/asmjit/x86/x86operand.h +++ b/src/asmjit/x86/x86operand.h @@ -15,215 +15,501 @@ #include "../base/intutil.h" #include "../base/operand.h" #include "../base/vectypes.h" -#include "../x86/x86regs.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 _OP_ID(_Op_) reinterpret_cast(_Op_).getId() + namespace asmjit { -namespace x86x64 { // ============================================================================ // [Forward Declarations] // ============================================================================ -struct VarInfo; - struct X86Reg; +struct X86GpReg; +struct X86FpReg; +struct X86MmReg; +struct X86XmmReg; +struct X86YmmReg; +struct X86SegReg; + +#if !defined(ASMJIT_DISABLE_COMPILER) struct X86Var; +struct X86GpVar; +struct X86MmVar; +struct X86XmmVar; +struct X86YmmVar; +#endif // !ASMJIT_DISABLE_COMPILER -struct GpReg; -struct GpVar; - -struct MmReg; -struct MmVar; - -struct XmmReg; -struct XmmVar; - -struct YmmReg; -struct YmmVar; - -#define _OP_ID(_Op_) reinterpret_cast(_Op_).getId() - -// ============================================================================ -// [asmjit::x86x64::Typedefs] -// ============================================================================ - -//! \addtogroup asmjit_x86x64_general +//! \addtogroup asmjit_x86_general //! \{ -typedef Vec64Data MmData; -typedef Vec128Data XmmData; -typedef Vec256Data YmmData; - // ============================================================================ -// [asmjit::x86x64::Variables] +// [asmjit::kX86RegClass] // ============================================================================ -//! \internal -ASMJIT_VAR const VarInfo _varInfo[]; +//! X86/X64 variable class. +ASMJIT_ENUM(kX86RegClass) { + //! X86/X64 Gp register class (compatible with universal \ref kRegClassGp). + kX86RegClassGp = kRegClassGp, + //! X86/X64 Fp register class. + kX86RegClassFp = 1, + //! X86/X64 Mm register class. + kX86RegClassMm = 2, + //! X86/X64 Xmm/Ymm/Zmm register class. + kX86RegClassXyz = 3, -// ============================================================================ -// [asmjit::x86x64::kMemVSib] -// ============================================================================ - -//! X86/X64 index register legacy and AVX2 (VSIB) support. -ASMJIT_ENUM(kMemVSib) { - //! Memory operand uses Gp or no index register. - kMemVSibGpz = 0, - //! Memory operand uses Xmm or no index register. - kMemVSibXmm = 1, - //! Memory operand uses Ymm or no index register. - kMemVSibYmm = 2 + //! Count of X86/X64 register classes. + kX86RegClassCount = 4 }; // ============================================================================ -// [asmjit::x86x64::kMemFlags] +// [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. + kX86RegTypeGpq = 0x30, + + //! Fp register. + kX86RegTypeFp = 0x50, + //! Mm register. + kX86RegTypeMm = 0x60, + + //! Xmm register. + kX86RegTypeXmm = 0x70, + //! Ymm register. + kX86RegTypeYmm = 0x80, + //! Zmm register. + kX86RegTypeZmm = 0x90, + + //! 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 Gp or no index register. + kX86MemVSibGpz = 0, + //! Memory operand uses Xmm or no index register. + kX86MemVSibXmm = 1, + //! Memory operand uses Ymm or no index register. + kX86MemVSibYmm = 2 +}; + +// ============================================================================ +// [asmjit::kX86MemFlags] // ============================================================================ //! \internal //! //! X86/X64 specific memory flags. -ASMJIT_ENUM(kMemFlags) { - kMemSegBits = 0x7, - kMemSegIndex = 0, - kMemSegMask = kMemSegBits << kMemSegIndex, +ASMJIT_ENUM(kX86MemFlags) { + kX86MemSegBits = 0x7, + kX86MemSegIndex = 0, + kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex, - kMemGpdBits = 0x1, - kMemGpdIndex = 3, - kMemGpdMask = kMemGpdBits << kMemGpdIndex, + kX86MemGpdBits = 0x1, + kX86MemGpdIndex = 3, + kX86MemGpdMask = kX86MemGpdBits << kX86MemGpdIndex, - kMemVSibBits = 0x3, - kMemVSibIndex = 4, - kMemVSibMask = kMemVSibBits << kMemVSibIndex, + kX86MemVSibBits = 0x3, + kX86MemVSibIndex = 4, + kX86MemVSibMask = kX86MemVSibBits << kX86MemVSibIndex, - kMemShiftBits = 0x3, - kMemShiftIndex = 6, - kMemShiftMask = kMemShiftBits << kMemShiftIndex + kX86MemShiftBits = 0x3, + kX86MemShiftIndex = 6, + kX86MemShiftMask = kX86MemShiftBits << kX86MemShiftIndex }; -// ============================================================================ -// [asmjit::x86x64::kVarType] -// ============================================================================ - -//! X86/X64 variable type. -ASMJIT_ENUM(kVarType) { - //! Variable is Mm (MMX). - kVarTypeMm = 12, - - //! Variable is Xmm (SSE+). - kVarTypeXmm, - //! Variable is scalar Xmm SP-FP number. - kVarTypeXmmSs, - //! Variable is packed Xmm SP-FP number (4 floats). - kVarTypeXmmPs, - //! Variable is scalar Xmm DP-FP number. - kVarTypeXmmSd, - //! Variable is packed Xmm DP-FP number (2 doubles). - kVarTypeXmmPd, - - //! Variable is Ymm (AVX+). - kVarTypeYmm, - //! Variable is packed Ymm SP-FP number (8 floats). - kVarTypeYmmPs, - //! Variable is packed Ymm DP-FP number (4 doubles). - kVarTypeYmmPd, - - //! Count of variable types. - kVarTypeCount, - - //! \internal - //! \{ - _kVarTypeMmStart = kVarTypeMm, - _kVarTypeMmEnd = kVarTypeMm, - - _kVarTypeXmmStart = kVarTypeXmm, - _kVarTypeXmmEnd = kVarTypeXmmPd, - - _kVarTypeYmmStart = kVarTypeYmm, - _kVarTypeYmmEnd = kVarTypeYmmPd - //! \} -}; +// This is only defined by `x86operand_regs.cpp` when exporting registers. +#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) // ============================================================================ -// [asmjit::x86x64::kVarDesc] +// [asmjit::X86RegCount] // ============================================================================ //! \internal //! -//! X86/X64 variable description. -ASMJIT_ENUM(kVarDesc) { - //! Variable contains single-precision floating-point(s). - kVarDescSp = 0x10, - //! Variable contains double-precision floating-point(s). - kVarDescDp = 0x20, - //! Variable is packed (for example float4x, double2x, ...). - kVarDescPacked = 0x40 -}; - -//! \} - -// ============================================================================ -// [asmjit::x86x64::VarInfo] -// ============================================================================ - -//! \addtogroup asmjit_x86x64_util -//! \{ - -//! \internal -//! -//! X86 variable information. -struct VarInfo { +//! X86/X64 registers count (Gp, Fp, Mm, Xmm). +struct X86RegCount { // -------------------------------------------------------------------------- - // [Accessors] + // [Zero] // -------------------------------------------------------------------------- - //! Get register type, see `kRegType`. - 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 `kVarDesc`. - ASMJIT_INLINE uint32_t getDesc() const { return _desc; } - //! Get variable type name. - ASMJIT_INLINE const char* getName() const { return _name; } + ASMJIT_INLINE void reset() { + _packed = 0; + } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t get(uint32_t c) const { + ASMJIT_ASSERT(c < kX86RegClassCount); + return _regs[c]; + } + + ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; } + ASMJIT_INLINE uint32_t getFp() const { return _regs[kX86RegClassFp]; } + ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; } + ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void set(uint32_t c, uint32_t n) { + ASMJIT_ASSERT(c < kX86RegClassCount); + ASMJIT_ASSERT(n < 0x100); + + _regs[c] = static_cast(n); + } + + ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); } + ASMJIT_INLINE void setFp(uint32_t n) { set(kX86RegClassFp, n); } + ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); } + ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) { + ASMJIT_ASSERT(c < kX86RegClassCount); + ASMJIT_ASSERT(n < 0x100); + + _regs[c] += static_cast(n); + } + + ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); } + ASMJIT_INLINE void addFp(uint32_t n) { add(kX86RegClassFp, n); } + ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); } + ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Misc] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void makeIndex(const X86RegCount& count) { + uint8_t a = count._regs[0]; + uint8_t b = count._regs[1]; + uint8_t c = count._regs[2]; + + _regs[0] = 0; + _regs[1] = a; + _regs[2] = a + b; + _regs[3] = a + b + c; + } // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- - //! Register type, see `kRegType`. - uint8_t _reg; - //! Register size in bytes. - uint8_t _size; - //! Register class, see `kRegClass`. - uint8_t _class; - //! Variable flags, see `kVarDesc`. - uint8_t _desc; - //! Variable type name. - char _name[4]; + union { + struct { + uint8_t _gp; + uint8_t _fp; + uint8_t _mm; + uint8_t _xy; + }; + + uint8_t _regs[4]; + uint32_t _packed; + }; }; // ============================================================================ -// [asmjit::x86x64::X86Reg] +// [asmjit::X86RegMask] // ============================================================================ -//! X86/X64 register. -struct X86Reg : public BaseReg { +//! \internal +//! +//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm). +struct X86RegMask { + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _packed.reset(); + } + + // -------------------------------------------------------------------------- + // [IsEmpty / Has] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isEmpty() const { + return _packed.isZero(); + } + + ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const { + switch (c) { + case kX86RegClassGp : return (static_cast(_gp ) & mask) != 0; + case kX86RegClassFp : return (static_cast(_fp ) & mask) != 0; + case kX86RegClassMm : return (static_cast(_mm ) & mask) != 0; + case kX86RegClassXyz: return (static_cast(_xyz) & mask) != 0; + } + + ASMJIT_ASSERT(!"Reached"); + return false; + } + + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void zero(uint32_t c) { + switch (c) { + case kX86RegClassGp : _gp = 0; break; + case kX86RegClassFp : _fp = 0; break; + case kX86RegClassMm : _mm = 0; break; + case kX86RegClassXyz: _xyz = 0; break; + } + } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t get(uint32_t c) const { + switch (c) { + case kX86RegClassGp : return _gp; + case kX86RegClassFp : return _fp; + case kX86RegClassMm : return _mm; + case kX86RegClassXyz: return _xyz; + } + + ASMJIT_ASSERT(!"Reached"); + return 0; + } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void set(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp = static_cast(mask); break; + case kX86RegClassFp : _fp = static_cast(mask); break; + case kX86RegClassMm : _mm = static_cast(mask); break; + case kX86RegClassXyz: _xyz = static_cast(mask); break; + } + } + + ASMJIT_INLINE void set(const X86RegMask& other) { + _packed.setUInt64(other._packed); + } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void add(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp |= static_cast(mask); break; + case kX86RegClassFp : _fp |= static_cast(mask); break; + case kX86RegClassMm : _mm |= static_cast(mask); break; + case kX86RegClassXyz: _xyz |= static_cast(mask); break; + } + } + + ASMJIT_INLINE void add(const X86RegMask& other) { + _packed.or_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Del] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void del(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp &= ~static_cast(mask); break; + case kX86RegClassFp : _fp &= ~static_cast(mask); break; + case kX86RegClassMm : _mm &= ~static_cast(mask); break; + case kX86RegClassXyz: _xyz &= ~static_cast(mask); break; + } + } + + ASMJIT_INLINE void del(const X86RegMask& other) { + _packed.del(other._packed); + } + + // -------------------------------------------------------------------------- + // [And] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp &= static_cast(mask); break; + case kX86RegClassFp : _fp &= static_cast(mask); break; + case kX86RegClassMm : _mm &= static_cast(mask); break; + case kX86RegClassXyz: _xyz &= static_cast(mask); break; + } + } + + ASMJIT_INLINE void and_(const X86RegMask& other) { + _packed.and_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Xor] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp ^= static_cast(mask); break; + case kX86RegClassFp : _fp ^= static_cast(mask); break; + case kX86RegClassMm : _mm ^= static_cast(mask); break; + case kX86RegClassXyz: _xyz ^= static_cast(mask); break; + } + } + + ASMJIT_INLINE void xor_(const X86RegMask& other) { + _packed.xor_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Gp mask (16-bit). + uint16_t _gp; + //! Fp mask (8-bit). + uint8_t _fp; + //! Mm mask (8-bit). + uint8_t _mm; + //! Xmm/Ymm/Zmm mask (32-bit). + uint32_t _xyz; + }; + + //! All masks as 64-bit integer. + UInt64 _packed; + }; +}; + +// ============================================================================ +// [asmjit::X86Reg] +// ============================================================================ + +//! Base class for all X86 registers. +struct X86Reg : public Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy X86 register. - ASMJIT_INLINE X86Reg() : BaseReg() {} - //! Create a custom X86 register. - ASMJIT_INLINE X86Reg(uint32_t type, uint32_t index, uint32_t size) : BaseReg(type, index, size) {} + ASMJIT_INLINE X86Reg() : Reg() {} //! Create a reference to `other` X86 register. - ASMJIT_INLINE X86Reg(const X86Reg& other) : BaseReg(other) {} + 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&) : BaseReg(NoInit) {} + explicit ASMJIT_INLINE X86Reg(const _NoInit&) : Reg(NoInit) {} // -------------------------------------------------------------------------- // [X86Reg Specific] @@ -232,343 +518,370 @@ struct X86Reg : public BaseReg { ASMJIT_REG_OP(X86Reg) //! Get whether the register is Gp register. - ASMJIT_INLINE bool isGp() const { return _vreg.type <= kRegTypeGpq; } + 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 <= kRegTypeGpbHi; } + 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 == kRegTypeGpbLo; } + 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 == kRegTypeGpbHi; } + 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 == kRegTypeGpw; } + 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 == kRegTypeGpd; } + 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 == kRegTypeGpq; } + ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; } //! Get whether the register is Fp register. - ASMJIT_INLINE bool isFp() const { return _vreg.type == kRegTypeFp; } + 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 == kRegTypeMm; } + ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } //! Get whether the register is Xmm (128-bit) register. - ASMJIT_INLINE bool isXmm() const { return _vreg.type == kRegTypeXmm; } + 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 == kRegTypeYmm; } + 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 a segment. - ASMJIT_INLINE bool isSeg() const { return _vreg.type == kRegTypeSeg; } + 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::x86x64::GpReg] +// [asmjit::X86GpReg] // ============================================================================ //! X86/X64 Gpb/Gpw/Gpd/Gpq register. -struct GpReg : public X86Reg { +struct X86GpReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy Gp register. - ASMJIT_INLINE GpReg() : X86Reg() {} + ASMJIT_INLINE X86GpReg() : X86Reg() {} //! Create a reference to `other` Gp register. - ASMJIT_INLINE GpReg(const GpReg& other) : X86Reg(other) {} + 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 GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized Gp register. - explicit ASMJIT_INLINE GpReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86GpReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [GpReg Specific] + // [X86GpReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(GpReg) + ASMJIT_REG_OP(X86GpReg) }; // ============================================================================ -// [asmjit::x86x64::FpReg] +// [asmjit::X86FpReg] // ============================================================================ //! X86/X64 80-bit Fp register. -struct FpReg : public X86Reg { +struct X86FpReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy Fp register. - ASMJIT_INLINE FpReg() : X86Reg() {} - //! Create a reference to `other` FPU register. - ASMJIT_INLINE FpReg(const FpReg& other) : X86Reg(other) {} + 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 FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized Fp register. - explicit ASMJIT_INLINE FpReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86FpReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [FpReg Specific] + // [X86FpReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(FpReg) + ASMJIT_REG_OP(X86FpReg) }; // ============================================================================ -// [asmjit::x86x64::MmReg] +// [asmjit::X86MmReg] // ============================================================================ //! X86/X64 64-bit Mm register. -struct MmReg : public X86Reg { +struct X86MmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy Mm register. - ASMJIT_INLINE MmReg() : X86Reg() {} + ASMJIT_INLINE X86MmReg() : X86Reg() {} //! Create a reference to `other` Mm register. - ASMJIT_INLINE MmReg(const MmReg& other) : X86Reg(other) {} + 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 MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized Mm register. - explicit ASMJIT_INLINE MmReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86MmReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [MmReg Specific] + // [X86MmReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(MmReg) + ASMJIT_REG_OP(X86MmReg) }; // ============================================================================ -// [asmjit::x86x64::XmmReg] +// [asmjit::X86XmmReg] // ============================================================================ //! X86/X64 128-bit Xmm register. -struct XmmReg : public X86Reg { +struct X86XmmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy Xmm register. - ASMJIT_INLINE XmmReg() : X86Reg() {} + ASMJIT_INLINE X86XmmReg() : X86Reg() {} //! Create a reference to `other` Xmm register. - ASMJIT_INLINE XmmReg(const XmmReg& other) : X86Reg(other) {} + 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 XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized Xmm register. - explicit ASMJIT_INLINE XmmReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [XmmReg Specific] + // [X86XmmReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(XmmReg) + ASMJIT_REG_OP(X86XmmReg) }; // ============================================================================ -// [asmjit::x86x64::YmmReg] +// [asmjit::X86YmmReg] // ============================================================================ //! X86/X64 256-bit Ymm register. -struct YmmReg : public X86Reg { +struct X86YmmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy Ymm register. - ASMJIT_INLINE YmmReg() : X86Reg() {} + ASMJIT_INLINE X86YmmReg() : X86Reg() {} //! Create a reference to `other` Xmm register. - ASMJIT_INLINE YmmReg(const YmmReg& other) : X86Reg(other) {} + 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 YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized Ymm register. - explicit ASMJIT_INLINE YmmReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [YmmReg Specific] + // [X86YmmReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(YmmReg) + ASMJIT_REG_OP(X86YmmReg) }; // ============================================================================ -// [asmjit::x86x64::SegReg] +// [asmjit::X86SegReg] // ============================================================================ //! X86/X64 segment register. -struct SegReg : public X86Reg { +struct X86SegReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- //! Create a dummy segment register. - ASMJIT_INLINE SegReg() : X86Reg() {} + ASMJIT_INLINE X86SegReg() : X86Reg() {} //! Create a reference to `other` segment register. - ASMJIT_INLINE SegReg(const SegReg& other) : X86Reg(other) {} + 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 SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} //! Create non-initialized segment register. - explicit ASMJIT_INLINE SegReg(const _NoInit&) : X86Reg(NoInit) {} + explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [SegReg Specific] + // [X86SegReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(SegReg) + ASMJIT_REG_OP(X86SegReg) }; // ============================================================================ -// [asmjit::x86x64::Mem] +// [asmjit::X86Mem] // ============================================================================ //! X86 memory operand. -struct Mem : public BaseMem { +struct X86Mem : public BaseMem { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE Mem() : BaseMem(NoInit) { + ASMJIT_INLINE X86Mem() : BaseMem(NoInit) { reset(); } - ASMJIT_INLINE Mem(const Label& label, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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 Mem(const Label& label, const GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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, - (kMemVSibGpz << kMemVSibIndex) - + (shift << kMemShiftIndex), + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), label.getId()); _vmem.index = index.getRegIndex(); _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const Label& label, const GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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, - (kMemVSibGpz << kMemVSibIndex) - + (shift << kMemShiftIndex), + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), label.getId()); _vmem.index = _OP_ID(index); _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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(base) - + (kMemVSibGpz << kMemVSibIndex), - base.getRegIndex()); - _init_packed_d2_d3(kInvalidValue, disp); - } - - ASMJIT_INLINE Mem(const GpReg& base, const GpReg& 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 << kMemShiftIndex), - base.getRegIndex()); - _vmem.index = index.getRegIndex(); - _vmem.displacement = disp; - } - - ASMJIT_INLINE Mem(const GpReg& base, const XmmReg& 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) - + (kMemVSibXmm << kMemVSibIndex) - + (shift << kMemShiftIndex), - base.getRegIndex()); - _vmem.index = index.getRegIndex(); - _vmem.displacement = disp; - } - - ASMJIT_INLINE Mem(const GpReg& base, const YmmReg& 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) - + (kMemVSibYmm << kMemVSibIndex) - + (shift << kMemShiftIndex), - base.getRegIndex()); - _vmem.index = index.getRegIndex(); - _vmem.displacement = disp; - } - - ASMJIT_INLINE Mem(const GpVar& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { - _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, - _getGpdFlags(reinterpret_cast(base)) - + (kMemVSibGpz << kMemVSibIndex), + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibGpz << kX86MemVSibIndex), _OP_ID(base)); _init_packed_d2_d3(kInvalidValue, disp); } - - ASMJIT_INLINE Mem(const GpVar& base, const GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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 << kMemShiftIndex), + _getGpdFlags(reinterpret_cast(base)) + + (shift << kX86MemShiftIndex), _OP_ID(base)); _vmem.index = _OP_ID(index); _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const GpVar& base, const XmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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)) - + (kMemVSibXmm << kMemVSibIndex) - + (shift << kMemShiftIndex), + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibXmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), _OP_ID(base)); _vmem.index = _OP_ID(index); _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const GpVar& base, const YmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + 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)) - + (kMemVSibYmm << kMemVSibIndex) - + (shift << kMemShiftIndex), + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibYmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), _OP_ID(base)); _vmem.index = _OP_ID(index); _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) { + 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, _OP_ID(base)); _vmem.index = kInvalidValue; _vmem.displacement = disp; } - ASMJIT_INLINE Mem(const _Init&, uint32_t memType, const X86Var& base, const GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) { + 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 << kMemShiftIndex, _OP_ID(base)); + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, _OP_ID(base)); _vmem.index = _OP_ID(index); _vmem.displacement = disp; } +#endif // !ASMJIT_DISABLE_COMPILER - ASMJIT_INLINE Mem(const Mem& other) : BaseMem(other) {} - explicit ASMJIT_INLINE Mem(const _NoInit&) : BaseMem(NoInit) {} + ASMJIT_INLINE X86Mem(const X86Mem& other) : BaseMem(other) {} + explicit ASMJIT_INLINE X86Mem(const _NoInit&) : BaseMem(NoInit) {} // -------------------------------------------------------------------------- - // [Mem Specific] + // [X86Mem Specific] // -------------------------------------------------------------------------- - //! Clone Mem operand. - ASMJIT_INLINE Mem clone() const { - return Mem(*this); + //! Clone X86Mem operand. + ASMJIT_INLINE X86Mem clone() const { + return X86Mem(*this); } - //! Reset Mem operand. + //! 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); @@ -587,23 +900,23 @@ struct Mem : public BaseMem { //! Get whether the memory operand has segment override prefix. ASMJIT_INLINE bool hasSegment() const { - return (_vmem.flags & kMemSegMask) != (kSegDefault << kMemSegIndex); + return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex); } - //! Get memory operand segment, see `kSeg`. + //! Get memory operand segment, see `kX86Seg`. ASMJIT_INLINE uint32_t getSegment() const { - return (static_cast(_vmem.flags) >> kMemSegIndex) & kMemSegBits; + return (static_cast(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits; } - //! Set memory operand segment, see `kSeg`. - ASMJIT_INLINE Mem& setSegment(uint32_t segIndex) { + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) { _vmem.flags = static_cast( - (static_cast(_vmem.flags) & kMemSegMask) + (segIndex << kMemSegIndex)); + (static_cast(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex)); return *this; } - //! Set memory operand segment, see `kSeg`. - ASMJIT_INLINE Mem& setSegment(const SegReg& seg) { + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) { return setSegment(seg.getRegIndex()); } @@ -613,19 +926,19 @@ struct Mem : public BaseMem { //! 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, kMemGpdMask)) != 0; + 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 Mem& setGpdBase() { - _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, kMemGpdMask); + 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 Mem& setGpdBase(uint32_t b) { - _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kMemGpdMask); - _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, b << kMemGpdIndex); + 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; } @@ -635,13 +948,13 @@ struct Mem : public BaseMem { //! Get SIB type. ASMJIT_INLINE uint32_t getVSib() const { - return (static_cast(_vmem.flags) >> kMemVSibIndex) & kMemVSibBits; + return (static_cast(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits; } //! Set SIB type. - ASMJIT_INLINE Mem& _setVSib(uint32_t vsib) { - _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kMemVSibMask); - _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kMemVSibIndex); + 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; } @@ -650,7 +963,7 @@ struct Mem : public BaseMem { // -------------------------------------------------------------------------- //! Set memory operand size. - ASMJIT_INLINE Mem& setSize(uint32_t size) { + ASMJIT_INLINE X86Mem& setSize(uint32_t size) { _vmem.size = static_cast(size); return *this; } @@ -670,7 +983,7 @@ struct Mem : public BaseMem { } //! Set memory operand base register code, variable id, or `kInvalidValue`. - ASMJIT_INLINE Mem& setBase(uint32_t base) { + ASMJIT_INLINE X86Mem& setBase(uint32_t base) { _vmem.base = base; return *this; } @@ -690,87 +1003,90 @@ struct Mem : public BaseMem { } //! Set memory operand index register code, variable id, or `kInvalidValue`. - ASMJIT_INLINE Mem& setIndex(uint32_t index) { + ASMJIT_INLINE X86Mem& setIndex(uint32_t index) { _vmem.index = index; return *this; } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const GpReg& index) { + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibGpz); + return _setVSib(kX86MemVSibGpz); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const GpReg& index, uint32_t shift) { + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index, uint32_t shift) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibGpz).setShift(shift); + return _setVSib(kX86MemVSibGpz).setShift(shift); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const GpVar& index) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibGpz); - } - - //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const GpVar& index, uint32_t shift) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibGpz).setShift(shift); - } - - //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const XmmReg& index) { + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibXmm); + return _setVSib(kX86MemVSibXmm); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const XmmReg& index, uint32_t shift) { + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index, uint32_t shift) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibXmm).setShift(shift); + return _setVSib(kX86MemVSibXmm).setShift(shift); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const XmmVar& index) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibXmm); - } - - //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const XmmVar& index, uint32_t shift) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibXmm).setShift(shift); - } - - //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const YmmReg& index) { + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibYmm); + return _setVSib(kX86MemVSibYmm); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const YmmReg& index, uint32_t shift) { + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index, uint32_t shift) { _vmem.index = index.getRegIndex(); - return _setVSib(kMemVSibYmm).setShift(shift); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } + +#if !defined(ASMJIT_DISABLE_COMPILER) + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibGpz); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const YmmVar& index) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibYmm); + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibGpz).setShift(shift); + } + + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibXmm); } //! Set memory index. - ASMJIT_INLINE Mem& setIndex(const YmmVar& index, uint32_t shift) { - _vmem.index = reinterpret_cast(index).getId(); - return _setVSib(kMemVSibYmm).setShift(shift); + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibXmm).setShift(shift); } + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibYmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } +#endif // !ASMJIT_DISABLE_COMPILER + //! Reset memory index. - ASMJIT_INLINE Mem& resetIndex() { + ASMJIT_INLINE X86Mem& resetIndex() { _vmem.index = kInvalidValue; - return _setVSib(kMemVSibGpz); + return _setVSib(kX86MemVSibGpz); } // -------------------------------------------------------------------------- @@ -793,18 +1109,18 @@ struct Mem : public BaseMem { //! Get whether the memory operand has shift used. ASMJIT_INLINE bool hasShift() const { - return (_vmem.flags & kMemShiftMask) != 0; + return (_vmem.flags & kX86MemShiftMask) != 0; } //! Get memory operand index scale (0, 1, 2 or 3). ASMJIT_INLINE uint32_t getShift() const { - return _vmem.flags >> kMemShiftIndex; + return _vmem.flags >> kX86MemShiftIndex; } //! Set memory operand index scale (0, 1, 2 or 3). - ASMJIT_INLINE Mem& setShift(uint32_t shift) { - _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kMemShiftMask); - _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, shift << kMemShiftIndex); + 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; } @@ -818,26 +1134,26 @@ struct Mem : public BaseMem { } //! Set memory operand relative displacement. - ASMJIT_INLINE Mem& setDisplacement(int32_t disp) { + ASMJIT_INLINE X86Mem& setDisplacement(int32_t disp) { _vmem.displacement = disp; return *this; } //! Reset memory operand relative displacement. - ASMJIT_INLINE Mem& resetDisplacement(int32_t disp) { + ASMJIT_INLINE X86Mem& resetDisplacement(int32_t disp) { _vmem.displacement = 0; return *this; } //! Adjust memory operand relative displacement by `disp`. - ASMJIT_INLINE Mem& adjust(int32_t disp) { + ASMJIT_INLINE X86Mem& adjust(int32_t disp) { _vmem.displacement += disp; return *this; } //! Get new memory operand adjusted by `disp`. - ASMJIT_INLINE Mem adjusted(int32_t disp) const { - Mem result(*this); + ASMJIT_INLINE X86Mem adjusted(int32_t disp) const { + X86Mem result(*this); result.adjust(disp); return result; } @@ -846,16 +1162,16 @@ struct Mem : public BaseMem { // [Operator Overload] // -------------------------------------------------------------------------- - ASMJIT_INLINE Mem& operator=(const Mem& other) { + ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) { _copy(other); return *this; } - ASMJIT_INLINE bool operator==(const Mem& other) const { + ASMJIT_INLINE bool operator==(const X86Mem& other) const { return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]) ; } - ASMJIT_INLINE bool operator!=(const Mem& other) const { + ASMJIT_INLINE bool operator!=(const X86Mem& other) const { return !(*this == other); } @@ -864,789 +1180,348 @@ struct Mem : public BaseMem { // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t _getGpdFlags(const Operand& base) { - return (base._vreg.size & 0x4) << (kMemGpdIndex - 2); + return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2); } }; - -// ============================================================================ -// [asmjit::x86x64::X86Var] -// ============================================================================ - -//! Base class for all variables. -struct X86Var : public BaseVar { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE X86Var() : BaseVar(NoInit) { - reset(); - } - - ASMJIT_INLINE X86Var(const X86Var& other) : BaseVar(other) {} - - explicit ASMJIT_INLINE X86Var(const _NoInit&) : BaseVar(NoInit) {} - - // -------------------------------------------------------------------------- - // [X86Var Specific] - // -------------------------------------------------------------------------- - - //! Clone X86Var operand. - ASMJIT_INLINE X86Var clone() const { - return X86Var(*this); - } - - //! Reset X86Var operand. - ASMJIT_INLINE void reset() { - _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue); - _init_packed_d2_d3(kInvalidValue, kInvalidValue); - } - - // -------------------------------------------------------------------------- - // [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 Gpb register. - ASMJIT_INLINE bool isGp() const { return _vreg.type <= kRegTypeGpq; } - //! Get whether the variable is Gpb register. - ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kRegTypeGpbHi; } - //! Get whether the variable is Gpb-lo register. - ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kRegTypeGpbLo; } - //! Get whether the variable is Gpb-hi register. - ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kRegTypeGpbHi; } - //! Get whether the variable is Gpw register. - ASMJIT_INLINE bool isGpw() const { return _vreg.type == kRegTypeGpw; } - //! Get whether the variable is Gpd register. - ASMJIT_INLINE bool isGpd() const { return _vreg.type == kRegTypeGpd; } - //! Get whether the variable is Gpq register. - ASMJIT_INLINE bool isGpq() const { return _vreg.type == kRegTypeGpq; } - - //! Get whether the variable is Fp register. - ASMJIT_INLINE bool isFp() const { return _vreg.type == kRegTypeFp; } - //! Get whether the variable is Mm type. - ASMJIT_INLINE bool isMm() const { return _vreg.type == kRegTypeMm; } - //! Get whether the variable is Xmm type. - ASMJIT_INLINE bool isXmm() const { return _vreg.type == kRegTypeXmm; } - //! Get whether the variable is Ymm type. - ASMJIT_INLINE bool isYmm() const { return _vreg.type == kRegTypeYmm; } - - // -------------------------------------------------------------------------- - // [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 Mem m(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, getSize()); - } - - //! \overload - ASMJIT_INLINE Mem m(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, getSize()); - } - - //! Cast this variable to 8-bit memory operand. - ASMJIT_INLINE Mem m8(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 1); - } - - //! \overload - ASMJIT_INLINE Mem m8(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 1); - } - - //! Cast this variable to 16-bit memory operand. - ASMJIT_INLINE Mem m16(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 2); - } - - //! \overload - ASMJIT_INLINE Mem m16(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 2); - } - - //! Cast this variable to 32-bit memory operand. - ASMJIT_INLINE Mem m32(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 4); - } - - //! \overload - ASMJIT_INLINE Mem m32(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 4); - } - - //! Cast this variable to 64-bit memory operand. - ASMJIT_INLINE Mem m64(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 8); - } - - //! \overload - ASMJIT_INLINE Mem m64(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 8); - } - - //! Cast this variable to 80-bit memory operand (long double). - ASMJIT_INLINE Mem m80(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 10); - } - - //! \overload - ASMJIT_INLINE Mem m80(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 10); - } - - //! Cast this variable to 128-bit memory operand. - ASMJIT_INLINE Mem m128(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 16); - } - - //! \overload - ASMJIT_INLINE Mem m128(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 16); - } - - //! Cast this variable to 256-bit memory operand. - ASMJIT_INLINE Mem m256(int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, disp, 32); - } - - //! \overload - ASMJIT_INLINE Mem m256(const GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { - return Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 32); - } - - // -------------------------------------------------------------------------- - // [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 !operator==(other); } - - // -------------------------------------------------------------------------- - // [Private] - // -------------------------------------------------------------------------- - -protected: - ASMJIT_INLINE X86Var(const X86Var& other, uint32_t reg, uint32_t size) : BaseVar(NoInit) { - _init_packed_op_sz_w0_id(kOperandTypeVar, size, (reg << 8) + other._vreg.index, other._base.id); - _vreg.vType = other._vreg.vType; - } -}; - -// ============================================================================ -// [asmjit::x86x64::GpVar] -// ============================================================================ - -//! Gp variable. -struct GpVar : public X86Var { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new uninitialized `GpVar` instance. - ASMJIT_INLINE GpVar() : X86Var() {} - - //! Create a new initialized `GpVar` instance. - ASMJIT_INLINE GpVar(BaseCompiler& c, uint32_t type = kVarTypeIntPtr, const char* name = NULL) : X86Var(NoInit) { - c._newVar(this, type, name); - } - - //! Create a clone of `other`. - ASMJIT_INLINE GpVar(const GpVar& other) : X86Var(other) {} - - //! Create a new uninitialized `GpVar` instance (internal). - explicit ASMJIT_INLINE GpVar(const _NoInit&) : X86Var(NoInit) {} - - // -------------------------------------------------------------------------- - // [GpVar Specific] - // -------------------------------------------------------------------------- - - //! Clone GpVar operand. - ASMJIT_INLINE GpVar clone() const { - return GpVar(*this); - } - - //! Reset GpVar operand. - ASMJIT_INLINE void reset() { - X86Var::reset(); - } - - // -------------------------------------------------------------------------- - // [GpVar Cast] - // -------------------------------------------------------------------------- - - //! Cast this variable to 8-bit (LO) part of variable - ASMJIT_INLINE GpVar r8() const { return GpVar(*this, kRegTypeGpbLo, 1); } - //! Cast this variable to 8-bit (LO) part of variable - ASMJIT_INLINE GpVar r8Lo() const { return GpVar(*this, kRegTypeGpbLo, 1); } - //! Cast this variable to 8-bit (HI) part of variable - ASMJIT_INLINE GpVar r8Hi() const { return GpVar(*this, kRegTypeGpbHi, 1); } - - //! Cast this variable to 16-bit part of variable - ASMJIT_INLINE GpVar r16() const { return GpVar(*this, kRegTypeGpw, 2); } - //! Cast this variable to 32-bit part of variable - ASMJIT_INLINE GpVar r32() const { return GpVar(*this, kRegTypeGpd, 4); } - //! Cast this variable to 64-bit part of variable - ASMJIT_INLINE GpVar r64() const { return GpVar(*this, kRegTypeGpq, 8); } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE GpVar& operator=(const GpVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const GpVar& other) const { return X86Var::operator==(other); } - ASMJIT_INLINE bool operator!=(const GpVar& other) const { return X86Var::operator!=(other); } - - // -------------------------------------------------------------------------- - // [Private] - // -------------------------------------------------------------------------- - -protected: - ASMJIT_INLINE GpVar(const GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {} -}; - -// ============================================================================ -// [asmjit::x86x64::FpVar] -// ============================================================================ - -//! Fpu variable. -struct FpVar : public X86Var { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new uninitialized `FpVar` instance. - ASMJIT_INLINE FpVar() : X86Var() {} - //! Create a new variable that links to `other`. - ASMJIT_INLINE FpVar(const FpVar& other) : X86Var(other) {} - - //! Create a new uninitialized `FpVar` instance (internal). - explicit ASMJIT_INLINE FpVar(const _NoInit&) : X86Var(NoInit) {} - - // -------------------------------------------------------------------------- - // [FpVar Specific] - // -------------------------------------------------------------------------- - - //! Clone FpVar operand. - ASMJIT_INLINE FpVar clone() const { - return FpVar(*this); - } - - //! Reset FpVar operand. - ASMJIT_INLINE void reset() { - X86Var::reset(); - } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE FpVar& operator=(const FpVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const FpVar& other) const { return X86Var::operator==(other); } - ASMJIT_INLINE bool operator!=(const FpVar& other) const { return X86Var::operator!=(other); } -}; - -// ============================================================================ -// [asmjit::x86x64::MmVar] -// ============================================================================ - -//! Mm variable. -struct MmVar : public X86Var { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new uninitialized `MmVar` instance. - ASMJIT_INLINE MmVar() : X86Var() {} - //! Create a new initialized `MmVar` instance. - ASMJIT_INLINE MmVar(BaseCompiler& c, uint32_t type = kVarTypeMm, const char* name = NULL) : X86Var(NoInit) { - c._newVar(this, type, name); - } - - //! Create a clone of `other`. - ASMJIT_INLINE MmVar(const MmVar& other) : X86Var(other) {} - - //! Create a new uninitialized `MmVar` instance (internal). - explicit ASMJIT_INLINE MmVar(const _NoInit&) : X86Var(NoInit) {} - - // -------------------------------------------------------------------------- - // [MmVar Specific] - // -------------------------------------------------------------------------- - - //! Clone MmVar operand. - ASMJIT_INLINE MmVar clone() const { - return MmVar(*this); - } - - //! Reset MmVar operand. - ASMJIT_INLINE void reset() { - X86Var::reset(); - } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE MmVar& operator=(const MmVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const MmVar& other) const { return X86Var::operator==(other); } - ASMJIT_INLINE bool operator!=(const MmVar& other) const { return X86Var::operator!=(other); } -}; - -// ============================================================================ -// [asmjit::x86x64::XmmVar] -// ============================================================================ - -//! Xmm variable. -struct XmmVar : public X86Var { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new uninitialized `XmmVar` instance. - ASMJIT_INLINE XmmVar() : X86Var() {} - //! Create a new initialized `XmmVar` instance. - ASMJIT_INLINE XmmVar(BaseCompiler& c, uint32_t type = kVarTypeXmm, const char* name = NULL) : X86Var(NoInit) { - c._newVar(this, type, name); - } - - //! Create a clone of `other`. - ASMJIT_INLINE XmmVar(const XmmVar& other) : X86Var(other) {} - - //! Create a new uninitialized `XmmVar` instance (internal). - explicit ASMJIT_INLINE XmmVar(const _NoInit&) : X86Var(NoInit) {} - - // -------------------------------------------------------------------------- - // [XmmVar Specific] - // -------------------------------------------------------------------------- - - //! Clone XmmVar operand. - ASMJIT_INLINE XmmVar clone() const { - return XmmVar(*this); - } - - //! Reset XmmVar operand. - ASMJIT_INLINE void reset() { - X86Var::reset(); - } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE XmmVar& operator=(const XmmVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const XmmVar& other) const { return X86Var::operator==(other); } - ASMJIT_INLINE bool operator!=(const XmmVar& other) const { return X86Var::operator!=(other); } -}; - -// ============================================================================ -// [asmjit::x86x64::YmmVar] -// ============================================================================ - -//! Ymm variable. -struct YmmVar : public X86Var { - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a new uninitialized `YmmVar` instance. - ASMJIT_INLINE YmmVar() : X86Var() {} - //! Create a new initialized `YmmVar` instance. - ASMJIT_INLINE YmmVar(BaseCompiler& c, uint32_t type = kVarTypeYmm, const char* name = NULL) : X86Var(NoInit) { - c._newVar(this, type, name); - } - - //! Create a clone of `other`. - ASMJIT_INLINE YmmVar(const YmmVar& other) : X86Var(other) {} - - //! Create a new uninitialized `YmmVar` instance (internal). - explicit ASMJIT_INLINE YmmVar(const _NoInit&) : X86Var(NoInit) {} - - // -------------------------------------------------------------------------- - // [YmmVar Specific] - // -------------------------------------------------------------------------- - - //! Clone YmmVar operand. - ASMJIT_INLINE YmmVar clone() const { - return YmmVar(*this); - } - - //! Reset YmmVar operand. - ASMJIT_INLINE void reset() { - X86Var::reset(); - } - - // -------------------------------------------------------------------------- - // [Operator Overload] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE YmmVar& operator=(const YmmVar& other) { _copy(other); return *this; } - - ASMJIT_INLINE bool operator==(const YmmVar& other) const { return X86Var::operator==(other); } - ASMJIT_INLINE bool operator!=(const YmmVar& other) const { return X86Var::operator!=(other); } -}; - -// ============================================================================ -// [asmjit::x86x64::Registers] -// ============================================================================ - -//! Make 8-bit Gpb-lo register operand. -static ASMJIT_INLINE GpReg gpb_lo(uint32_t index) { return GpReg(kRegTypeGpbLo, index, 1); } -//! Make 8-bit Gpb-hi register operand. -static ASMJIT_INLINE GpReg gpb_hi(uint32_t index) { return GpReg(kRegTypeGpbHi, index, 1); } -//! Make 16-bit Gpw register operand. -static ASMJIT_INLINE GpReg gpw(uint32_t index) { return GpReg(kRegTypeGpw, index, 2); } -//! Make 32-bit Gpd register operand. -static ASMJIT_INLINE GpReg gpd(uint32_t index) { return GpReg(kRegTypeGpd, index, 4); } -//! Make 64-bit Gpq register operand (X64). -static ASMJIT_INLINE GpReg gpq(uint32_t index) { return GpReg(kRegTypeGpq, index, 8); } -//! Make 80-bit Fp register operand. -static ASMJIT_INLINE FpReg fp(uint32_t index) { return FpReg(kRegTypeFp, index, 10); } -//! Make 64-bit Mm register operand. -static ASMJIT_INLINE MmReg mm(uint32_t index) { return MmReg(kRegTypeMm, index, 8); } -//! Make 128-bit Xmm register operand. -static ASMJIT_INLINE XmmReg xmm(uint32_t index) { return XmmReg(kRegTypeXmm, index, 16); } -//! Make 256-bit Ymm register operand. -static ASMJIT_INLINE YmmReg ymm(uint32_t index) { return YmmReg(kRegTypeYmm, index, 32); } - -// ============================================================================ -// [asmjit::x86x64::Memory] -// ============================================================================ - -//! Make `[base.reg + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpReg& base, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, disp, size); -} -//! Make `[base.var + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpVar& base, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, disp, size); -} - -//! Make `[base.reg + (index.reg << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} -//! Make `[base.var + (index.var << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} - -//! Make `[base.reg + (xmm.reg << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpReg& base, const XmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} -//! Make `[base.var + (xmm.var << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpVar& base, const XmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} -//! Make `[base.reg + (ymm.reg << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpReg& base, const YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} -//! Make `[base.var + (ymm.var << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const GpVar& base, const YmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { - return Mem(base, index, shift, disp, size); -} - -//! Make `[label + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) { - return Mem(label, disp, size); -} -//! Make `[label + (index.reg << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const Label& label, const GpReg& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ - return Mem(label, index, shift, disp, size); \ -} -//! Make `[label + (index.var << shift) + disp]` memory operand with no/custom size information. -static ASMJIT_INLINE Mem ptr(const Label& label, const GpVar& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ - return Mem(label, index, shift, disp, size); \ -} - -//! Make `[pAbs + disp]` absolute memory operand with no/custom size information. -ASMJIT_API Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0); -//! Make `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information. -ASMJIT_API Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); -//! Make `[pAbs + (index.var << shift) + disp]` absolute memory operand with no/custom size information. -ASMJIT_API Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); - -//! \internal -#define ASMJIT_X86_DEFINE_PTR(_Prefix_, _Size_) \ - /*! Make `[base.reg + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpReg& base, int32_t disp = 0) { \ - return Mem(base, disp, _Size_); \ - } \ - /*! Make `[base.var + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpVar& base, int32_t disp = 0) { \ - return Mem(base, disp, _Size_); \ - } \ - /*! Make `[base.reg + (index.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[base.var + (index.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[base.reg + (xmm.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpReg& base, const XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[base.var + (xmm.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpVar& base, const XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[base.reg + (ymm.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpReg& base, const YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[base.var + (ymm.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const GpVar& base, const YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr(base, index, shift, disp, _Size_); \ - } \ - /*! Make `[label + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const Label& label, int32_t disp = 0) { \ - return ptr(label, disp, _Size_); \ - } \ - /*! Make `[label + (index.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const Label& label, const GpReg& index, uint32_t shift, int32_t disp = 0) { \ - return ptr(label, index, shift, disp, _Size_); \ - } \ - /*! Make `[label + (index.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr(const Label& label, const GpVar& index, uint32_t shift, int32_t disp = 0) { \ - return ptr(label, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \ - return ptr_abs(pAbs, disp, _Size_); \ - } \ - /*! Make `[pAbs + (index.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + (index.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + (xmm.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + (xmm.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + (ymm.reg << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } \ - /*! Make `[pAbs + (ymm.var << shift) + disp]` memory operand. */ \ - static ASMJIT_INLINE Mem _Prefix_##_ptr##_abs(Ptr pAbs, const YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ - return ptr_abs(pAbs, index, shift, disp, _Size_); \ - } - -ASMJIT_X86_DEFINE_PTR(byte, 1) -ASMJIT_X86_DEFINE_PTR(word, 2) -ASMJIT_X86_DEFINE_PTR(dword, 4) -ASMJIT_X86_DEFINE_PTR(qword, 8) -ASMJIT_X86_DEFINE_PTR(tword, 10) -ASMJIT_X86_DEFINE_PTR(oword, 16) -ASMJIT_X86_DEFINE_PTR(yword, 32) - -#undef ASMJIT_X86_DEFINE_PTR - -// ============================================================================ -// [asmjit::x86x64::x86VarTypeToClass] -// ============================================================================ - -static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) { - // Getting varClass is the only safe operation when dealing with denormalized - // varType. Any other property would require to map vType to the architecture - // specific one. - ASMJIT_ASSERT(vType < kVarTypeCount); - return _varInfo[vType].getClass(); -} - -//! \} - -} // x86x64 namespace -} // asmjit namespace +#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS // ============================================================================ // [asmjit::x86] // ============================================================================ -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { namespace x86 { -//! \addtogroup asmjit_x86x64_general -//! \{ - // ============================================================================ -// [asmjit::x86::kRegCount] +// [asmjit::x86 - Reg] // ============================================================================ -//! X86 registers count per class. -ASMJIT_ENUM(kRegCount) { - //! Base count of registers (8). - kRegCountBase = 8, - //! Count of Gp registers (8). - kRegCountGp = kRegCountBase, - //! Count of Xmm registers (8). - kRegCountXmm = kRegCountBase, - //! Count of Ymm registers (8). - kRegCountYmm = kRegCountBase -}; +//! No Gp register, can be used only within `X86Mem` operand. +ASMJIT_VAR const X86GpReg noGpReg; + +ASMJIT_VAR const X86GpReg al; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg cl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg dl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg bl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg spl; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg bpl; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg sil; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg dil; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r8b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r9b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r10b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r11b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r12b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r13b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r14b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r15b; //!< 8-bit Gpb-lo register (X64). + +ASMJIT_VAR const X86GpReg ah; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg ch; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg dh; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg bh; //!< 8-bit Gpb-hi register. + +ASMJIT_VAR const X86GpReg ax; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg cx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg dx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg bx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg sp; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg bp; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg si; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg di; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg r8w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r9w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r10w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r11w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r12w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r13w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r14w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r15w; //!< 16-bit Gpw register (X64). + +ASMJIT_VAR const X86GpReg eax; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ecx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg edx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ebx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg esp; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ebp; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg esi; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg edi; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg r8d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r9d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r10d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r11d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r12d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r13d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r14d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r15d; //!< 32-bit Gpd register (X64). + +ASMJIT_VAR const X86GpReg rax; //!< 64-bit Gpq register (X64). +ASMJIT_VAR const X86GpReg rcx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rdx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rbx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rsp; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rbp; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rsi; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rdi; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r8; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r9; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r10; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r11; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r12; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r13; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r14; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r15; //!< 64-bit Gpq register (X64) + +ASMJIT_VAR const X86FpReg fp0; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp1; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp2; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp3; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp4; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp5; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp6; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp7; //!< 80-bit Fp register. + +ASMJIT_VAR const X86MmReg mm0; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm1; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm2; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm3; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm4; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm5; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm6; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm7; //!< 64-bit Mm register. + +ASMJIT_VAR const X86XmmReg xmm0; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm1; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm2; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm3; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm4; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm5; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm6; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm7; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm8; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm9; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm10; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm11; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm12; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm13; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm14; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm15; //!< 128-bit Xmm register (X64). + +ASMJIT_VAR const X86YmmReg ymm0; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm1; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm2; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm3; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm4; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm5; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm6; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm7; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm8; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm9; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm10; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm11; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm12; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm13; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm14; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm15; //!< 256-bit Ymm register (X64). + +ASMJIT_VAR const X86SegReg cs; //!< Cs segment register. +ASMJIT_VAR const X86SegReg ss; //!< Ss segment register. +ASMJIT_VAR const X86SegReg ds; //!< Ds segment register. +ASMJIT_VAR const X86SegReg es; //!< Es segment register. +ASMJIT_VAR const X86SegReg fs; //!< Fs segment register. +ASMJIT_VAR const X86SegReg gs; //!< Gs segment register. + +// 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 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); } // ============================================================================ -// [asmjit::x86::Variables] +// [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 -//! -//! Mapping of x86 variables into their real IDs. -//! -//! This mapping translates the following: -//! - `kVarTypeInt64` to `kVarTypeInvalid`. -//! - `kVarTypeUInt64` to `kVarTypeInvalid`. -//! - `kVarTypeIntPtr` to `kVarTypeInt32`. -//! - `kVarTypeUIntPtr` to `kVarTypeUInt32`. -ASMJIT_VAR const uint8_t _varMapping[kVarTypeCount]; +#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::Registers] +// [asmjit::x86 - Ptr (Var)] // ============================================================================ -//! Get Gp qword register. -static ASMJIT_INLINE GpReg gpz(uint32_t index) { return GpReg(kRegTypeGpd, index, 4); } +#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); \ +} -// ============================================================================ -// [asmjit::x86::Mem] -// ============================================================================ +//! 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); -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpReg& base, int32_t disp = 0) { return ptr(base, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpVar& base, int32_t disp = 0) { return ptr(base, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, int32_t disp = 0) { return ptr(base, index, shift, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, int32_t disp = 0) { return ptr(base, index, shift, disp, 4); } +//! \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_); \ + } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, int32_t disp = 0) { return ptr(label, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, const GpReg& index, uint32_t shift, int32_t disp = 0) { return ptr(label, index, shift, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, const GpVar& index, uint32_t shift, int32_t disp = 0) { return ptr(label, index, shift, disp, 4); } +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 -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) { return ptr_abs(pAbs, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, const GpReg& index, uint32_t shift, int32_t disp = 0) { return ptr_abs(pAbs, index, shift, disp, 4); } -//! Create an intptr_t 32-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, const GpVar& index, uint32_t shift, int32_t disp = 0) { return ptr_abs(pAbs, index, shift, disp, 4); } - -//! \} +#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS } // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -//! \addtogroup asmjit_x86x64_general -//! \{ - -// ============================================================================ -// [asmjit::x64::kRegCount] -// ============================================================================ - -//! X86 registers count per class. -ASMJIT_ENUM(kRegCount) { - //! Base count of registers (16). - kRegCountBase = 16, - //! Count of Gp registers (16). - kRegCountGp = kRegCountBase, - //! Count of Xmm registers (16). - kRegCountXmm = kRegCountBase, - //! Count of Ymm registers (16). - kRegCountYmm = kRegCountBase -}; - -// ============================================================================ -// [asmjit::x64::Variables] -// ============================================================================ - -//! \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 _varMapping[kVarTypeCount]; - -// ============================================================================ -// [asmjit::x64::Registers] -// ============================================================================ - -//! Get Gpq register. -static ASMJIT_INLINE GpReg gpz(uint32_t index) { return GpReg(kRegTypeGpq, index, 8); } - -// ============================================================================ -// [asmjit::x64::Mem] -// ============================================================================ - -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, int32_t disp = 0) { return ptr(label, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, const GpReg& index, uint32_t shift, int32_t disp = 0) { return ptr(label, index, shift, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const Label& label, const GpVar& index, uint32_t shift, int32_t disp = 0) { return ptr(label, index, shift, disp, 8); } - -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) { return ptr_abs(pAbs, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, const GpReg& index, uint32_t shift, int32_t disp = 0) { return ptr_abs(pAbs, index, shift, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr_abs(Ptr pAbs, const GpVar& index, uint32_t shift, int32_t disp = 0) { return ptr_abs(pAbs, index, shift, disp, 8); } - -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpReg& base, int32_t disp = 0) { return ptr(base, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpVar& base, int32_t disp = 0) { return ptr(base, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpReg& base, const GpReg& index, uint32_t shift = 0, int32_t disp = 0) { return ptr(base, index, shift, disp, 8); } -//! Create an intptr_t 64-bit pointer operand. -static ASMJIT_INLINE Mem intptr_ptr(const GpVar& base, const GpVar& index, uint32_t shift = 0, int32_t disp = 0) { return ptr(base, index, shift, disp, 8); } //! \} -} // x64 namespace } // asmjit namespace -#endif // ASMJIT_BUILD_X64 - #undef _OP_ID // [Api-End] diff --git a/src/asmjit/x86/x86operand_regs.cpp b/src/asmjit/x86/x86operand_regs.cpp new file mode 100644 index 0000000..b215ae4 --- /dev/null +++ b/src/asmjit/x86/x86operand_regs.cpp @@ -0,0 +1,188 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS +#define ASMJIT_EXPORTS_X86OPERAND_REGS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../x86/x86operand.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// Prevent static initialization. +// +// Remap all classes to POD structs so they can be statically initialized +// without calling a constructor. Compiler will store these in data section. +struct X86GpReg { Operand::VRegOp data; }; +struct X86FpReg { Operand::VRegOp data; }; +struct X86MmReg { Operand::VRegOp data; }; +struct X86XmmReg { Operand::VRegOp data; }; +struct X86YmmReg { Operand::VRegOp data; }; +struct X86SegReg { Operand::VRegOp data; }; + +namespace x86 { + +// ============================================================================ +// [asmjit::x86::Registers] +// ============================================================================ + +#define REG(_Class_, _Name_, _Type_, _Index_, _Size_) \ + const _Class_ _Name_ = {{ \ + kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \ + }} + +REG(X86GpReg, noGpReg, kInvalidReg, kInvalidReg, 0); + +REG(X86GpReg, al, kX86RegTypeGpbLo, kX86RegIndexAx, 1); +REG(X86GpReg, cl, kX86RegTypeGpbLo, kX86RegIndexCx, 1); +REG(X86GpReg, dl, kX86RegTypeGpbLo, kX86RegIndexDx, 1); +REG(X86GpReg, bl, kX86RegTypeGpbLo, kX86RegIndexBx, 1); +REG(X86GpReg, spl, kX86RegTypeGpbLo, kX86RegIndexSp, 1); +REG(X86GpReg, bpl, kX86RegTypeGpbLo, kX86RegIndexBp, 1); +REG(X86GpReg, sil, kX86RegTypeGpbLo, kX86RegIndexSi, 1); +REG(X86GpReg, dil, kX86RegTypeGpbLo, kX86RegIndexDi, 1); +REG(X86GpReg, r8b, kX86RegTypeGpbLo, 8, 1); +REG(X86GpReg, r9b, kX86RegTypeGpbLo, 9, 1); +REG(X86GpReg, r10b, kX86RegTypeGpbLo, 10, 1); +REG(X86GpReg, r11b, kX86RegTypeGpbLo, 11, 1); +REG(X86GpReg, r12b, kX86RegTypeGpbLo, 12, 1); +REG(X86GpReg, r13b, kX86RegTypeGpbLo, 13, 1); +REG(X86GpReg, r14b, kX86RegTypeGpbLo, 14, 1); +REG(X86GpReg, r15b, kX86RegTypeGpbLo, 15, 1); + +REG(X86GpReg, ah, kX86RegTypeGpbHi, kX86RegIndexAx, 1); +REG(X86GpReg, ch, kX86RegTypeGpbHi, kX86RegIndexCx, 1); +REG(X86GpReg, dh, kX86RegTypeGpbHi, kX86RegIndexDx, 1); +REG(X86GpReg, bh, kX86RegTypeGpbHi, kX86RegIndexBx, 1); + +REG(X86GpReg, ax, kX86RegTypeGpw, kX86RegIndexAx, 2); +REG(X86GpReg, cx, kX86RegTypeGpw, kX86RegIndexCx, 2); +REG(X86GpReg, dx, kX86RegTypeGpw, kX86RegIndexDx, 2); +REG(X86GpReg, bx, kX86RegTypeGpw, kX86RegIndexBx, 2); +REG(X86GpReg, sp, kX86RegTypeGpw, kX86RegIndexSp, 2); +REG(X86GpReg, bp, kX86RegTypeGpw, kX86RegIndexBp, 2); +REG(X86GpReg, si, kX86RegTypeGpw, kX86RegIndexSi, 2); +REG(X86GpReg, di, kX86RegTypeGpw, kX86RegIndexDi, 2); +REG(X86GpReg, r8w, kX86RegTypeGpw, 8, 2); +REG(X86GpReg, r9w, kX86RegTypeGpw, 9, 2); +REG(X86GpReg, r10w, kX86RegTypeGpw, 10, 2); +REG(X86GpReg, r11w, kX86RegTypeGpw, 11, 2); +REG(X86GpReg, r12w, kX86RegTypeGpw, 12, 2); +REG(X86GpReg, r13w, kX86RegTypeGpw, 13, 2); +REG(X86GpReg, r14w, kX86RegTypeGpw, 14, 2); +REG(X86GpReg, r15w, kX86RegTypeGpw, 15, 2); + +REG(X86GpReg, eax, kX86RegTypeGpd, kX86RegIndexAx, 4); +REG(X86GpReg, ecx, kX86RegTypeGpd, kX86RegIndexCx, 4); +REG(X86GpReg, edx, kX86RegTypeGpd, kX86RegIndexDx, 4); +REG(X86GpReg, ebx, kX86RegTypeGpd, kX86RegIndexBx, 4); +REG(X86GpReg, esp, kX86RegTypeGpd, kX86RegIndexSp, 4); +REG(X86GpReg, ebp, kX86RegTypeGpd, kX86RegIndexBp, 4); +REG(X86GpReg, esi, kX86RegTypeGpd, kX86RegIndexSi, 4); +REG(X86GpReg, edi, kX86RegTypeGpd, kX86RegIndexDi, 4); +REG(X86GpReg, r8d, kX86RegTypeGpd, 8, 4); +REG(X86GpReg, r9d, kX86RegTypeGpd, 9, 4); +REG(X86GpReg, r10d, kX86RegTypeGpd, 10, 4); +REG(X86GpReg, r11d, kX86RegTypeGpd, 11, 4); +REG(X86GpReg, r12d, kX86RegTypeGpd, 12, 4); +REG(X86GpReg, r13d, kX86RegTypeGpd, 13, 4); +REG(X86GpReg, r14d, kX86RegTypeGpd, 14, 4); +REG(X86GpReg, r15d, kX86RegTypeGpd, 15, 4); + +REG(X86GpReg, rax, kX86RegTypeGpq, kX86RegIndexAx, 8); +REG(X86GpReg, rcx, kX86RegTypeGpq, kX86RegIndexCx, 8); +REG(X86GpReg, rdx, kX86RegTypeGpq, kX86RegIndexDx, 8); +REG(X86GpReg, rbx, kX86RegTypeGpq, kX86RegIndexBx, 8); +REG(X86GpReg, rsp, kX86RegTypeGpq, kX86RegIndexSp, 8); +REG(X86GpReg, rbp, kX86RegTypeGpq, kX86RegIndexBp, 8); +REG(X86GpReg, rsi, kX86RegTypeGpq, kX86RegIndexSi, 8); +REG(X86GpReg, rdi, kX86RegTypeGpq, kX86RegIndexDi, 8); +REG(X86GpReg, r8, kX86RegTypeGpq, 8, 8); +REG(X86GpReg, r9, kX86RegTypeGpq, 9, 8); +REG(X86GpReg, r10, kX86RegTypeGpq, 10, 8); +REG(X86GpReg, r11, kX86RegTypeGpq, 11, 8); +REG(X86GpReg, r12, kX86RegTypeGpq, 12, 8); +REG(X86GpReg, r13, kX86RegTypeGpq, 13, 8); +REG(X86GpReg, r14, kX86RegTypeGpq, 14, 8); +REG(X86GpReg, r15, kX86RegTypeGpq, 15, 8); + +REG(X86FpReg, fp0, kX86RegTypeFp, 0, 10); +REG(X86FpReg, fp1, kX86RegTypeFp, 1, 10); +REG(X86FpReg, fp2, kX86RegTypeFp, 2, 10); +REG(X86FpReg, fp3, kX86RegTypeFp, 3, 10); +REG(X86FpReg, fp4, kX86RegTypeFp, 4, 10); +REG(X86FpReg, fp5, kX86RegTypeFp, 5, 10); +REG(X86FpReg, fp6, kX86RegTypeFp, 6, 10); +REG(X86FpReg, fp7, kX86RegTypeFp, 7, 10); + +REG(X86MmReg, mm0, kX86RegTypeMm, 0, 8); +REG(X86MmReg, mm1, kX86RegTypeMm, 1, 8); +REG(X86MmReg, mm2, kX86RegTypeMm, 2, 8); +REG(X86MmReg, mm3, kX86RegTypeMm, 3, 8); +REG(X86MmReg, mm4, kX86RegTypeMm, 4, 8); +REG(X86MmReg, mm5, kX86RegTypeMm, 5, 8); +REG(X86MmReg, mm6, kX86RegTypeMm, 6, 8); +REG(X86MmReg, mm7, kX86RegTypeMm, 7, 8); + +REG(X86XmmReg, xmm0, kX86RegTypeXmm, 0, 16); +REG(X86XmmReg, xmm1, kX86RegTypeXmm, 1, 16); +REG(X86XmmReg, xmm2, kX86RegTypeXmm, 2, 16); +REG(X86XmmReg, xmm3, kX86RegTypeXmm, 3, 16); +REG(X86XmmReg, xmm4, kX86RegTypeXmm, 4, 16); +REG(X86XmmReg, xmm5, kX86RegTypeXmm, 5, 16); +REG(X86XmmReg, xmm6, kX86RegTypeXmm, 6, 16); +REG(X86XmmReg, xmm7, kX86RegTypeXmm, 7, 16); +REG(X86XmmReg, xmm8, kX86RegTypeXmm, 8, 16); +REG(X86XmmReg, xmm9, kX86RegTypeXmm, 9, 16); +REG(X86XmmReg, xmm10, kX86RegTypeXmm, 10, 16); +REG(X86XmmReg, xmm11, kX86RegTypeXmm, 11, 16); +REG(X86XmmReg, xmm12, kX86RegTypeXmm, 12, 16); +REG(X86XmmReg, xmm13, kX86RegTypeXmm, 13, 16); +REG(X86XmmReg, xmm14, kX86RegTypeXmm, 14, 16); +REG(X86XmmReg, xmm15, kX86RegTypeXmm, 15, 16); + +REG(X86YmmReg, ymm0, kX86RegTypeYmm, 0, 32); +REG(X86YmmReg, ymm1, kX86RegTypeYmm, 1, 32); +REG(X86YmmReg, ymm2, kX86RegTypeYmm, 2, 32); +REG(X86YmmReg, ymm3, kX86RegTypeYmm, 3, 32); +REG(X86YmmReg, ymm4, kX86RegTypeYmm, 4, 32); +REG(X86YmmReg, ymm5, kX86RegTypeYmm, 5, 32); +REG(X86YmmReg, ymm6, kX86RegTypeYmm, 6, 32); +REG(X86YmmReg, ymm7, kX86RegTypeYmm, 7, 32); +REG(X86YmmReg, ymm8, kX86RegTypeYmm, 8, 32); +REG(X86YmmReg, ymm9, kX86RegTypeYmm, 9, 32); +REG(X86YmmReg, ymm10, kX86RegTypeYmm, 10, 32); +REG(X86YmmReg, ymm11, kX86RegTypeYmm, 11, 32); +REG(X86YmmReg, ymm12, kX86RegTypeYmm, 12, 32); +REG(X86YmmReg, ymm13, kX86RegTypeYmm, 13, 32); +REG(X86YmmReg, ymm14, kX86RegTypeYmm, 14, 32); +REG(X86YmmReg, ymm15, kX86RegTypeYmm, 15, 32); + +REG(X86SegReg, cs, kX86RegTypeSeg, kX86SegCs, 2); +REG(X86SegReg, ss, kX86RegTypeSeg, kX86SegSs, 2); +REG(X86SegReg, ds, kX86RegTypeSeg, kX86SegDs, 2); +REG(X86SegReg, es, kX86RegTypeSeg, kX86SegEs, 2); +REG(X86SegReg, fs, kX86RegTypeSeg, kX86SegFs, 2); +REG(X86SegReg, gs, kX86RegTypeSeg, kX86SegGs, 2); + +#undef REG + +} // x86 namespace +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/src/asmjit/x86/x86regs.cpp b/src/asmjit/x86/x86regs.cpp deleted file mode 100644 index e2eb77e..0000000 --- a/src/asmjit/x86/x86regs.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Export] -#define ASMJIT_EXPORTS -#define ASMJIT_REGS_INIT - -// [Guard] -#include "../build.h" -#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) - -// [Dependencies - AsmJit] -#include "../x86/x86regs.h" - -// [Api-Begin] -#include "../apibegin.h" - -#define DEFINE_REG(_Class_, _Name_, _Type_, _Index_, _Size_) \ - const _Class_ _Name_ = { { kOperandTypeReg, _Size_, ((_Type_) << 8) + _Index_, kInvalidValue, kVarTypeInvalid, 0 } } - -namespace asmjit { -namespace x86x64 { - -// ============================================================================ -// [asmjit::x86x64::Registers] -// ============================================================================ - -DEFINE_REG(GpReg, noGpReg, kInvalidReg, kInvalidReg, 0); - -DEFINE_REG(GpReg, al, kRegTypeGpbLo, kRegIndexAx, 1); -DEFINE_REG(GpReg, cl, kRegTypeGpbLo, kRegIndexCx, 1); -DEFINE_REG(GpReg, dl, kRegTypeGpbLo, kRegIndexDx, 1); -DEFINE_REG(GpReg, bl, kRegTypeGpbLo, kRegIndexBx, 1); -DEFINE_REG(GpReg, spl, kRegTypeGpbLo, kRegIndexSp, 1); -DEFINE_REG(GpReg, bpl, kRegTypeGpbLo, kRegIndexBp, 1); -DEFINE_REG(GpReg, sil, kRegTypeGpbLo, kRegIndexSi, 1); -DEFINE_REG(GpReg, dil, kRegTypeGpbLo, kRegIndexDi, 1); -DEFINE_REG(GpReg, r8b, kRegTypeGpbLo, 8, 1); -DEFINE_REG(GpReg, r9b, kRegTypeGpbLo, 9, 1); -DEFINE_REG(GpReg, r10b, kRegTypeGpbLo, 10, 1); -DEFINE_REG(GpReg, r11b, kRegTypeGpbLo, 11, 1); -DEFINE_REG(GpReg, r12b, kRegTypeGpbLo, 12, 1); -DEFINE_REG(GpReg, r13b, kRegTypeGpbLo, 13, 1); -DEFINE_REG(GpReg, r14b, kRegTypeGpbLo, 14, 1); -DEFINE_REG(GpReg, r15b, kRegTypeGpbLo, 15, 1); - -DEFINE_REG(GpReg, ah, kRegTypeGpbHi, kRegIndexAx, 1); -DEFINE_REG(GpReg, ch, kRegTypeGpbHi, kRegIndexCx, 1); -DEFINE_REG(GpReg, dh, kRegTypeGpbHi, kRegIndexDx, 1); -DEFINE_REG(GpReg, bh, kRegTypeGpbHi, kRegIndexBx, 1); - -DEFINE_REG(GpReg, ax, kRegTypeGpw, kRegIndexAx, 2); -DEFINE_REG(GpReg, cx, kRegTypeGpw, kRegIndexCx, 2); -DEFINE_REG(GpReg, dx, kRegTypeGpw, kRegIndexDx, 2); -DEFINE_REG(GpReg, bx, kRegTypeGpw, kRegIndexBx, 2); -DEFINE_REG(GpReg, sp, kRegTypeGpw, kRegIndexSp, 2); -DEFINE_REG(GpReg, bp, kRegTypeGpw, kRegIndexBp, 2); -DEFINE_REG(GpReg, si, kRegTypeGpw, kRegIndexSi, 2); -DEFINE_REG(GpReg, di, kRegTypeGpw, kRegIndexDi, 2); -DEFINE_REG(GpReg, r8w, kRegTypeGpw, 8, 2); -DEFINE_REG(GpReg, r9w, kRegTypeGpw, 9, 2); -DEFINE_REG(GpReg, r10w, kRegTypeGpw, 10, 2); -DEFINE_REG(GpReg, r11w, kRegTypeGpw, 11, 2); -DEFINE_REG(GpReg, r12w, kRegTypeGpw, 12, 2); -DEFINE_REG(GpReg, r13w, kRegTypeGpw, 13, 2); -DEFINE_REG(GpReg, r14w, kRegTypeGpw, 14, 2); -DEFINE_REG(GpReg, r15w, kRegTypeGpw, 15, 2); - -DEFINE_REG(GpReg, eax, kRegTypeGpd, kRegIndexAx, 4); -DEFINE_REG(GpReg, ecx, kRegTypeGpd, kRegIndexCx, 4); -DEFINE_REG(GpReg, edx, kRegTypeGpd, kRegIndexDx, 4); -DEFINE_REG(GpReg, ebx, kRegTypeGpd, kRegIndexBx, 4); -DEFINE_REG(GpReg, esp, kRegTypeGpd, kRegIndexSp, 4); -DEFINE_REG(GpReg, ebp, kRegTypeGpd, kRegIndexBp, 4); -DEFINE_REG(GpReg, esi, kRegTypeGpd, kRegIndexSi, 4); -DEFINE_REG(GpReg, edi, kRegTypeGpd, kRegIndexDi, 4); -DEFINE_REG(GpReg, r8d, kRegTypeGpd, 8, 4); -DEFINE_REG(GpReg, r9d, kRegTypeGpd, 9, 4); -DEFINE_REG(GpReg, r10d, kRegTypeGpd, 10, 4); -DEFINE_REG(GpReg, r11d, kRegTypeGpd, 11, 4); -DEFINE_REG(GpReg, r12d, kRegTypeGpd, 12, 4); -DEFINE_REG(GpReg, r13d, kRegTypeGpd, 13, 4); -DEFINE_REG(GpReg, r14d, kRegTypeGpd, 14, 4); -DEFINE_REG(GpReg, r15d, kRegTypeGpd, 15, 4); - -DEFINE_REG(GpReg, rax, kRegTypeGpq, kRegIndexAx, 8); -DEFINE_REG(GpReg, rcx, kRegTypeGpq, kRegIndexCx, 8); -DEFINE_REG(GpReg, rdx, kRegTypeGpq, kRegIndexDx, 8); -DEFINE_REG(GpReg, rbx, kRegTypeGpq, kRegIndexBx, 8); -DEFINE_REG(GpReg, rsp, kRegTypeGpq, kRegIndexSp, 8); -DEFINE_REG(GpReg, rbp, kRegTypeGpq, kRegIndexBp, 8); -DEFINE_REG(GpReg, rsi, kRegTypeGpq, kRegIndexSi, 8); -DEFINE_REG(GpReg, rdi, kRegTypeGpq, kRegIndexDi, 8); -DEFINE_REG(GpReg, r8, kRegTypeGpq, 8, 8); -DEFINE_REG(GpReg, r9, kRegTypeGpq, 9, 8); -DEFINE_REG(GpReg, r10, kRegTypeGpq, 10, 8); -DEFINE_REG(GpReg, r11, kRegTypeGpq, 11, 8); -DEFINE_REG(GpReg, r12, kRegTypeGpq, 12, 8); -DEFINE_REG(GpReg, r13, kRegTypeGpq, 13, 8); -DEFINE_REG(GpReg, r14, kRegTypeGpq, 14, 8); -DEFINE_REG(GpReg, r15, kRegTypeGpq, 15, 8); - -DEFINE_REG(FpReg, fp0, kRegTypeFp, 0, 10); -DEFINE_REG(FpReg, fp1, kRegTypeFp, 1, 10); -DEFINE_REG(FpReg, fp2, kRegTypeFp, 2, 10); -DEFINE_REG(FpReg, fp3, kRegTypeFp, 3, 10); -DEFINE_REG(FpReg, fp4, kRegTypeFp, 4, 10); -DEFINE_REG(FpReg, fp5, kRegTypeFp, 5, 10); -DEFINE_REG(FpReg, fp6, kRegTypeFp, 6, 10); -DEFINE_REG(FpReg, fp7, kRegTypeFp, 7, 10); - -DEFINE_REG(MmReg, mm0, kRegTypeMm, 0, 8); -DEFINE_REG(MmReg, mm1, kRegTypeMm, 1, 8); -DEFINE_REG(MmReg, mm2, kRegTypeMm, 2, 8); -DEFINE_REG(MmReg, mm3, kRegTypeMm, 3, 8); -DEFINE_REG(MmReg, mm4, kRegTypeMm, 4, 8); -DEFINE_REG(MmReg, mm5, kRegTypeMm, 5, 8); -DEFINE_REG(MmReg, mm6, kRegTypeMm, 6, 8); -DEFINE_REG(MmReg, mm7, kRegTypeMm, 7, 8); - -DEFINE_REG(XmmReg, xmm0, kRegTypeXmm, 0, 16); -DEFINE_REG(XmmReg, xmm1, kRegTypeXmm, 1, 16); -DEFINE_REG(XmmReg, xmm2, kRegTypeXmm, 2, 16); -DEFINE_REG(XmmReg, xmm3, kRegTypeXmm, 3, 16); -DEFINE_REG(XmmReg, xmm4, kRegTypeXmm, 4, 16); -DEFINE_REG(XmmReg, xmm5, kRegTypeXmm, 5, 16); -DEFINE_REG(XmmReg, xmm6, kRegTypeXmm, 6, 16); -DEFINE_REG(XmmReg, xmm7, kRegTypeXmm, 7, 16); -DEFINE_REG(XmmReg, xmm8, kRegTypeXmm, 8, 16); -DEFINE_REG(XmmReg, xmm9, kRegTypeXmm, 9, 16); -DEFINE_REG(XmmReg, xmm10, kRegTypeXmm, 10, 16); -DEFINE_REG(XmmReg, xmm11, kRegTypeXmm, 11, 16); -DEFINE_REG(XmmReg, xmm12, kRegTypeXmm, 12, 16); -DEFINE_REG(XmmReg, xmm13, kRegTypeXmm, 13, 16); -DEFINE_REG(XmmReg, xmm14, kRegTypeXmm, 14, 16); -DEFINE_REG(XmmReg, xmm15, kRegTypeXmm, 15, 16); - -DEFINE_REG(YmmReg, ymm0, kRegTypeYmm, 0, 32); -DEFINE_REG(YmmReg, ymm1, kRegTypeYmm, 1, 32); -DEFINE_REG(YmmReg, ymm2, kRegTypeYmm, 2, 32); -DEFINE_REG(YmmReg, ymm3, kRegTypeYmm, 3, 32); -DEFINE_REG(YmmReg, ymm4, kRegTypeYmm, 4, 32); -DEFINE_REG(YmmReg, ymm5, kRegTypeYmm, 5, 32); -DEFINE_REG(YmmReg, ymm6, kRegTypeYmm, 6, 32); -DEFINE_REG(YmmReg, ymm7, kRegTypeYmm, 7, 32); -DEFINE_REG(YmmReg, ymm8, kRegTypeYmm, 8, 32); -DEFINE_REG(YmmReg, ymm9, kRegTypeYmm, 9, 32); -DEFINE_REG(YmmReg, ymm10, kRegTypeYmm, 10, 32); -DEFINE_REG(YmmReg, ymm11, kRegTypeYmm, 11, 32); -DEFINE_REG(YmmReg, ymm12, kRegTypeYmm, 12, 32); -DEFINE_REG(YmmReg, ymm13, kRegTypeYmm, 13, 32); -DEFINE_REG(YmmReg, ymm14, kRegTypeYmm, 14, 32); -DEFINE_REG(YmmReg, ymm15, kRegTypeYmm, 15, 32); - -DEFINE_REG(SegReg, cs, kRegTypeSeg, kSegCs, 2); -DEFINE_REG(SegReg, ss, kRegTypeSeg, kSegSs, 2); -DEFINE_REG(SegReg, ds, kRegTypeSeg, kSegDs, 2); -DEFINE_REG(SegReg, es, kRegTypeSeg, kSegEs, 2); -DEFINE_REG(SegReg, fs, kRegTypeSeg, kSegFs, 2); -DEFINE_REG(SegReg, gs, kRegTypeSeg, kSegGs, 2); - -} // x86x64 namespace -} // asmjit namespace - -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -DEFINE_REG(GpReg, zax, kRegTypeGpd, kRegIndexAx, 4); -DEFINE_REG(GpReg, zcx, kRegTypeGpd, kRegIndexCx, 4); -DEFINE_REG(GpReg, zdx, kRegTypeGpd, kRegIndexDx, 4); -DEFINE_REG(GpReg, zbx, kRegTypeGpd, kRegIndexBx, 4); -DEFINE_REG(GpReg, zsp, kRegTypeGpd, kRegIndexSp, 4); -DEFINE_REG(GpReg, zbp, kRegTypeGpd, kRegIndexBp, 4); -DEFINE_REG(GpReg, zsi, kRegTypeGpd, kRegIndexSi, 4); -DEFINE_REG(GpReg, zdi, kRegTypeGpd, kRegIndexDi, 4); - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) -namespace asmjit { -namespace x64 { - -DEFINE_REG(GpReg, zax, kRegTypeGpq, kRegIndexAx, 8); -DEFINE_REG(GpReg, zcx, kRegTypeGpq, kRegIndexCx, 8); -DEFINE_REG(GpReg, zdx, kRegTypeGpq, kRegIndexDx, 8); -DEFINE_REG(GpReg, zbx, kRegTypeGpq, kRegIndexBx, 8); -DEFINE_REG(GpReg, zsp, kRegTypeGpq, kRegIndexSp, 8); -DEFINE_REG(GpReg, zbp, kRegTypeGpq, kRegIndexBp, 8); -DEFINE_REG(GpReg, zsi, kRegTypeGpq, kRegIndexSi, 8); -DEFINE_REG(GpReg, zdi, kRegTypeGpq, kRegIndexDi, 8); - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - -#include "../apiend.h" - -// [Guard] -#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/src/asmjit/x86/x86regs.h b/src/asmjit/x86/x86regs.h deleted file mode 100644 index b38217c..0000000 --- a/src/asmjit/x86/x86regs.h +++ /dev/null @@ -1,412 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_X86_X86REGS_H -#define _ASMJIT_X86_X86REGS_H - -// [Dependencies - AsmJit] -#include "../base/operand.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -namespace x86x64 { - -struct GpReg; -struct FpReg; -struct MmReg; -struct XmmReg; -struct YmmReg; -struct SegReg; - -#if defined(ASMJIT_REGS_INIT) -// Remap all classes to POD structs that can be statically initialized. -struct GpReg { Operand::InitRegOp data; }; -struct FpReg { Operand::InitRegOp data; }; -struct MmReg { Operand::InitRegOp data; }; -struct XmmReg { Operand::InitRegOp data; }; -struct YmmReg { Operand::InitRegOp data; }; -struct SegReg { Operand::InitRegOp data; }; -#endif // ASMJIT_REGS_INIT - -//! \addtogroup asmjit_x86x64_general -//! \{ - -// ============================================================================ -// [asmjit::x86x64::kRegClass] -// ============================================================================ - -//! X86/X64 variable class. -ASMJIT_ENUM(kRegClass) { - // kRegClassGp defined earlier. - - //! X86/X64 Fp register class. - kRegClassFp = 1, - //! X86/X64 Mm register class. - kRegClassMm = 2, - //! X86/X64 Xmm/Ymm/Zmm register class. - kRegClassXyz = 3, - - //! Count of X86/X64 register classes. - kRegClassCount = 4 -}; - -// ============================================================================ -// [asmjit::x86x64::kRegCount] -// ============================================================================ - -//! X86/X64 registers count. -ASMJIT_ENUM(kRegCount) { - //! Count of Fp registers (8). - kRegCountFp = 8, - //! Count of Mm registers (8). - kRegCountMm = 8, - //! Count of segment registers (6). - kRegCountSeg = 6 -}; - -// ============================================================================ -// [asmjit::x86x64::kRegType] -// ============================================================================ - -//! X86/X64 register type. -ASMJIT_ENUM(kRegType) { - //! Gpb-lo register (AL, BL, CL, DL, ...). - kRegTypeGpbLo = 0x01, - //! Gpb-hi register (AH, BH, CH, DH only). - kRegTypeGpbHi = 0x02, - - //! \internal - //! - //! Gpb-hi register patched to native index (4-7). - kRegTypePatchedGpbHi = kRegTypeGpbLo | kRegTypeGpbHi, - - //! Gpw register. - kRegTypeGpw = 0x10, - //! Gpd register. - kRegTypeGpd = 0x20, - //! Gpq register. - kRegTypeGpq = 0x30, - - //! Fp register. - kRegTypeFp = 0x50, - //! Mm register. - kRegTypeMm = 0x60, - - //! Xmm register. - kRegTypeXmm = 0x70, - //! Ymm register. - kRegTypeYmm = 0x80, - //! Zmm register. - kRegTypeZmm = 0x90, - - //! Segment register. - kRegTypeSeg = 0xF0 -}; - -// ============================================================================ -// [asmjit::x86x64::kRegIndex] -// ============================================================================ - -//! 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(kRegIndex) { - //! Index of Al/Ah/Ax/Eax/Rax registers. - kRegIndexAx = 0, - //! Index of Cl/Ch/Cx/Ecx/Rcx registers. - kRegIndexCx = 1, - //! Index of Dl/Dh/Dx/Edx/Rdx registers. - kRegIndexDx = 2, - //! Index of Bl/Bh/Bx/Ebx/Rbx registers. - kRegIndexBx = 3, - //! Index of Spl/Sp/Esp/Rsp registers. - kRegIndexSp = 4, - //! Index of Bpl/Bp/Ebp/Rbp registers. - kRegIndexBp = 5, - //! Index of Sil/Si/Esi/Rsi registers. - kRegIndexSi = 6, - //! Index of Dil/Di/Edi/Rdi registers. - kRegIndexDi = 7, - //! Index of R8b/R8w/R8d/R8 registers (64-bit only). - kRegIndexR8 = 8, - //! Index of R9B/R9w/R9d/R9 registers (64-bit only). - kRegIndexR9 = 9, - //! Index of R10B/R10w/R10D/R10 registers (64-bit only). - kRegIndexR10 = 10, - //! Index of R11B/R11w/R11d/R11 registers (64-bit only). - kRegIndexR11 = 11, - //! Index of R12B/R12w/R12d/R12 registers (64-bit only). - kRegIndexR12 = 12, - //! Index of R13B/R13w/R13d/R13 registers (64-bit only). - kRegIndexR13 = 13, - //! Index of R14B/R14w/R14d/R14 registers (64-bit only). - kRegIndexR14 = 14, - //! Index of R15B/R15w/R15d/R15 registers (64-bit only). - kRegIndexR15 = 15 -}; - -// ============================================================================ -// [asmjit::x86x64::kSeg] -// ============================================================================ - -//! X86/X64 segment codes. -ASMJIT_ENUM(kSeg) { - //! No/Default segment. - kSegDefault = 0, - //! Es segment. - kSegEs = 1, - //! Cs segment. - kSegCs = 2, - //! Ss segment. - kSegSs = 3, - //! Ds segment. - kSegDs = 4, - //! Fs segment. - kSegFs = 5, - //! Gs segment. - kSegGs = 6 -}; - -// ============================================================================ -// [asmjit::x86x64::Registers] -// ============================================================================ - -//! No Gp register, can be used only within `Mem` operand. -ASMJIT_VAR const GpReg noGpReg; - -ASMJIT_VAR const GpReg al; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const GpReg cl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const GpReg dl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const GpReg bl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const GpReg spl; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg bpl; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg sil; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg dil; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r8b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r9b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r10b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r11b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r12b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r13b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r14b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const GpReg r15b; //!< 8-bit Gpb-lo register (X64). - -ASMJIT_VAR const GpReg ah; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const GpReg ch; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const GpReg dh; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const GpReg bh; //!< 8-bit Gpb-hi register. - -ASMJIT_VAR const GpReg ax; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg cx; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg dx; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg bx; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg sp; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg bp; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg si; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg di; //!< 16-bit Gpw register. -ASMJIT_VAR const GpReg r8w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r9w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r10w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r11w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r12w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r13w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r14w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const GpReg r15w; //!< 16-bit Gpw register (X64). - -ASMJIT_VAR const GpReg eax; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg ecx; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg edx; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg ebx; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg esp; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg ebp; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg esi; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg edi; //!< 32-bit Gpd register. -ASMJIT_VAR const GpReg r8d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r9d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r10d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r11d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r12d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r13d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r14d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const GpReg r15d; //!< 32-bit Gpd register (X64). - -ASMJIT_VAR const GpReg rax; //!< 64-bit Gpq register (X64). -ASMJIT_VAR const GpReg rcx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rdx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rbx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rsp; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rbp; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rsi; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg rdi; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r8; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r9; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r10; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r11; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r12; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r13; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r14; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const GpReg r15; //!< 64-bit Gpq register (X64) - -ASMJIT_VAR const FpReg fp0; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp1; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp2; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp3; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp4; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp5; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp6; //!< 80-bit Fp register. -ASMJIT_VAR const FpReg fp7; //!< 80-bit Fp register. - -ASMJIT_VAR const MmReg mm0; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm1; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm2; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm3; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm4; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm5; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm6; //!< 64-bit Mm register. -ASMJIT_VAR const MmReg mm7; //!< 64-bit Mm register. - -ASMJIT_VAR const XmmReg xmm0; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm1; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm2; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm3; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm4; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm5; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm6; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm7; //!< 128-bit Xmm register. -ASMJIT_VAR const XmmReg xmm8; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm9; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm10; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm11; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm12; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm13; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm14; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const XmmReg xmm15; //!< 128-bit Xmm register (X64). - -ASMJIT_VAR const YmmReg ymm0; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm1; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm2; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm3; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm4; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm5; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm6; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm7; //!< 256-bit Ymm register. -ASMJIT_VAR const YmmReg ymm8; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm9; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm10; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm11; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm12; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm13; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm14; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const YmmReg ymm15; //!< 256-bit Ymm register (X64). - -ASMJIT_VAR const SegReg cs; //!< Cs segment register. -ASMJIT_VAR const SegReg ss; //!< Ss segment register. -ASMJIT_VAR const SegReg ds; //!< Ds segment register. -ASMJIT_VAR const SegReg es; //!< Es segment register. -ASMJIT_VAR const SegReg fs; //!< Fs segment register. -ASMJIT_VAR const SegReg gs; //!< Gs segment register. - -//! \} - -} // x86x64 namespace -} // asmjit namespace - -// ============================================================================ -// [asmjit::x86] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X86) - -namespace asmjit { -namespace x86 { - -// This is the only place where the x86x64 namespace is included into x86. -using namespace ::asmjit::x86x64; - -//! \addtogroup asmjit_x86x64_general -//! \{ - -// ============================================================================ -// [asmjit::x86::Registers] -// ============================================================================ - -//! Gpd register. -ASMJIT_VAR const GpReg zax; -//! Gpd register. -ASMJIT_VAR const GpReg zcx; -//! Gpd register. -ASMJIT_VAR const GpReg zdx; -//! Gpd register. -ASMJIT_VAR const GpReg zbx; -//! Gpd register. -ASMJIT_VAR const GpReg zsp; -//! Gpd register. -ASMJIT_VAR const GpReg zbp; -//! Gpd register. -ASMJIT_VAR const GpReg zsi; -//! Gpd register. -ASMJIT_VAR const GpReg zdi; - -//! \} - -} // x86 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X86 - -// ============================================================================ -// [asmjit::x64] -// ============================================================================ - -#if defined(ASMJIT_BUILD_X64) - -namespace asmjit { -namespace x64 { - -// This is the only place where the x86x64 namespace is included into x64. -using namespace ::asmjit::x86x64; - -//! \addtogroup asmjit_x86x64_general -//! \{ - -// ============================================================================ -// [asmjit::x64::Registers] -// ============================================================================ - -//! Gpq register. -ASMJIT_VAR const GpReg zax; -//! Gpq register. -ASMJIT_VAR const GpReg zcx; -//! Gpq register. -ASMJIT_VAR const GpReg zdx; -//! Gpq register. -ASMJIT_VAR const GpReg zbx; -//! Gpq register. -ASMJIT_VAR const GpReg zsp; -//! Gpq register. -ASMJIT_VAR const GpReg zbp; -//! Gpq register. -ASMJIT_VAR const GpReg zsi; -//! Gpq register. -ASMJIT_VAR const GpReg zdi; - -//! \} - -} // x64 namespace -} // asmjit namespace - -#endif // ASMJIT_BUILD_X64 - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // _ASMJIT_X86_X86REGS_H diff --git a/src/asmjit/x86/x86scheduler.cpp b/src/asmjit/x86/x86scheduler.cpp new file mode 100644 index 0000000..33ddb61 --- /dev/null +++ b/src/asmjit/x86/x86scheduler.cpp @@ -0,0 +1,94 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) + +// [Dependencies - AsmJit] +#include "../base/containers.h" +#include "../x86/x86scheduler_p.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Internals] +// ============================================================================ + +//! \internal +struct X86ScheduleData { + //! Registers read by the instruction. + X86RegMask regsIn; + //! Registers written by the instruction. + X86RegMask regsOut; + + //! Flags read by the instruction. + uint8_t flagsIn; + //! Flags written by the instruction. + uint8_t flagsOut; + + //! How many `uops` or `cycles` the instruction takes. + uint8_t ops; + //! Instruction latency. + uint8_t latency; + + //! Which ports the instruction can run at. + uint16_t ports; + //! \internal + uint16_t reserved; + + //! All instructions that this instruction depends on. + PodList::Link* dependsOn; + //! All instructions that use the result of this instruction. + PodList::Link* usedBy; +}; + +// ============================================================================ +// [asmjit::X86Scheduler - Construction / Destruction] +// ============================================================================ + +X86Scheduler::X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo) : + _compiler(compiler), + _cpuInfo(cpuInfo) {} +X86Scheduler::~X86Scheduler() {} + +// ============================================================================ +// [asmjit::X86Scheduler - Run] +// ============================================================================ + +Error X86Scheduler::run(Node* start, Node* stop) { + /* + ASMJIT_TLOG("[Schedule] === Begin ==="); + + Zone zone(8096 - kZoneOverhead); + Node* node_ = start; + + while (node_ != stop) { + Node* next = node_->getNext(); + ASMJIT_ASSERT(node_->getType() == kNodeTypeInst); + + printf(" %s\n", X86Util::getInstInfo(static_cast(node_)->getCode()).getInstName()); + node_ = next; + } + + ASMJIT_TLOG("[Schedule] === End ==="); + */ + return kErrorOk; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) diff --git a/src/asmjit/x86/x86scheduler_p.h b/src/asmjit/x86/x86scheduler_p.h new file mode 100644 index 0000000..1afeb90 --- /dev/null +++ b/src/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 diff --git a/src/asmjit/x86/x86util.cpp b/src/asmjit/x86/x86util.cpp deleted file mode 100644 index 12fe100..0000000 --- a/src/asmjit/x86/x86util.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Export] -#define ASMJIT_EXPORTS - -// [Guard] -#include "../build.h" -#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) - -// [Dependencies - AsmJit] -#include "../x86/x86util.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -namespace x86x64 { - -// ============================================================================ -// [asmjit::x86x64::Condition Codes] -// ============================================================================ - -#define CC_TO_INST(_Inst_) { \ - _Inst_##o, \ - _Inst_##no, \ - _Inst_##b, \ - _Inst_##ae, \ - _Inst_##e, \ - _Inst_##ne, \ - _Inst_##be, \ - _Inst_##a, \ - _Inst_##s, \ - _Inst_##ns, \ - _Inst_##pe, \ - _Inst_##po, \ - _Inst_##l, \ - _Inst_##ge, \ - _Inst_##le, \ - _Inst_##g, \ - \ - kInstNone, \ - kInstNone, \ - kInstNone, \ - kInstNone \ -} - -const uint32_t _reverseCond[20] = { - /* kCondO -> */ kCondO, - /* kCondNO -> */ kCondNO, - /* kCondB -> */ kCondA, - /* kCondAE -> */ kCondBE, - /* kCondE -> */ kCondE, - /* kCondNE -> */ kCondNE, - /* kCondBE -> */ kCondAE, - /* kCondA -> */ kCondB, - /* kCondS -> */ kCondS, - /* kCondNS -> */ kCondNS, - /* kCondPE -> */ kCondPE, - /* kCondPO -> */ kCondPO, - - /* kCondL -> */ kCondG, - /* kCondGE -> */ kCondLE, - - /* kCondLE -> */ kCondGE, - /* kCondG -> */ kCondL, - - /* kCondFpuUnordered -> */ kCondFpuUnordered, - /* kCondFpuNotUnordered -> */ kCondFpuNotUnordered, - - 0x12, - 0x13 -}; - -const uint32_t _condToCmovcc[20] = CC_TO_INST(kInstCmov); -const uint32_t _condToJcc [20] = CC_TO_INST(kInstJ ); -const uint32_t _condToSetcc [20] = CC_TO_INST(kInstSet ); - -#undef CC_TO_INST - -} // x86x64 namespace -} // asmjit namespace - -#include "../apiend.h" - -// [Guard] -#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/src/asmjit/x86/x86util.h b/src/asmjit/x86/x86util.h deleted file mode 100644 index 24583d9..0000000 --- a/src/asmjit/x86/x86util.h +++ /dev/null @@ -1,394 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_X86_X86UTIL_H -#define _ASMJIT_X86_X86UTIL_H - -// [Dependencies - AsmJit] -#include "../base/func.h" -#include "../x86/x86inst.h" -#include "../x86/x86operand.h" - -// [Api-Begin] -#include "../apibegin.h" - -namespace asmjit { -namespace x86x64 { - -//! \addtogroup asmjit_x86x64_util -//! \{ - -// ============================================================================ -// [asmjit::x86x64::Internal] -// ============================================================================ - -//! \internal -//! -//! X86/X64 condition codes to reversed condition codes map. -ASMJIT_VAR const uint32_t _reverseCond[20]; - -//! \internal -//! -//! X86X64 condition codes to "cmovcc" group map. -ASMJIT_VAR const uint32_t _condToCmovcc[20]; - -//! \internal -//! -//! X86X64 condition codes to "jcc" group map. -ASMJIT_VAR const uint32_t _condToJcc[20]; - -//! \internal -//! -//! X86X64 condition codes to "setcc" group map. -ASMJIT_VAR const uint32_t _condToSetcc[20]; - -// ============================================================================ -// [asmjit::x86x64::RegCount] -// ============================================================================ - -//! \internal -//! -//! X86/X64 registers count (Gp, Fp, Mm, Xmm). -struct RegCount { - // -------------------------------------------------------------------------- - // [Zero] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void reset() { - _packed = 0; - } - - // -------------------------------------------------------------------------- - // [Get] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE uint32_t get(uint32_t c) const { - ASMJIT_ASSERT(c < kRegClassCount); - return _regs[c]; - } - - // -------------------------------------------------------------------------- - // [Set] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void set(uint32_t c, uint32_t n) { - ASMJIT_ASSERT(c < kRegClassCount); - ASMJIT_ASSERT(n < 0x100); - - _regs[c] = static_cast(n); - } - - // -------------------------------------------------------------------------- - // [Add] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) { - ASMJIT_ASSERT(c < kRegClassCount); - ASMJIT_ASSERT(n < 0x100); - - _regs[c] += static_cast(n); - } - - // -------------------------------------------------------------------------- - // [Misc] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void makeIndex(const RegCount& count) { - uint8_t a = count._regs[0]; - uint8_t b = count._regs[1]; - uint8_t c = count._regs[2]; - - _regs[0] = 0; - _regs[1] = a; - _regs[2] = a + b; - _regs[3] = a + b + c; - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - union { - struct { - uint8_t _gp; - uint8_t _fp; - uint8_t _mm; - uint8_t _xy; - }; - - uint8_t _regs[4]; - uint32_t _packed; - }; -}; - -// ============================================================================ -// [asmjit::x86x64::RegMask] -// ============================================================================ - -//! \internal -//! -//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm). -struct RegMask { - // -------------------------------------------------------------------------- - // [Reset] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void reset() { - _packed.reset(); - } - - // -------------------------------------------------------------------------- - // [IsEmpty / Has] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE bool isEmpty() const { - return _packed.isZero(); - } - - ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const { - switch (c) { - case kRegClassGp : return (static_cast(_gp ) & mask) != 0; - case kRegClassFp : return (static_cast(_fp ) & mask) != 0; - case kRegClassMm : return (static_cast(_mm ) & mask) != 0; - case kRegClassXyz: return (static_cast(_xyz) & mask) != 0; - } - - ASMJIT_ASSERT(!"Reached"); - return false; - } - - // -------------------------------------------------------------------------- - // [Zero] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void zero(uint32_t c) { - switch (c) { - case kRegClassGp : _gp = 0; break; - case kRegClassFp : _fp = 0; break; - case kRegClassMm : _mm = 0; break; - case kRegClassXyz: _xyz = 0; break; - } - } - - // -------------------------------------------------------------------------- - // [Get] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE uint32_t get(uint32_t c) const { - switch (c) { - case kRegClassGp : return _gp; - case kRegClassFp : return _fp; - case kRegClassMm : return _mm; - case kRegClassXyz: return _xyz; - } - - ASMJIT_ASSERT(!"Reached"); - return 0; - } - - // -------------------------------------------------------------------------- - // [Set] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void set(uint32_t c, uint32_t mask) { - switch (c) { - case kRegClassGp : _gp = static_cast(mask); break; - case kRegClassFp : _fp = static_cast(mask); break; - case kRegClassMm : _mm = static_cast(mask); break; - case kRegClassXyz: _xyz = static_cast(mask); break; - } - } - - ASMJIT_INLINE void set(const RegMask& other) { - _packed.setUInt64(other._packed); - } - - // -------------------------------------------------------------------------- - // [Add] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void add(uint32_t c, uint32_t mask) { - switch (c) { - case kRegClassGp : _gp |= static_cast(mask); break; - case kRegClassFp : _fp |= static_cast(mask); break; - case kRegClassMm : _mm |= static_cast(mask); break; - case kRegClassXyz: _xyz |= static_cast(mask); break; - } - } - - ASMJIT_INLINE void add(const RegMask& other) { - _packed.or_(other._packed); - } - - // -------------------------------------------------------------------------- - // [Del] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void del(uint32_t c, uint32_t mask) { - switch (c) { - case kRegClassGp : _gp &= ~static_cast(mask); break; - case kRegClassFp : _fp &= ~static_cast(mask); break; - case kRegClassMm : _mm &= ~static_cast(mask); break; - case kRegClassXyz: _xyz &= ~static_cast(mask); break; - } - } - - ASMJIT_INLINE void del(const RegMask& other) { - _packed.del(other._packed); - } - - // -------------------------------------------------------------------------- - // [And] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) { - switch (c) { - case kRegClassGp : _gp &= static_cast(mask); break; - case kRegClassFp : _fp &= static_cast(mask); break; - case kRegClassMm : _mm &= static_cast(mask); break; - case kRegClassXyz: _xyz &= static_cast(mask); break; - } - } - - ASMJIT_INLINE void and_(const RegMask& other) { - _packed.and_(other._packed); - } - - // -------------------------------------------------------------------------- - // [Xor] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) { - switch (c) { - case kRegClassGp : _gp ^= static_cast(mask); break; - case kRegClassFp : _fp ^= static_cast(mask); break; - case kRegClassMm : _mm ^= static_cast(mask); break; - case kRegClassXyz: _xyz ^= static_cast(mask); break; - } - } - - ASMJIT_INLINE void xor_(const RegMask& other) { - _packed.xor_(other._packed); - } - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - union { - struct { - //! Gp mask (16-bit). - uint16_t _gp; - //! Fp mask (8-bit). - uint8_t _fp; - //! Mm mask (8-bit). - uint8_t _mm; - //! Xmm/Ymm/Zmm mask (32-bit). - uint32_t _xyz; - }; - - //! All masks as 64-bit integer. - UInt64 _packed; - }; -}; - -// ============================================================================ -// [asmjit::x86x64::X86Util] -// ============================================================================ - -//! X86/X64 utilities. -struct X86Util { - // -------------------------------------------------------------------------- - // [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(_reverseCond)); - return _reverseCond[cond]; - } - - //! Get the equivalent of negated condition code. - static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) { - ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_reverseCond)); - return static_cast(cond ^ static_cast(cond < kCondNone)); - } - - //! Translate condition code `cc` to `cmovcc` instruction code. - //! \sa \ref kInstCode, \ref _kInstCmovcc. - static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) { - ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_condToCmovcc)); - return _condToCmovcc[cond]; - } - - //! Translate condition code `cc` to `jcc` instruction code. - //! \sa \ref kInstCode, \ref _kInstJcc. - static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) { - ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_condToJcc)); - return _condToJcc[cond]; - } - - //! Translate condition code `cc` to `setcc` instruction code. - //! \sa \ref kInstCode, \ref _kInstSetcc. - static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) { - ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_condToSetcc)); - return _condToSetcc[cond]; - } - - // -------------------------------------------------------------------------- - // [Registers] - // -------------------------------------------------------------------------- - - //! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register. - static ASMJIT_INLINE bool isGpbRegOp(const Operand& op) { - const uint32_t mask = IntUtil::pack32_2x8_1x16(0xFF, 0xFF, ~(kRegTypePatchedGpbHi << 8) & 0xFF00); - return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000); - } - - // -------------------------------------------------------------------------- - // [Immediates] - // -------------------------------------------------------------------------- - - //! 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: - //! - `X86X64Assembler::shufpd()` and `X86X64Compiler::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: - //! - `X86X64Assembler::pshufw()` and `X86X64Compiler::pshufw()` - //! - `X86X64Assembler::pshufd()` and `X86X64Compiler::pshufd()` - //! - `X86X64Assembler::pshufhw()` and `X86X64Compiler::pshufhw()` - //! - `X86X64Assembler::pshuflw()` and `X86X64Compiler::pshuflw()` - //! - `X86X64Assembler::shufps()` and `X86X64Compiler::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); - } -}; - -//! \} - -} // x86x64 namespace -} // asmjit namespace - -// [Api-End] -#include "../apiend.h" - -// [Guard] -#endif // _ASMJIT_X86_X86UTIL_H diff --git a/tools/src-gendefs.js b/tools/src-gendefs.js index 9f738b1..d1c1b33 100644 --- a/tools/src-gendefs.js +++ b/tools/src-gendefs.js @@ -1,33 +1,31 @@ // [GenDefs] // // The purpose of this script is to fetch all instructions' names into a single -// string. It prevents relocation that has to be done by linked to make all -// pointers the binary application/library uses valid. This approach decreases -// the final size of AsmJit binary. +// string and to optimize common patterns that appear in instruction data. It +// prevents relocation of small strings (instruction names) that has to be done +// by a linker to make all pointers the binary application/library uses valid. +// This approach decreases the final size of AsmJit binary and relocation data. var fs = require("fs"); -// ---------------------------------------------------------------------------- -// [Configuration] -// ---------------------------------------------------------------------------- - -var injectStartMarker = "// ${kInstData:Begin}\n"; -var injectEndMarker = "// ${kInstData:End}\n"; - // ---------------------------------------------------------------------------- // [Utilities] // ---------------------------------------------------------------------------- -var uppercaseFirst = function(s) { +var upFirst = function(s) { if (!s) return s; return s[0].toUpperCase() + s.substr(1); }; +var trimLeft = function(s) { + return s.replace(/^\s+/, ""); +} + var inject = function(s, start, end, code) { var iStart = s.indexOf(start); var iEnd = s.indexOf(end); - + if (iStart === -1) throw new Error("Couldn't locate start mark."); @@ -41,9 +39,8 @@ var inject = function(s, start, end, code) { // [Database] // ---------------------------------------------------------------------------- -// FullIndex - Index of the name of the instruction in one big string. - var Database = (function() { + // `IndexedString` class. var IndexedString = function() { this.array = []; this.index = 0; @@ -52,6 +49,7 @@ var Database = (function() { IndexedString.prototype.add = function(s) { var index = this.map[s]; + if (typeof index === "number") return index; @@ -84,38 +82,58 @@ var Database = (function() { return this.index; }; + // `Database` class. var Database = function() { - this.map = {}; - this.alphabetical = new Array(26); - this.fullString = new IndexedString(); + this.instMap = {}; + this.instNames = new IndexedString(); + this.instAlpha = new Array(26); + + this.extendedData = []; + this.extendedMap = {}; }; - Database.prototype.add = function(name, id) { - this.map[name] = { - id: id, - fullIndex: 0, - hasV: 0 + Database.prototype.add = function(name, id, extendedData) { + this.instMap[name] = { + id : id, // Instruction ID. + nameIndex : 0, // Instruction name-index, used directly by AsmJit. + vPrefix : 0, // Instruction starts with 'v', not used at this point. + extendedData : extendedData, + extendedIndex : "" }; }; Database.prototype.index = function() { - var map = this.map; - var alphabetical = this.alphabetical; + var instMap = this.instMap; + var instNames = this.instNames; + var instAlpha = this.instAlpha; - for (var name in map) { - var inst = map[name]; - inst.fullIndex = this.fullString.add(name); + var extendedData = this.extendedData; + var extendedMap = this.extendedMap; + + for (var name in instMap) { + var inst = instMap[name]; + + var nameIndex = instNames.add(name); + var extendedIndex = extendedMap[inst.extendedData]; + + if (typeof extendedIndex !== "number") { + extendedIndex = extendedData.length; + extendedMap[inst.extendedData] = extendedIndex; + extendedData.push(inst.extendedData); + } + + inst.nameIndex = nameIndex; + inst.extendedIndex = extendedIndex; var aIndex = name.charCodeAt(0) - 'a'.charCodeAt(0); if (aIndex < 0 || aIndex >= 26) throw new Error("Alphabetical index error"); - if (alphabetical[aIndex] === undefined) - alphabetical[aIndex] = inst.id; + if (instAlpha[aIndex] === undefined) + instAlpha[aIndex] = inst.id; if (name.indexOf("v") === 0) { - inst.hasV = 1; - name = name.substr(1); + inst.vPrefix = 1; } } }; @@ -127,64 +145,154 @@ var Database = (function() { // [Generate] // ---------------------------------------------------------------------------- +var decToHex = function(n, nPad) { + var hex = Number(n < 0 ? 0x100000000 + n : n).toString(16); + while (nPad > hex.length) + hex = "0" + hex; + return "0x" + hex.toUpperCase(); +}; + +var getEFlagsMask = function(eflags, passing) { + var msk = 0x0; + var bit = 0x1; + + for (var i = 0; i < 8; i++, bit <<= 1) { + if (passing.indexOf(eflags[i]) !== -1) + msk |= bit; + } + + return msk; +}; + var generate = function(fileName, arch) { + var Arch = upFirst(arch); var oldData = fs.readFileSync(fileName, "utf8").replace(/\r\n/g, "\n"); var data = oldData; var code = ""; - - var Arch = uppercaseFirst(arch); - + var disclaimer = "// Automatically generated, do not edit.\n"; + // Create database. var db = new Database(); - var re = new RegExp("INST\\(([A-Za-z0-9_]+)\\s*,\\s*\\\"([A-Za-z0-9_ ]*)\\\"", "g"); + var re = new RegExp( + "INST\\(([A-Za-z0-9_]+)\\s*," + // [01] Inst-Code. + "\\s*\\\"([A-Za-z0-9_ ]*)\\\"\\s*," + // [02] Inst-Name. + "([^,]+)," + // [03] Inst-Group. + "([^,]+)," + // [04] Inst-Flags. + "([^,]+)," + // [05] Move-Size. + "([^,]+)," + // [06] Operand-Flags[0]. + "([^,]+)," + // [07] Operand-Flags[1]. + "([^,]+)," + // [08] Operand-Flags[2]. + "([^,]+)," + // [09] Operand-Flags[3]. + "\\s*E\\(([A-Z_]+)\\)\\s*," + // [10] EFLAGS. + "(.{17}[^,]*)," + // [11] OpCode[0]. + "(.{17}[^\\)]*)\\)", // [12] OpCode[1]. + "g"); while (m = re.exec(data)) { + // Extract instruction ID and Name. var id = m[1]; var name = m[2]; - db.add(name, id); + // Extract data that goes to the secondary table (ExtendedInfo). + var instGroup = trimLeft(m[3]); + var instFlags = trimLeft(m[4]); + var moveSize = trimLeft(m[5]); + + var opFlags0 = trimLeft(m[6]); + var opFlags1 = trimLeft(m[7]); + var opFlags2 = trimLeft(m[8]); + var opFlags3 = trimLeft(m[9]); + var eflags = m[10]; + var opCode1 = trimLeft(m[12]); + + // Generate EFlags-In and EFlags-Out. + var eflagsIn = decToHex(getEFlagsMask(eflags, "RX"), 2); + var eflagsOut = decToHex(getEFlagsMask(eflags, "WXU"), 2); + + var extData = "" + + instGroup + ", " + + moveSize + ", " + + eflagsIn + ", " + + eflagsOut + ", " + + instFlags + ", " + + "{ " + opFlags0 + ", " + opFlags1 + ", " + opFlags2 + ", " + opFlags3 + ", U }, " + + opCode1; + + db.add(name, id, extData); } db.index(); - console.log("Full size: " + db.fullString.getSize()); + console.log("Number of instructions: " + db.instNames.array.length); + console.log("Instruction names size: " + db.instNames.getSize()); + console.log("Extended-info length : " + db.extendedData.length); // Generate InstName[] string. - code += "const char _instName[] =\n"; - for (var k in db.map) { - var inst = db.map[k]; + code += disclaimer; + code += "#if !defined(ASMJIT_DISABLE_INST_NAMES)\n"; + code += "const char _" + arch + "InstName[] =\n"; + for (var k in db.instMap) { + var inst = db.instMap[k]; code += " \"" + k + "\\0\"\n"; } code = code.substr(code, code.length - 1) + ";\n\n"; // Generate AlphaIndex. - code += "enum kInstAlphaIndex {\n"; - code += " kInstAlphaIndexFirst = 'a',\n"; - code += " kInstAlphaIndexLast = 'z',\n"; - code += " kInstAlphaIndexInvalid = 0xFFFF\n"; + code += disclaimer; + code += "enum k" + Arch + "InstAlphaIndex {\n"; + code += " k" + Arch + "InstAlphaIndexFirst = 'a',\n"; + code += " k" + Arch + "InstAlphaIndexLast = 'z',\n"; + code += " k" + Arch + "InstAlphaIndexInvalid = 0xFFFF\n"; code += "};\n"; code += "\n"; - // Generate NameIndex. - code += "static const uint16_t _instAlphaIndex[26] = {\n"; - for (var i = 0; i < db.alphabetical.length; i++) { - var id = db.alphabetical[i]; + code += disclaimer; + code += "static const uint16_t _" + arch + "InstAlphaIndex[26] = {\n"; + for (var i = 0; i < db.instAlpha.length; i++) { + var id = db.instAlpha[i]; code += " " + (id === undefined ? "0xFFFF" : id); - if (i !== db.alphabetical.length - 1) + if (i !== db.instAlpha.length - 1) code += ","; code += "\n"; } code += "};\n\n"; - code += "enum kInstData_NameIndex {\n"; - for (var k in db.map) { - var inst = db.map[k]; - code += " " + inst.id + "_NameIndex = " + inst.fullIndex + ",\n"; + // Generate NameIndex. + code += disclaimer; + code += "enum k" + Arch + "InstData_NameIndex {\n"; + for (var k in db.instMap) { + var inst = db.instMap[k]; + code += " " + inst.id + "_NameIndex = " + inst.nameIndex + ",\n"; } - code = code.substr(code, code.length - 2) + "\n};\n"; + code = code.substr(0, code.length - 2) + "\n};\n"; + code += "#endif // !ASMJIT_DISABLE_INST_NAMES\n" + code += "\n"; + + // Generate ExtendedInfo. + code += disclaimer; + code += "const " + Arch + "InstExtendedInfo _" + arch + "InstExtendedInfo[] = {\n"; + for (var i = 0; i < db.extendedData.length; i++) { + code += " { " + db.extendedData[i] + " }"; + if (i !== db.extendedData.length - 1) + code += ","; + code += "\n"; + } + code += "};\n"; + code += "\n"; + + code += disclaimer; + code += "enum k" + Arch + "InstData_ExtendedIndex {\n"; + for (var k in db.instMap) { + var inst = db.instMap[k]; + code += " " + inst.id + "_ExtendedIndex = " + inst.extendedIndex + ",\n"; + } + code = code.substr(0, code.length - 2) + "\n};\n"; // Inject. - data = inject(data, injectStartMarker, injectEndMarker, code); + data = inject(data, + "// ${" + Arch + "InstData:Begin}\n", + "// ${" + Arch + "InstData:End}\n", + code); // Save only if modified. if (data !== oldData)