Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2021-12-13 11:11:58 +0300
committerkobalicek <kobalicek.petr@gmail.com>2021-12-13 21:34:56 +0300
commit996deae3273073bf75fbd6ddeac038dff5fdb6eb (patch)
tree47b3078b82a6f4cecb9362b70a5b1395866eb2e4
parent4ec760a3d1f69e32ba460ecd2513f29b8428700b (diff)
[ABI] Refactored AsmJit to use strong-typed enums, this breaks both API and ABI
[ABI] Added ABI version as an inline namespace, which forms asmjit::_abi_MAJOR_MINOR [ABI] Added support for AVX512_FP16, 16-bit broadcast, and AVX512_FP16 tests [ABI] Added initial support for consecutive registers into instruction database and register allocator [ABI] Added a possibility to use temporary memory in CodeHolder's zone [ABI] Compiler::setArg() is now deprecated, use FuncNode::setArg() [Bug] Fixed correct RW information of instructions that only support implicit zeroing with {k} [Bug] Fixed broadcast to be able to broadcast bcst16 operands
-rw-r--r--.github/workflows/build-config.json4
-rw-r--r--.github/workflows/build.yml118
-rw-r--r--CMakeLists.txt49
-rw-r--r--README.md8
-rw-r--r--src/asmjit.natvis166
-rw-r--r--src/asmjit/asmjit-scope-begin.h24
-rw-r--r--src/asmjit/asmjit-scope-end.h24
-rw-r--r--src/asmjit/asmjit.h8
-rw-r--r--src/asmjit/core.h1341
-rw-r--r--src/asmjit/core/api-build_p.h28
-rw-r--r--src/asmjit/core/api-config.h288
-rw-r--r--src/asmjit/core/archcommons.h186
-rw-r--r--src/asmjit/core/archtraits.cpp110
-rw-r--r--src/asmjit/core/archtraits.h257
-rw-r--r--src/asmjit/core/assembler.cpp115
-rw-r--r--src/asmjit/core/assembler.h33
-rw-r--r--src/asmjit/core/builder.cpp174
-rw-r--r--src/asmjit/core/builder.h731
-rw-r--r--src/asmjit/core/codebuffer.h61
-rw-r--r--src/asmjit/core/codeholder.cpp251
-rw-r--r--src/asmjit/core/codeholder.h703
-rw-r--r--src/asmjit/core/codewriter.cpp32
-rw-r--r--src/asmjit/core/codewriter_p.h75
-rw-r--r--src/asmjit/core/compiler.cpp283
-rw-r--r--src/asmjit/core/compiler.h366
-rw-r--r--src/asmjit/core/compilerdefs.h103
-rw-r--r--src/asmjit/core/constpool.cpp79
-rw-r--r--src/asmjit/core/constpool.h70
-rw-r--r--src/asmjit/core/cpuinfo.cpp1147
-rw-r--r--src/asmjit/core/cpuinfo.h755
-rw-r--r--src/asmjit/core/datatypes.h1071
-rw-r--r--src/asmjit/core/emithelper.cpp118
-rw-r--r--src/asmjit/core/emithelper_p.h45
-rw-r--r--src/asmjit/core/emitter.cpp165
-rw-r--r--src/asmjit/core/emitter.h665
-rw-r--r--src/asmjit/core/emitterutils.cpp83
-rw-r--r--src/asmjit/core/emitterutils_p.h58
-rw-r--r--src/asmjit/core/environment.cpp24
-rw-r--r--src/asmjit/core/environment.h728
-rw-r--r--src/asmjit/core/errorhandler.cpp29
-rw-r--r--src/asmjit/core/errorhandler.h127
-rw-r--r--src/asmjit/core/features.h186
-rw-r--r--src/asmjit/core/formatter.cpp273
-rw-r--r--src/asmjit/core/formatter.h267
-rw-r--r--src/asmjit/core/formatter_p.h34
-rw-r--r--src/asmjit/core/func.cpp142
-rw-r--r--src/asmjit/core/func.h1002
-rw-r--r--src/asmjit/core/funcargscontext.cpp97
-rw-r--r--src/asmjit/core/funcargscontext_p.h99
-rw-r--r--src/asmjit/core/globals.cpp45
-rw-r--r--src/asmjit/core/globals.h187
-rw-r--r--src/asmjit/core/inst.cpp54
-rw-r--r--src/asmjit/core/inst.h681
-rw-r--r--src/asmjit/core/jitallocator.cpp310
-rw-r--r--src/asmjit/core/jitallocator.h197
-rw-r--r--src/asmjit/core/jitruntime.cpp102
-rw-r--r--src/asmjit/core/jitruntime.h53
-rw-r--r--src/asmjit/core/logger.cpp51
-rw-r--r--src/asmjit/core/logger.h107
-rw-r--r--src/asmjit/core/misc_p.h24
-rw-r--r--src/asmjit/core/operand.cpp61
-rw-r--r--src/asmjit/core/operand.h1631
-rw-r--r--src/asmjit/core/osutils.cpp28
-rw-r--r--src/asmjit/core/osutils.h40
-rw-r--r--src/asmjit/core/osutils_p.h58
-rw-r--r--src/asmjit/core/raassignment_p.h132
-rw-r--r--src/asmjit/core/rabuilders_p.h206
-rw-r--r--src/asmjit/core/radefs_p.h845
-rw-r--r--src/asmjit/core/ralocal.cpp458
-rw-r--r--src/asmjit/core/ralocal_p.h80
-rw-r--r--src/asmjit/core/rapass.cpp547
-rw-r--r--src/asmjit/core/rapass_p.h462
-rw-r--r--src/asmjit/core/rastack.cpp56
-rw-r--r--src/asmjit/core/rastack_p.h48
-rw-r--r--src/asmjit/core/string.cpp105
-rw-r--r--src/asmjit/core/string.h178
-rw-r--r--src/asmjit/core/support.cpp37
-rw-r--r--src/asmjit/core/support.h584
-rw-r--r--src/asmjit/core/target.cpp31
-rw-r--r--src/asmjit/core/target.h138
-rw-r--r--src/asmjit/core/type.cpp116
-rw-r--r--src/asmjit/core/type.h592
-rw-r--r--src/asmjit/core/virtmem.cpp395
-rw-r--r--src/asmjit/core/virtmem.h263
-rw-r--r--src/asmjit/core/zone.cpp93
-rw-r--r--src/asmjit/core/zone.h210
-rw-r--r--src/asmjit/core/zonehash.cpp44
-rw-r--r--src/asmjit/core/zonehash.h46
-rw-r--r--src/asmjit/core/zonelist.cpp29
-rw-r--r--src/asmjit/core/zonelist.h86
-rw-r--r--src/asmjit/core/zonestack.cpp53
-rw-r--r--src/asmjit/core/zonestack.h115
-rw-r--r--src/asmjit/core/zonestring.h65
-rw-r--r--src/asmjit/core/zonetree.cpp29
-rw-r--r--src/asmjit/core/zonetree.h81
-rw-r--r--src/asmjit/core/zonevector.cpp39
-rw-r--r--src/asmjit/core/zonevector.h142
-rw-r--r--src/asmjit/x86.h82
-rw-r--r--src/asmjit/x86/x86archtraits_p.h160
-rw-r--r--src/asmjit/x86/x86assembler.cpp931
-rw-r--r--src/asmjit/x86/x86assembler.h270
-rw-r--r--src/asmjit/x86/x86builder.cpp40
-rw-r--r--src/asmjit/x86/x86builder.h121
-rw-r--r--src/asmjit/x86/x86compiler.cpp40
-rw-r--r--src/asmjit/x86/x86compiler.h278
-rw-r--r--src/asmjit/x86/x86emithelper.cpp243
-rw-r--r--src/asmjit/x86/x86emithelper_p.h40
-rw-r--r--src/asmjit/x86/x86emitter.h415
-rw-r--r--src/asmjit/x86/x86features.cpp452
-rw-r--r--src/asmjit/x86/x86features.h318
-rw-r--r--src/asmjit/x86/x86formatter.cpp353
-rw-r--r--src/asmjit/x86/x86formatter_p.h42
-rw-r--r--src/asmjit/x86/x86func.cpp398
-rw-r--r--src/asmjit/x86/x86func_p.h30
-rw-r--r--src/asmjit/x86/x86globals.h1099
-rw-r--r--src/asmjit/x86/x86instapi.cpp784
-rw-r--r--src/asmjit/x86/x86instapi_p.h34
-rw-r--r--src/asmjit/x86/x86instdb.cpp5877
-rw-r--r--src/asmjit/x86/x86instdb.h672
-rw-r--r--src/asmjit/x86/x86instdb_p.h64
-rw-r--r--src/asmjit/x86/x86opcode_p.h316
-rw-r--r--src/asmjit/x86/x86operand.cpp63
-rw-r--r--src/asmjit/x86/x86operand.h723
-rw-r--r--src/asmjit/x86/x86rapass.cpp707
-rw-r--r--src/asmjit/x86/x86rapass_p.h73
-rw-r--r--test/asmjit_test_assembler.cpp26
-rw-r--r--test/asmjit_test_assembler.h30
-rw-r--r--test/asmjit_test_assembler_x64.cpp9655
-rw-r--r--test/asmjit_test_assembler_x86.cpp671
-rw-r--r--test/asmjit_test_compiler.cpp225
-rw-r--r--test/asmjit_test_compiler.h36
-rw-r--r--test/asmjit_test_compiler_x86.cpp946
-rw-r--r--test/asmjit_test_emitters.cpp65
-rw-r--r--test/asmjit_test_instinfo.cpp105
-rw-r--r--test/asmjit_test_misc.h46
-rw-r--r--test/asmjit_test_perf.cpp24
-rw-r--r--test/asmjit_test_perf.h32
-rw-r--r--test/asmjit_test_perf_x86.cpp60
-rw-r--r--test/asmjit_test_unit.cpp80
-rw-r--r--test/asmjit_test_x86_sections.cpp40
-rw-r--r--test/asmjitutils.h38
-rw-r--r--test/cmdline.h28
-rw-r--r--test/performancetimer.h24
-rwxr-xr-xtools/configure-makefiles.sh2
-rwxr-xr-xtools/configure-ninja.sh2
-rwxr-xr-xtools/configure-sanitizers.sh4
-rw-r--r--tools/configure-vs-x64.bat9
-rw-r--r--tools/configure-vs-x86.bat9
-rw-r--r--tools/configure-vs2019-x64.bat2
-rw-r--r--tools/configure-vs2019-x86.bat2
-rw-r--r--tools/configure-vs2022-x64.bat2
-rw-r--r--tools/configure-vs2022-x86.bat2
-rw-r--r--tools/tablegen-x86.js804
-rw-r--r--tools/tablegen.js31
154 files changed, 29354 insertions, 21007 deletions
diff --git a/.github/workflows/build-config.json b/.github/workflows/build-config.json
index 3c76bd0..2be4612 100644
--- a/.github/workflows/build-config.json
+++ b/.github/workflows/build-config.json
@@ -20,6 +20,10 @@
"optional": true
},
{
+ "cmd": ["asmjit_test_assembler", "--quiet", "--validate"],
+ "optional": true
+ },
+ {
"cmd": ["asmjit_test_emitters"],
"optional": true
},
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b322364..d7877f1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -31,58 +31,59 @@ jobs:
fail-fast: false
matrix:
include:
- - { title: "linux-lib" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", problem_matcher: "cpp" }
- - { title: "windows-lib" , os: "windows-latest", cc: "vs2019" , arch: "x86", build_type: "Debug" , problem_matcher: "cpp" }
-
- - { title: "diag-asan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "address" }
- - { title: "diag-ubsan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "undefined" }
- - { title: "diag-valgrind" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "valgrind" }
-
- - { title: "no-deprecated" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_DEPRECATED=1" }
- - { title: "no-intrinsics" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_INTRINSICS=1" }
- - { title: "no-logging" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_LOGGING=1" }
- - { title: "no-builder" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_BUILDER=1" }
- - { title: "no-compiler" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_COMPILER=1" }
-
- - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
-
- - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "macos-10.15" , os: "macos-10.15" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "macos-10.15" , os: "macos-10.15" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux-lib" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", problem_matcher: "cpp" }
+ - { title: "windows-lib" , os: "windows-2022" , cc: "vs2022" , arch: "x86", build_type: "Debug" , problem_matcher: "cpp" }
+
+ - { title: "diag-asan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "address" }
+ - { title: "diag-ubsan" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "undefined" }
+ - { title: "diag-valgrind" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON", diagnostics: "valgrind" }
+ - { title: "diag-scan-build", os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON", diagnostics: "scan-build" }
+
+ - { title: "no-deprecated" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_DEPRECATED=1" }
+ - { title: "no-intrinsics" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_INTRINSICS=1" }
+ - { title: "no-logging" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_LOGGING=1" }
+ - { title: "no-builder" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_BUILDER=1" }
+ - { title: "no-compiler" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON,ASMJIT_NO_COMPILER=1" }
+
+ - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "gcc" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-4.8" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-5" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-18.04" , cc: "gcc-6" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-7" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-8" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "gcc-10" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-latest" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "linux" , os: "ubuntu-20.04" , cc: "clang-10", arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+
+ - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "macos-10.15" , os: "macos-10.15" , cc: "gcc-9" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "macos-10.15" , os: "macos-10.15" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "macos-10.15" , os: "macos-10.15" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
# Disabled, because of GitHub actions infrastructure issues (builds not starting).
#- { title: "macos-11.0" , os: "macos-11.0" , cc: "gcc-10" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
@@ -90,10 +91,15 @@ jobs:
#- { title: "macos-11.0" , os: "macos-11.0" , cc: "clang" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
#- { title: "macos-11.0" , os: "macos-11.0" , cc: "clang" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "windows" , os: "windows-latest", cc: "vs2019" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "windows" , os: "windows-latest", cc: "vs2019" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
- - { title: "windows" , os: "windows-latest", cc: "vs2019" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
- - { title: "windows" , os: "windows-latest", cc: "vs2019" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2019" , cc: "vs2019" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+
+ - { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x86", build_type: "Release", defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", build_type: "Debug" , defs: "ASMJIT_TEST=ON" }
+ - { title: "windows" , os: "windows-2022" , cc: "vs2022" , arch: "x64", build_type: "Release", defs: "ASMJIT_TEST=ON" }
name: "${{matrix.title}} (${{matrix.cc}}, ${{matrix.arch}}, ${{matrix.build_type}})"
runs-on: "${{matrix.os}}"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6a8c081..554722c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,9 +19,8 @@ endif()
include(CheckCXXCompilerFlag)
include(GNUInstallDirs)
-# =============================================================================
-# [AsmJit - Deprecated]
-# =============================================================================
+# AsmJit - Deprecated
+# ===================
if (DEFINED ASMJIT_BUILD_EMBED)
message(DEPRECATION "ASMJIT_BUILD_EMBED is deprecated, use ASMJIT_EMBED")
@@ -33,9 +32,8 @@ if (DEFINED ASMJIT_BUILD_STATIC)
set(ASMJIT_STATIC "${ASMJIT_BUILD_STATIC}")
endif()
-# =============================================================================
-# [AsmJit - Configuration]
-# =============================================================================
+# AsmJit - Configuration
+# ======================
if (NOT DEFINED ASMJIT_TEST)
set(ASMJIT_TEST FALSE)
@@ -84,9 +82,8 @@ set(ASMJIT_NO_FOREIGN "${ASMJIT_NO_FOREIGN}" CACHE BOOL "Disable all f
set(ASMJIT_NO_NATVIS "${ASMJIT_NO_NATVIS}" CACHE BOOL "Disable natvis support (embedding asmjit.natvis in PDB)")
set(ASMJIT_NO_CUSTOM_FLAGS "${ASMJIT_NO_CUSTOM_FLAGS}" CACHE BOOL "Disable extra compilation flags added by AsmJit to its targets")
-# =============================================================================
-# [AsmJit - Project]
-# =============================================================================
+# AsmJit - Project
+# ================
set(ASMJIT_INCLUDE_DIRS "${ASMJIT_DIR}/src") # Include directory is the same as source dir.
set(ASMJIT_DEPS "") # AsmJit dependencies (libraries) for the linker.
@@ -98,9 +95,8 @@ set(ASMJIT_PRIVATE_CFLAGS_REL "") # Private compiler flags used b
set(ASMJIT_SANITIZE_CFLAGS "") # Compiler flags required by currently enabled sanitizers.
set(ASMJIT_SANITIZE_LFLAGS "") # Linker flags required by currently enabled sanitizers.
-# =============================================================================
-# [AsmJit - Utilities]
-# =============================================================================
+# AsmJit - Utilities
+# ==================
function(asmjit_detect_cflags out)
set(out_array ${${out}})
@@ -172,9 +168,8 @@ function(asmjit_add_target target target_type)
endif()
endfunction()
-# =============================================================================
-# [AsmJit - Compiler Support]
-# =============================================================================
+# AsmJit - Compiler Support
+# =========================
set(ASMJIT_INCLUDE_DIRS "${ASMJIT_DIR}/src") # Include directory is the same as source dir.
set(ASMJIT_DEPS "") # AsmJit dependencies (libraries) for the linker.
@@ -283,9 +278,8 @@ foreach(build_option ASMJIT_STATIC
endif()
endforeach()
-# =============================================================================
-# [AsmJit - Linker Support]
-# =============================================================================
+# AsmJit - Linker Support
+# =======================
if (WIN32)
if(CMAKE_LINKER MATCHES "link\\.exe" OR CMAKE_LINKER MATCHES "lld-link\\.exe")
@@ -293,9 +287,8 @@ if (WIN32)
endif()
endif()
-# =============================================================================
-# [AsmJit - Source]
-# =============================================================================
+# AsmJit - Source
+# ===============
set(ASMJIT_SRC_LIST
asmjit/asmjit.h
@@ -324,7 +317,6 @@ set(ASMJIT_SRC_LIST
asmjit/core/constpool.h
asmjit/core/cpuinfo.cpp
asmjit/core/cpuinfo.h
- asmjit/core/datatypes.h
asmjit/core/emithelper.cpp
asmjit/core/emithelper_p.h
asmjit/core/emitter.cpp
@@ -335,7 +327,6 @@ set(ASMJIT_SRC_LIST
asmjit/core/environment.h
asmjit/core/errorhandler.cpp
asmjit/core/errorhandler.h
- asmjit/core/features.h
asmjit/core/formatter.cpp
asmjit/core/formatter.h
asmjit/core/func.cpp
@@ -401,8 +392,6 @@ set(ASMJIT_SRC_LIST
asmjit/x86/x86emithelper.cpp
asmjit/x86/x86emithelper_p.h
asmjit/x86/x86emitter.h
- asmjit/x86/x86features.cpp
- asmjit/x86/x86features.h
asmjit/x86/x86formatter.cpp
asmjit/x86/x86formatter_p.h
asmjit/x86/x86func.cpp
@@ -439,9 +428,8 @@ if (NOT ${CMAKE_VERSION} VERSION_LESS "3.8.0")
source_group(TREE "${ASMJIT_DIR}" FILES ${ASMJIT_SRC})
endif()
-# =============================================================================
-# [AsmJit - Summary]
-# =============================================================================
+# AsmJit - Summary
+# ================
message("** AsmJit Summary **")
message(" ASMJIT_DIR=${ASMJIT_DIR}")
@@ -454,9 +442,8 @@ message(" ASMJIT_PRIVATE_CFLAGS=${ASMJIT_PRIVATE_CFLAGS}")
message(" ASMJIT_PRIVATE_CFLAGS_DBG=${ASMJIT_PRIVATE_CFLAGS_DBG}")
message(" ASMJIT_PRIVATE_CFLAGS_REL=${ASMJIT_PRIVATE_CFLAGS_REL}")
-# =============================================================================
-# [AsmJit - Targets]
-# =============================================================================
+# AsmJit - Targets
+# ================
if (NOT ASMJIT_EMBED)
# Add AsmJit target.
diff --git a/README.md b/README.md
index 08ac033..c683989 100644
--- a/README.md
+++ b/README.md
@@ -47,12 +47,10 @@ TODO
* [ ] Core:
* [ ] Add support for user external buffers in CodeBuffer / CodeHolder.
- * [ ] Register allocator doesn't understand register pairs, affected instructions:
- * [ ] v4fmaddps, v4fmaddss, v4fnmaddps, v4fnmaddss
- * [ ] vp4dpwssd, vp4dpwssds
- * [ ] vp2intersectd, vp2intersectq
* [ ] Ports:
- * [ ] ARM/Thumb/AArch64 support.
+ * [ ] 32-bit ARM/Thumb port.
+ * [ ] 64-bit ARM (AArch64) port.
+ * [ ] RISC-V port.
Support
-------
diff --git a/src/asmjit.natvis b/src/asmjit.natvis
index b73d848..68012e0 100644
--- a/src/asmjit.natvis
+++ b/src/asmjit.natvis
@@ -34,50 +34,94 @@
</Expand>
</Type>
- <Type Name="asmjit::Operand_">
- <Intrinsic Name="opType" Expression="(unsigned int)(_signature &amp; 0x7)" />
- <Intrinsic Name="opSize" Expression="(_signature &gt;&gt; 24) &amp; 0xFF" />
-
- <Intrinsic Name="regType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F" />
- <Intrinsic Name="regGroup" Expression="(_signature &gt;&gt; 8) &amp; 0xF" />
-
- <Intrinsic Name="memBaseType" Expression="(_signature &gt;&gt; 3) &amp; 0x1F" />
- <Intrinsic Name="memIndexType" Expression="(_signature &gt;&gt; 8) &amp; 0x1F" />
- <Intrinsic Name="memAddrType" Expression="(_signature &gt;&gt; 13) &amp; 0x3" />
- <Intrinsic Name="memRegHome" Expression="(_signature &gt;&gt; 15) &amp; 0x1" />
+ <Type Name="asmjit::OperandSignature">
+ <Intrinsic Name="opType" Expression="(asmjit::OperandType)(_bits &amp; 0x7)" />
+ <Intrinsic Name="opSize" Expression="(_bits &gt;&gt; 24) &amp; 0xFF" />
+ <Intrinsic Name="regType" Expression="(asmjit::RegType)((_bits &gt;&gt; 3) &amp; 0x1F)" />
+ <Intrinsic Name="regGroup" Expression="(asmjit::RegGroup)((_bits &gt;&gt; 8) &amp; 0xF)" />
+ <Intrinsic Name="memBaseType" Expression="(asmjit::RegType)((_bits &gt;&gt; 3) &amp; 0x1F)" />
+ <Intrinsic Name="memIndexType" Expression="(asmjit::RegType)((_bits &gt;&gt; 8) &amp; 0x1F)" />
+ <Intrinsic Name="memRegHome" Expression="(bool)((_bits &gt;&gt; 13) &amp; 0x1)" />
+ <Intrinsic Name="memX86Segment" Expression="(asmjit::x86::SReg::Id)((_bits &gt;&gt; 18) &amp; 0x7)" />
+ <Intrinsic Name="memX86AddrType" Expression="(asmjit::x86::Mem::AddrType)((_bits &gt;&gt; 14) &amp; 0x3)" />
+ <Intrinsic Name="memX86ShiftValue" Expression="((_bits &gt;&gt; 16) &amp; 0x3)" />
+ <Intrinsic Name="memX86Broadcast" Expression="(asmjit::x86::Mem::Broadcast)((_bits &gt;&gt; 21) &amp; 0x7)" />
+ <Intrinsic Name="immType" Expression="(asmjit::ImmType)((_bits &gt;&gt; 3) &amp; 0x1)" />
+
+ <DisplayString Condition="opType() == asmjit::OperandType::kNone">[None]</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kReg">[Reg] {{ type={regType()} group={regGroup()} size={opSize(), d} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kMem">[Mem] {{ base={memBaseType()} index={memIndexType()} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kImm">[Imm] {{ type={immType()} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kLabel">[Label]</DisplayString>
+ <DisplayString Condition="opType() &gt; asmjit::OperandType::kMaxValue">[Unknown]</DisplayString>
+ <Expand HideRawView="true">
+ <Item Name="bits">_bits, X</Item>
+ <Item Name="op.type">opType()</Item>
+ <Item Name="reg.type" Condition="opType() == asmjit::OperandType::kReg">regType()</Item>
+ <Item Name="reg.group" Condition="opType() == asmjit::OperandType::kReg">regGroup()</Item>
+ <Item Name="reg.size" Condition="opType() == asmjit::OperandType::kReg">opSize(), d</Item>
+ <Item Name="mem.baseType" Condition="opType() == asmjit::OperandType::kMem">memBaseType()</Item>
+ <Item Name="mem.indexType" Condition="opType() == asmjit::OperandType::kMem">memIndexType()</Item>
+ <Item Name="mem.regHome" Condition="opType() == asmjit::OperandType::kMem">memRegHome()</Item>
+ <Item Name="mem.size" Condition="opType() == asmjit::OperandType::kMem">opSize(), d</Item>
+ <Item Name="mem.x86.segment" Condition="opType() == asmjit::OperandType::kMem">memX86Segment()</Item>
+ <Item Name="mem.x86.addrType" Condition="opType() == asmjit::OperandType::kMem">memX86AddrType()</Item>
+ <Item Name="mem.x86.shift" Condition="opType() == asmjit::OperandType::kMem">memX86ShiftValue()</Item>
+ <Item Name="mem.x86.broadcast" Condition="opType() == asmjit::OperandType::kMem">memX86Broadcast()</Item>
+ <Item Name="imm.type" Condition="opType() == asmjit::OperandType::kImm">immType()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="asmjit::Operand_">
+ <Intrinsic Name="opType" Expression="(asmjit::OperandType)(_signature._bits &amp; 0x7)" />
+ <Intrinsic Name="opSize" Expression="(_signature._bits &gt;&gt; 24) &amp; 0xFF" />
+ <Intrinsic Name="regType" Expression="(asmjit::RegType)((_signature._bits &gt;&gt; 3) &amp; 0x1F)" />
+ <Intrinsic Name="regGroup" Expression="(asmjit::RegGroup)((_signature._bits &gt;&gt; 8) &amp; 0xF)" />
+ <Intrinsic Name="memBaseType" Expression="(asmjit::RegType)((_signature._bits &gt;&gt; 3) &amp; 0x1F)" />
+ <Intrinsic Name="memIndexType" Expression="(asmjit::RegType)((_signature._bits &gt;&gt; 8) &amp; 0x1F)" />
+ <Intrinsic Name="memRegHome" Expression="(bool)((_signature._bits &gt;&gt; 13) &amp; 0x1)" />
+ <Intrinsic Name="memX86Segment" Expression="(asmjit::x86::SReg::Id)((_signature._bits &gt;&gt; 18) &amp; 0x7)" />
+ <Intrinsic Name="memX86AddrType" Expression="(asmjit::x86::Mem::AddrType)((_signature._bits &gt;&gt; 14) &amp; 0x3)" />
+ <Intrinsic Name="memX86ShiftValue" Expression="((_signature._bits &gt;&gt; 16) &amp; 0x3)" />
+ <Intrinsic Name="memX86Broadcast" Expression="(asmjit::x86::Mem::Broadcast)((_signature._bits &gt;&gt; 21) &amp; 0x7)" />
<Intrinsic Name="memBaseId" Expression="_baseId" />
<Intrinsic Name="memIndexId" Expression="_data[0]" />
-
<Intrinsic Name="memOffset32b" Expression="(__int64)int(_data[1])" />
<Intrinsic Name="memOffset64b" Expression="(__int64) ((unsigned __int64)_baseId &lt;&lt; 32) | ((unsigned __int64)_data[1])" />
- <Intrinsic Name="memOffset" Expression="memBaseType() != 0 ? memOffset32b() : memOffset64b()" />
-
+ <Intrinsic Name="memOffset" Expression="memBaseType() != asmjit::RegType::kNone ? memOffset32b() : memOffset64b()" />
+ <Intrinsic Name="immType" Expression="(asmjit::ImmType)((_signature._bits &gt;&gt; 3) &amp; 0x1)" />
<Intrinsic Name="immValue" Expression="((__int64)_data[1] &lt;&lt; 32) | (__int64)_data[0]" />
- <DisplayString Condition="opType() == 0">[None]</DisplayString>
- <DisplayString Condition="opType() == 1">[Reg] {{ id={_baseId, d} group={regGroup(), d} type={regType(), d} size={opSize(), d} }}</DisplayString>
- <DisplayString Condition="opType() == 2">[Mem] {{ baseId={memBaseId(), d} indexId={memIndexId(), d} offset={(__int64)memOffset(), d} }}</DisplayString>
- <DisplayString Condition="opType() == 3">[Imm] {{ val={immValue(), d} hex={immValue(), X} }}</DisplayString>
- <DisplayString Condition="opType() == 4">[Label] {{ id={_baseId} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kNone">[None]</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kReg">[Reg] {{ id={_baseId, d} group={regGroup(), d} type={regType(), d} size={opSize(), d} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kMem">[Mem] {{ baseId={memBaseId(), d} indexId={memIndexId(), d} offset={(__int64)memOffset(), d} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kImm">[Imm] {{ val={immValue(), d} hex={immValue(), X} }}</DisplayString>
+ <DisplayString Condition="opType() == asmjit::OperandType::kLabel">[Label] {{ id={_baseId} }}</DisplayString>
<DisplayString Condition="opType() &gt; 4">[Unknown]</DisplayString>
<Expand HideRawView="true">
- <Item Name="_signature">_signature, X</Item>
- <Item Name="_signature.any.type">(asmjit::Operand_::OpType)opType()</Item>
- <Item Name="_signature.any.size">opSize(), d</Item>
- <Item Name="_signature.reg.type" Condition="opType() == 1">(asmjit::BaseReg::RegType)regType()</Item>
- <Item Name="_signature.reg.group" Condition="opType() == 1">(asmjit::BaseReg::RegGroup)regGroup()</Item>
- <Item Name="_signature.mem.baseType" Condition="opType() == 2">(asmjit::BaseReg::RegType)memBaseType()</Item>
- <Item Name="_signature.mem.indexType" Condition="opType() == 2">(asmjit::BaseReg::RegType)memIndexType()</Item>
- <Item Name="_signature.mem.addrType" Condition="opType() == 2">(asmjit::BaseMem::AddrType)memAddrType()</Item>
- <Item Name="_signature.mem.regHome" Condition="opType() == 2">(bool)memRegHome()</Item>
- <Item Name="_baseId">_baseId</Item>
- <Item Name="_data[0]" Condition="opType() != 2 &amp;&amp; opType() != 3">_data[0]</Item>
- <Item Name="_data[1]" Condition="opType() != 2 &amp;&amp; opType() != 3">_data[1]</Item>
- <Item Name="_data[IndexId]" Condition="opType() == 2">_data[0]</Item>
- <Item Name="_data[OffsetLo]" Condition="opType() == 2">_data[1]</Item>
- <Item Name="_data[ImmHi]" Condition="opType() == 3">_data[0]</Item>
- <Item Name="_data[ImmLo]" Condition="opType() == 3">_data[1]</Item>
+ <Item Name="_signature">_signature._bits, X</Item>
+ <Item Name="op.type">opType()</Item>
+ <Item Name="op.size">opSize(), d</Item>
+ <Item Name="reg.type" Condition="opType() == asmjit::OperandType::kReg">regType()</Item>
+ <Item Name="reg.group" Condition="opType() == asmjit::OperandType::kReg">regGroup()</Item>
+ <Item Name="reg.id" Condition="opType() == asmjit::OperandType::kReg">_baseId, d</Item>
+ <Item Name="mem.baseType" Condition="opType() == asmjit::OperandType::kMem">memBaseType()</Item>
+ <Item Name="mem.baseId" Condition="opType() == asmjit::OperandType::kMem &amp;&amp; memBaseType() != asmjit::RegType::kNone">memBaseId()</Item>
+ <Item Name="mem.indexType" Condition="opType() == asmjit::OperandType::kMem">memIndexType()</Item>
+ <Item Name="mem.indexId" Condition="opType() == asmjit::OperandType::kMem &amp;&amp; memIndexType() != asmjit::RegType::kNone">memIndexId()</Item>
+ <Item Name="mem.regHome" Condition="opType() == asmjit::OperandType::kMem">memRegHome()</Item>
+ <Item Name="mem.offset" Condition="opType() == asmjit::OperandType::kMem">memOffset(), d</Item>
+ <Item Name="mem.x86.segment" Condition="opType() == asmjit::OperandType::kMem">memX86Segment()</Item>
+ <Item Name="mem.x86.addrType" Condition="opType() == asmjit::OperandType::kMem">memX86AddrType()</Item>
+ <Item Name="mem.x86.shift" Condition="opType() == asmjit::OperandType::kMem">memX86ShiftValue()</Item>
+ <Item Name="mem.x86.broadcast" Condition="opType() == asmjit::OperandType::kMem">memX86Broadcast()</Item>
+ <Item Name="imm.type" Condition="opType() == asmjit::OperandType::kImm">immType()</Item>
+ <Item Name="imm.value" Condition="opType() == asmjit::OperandType::kImm">immValue(), X</Item>
+ <Item Name="label.id" Condition="opType() == asmjit::OperandType::kLabel">_baseId, d</Item>
+ <Item Name="raw.baseId">_baseId</Item>
+ <Item Name="raw.data[0]">_data[0]</Item>
+ <Item Name="raw.data[1]">_data[1]</Item>
</Expand>
</Type>
@@ -98,7 +142,7 @@
<Expand HideRawView="true">
<Item Name="data">_data</Item>
- <Item Name="typeId">(asmjit::Type::Id)(typeId())</Item>
+ <Item Name="typeId">(asmjit::TypeId)(typeId())</Item>
<Item Name="regType" Condition="isReg()">(asmjit::BaseReg::RegType)regType()</Item>
<Item Name="regId" Condition="isReg()">regId()</Item>
<Item Name="stackOffset" Condition="isStack()">stackOffset()</Item>
@@ -108,26 +152,26 @@
<Type Name="asmjit::BaseNode">
<Intrinsic Name="nodeType" Expression="_any._nodeType" />
- <Intrinsic Name="isInst" Expression="nodeType() == asmjit::BaseNode::kNodeInst"></Intrinsic>
- <Intrinsic Name="isSection" Expression="nodeType() == asmjit::BaseNode::kNodeSection"></Intrinsic>
- <Intrinsic Name="isLabel" Expression="nodeType() == asmjit::BaseNode::kNodeLabel"></Intrinsic>
- <Intrinsic Name="isAlign" Expression="nodeType() == asmjit::BaseNode::kNodeAlign"></Intrinsic>
- <Intrinsic Name="isEmbedData" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedData"></Intrinsic>
- <Intrinsic Name="isEmbedLabel" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedLabel"></Intrinsic>
- <Intrinsic Name="isEmbedLabelDelta" Expression="nodeType() == asmjit::BaseNode::kNodeEmbedLabelDelta"></Intrinsic>
- <Intrinsic Name="isConstPool" Expression="nodeType() == asmjit::BaseNode::kNodeConstPool"></Intrinsic>
- <Intrinsic Name="isComment" Expression="nodeType() == asmjit::BaseNode::kNodeComment"></Intrinsic>
- <Intrinsic Name="isSentinel" Expression="nodeType() == asmjit::BaseNode::kNodeSentinel"></Intrinsic>
- <Intrinsic Name="isJump" Expression="nodeType() == asmjit::BaseNode::kNodeJump"></Intrinsic>
- <Intrinsic Name="isFunc" Expression="nodeType() == asmjit::BaseNode::kNodeFunc"></Intrinsic>
- <Intrinsic Name="isFuncRet" Expression="nodeType() == asmjit::BaseNode::kNodeFuncRet"></Intrinsic>
- <Intrinsic Name="isInvoke" Expression="nodeType() == asmjit::BaseNode::kNodeInvoke"></Intrinsic>
+ <Intrinsic Name="isInst" Expression="nodeType() == asmjit::NodeType::kInst"></Intrinsic>
+ <Intrinsic Name="isSection" Expression="nodeType() == asmjit::NodeType::kSection"></Intrinsic>
+ <Intrinsic Name="isLabel" Expression="nodeType() == asmjit::NodeType::kLabel"></Intrinsic>
+ <Intrinsic Name="isAlign" Expression="nodeType() == asmjit::NodeType::kAlign"></Intrinsic>
+ <Intrinsic Name="isEmbedData" Expression="nodeType() == asmjit::NodeType::kEmbedData"></Intrinsic>
+ <Intrinsic Name="isEmbedLabel" Expression="nodeType() == asmjit::NodeType::kEmbedLabel"></Intrinsic>
+ <Intrinsic Name="isEmbedLabelDelta" Expression="nodeType() == asmjit::NodeType::kEmbedLabelDelta"></Intrinsic>
+ <Intrinsic Name="isConstPool" Expression="nodeType() == asmjit::NodeType::kConstPool"></Intrinsic>
+ <Intrinsic Name="isComment" Expression="nodeType() == asmjit::NodeType::kComment"></Intrinsic>
+ <Intrinsic Name="isSentinel" Expression="nodeType() == asmjit::NodeType::kSentinel"></Intrinsic>
+ <Intrinsic Name="isJump" Expression="nodeType() == asmjit::NodeType::kJump"></Intrinsic>
+ <Intrinsic Name="isFunc" Expression="nodeType() == asmjit::NodeType::kFunc"></Intrinsic>
+ <Intrinsic Name="isFuncRet" Expression="nodeType() == asmjit::NodeType::kFuncRet"></Intrinsic>
+ <Intrinsic Name="isInvoke" Expression="nodeType() == asmjit::NodeType::kInvoke"></Intrinsic>
<Intrinsic Name="actsAsInst" Expression="isInst() || isJump() || isFunc() || isFuncRet() || isInvoke()" />
<Intrinsic Name="actsAsLabel" Expression="isLabel() || isFunc()" />
<DisplayString Condition="isInst()">[InstNode]</DisplayString>
- <DisplayString Condition="isSentinel()">[SectionNode]</DisplayString>
+ <DisplayString Condition="isSection()">[SectionNode]</DisplayString>
<DisplayString Condition="isLabel()">[LabelNode]</DisplayString>
<DisplayString Condition="isAlign()">[AlignNode]</DisplayString>
<DisplayString Condition="isEmbedData()">[EmbedDataNode]</DisplayString>
@@ -140,14 +184,14 @@
<DisplayString Condition="isFunc()">[FuncNode]</DisplayString>
<DisplayString Condition="isFuncRet()">[FuncRetNode]</DisplayString>
<DisplayString Condition="isInvoke()">[InvokeNode]</DisplayString>
- <DisplayString Condition="nodeType() == 0 || nodeType() &gt; 18">[UnknownNode {nodeType(), d}]</DisplayString>
+ <DisplayString Condition="nodeType() == asmjit::NodeType::kNone || nodeType() &gt; 18">[UnknownNode {nodeType(), d}]</DisplayString>
<Expand HideRawView="true">
<Item Name="prev">_prev</Item>
<Item Name="next">_next</Item>
- <Item Name="nodeType">(asmjit::BaseNode::NodeType)_any._nodeType</Item>
- <Item Name="nodeFlags">(asmjit::BaseNode::Flags)_any._nodeFlags</Item>
+ <Item Name="nodeType">_any._nodeType</Item>
+ <Item Name="nodeFlags">_any._nodeFlags</Item>
<Item Name="position">_position</Item>
<Item Name="userData.u64">_userDataU64</Item>
@@ -163,9 +207,9 @@
<Item Name="sectionId" Condition="isSection()">((asmjit::SectionNode*)this)-&gt;_id</Item>
<Item Name="nextSection" Condition="isSection()">((asmjit::SectionNode*)this)-&gt;_nextSection</Item>
- <Item Name="labelId" Condition="isLabel()">((asmjit::LabelNode*)this)-&gt;_id</Item>
+ <Item Name="labelId" Condition="isLabel()">((asmjit::LabelNode*)this)-&gt;_labelId</Item>
- <Item Name="alignMode" Condition="isAlign()">((asmjit::AlignNode*)this)-&gt;_alignMode</Item>
+ <Item Name="alignMode" Condition="isAlign()">((asmjit::AlignNode*)this)-&gt;_alignData._alignMode</Item>
<Item Name="alignment" Condition="isAlign()">((asmjit::AlignNode*)this)-&gt;_alignment</Item>
<Item Name="typeId" Condition="isEmbedData()">_embed._typeId, d</Item>
@@ -175,15 +219,15 @@
<Item Name="inlineData" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_inlineData</Item>
<Item Name="externalData" Condition="isEmbedData()">((asmjit::EmbedDataNode*)this)-&gt;_externalData</Item>
- <Item Name="labelId" Condition="isEmbedLabel()">((asmjit::EmbedLabelNode*)this)-&gt;_id</Item>
+ <Item Name="labelId" Condition="isEmbedLabel()">((asmjit::EmbedLabelNode*)this)-&gt;_labelId</Item>
- <Item Name="labelId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_id</Item>
- <Item Name="baseId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_baseId</Item>
+ <Item Name="labelId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_labelId</Item>
+ <Item Name="baseLabelId" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_baseLabelId</Item>
<Item Name="dataSize" Condition="isEmbedLabelDelta()">((asmjit::EmbedLabelDeltaNode*)this)-&gt;_dataSize</Item>
<Item Name="constPool" Condition="isConstPool()">((asmjit::ConstPoolNode*)this)-&gt;_constPool</Item>
- <Item Name="sentinel.sentinelType" Condition="isSentinel()">(asmjit::SentinelNode::SentinelType)_sentinel._sentinelType</Item>
+ <Item Name="sentinel.sentinelType" Condition="isSentinel()">_sentinel._sentinelType</Item>
<Item Name="annotation" Condition="isJump()">((asmjit::JumpNode*)this)-&gt;_annotation</Item>
@@ -194,7 +238,7 @@
<Item Name="args" Condition="isFunc()">((asmjit::FuncNode*)this)-&gt;_args, [((asmjit::FuncNode*)this)-&gt;_funcDetail._argCount]</Item>
<Item Name="funcDetail" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_funcDetail</Item>
- <Item Name="rets" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_rets, [((asmjit::InvokeNode*)this)-&gt;_funcDetail._retCount]</Item>
+ <Item Name="rets" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_rets</Item>
<Item Name="args" Condition="isInvoke()">((asmjit::InvokeNode*)this)-&gt;_args, [((asmjit::InvokeNode*)this)-&gt;_funcDetail._argCount]</Item>
</Expand>
</Type>
diff --git a/src/asmjit/asmjit-scope-begin.h b/src/asmjit/asmjit-scope-begin.h
index 6ee5050..93397b5 100644
--- a/src/asmjit/asmjit-scope-begin.h
+++ b/src/asmjit/asmjit-scope-begin.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifdef _WIN32
#pragma push_macro("min")
diff --git a/src/asmjit/asmjit-scope-end.h b/src/asmjit/asmjit-scope-end.h
index 447105a..702cef4 100644
--- a/src/asmjit/asmjit-scope-end.h
+++ b/src/asmjit/asmjit-scope-end.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifdef _WIN32
#pragma pop_macro("min")
diff --git a/src/asmjit/asmjit.h b/src/asmjit/asmjit.h
index 5f93fe4..1cd0651 100644
--- a/src/asmjit/asmjit.h
+++ b/src/asmjit/asmjit.h
@@ -1,9 +1,9 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
+// SPDX-License-Identifier: Zlib
+// Official GitHub Repository: https://github.com/asmjit/asmjit
//
-// Copyright (c) 2008-2020 The AsmJit Authors
+// Copyright (c) 2008-2021 The AsmJit Authors
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
diff --git a/src/asmjit/core.h b/src/asmjit/core.h
index 7620343..58a380d 100644
--- a/src/asmjit/core.h
+++ b/src/asmjit/core.h
@@ -1,88 +1,56 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_H_INCLUDED
#define ASMJIT_CORE_H_INCLUDED
//! Root namespace used by AsmJit.
-namespace asmjit {
-
-// ============================================================================
-// [Documentation - mainpage]
-// ============================================================================
+namespace asmjit {}
//! \mainpage API Reference
//!
//! AsmJit C++ API reference documentation generated by Doxygen.
//!
-//! AsmJit library uses one global namespace called \ref asmjit, which provides
-//! the whole functionality. Core functionality is within \ref asmjit namespace
-//! and architecture specific functionality is always in its own namespace. For
-//! example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
+//! AsmJit library uses one global namespace called \ref asmjit, which provides the whole functionality. Core
+//! functionality is within \ref asmjit namespace and architecture specific functionality is always in its own
+//! namespace. For example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
//!
//! \section main_groups Documentation Groups
//!
-//! AsmJit documentation is structured into groups. Groups can be followed in
-//! order to learn AsmJit, but knowledge from multiple groups is required to
-//! use AsmJit properly:
+//! AsmJit documentation is structured into groups. Groups can be followed in order to learn AsmJit, but knowledge
+//! from multiple groups is required to use AsmJit properly:
//!
//! $$DOCS_GROUP_OVERVIEW$$
//!
-//! \note It's important to understand that in order to learn AsmJit all groups
-//! are important. Some groups can be omitted if a particular tool is out of
-//! interest - for example \ref asmjit_assembler users don't need to know about
-//! \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users
-//! must know about \ref asmjit_assembler as it also uses operands, labels, and
-//! other concepts. Similarly \ref asmjit_compiler users must know how both \ref
-//! asmjit_assembler and \ref asmjit_builder tools work.
+//! \note It's important to understand that in order to learn AsmJit all groups are important. Some groups can be
+//! omitted if a particular tool is out of interest - for example \ref asmjit_assembler users don't need to know
+//! about \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users must know about \ref
+//! asmjit_assembler as it also uses operands, labels, and other concepts. Similarly \ref asmjit_compiler users
+//! must know how both \ref asmjit_assembler and \ref asmjit_builder tools work.
//!
//! \section where_to_start Where To Start
//!
-//! AsmJit \ref asmjit_core provides the following two classes that are essential
-//! from the code generation perspective:
+//! AsmJit \ref asmjit_core provides the following two classes that are essential from the code generation perspective:
//!
-//! - \ref CodeHolder provides functionality
-//! to temporarily hold the generated code. It stores all the necessary
-//! information about the code - code buffers, sections, labels, symbols,
-//! and information about relocations.
+//! - \ref CodeHolder provides functionality to temporarily hold the generated code. It stores all the necessary
+//! information about the code - code buffers, sections, labels, symbols, and information about relocations.
//!
-//! - \ref BaseEmitter provides interface used
-//! by emitter implementations. The interface provides basic building blocks
-//! that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and
-//! \ref BaseCompiler.
+//! - \ref BaseEmitter provides interface used by emitter implementations. The interface provides basic building
+//! blocks that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and \ref BaseCompiler.
//!
//! Code emitters:
//!
//! - \ref asmjit_assembler - provides direct machine code generation.
//!
-//! - \ref asmjit_builder - provides intermediate code generation that can
-//! be processed before it's serialized to \ref BaseAssembler.
+//! - \ref asmjit_builder - provides intermediate code generation that can be processed before it's serialized to
+//! \ref BaseAssembler.
//!
-//! - \ref asmjit_compiler - provides high-level code generation with built-in
-//! register allocation.
+//! - \ref asmjit_compiler - provides high-level code generation with built-in register allocation.
//!
-//! - \ref FuncNode - provides insight into how function looks from the Compiler
-//! perspective and how it's stored in a node-list.
+//! - \ref FuncNode - provides insight into how function looks from the Compiler perspective and how it's stored in
+//! a node-list.
//!
//! \section main_recommendations Recommendations
//!
@@ -92,76 +60,63 @@ namespace asmjit {
//!
//! - Make sure that you use \ref ErrorHandler, see \ref asmjit_error_handling.
//!
-//! - Instruction validation in your debug builds can reveal problems too.
-//! AsmJit provides validation at instruction level, that can be enabled
-//! by \ref BaseEmitter::addValidationOptions().
+//! - Instruction validation in your debug builds can reveal problems too. AsmJit provides validation at instruction
+//! level that can be enabled via \ref BaseEmitter::addDiagnosticOptions(). See \ref DiagnosticOptions for more
+//! details.
//!
-//! See \ref BaseEmitter::ValidationOptions for more details.
+//! - If you are a Compiler user, use diagnostic options and read carefully if anything suspicious pops out.
+//! Diagnostic options can be enabled via \ref BaseEmitter::addDiagnosticOptions(). If unsure which ones to use,
+//! enable annotations and all debug options: `DiagnosticOptions::kRAAnnotate | DiagnosticOptions::kRADebugAll`.
//!
-//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function
-//! if you have a problem with AsmJit returning errors during instruction
-//! encoding or register allocation. Having an active breakpoint there can
-//! help to reveal the origin of the error, to inspect variables and other
-//! conditions that caused to it.
+//! - Make sure you put a breakpoint into \ref DebugUtils::errored() function if you have a problem with AsmJit
+//! returning errors during instruction encoding or register allocation. Having an active breakpoint there can
+//! help to reveal the origin of the error, to inspect variables and other conditions that caused to it.
//!
-//! The reason for using \ref Logger and \ref ErrorHandler is that they provide
-//! a very useful information about what's happening inside emitters. In many
-//! cases the information provided by these two is crucial to quickly fix issues
-//! that happen during development (for example wrong instruction, address, or
-//! register used). In addition, output from \ref Logger is always necessary
-//! when filling bug reports. In other words, using logging and proper error
-//! handling can save a lot of time during the development.
+//! The reason for using \ref Logger and \ref ErrorHandler is that they provide a very useful information about what's
+//! happening inside emitters. In many cases the information provided by these two is crucial to quickly fix issues
+//! that happen during development (for example wrong instruction, address, or register used). In addition, output from
+//! \ref Logger is always necessary when filling bug reports. In other words, using logging and proper error handling
+//! can save a lot of time during the development.
//!
//! \section main_other Other Pages
//!
//! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically
//! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
-// ============================================================================
-// [Documentation - asmjit_build]
-// ============================================================================
//! \defgroup asmjit_build Build Instructions
//! \brief Build instructions, supported environments, and feature selection.
//!
//! ### Overview
//!
-//! AsmJit is designed to be easy embeddable in any project. However, it depends
-//! on some compile-time definitions that can be used to enable or disable
-//! features to decrease the resulting binary size. A typical way of building
-//! AsmJit is to use [cmake](https://www.cmake.org), but it's also possible to
-//! just include AsmJit source code in your project and to just build it. The
-//! easiest way to include AsmJit in your project is to just include **src**
-//! directory in your project and to define \ref ASMJIT_STATIC. AsmJit can be
-//! just updated from time to time without any changes to this integration
-//! process. Do not embed AsmJit's `test` files in such case as these are used
-//! exclusively for testing.
+//! AsmJit is designed to be easy embeddable in any project. However, it depends on some compile-time definitions that
+//! can be used to enable or disable features to decrease the resulting binary size. A typical way of building AsmJit
+//! is to use [cmake](https://www.cmake.org), but it's also possible to just include AsmJit source code in your project
+//! and to just build it. The easiest way to include AsmJit in your project is to just include **src** directory in
+//! your project and to define \ref ASMJIT_STATIC. AsmJit can be just updated from time to time without any changes to
+//! this integration process. Do not embed AsmJit's `test` files in such case as these are used exclusively for testing.
//!
//! ### Supported C++ Compilers
//!
//! - Requirements:
//!
-//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang
-//! you would have to enable at least C++11 standard through compiler flags.
+//! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang you would have to enable at least
+//! C++11 standard through compiler flags.
//!
//! - Tested:
//!
-//! - **Clang** - Tested by Travis-CI - Clang 3.9+ (with C++11 enabled) is
-//! officially supported (older Clang versions having C++11 support are
-//! probably fine, but are not regularly tested).
+//! - **Clang** - Tested by GitHub Actions - Clang 3.9+ (with C++11 enabled) is officially supported (older Clang
+//! versions having C++11 support are probably fine, but are not regularly tested).
//!
-//! - **GNU** - Tested by Travis-CI - GCC 4.8+ (with C++11 enabled) is
-//! officially supported.
+//! - **GNU** - Tested by GitHub Actions - GCC 4.8+ (with C++11 enabled) is officially supported.
//!
-//! - **MINGW** - Tested by Travis-CI - Use the latest version, if possible.
+//! - **MINGW** - Should work, but it's not tested in our CI environment.
//!
-//! - **MSVC** - Tested by Travis-CI - VS2017+ is officially supported, VS2015
-//! is reported to work.
+//! - **MSVC** - Tested by GitHub Actions - VS2017+ is officially supported, VS2015 is reported to work.
//!
//! - Untested:
//!
-//! - **Intel** - No maintainers and no CI environment to regularly test
-//! this compiler.
+//! - **Intel** - No maintainers and no CI environment to regularly test this compiler.
//!
//! - **Other** C++ compilers would require basic support in
//! [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h).
@@ -170,258 +125,259 @@ namespace asmjit {
//!
//! - Tested:
//!
-//! - **Linux** - Tested by Travis-CI (any distribution is generally supported).
+//! - **Linux** - Tested by GitHub Actions (any distribution is generally supported).
//!
-//! - **OSX** - Tested by Travis-CI (any version is supported).
+//! - **Mac OS** - Tested by GitHub Actions (any version is supported).
//!
-//! - **Windows** - Tested by Travis-CI - (Windows 7+ is officially supported).
+//! - **Windows** - Tested by GitHub Actions - (Windows 7+ is officially supported).
//!
-//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit
-//! cannot generate WASM code, but can be used to generate X86/X64 code
-//! within a browser, for example.
+//! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit cannot generate WASM code, but can be
+//! used to generate X86/X64 code within a browser, for example.
//!
//! - Untested:
//!
-//! - **BSDs** - No maintainers, no CI environment to regularly test BSDs,
-//! but they should work out of box.
+//! - **BSDs** - No maintainers, no CI environment to regularly test BSDs, but they should work out of box.
//!
//! - **Haiku** - Not regularly tested, but reported to work.
//!
-//! - **Other** operating systems would require some testing and support in
-//! the following files:
+//! - **Other** operating systems would require some testing and support in the following files:
//! - [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h)
//! - [core/osutils.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/osutils.cpp)
//! - [core/virtmem.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/virtmem.cpp)
//!
//! ### Supported Backends / Architectures
//!
-//! - **X86** - Both 32-bit and 64-bit backends tested by Travis-CI.
-//! - **ARM** - Work-in-progress (not public at the moment).
+//! - **X86** - Both 32-bit and 64-bit backends tested on our CI.
//!
//! ### Static Builds and Embedding
//!
-//! These definitions can be used to enable static library build. Embed is used
-//! when AsmJit's source code is embedded directly in another project, implies
-//! static build as well.
+//! These definitions can be used to enable static library build. Embed is used when AsmJit's source code is embedded
+//! directly in another project, implies static build as well.
//!
//! - \ref ASMJIT_EMBED - Asmjit is embedded, implies \ref ASMJIT_STATIC.
//! - \ref ASMJIT_STATIC - Enable static-library build.
//!
-//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in
-//! all compilation units that use AsmJit, otherwise AsmJit would use dynamic
-//! library imports in \ref ASMJIT_API decorator. The recommendation is to
-//! define this macro across the whole project that uses AsmJit this way.
+//! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in all compilation units that use AsmJit,
+//! otherwise AsmJit would use dynamic library imports in \ref ASMJIT_API decorator. The recommendation is to define
+//! this macro across the whole project that uses AsmJit this way.
//!
//! ### Build Configuration
//!
-//! These definitions control whether asserts are active or not. By default
-//! AsmJit would autodetect build configuration from existing pre-processor
-//! definitions, but this behavior can be overridden, for example to enable
-//! debug asserts in release configuration.
+//! These definitions control whether asserts are active or not. By default AsmJit would autodetect build configuration
+//! from existing pre-processor definitions, but this behavior can be overridden, for example to enable debug asserts
+//! in release configuration.
//!
-//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug,
-//! asserts will be enabled in this case.
-//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release,
-//! asserts will be disabled in this case.
+//! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug, asserts will be enabled in this case.
+//! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release, asserts will be disabled in this case.
//!
-//! \note There is usually no need to override the build configuration. AsmJit
-//! detects the build configuration by checking whether `NDEBUG` is defined and
-//! automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
-//! were not used. We only recommend using build configuration overrides in
-//! special situations, like using AsmJit in release configuration with asserts
-//! enabled for whatever reason.
+//! \note There is usually no need to override the build configuration. AsmJit detects the build configuration by
+//! checking whether `NDEBUG` is defined and automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
+//! were not used. We only recommend using build configuration overrides in special situations, like using AsmJit in
+//! release configuration with asserts enabled for whatever reason.
//!
//! ### AsmJit Backends
//!
-//! AsmJit currently supports only X86/X64 backend, but the plan is to add more
-//! backends in the future. By default AsmJit builds only the host backend, which
-//! is autodetected at compile-time, but this can be overridden.
+//! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. By default
+//! AsmJit builds only the host backend, which is autodetected at compile-time, but this can be overridden.
//!
//! - \ref ASMJIT_NO_X86 - Disable X86/X64 backends.
//! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architectures.
-//! If defined, it would internally set \ref ASMJIT_BUILD_HOST to true.
//!
//! ### Features Selection
//!
-//! AsmJit builds by defaults all supported features, which includes all emitters,
-//! logging, instruction validation and introspection, and JIT memory allocation.
-//! Features can be disabled at compile time by using `ASMJIT_NO_...` definitions.
+//! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and
+//! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...`
+//! definitions.
//!
-//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time
-//! so it won't be available and the compilation will fail if there is
-//! attempt to use such API. This includes deprecated classes, namespaces,
+//! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the
+//! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
//! enumerations, and functions.
//!
-//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality
-//! completely. This implies \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
-//! cannot be used without \ref asmjit_builder.
+//! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality completely. This implies \ref
+//! ASMJIT_NO_COMPILER as \ref asmjit_compiler cannot be used without \ref asmjit_builder.
//!
-//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality
-//! completely.
+//! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
//!
//! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
//!
//! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
//!
-//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string
-//! representation of AsmJit constants, should be used together with
-//! \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the
-//! ability to quiry instruction names, register names, etc...
+//! - \ref ASMJIT_NO_TEXT - Disables everything that contains string representation of AsmJit constants, should
+//! be used together with \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the ability to query
+//! instruction names, register names, etc...
//!
//! - \ref ASMJIT_NO_VALIDATION - Disables validation API.
//!
-//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API,
-//! must be used together with \ref ASMJIT_NO_COMPILER as \ref asmjit_compiler
-//! requires introspection for its liveness analysis and register allocation.
+//! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, must be used together with \ref
+//! ASMJIT_NO_COMPILER as \ref asmjit_compiler requires introspection for its liveness analysis and register
+//! allocation.
//!
-//! \note It's not recommended to disable features if you plan to build AsmJit
-//! as a shared library that will be used by multiple projects that you don't
-//! control how AsmJit was built (for example AsmJit in a Linux distribution).
-//! The possibility to disable certain features exists mainly for customized
-//! AsmJit builds.
+//! \note It's not recommended to disable features if you plan to build AsmJit as a shared library that will be
+//! used by multiple projects that you don't control how AsmJit was built (for example AsmJit in a Linux distribution).
+//! The possibility to disable certain features exists mainly for customized AsmJit builds.
-// ============================================================================
-// [Documentation - asmjit_breaking_changes]
-// ============================================================================
//! \defgroup asmjit_breaking_changes Breaking Changes
//! \brief Documentation of breaking changes
//!
//! ### Overview
//!
-//! AsmJit is a live project that is being actively developed. Deprecating the
-//! existing API in favor of a new one is preferred, but it's not always
-//! possible if the changes are significant. AsmJit authors prefer to do
-//! accumulated breaking changes at once instead of breaking the API often.
-//! This page documents deprecated and removed APIs and should serve as a how-to
-//! guide for people that want to port existing code to work with the newest AsmJit.
+//! AsmJit is a live project that is being actively developed. Deprecating the existing API in favor of a new
+//! one is preferred, but it's not always possible if the changes are significant. AsmJit authors prefer to do
+//! accumulated breaking changes at once instead of breaking the API often. This page documents deprecated and
+//! removed APIs and should serve as a how-to guide for people that want to port existing code to work with the
+//! newest AsmJit.
//!
//! ### Tips
//!
//! Useful tips before you start:
//!
-//! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if
-//! you need a quick help.
+//! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if you need a quick help.
+//!
+//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that you are not using deprecated
+//! functionality at all. Deprecated functions are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes
+//! it's not possible to decorate everything like classes, which are used by deprecated functions as well,
+//! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
+//! it's not using anything, which was deprecated.
//!
-//! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that
-//! you are not using deprecated functionality at all. Deprecated functions
-//! are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes it's not
-//! possible to decorate everything like classes, which are used by deprecated
-//! functions as well, because some compilers would warn about that. If your
-//! project compiles fine with `ASMJIT_NO_DEPRECATED` it's not using anything,
-//! which was deprecated.
+//! ### Changes committed at XXXX-XX-XX
+//!
+//! Core changes:
+//!
+//! - Removed old deprecated API.
+//!
+//! - Many enumerations were changed to enum class, and many public APIs were changed to use such enums instead
+//! of uint32_t. This change makes some APIs backward incompatible - there are no deprecations this time.
+//!
+//! - Extracted operand signature manipulation to `OperandSignature`.
+//! - Setting function arguments through `Compiler::setArg()` was deprecated, use FuncNode::setArg() instead.
+//! - Moved `{arch}::Features::k` to `CpuFeatures::{arch}::k`.
+//! - Moved `BaseEmitter::kEncodingOption` to `EncodingOptions::k`.
+//! - Moved `BaseEmitter::kFlag` to `EmitterFlags::k`.
+//! - Moved `BaseEmitter::kType` to `EmitterType::k`.
+//! - Moved `BaseEmitter::kValidationOption` to `DiagnosticOptions::kValidate`.
+//! - Moved `BaseFeatures` to `CpuFeatures`.
+//! - Moved `BaseInst::kControl` to `InstControlFlow::k`.
+//! - Moved `BaseInst::kOption` and `x86::Inst::kOption` to `InstOptions::k`.
+//! - Moved `BaseNode::kNode` to `NodeType::k`.
+//! - Moved `BaseReg::kGroup` and `x86::Reg::kGroup` to `RegGroup::k`.
+//! - Moved `BaseReg::kType` and `x86::Reg::kType` to `RegType::k`.
+//! - Moved `CallConv::kFlag` to `CallConvFlags::k`.
+//! - Moved `CallConv::kId` to `CallConvId::k`.
+//! - Moved `CallConv::kStrategy` to `CallConvStrategy::k`.
+//! - Moved `CodeBuffer::kFlag` to `CodeBufferFlags`.
+//! - Moved `ConstPool::kScope` to `ConstPoolScope::k`.
+//! - Moved `Environment::kArch` to `Arch::k`.
+//! - Moved `Environment::kSubArch` to `SubArch::k`.
+//! - Moved `Environment::kFormat` to `OjectFormat::k`.
+//! - Moved `Environment::kPlatform` to `Platform::k`.
+//! - Moved `Environment::kAbi` to `PlatformABI::k`.
+//! - Moved `Environment::kVendor` to `Vendor::k`.
+//! - Moved `FormatOptions::kFlag` to `FormatFlags::k` and `DiagnosticOptions::k` (Compiler diagnostics flags).
+//! - Moved `FormatOptions::kIndentation` to `FormatIndentationGroup::k`.
+//! - Moved `FuncFrame::kAttr` to `FuncAttributes::k`.
+//! - Moved `Globals::kReset` to `ResetPolicy::k`.
+//! - Moved `InstDB::kAvx512Flag` to `InstDB::Avx512Flags::k`.
+//! - Moved `InstDB::kFlag` to `InstDB::InstFlags::k`.
+//! - Moved `InstDB::kMemFlag` to `InstDB::OpFlags::kMem`.
+//! - Moved `InstDB::kMode` to `InstDB::Mode::k`.
+//! - Moved `InstDB::kOpFlag` to `InstDB::OpFlags::k{OpType}...`.
+//! - Moved `JitAllocator::kOption` to `JitAllocatorOptions::k`.
+//! - Moved `Label::kType` to `LabelType::k`.
+//! - Moved `Operand::kOpType` to `OperandType::k`.
+//! - Moved `OpRWInfo::kFlag` to `OpRWFlags::k`.
+//! - Moved `Type::kId` to `TypeId::k`.
+//! - Moved `VirtMem::k` to `VirtMem::MemoryFlags::k`.
//!
//! ### Changes committed at 2020-05-30
//!
-//! AsmJit has been cleaned up significantly, many todo items have been fixed
-//! and many functions and classes have been redesigned, some in an incompatible
-//! way.
+//! AsmJit has been cleaned up significantly, many todo items have been fixed and many functions and classes have
+//! been redesigned, some in an incompatible way.
//!
//! Core changes:
//!
-//! - \ref Imm operand has now only \ref Imm::value() and \ref Imm::valueAs()
-//! functions that return its value content, and \ref Imm::setValue() function
-//! that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
+//! - `Imm` operand has now only `Imm::value()` and `Imm::valueAs()` functions that return its value content,
+//! and `Imm::setValue()` function that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
//!
//! Old functions were deprecated, but code using them should still compile.
//!
-//! - `ArchInfo` has been replaced with \ref Environment. Environment provides
-//! more details about the architecture, but drops some properties that
-//! were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can
-//! be replaced with `registerSize()` getter, which returns a native register
-//! size of the architecture the environment uses. However, `gpCount()` was
-//! removed - at the moment \ref ArchRegs can be used to access such properties.
+//! - `ArchInfo` has been replaced with `Environment`. Environment provides more details about the architecture,
+//! but drops some properties that were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can be replaced
+//! with `registerSize()` getter, which returns a native register size of the architecture the environment uses.
+//! However, `gpCount()` was removed - at the moment `ArchTraits` can be used to access such properties.
//!
-//! Some other functions were renamed, like `ArchInfo::isX86Family()` is
-//! now \ref Environment::isFamilyX86(), etc. The reason for changing the
-//! order was support for more propertries and all the accessors now
-//! start with the type of the property, like \ref Environment::isPlatformWindows().
+//! Some other functions were renamed, like `ArchInfo::isX86Family()` is now `Environment::isFamilyX86()`, etc.
+//! The reason for changing the order was support for more propertries and all the accessors now start with the
+//! type of the property, like `Environment::isPlatformWindows()`.
//!
-//! This function causes many other classes to provide `environment()` getter
-//! instead of `archInfo()` getter. In addition, AsmJit now uses `arch()` to
-//! get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was renamed
-//! to `Environment::kArchXXX`.
+//! This function causes many other classes to provide `environment()` getter instead of `archInfo()` getter.
+//! In addition, AsmJit now uses `arch()` to get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was
+//! renamed to `Environment::kArchXXX`.
//!
//! Some functions were deprecated, some removed...
//!
-//! - `CodeInfo` has been removed in favor of \ref Environment. If you used
-//! `CodeInfo` to set architecture and base address, this is now possible
-//! with \ref Environment and setting base address explicitly by \ref
-//! CodeHolder::init() - the first argument is \ref Environment, and the
-//! second argument is base address, which defaults to \ref
-//! Globals::kNoBaseAddress.
+//! - `CodeInfo` has been removed in favor of `Environment`. If you used `CodeInfo` to set architecture and base
+//! address, this is now possible with `Environment` and setting base address explicitly by `CodeHolder::init()`
+//! - the first argument is `Environment`, and the second argument is base address, which defaults to
+//! `Globals::kNoBaseAddress`.
//!
-//! CodeInfo class was deprecated, but the code using it should still
-//! compile with warnings.
+//! CodeInfo class was deprecated, but the code using it should still compile with warnings.
//!
-//! - \ref CallConv has been updated to offer a more unified way of representing
-//! calling conventions - many calling conventions were abstracted to follow
-//! standard naming like \ref CallConv::kIdCDecl or \ref CallConv::kIdStdCall.
+//! - `CallConv` has been updated to offer a more unified way of representing calling conventions - many calling
+//! conventions were abstracted to follow standard naming like `CallConvId::kCDecl` or `CallConvId::kStdCall`.
//!
-//! This change means that other APIs like \ref FuncDetail::init() now
-//! require both, calling convention and target \ref Environment.
+//! This change means that other APIs like `FuncDetail::init()` now require both, calling convention and target
+//! `Environment`.
//!
-//! - `Logging` namespace has been renamed to \ref Formatter, which now
-//! provides general functionality for formatting in AsmJit.
+//! - `Logging` namespace has been renamed to `Formatter`, which now provides general functionality for formatting
+//! in AsmJit.
//!
-//! Logging namespace should still work, but its use is deprecated.
-//! Unfortunately this will be without deprecation warnings, so please
-//! make sure you don't use it.
+//! Logging namespace should still work, but its use is deprecated. Unfortunately this will be without deprecation
+//! warnings, so make sure you don't use it.
//!
-//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should
-//! no longer be used. There is no replacement, AsmJit users should simply
-//! create their own structures if they need them or use the new repeated
-//! embed API in emitters, see \ref BaseEmitter::embedDataArray().
+//! - `Data64`, `Data128`, and `Data256` structs were deprecated and should no longer be used. There is no replacement,
+//! AsmJit users should simply create their own structures if they need them or use the new repeated embed API in
+//! emitters, see `BaseEmitter::embedDataArray()`.
//!
//! Emitter changes:
//!
-//! - \ref BaseEmitter::emit() function signature has been changed to accept
-//! 3 operands by reference and the rest 3 operands as a continuous array.
-//! This change is purely cosmetic and shouldn't affect users as emit()
-//! has many overloads that dispatch to the right function.
+//! - `BaseEmitter::emit()` function signature has been changed to accept 3 operands by reference and the rest 3
+//! operands as a continuous array. This change is purely cosmetic and shouldn't affect users as emit() has many
+//! overloads that dispatch to the right function.
//!
-//! - \ref x86::Emitter (Assembler, Builder, Compiler) deprecates embed
-//! utilities like `dint8()`, `duint8()`, `duint16()`, `dxmm()`, etc...
-//! in favor of a new and more powerful \ref BaseEmitter::embedDataArray().
-//! This function also allows emitting repeated values and/or patterns,
-//! which is used by helpers \ref BaseEmitter::embedUInt8(), and others...
+//! - `x86::Emitter` (Assembler, Builder, Compiler) deprecates embed utilities like `dint8()`, `duint8()`, `duint16()`,
+//! `dxmm()`, etc... in favor of a new and more powerful `BaseEmitter::embedDataArray()`. This function also allows
+//! emitting repeated values and/or patterns, which is used by helpers `BaseEmitter::embedUInt8()`, and others...
//!
-//! - Validation is now available through \ref BaseEmitter::ValidationOptions,
-//! which can be enabled/disabled through \ref BaseEmitter::addValidationOptions()
-//! and \ref BaseEmitter::clearValidationOptions(), respectively. Validation
-//! options now separate between encoding and Builder/Compiler so it's possible
-//! to choose the granularity required.
+//! - Validation is now available through `BaseEmitter::DiagnosticOptions`, which can be enabled/disabled through
+//! `BaseEmitter::addDiagnosticOptions()` and `BaseEmitter::clearDiagnosticOptions()`, respectively. Validation
+//! options now separate between encoding and Builder/Compiler so it's possible to choose the granularity required.
//!
//! Builder changes:
//!
-//! - Internal functions for creating nodes were redesigned. They now accept
-//! a pointer to the node created as a first parameter. These changes should
-//! not affect AsmJit users as these functions were used internally.
+//! - Internal functions for creating nodes were redesigned. They now accept a pointer to the node created as
+//! a first parameter. These changes should not affect AsmJit users as these functions were used internally.
//!
//! Compiler changes:
//!
-//! - `FuncCallNode` has been renamed to \ref InvokeNode. Additionally, function
-//! calls should now use \ref x86::Compiler::invoke() instead of `call()`.
-//! The reason behind this is to remove the confusion between a `call`
-//! instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
+//! - `FuncCallNode` has been renamed to `InvokeNode`. Additionally, function calls should now use
+//! `x86::Compiler::invoke()` instead of `call()`. The reason behind this is to remove the confusion between a
+//! `call` instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
//!
-//! - Creating new nodes also changed. Now the preferred way of invoking a
-//! function is to call \ref x86::Compiler::invoke() where the first
-//! argument is `InvokeNode**`. The function now returns an error and would
-//! call \ref ErrorHandler in case of a failure. Error handling was
-//! unspecified in the past - the function was marked noexcept, but called
-//! error handler, which could throw.
+//! - Creating new nodes also changed. Now the preferred way of invoking a function is to call
+//! `x86::Compiler::invoke()` where the first argument is `InvokeNode**`. The function now returns an error and
+//! would call `ErrorHandler` in case of a failure. Error handling was unspecified in the past - the function was
+//! marked noexcept, but called error handler, which could throw.
//!
-//! The reason behind this change is to make the API consistent with other
-//! changes and to also make it possible to inspect the possible error. In
-//! the previous API it returned a new node or `nullptr` in case of error,
-//! which the user couldn't inspect unless there was an attached \ref
-//! ErrorHandler.
+//! The reason behind this change is to make the API consistent with other changes and to also make it possible
+//! to inspect the possible error. In the previous API it returned a new node or `nullptr` in case of error,
+//! which the user couldn't inspect unless there was an attached `ErrorHandler`.
//!
//! Samples:
//!
//! ```
//! #include <asmjit/x86.h>
+//!
//! using namespace asmjit;
//!
//! // The basic setup of JitRuntime and CodeHolder changed, use environment()
@@ -438,55 +394,46 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_core]
-// ============================================================================
//! \defgroup asmjit_core Core
//! \brief Globals, code storage, and emitter interface.
//!
//! ### Overview
//!
-//! AsmJit library uses \ref CodeHolder to hold code during code generation and
-//! emitters inheriting from \ref BaseEmitter to emit code. CodeHolder uses
-//! containers to manage its data:
+//! AsmJit library uses \ref CodeHolder to hold code during code generation and emitters inheriting from \ref
+//! BaseEmitter to emit code. CodeHolder uses containers to manage its data:
//!
//! - \ref Section - stores information about a code or data section.
//! - \ref CodeBuffer - stores actual code or data, part of \ref Section.
-//! - \ref LabelEntry - stores information about a label - its name, offset,
-//! section where it belongs to, and other bits.
-//! - \ref LabelLink - stores information about yet unbound label, which was
-//! already used by the assembler.
+//! - \ref LabelEntry - stores information about a label - its name, offset, section where it belongs to, and
+//! other bits.
+//! - \ref LabelLink - stores information about yet unbound label, which was already used by the assembler.
//! - \ref RelocEntry - stores information about a relocation.
-//! - \ref AddressTableEntry - stores information about an address, which was
-//! used in a jump or call. Such address may need relocation.
+//! - \ref AddressTableEntry - stores information about an address, which was used in a jump or call. Such
+//! address may need relocation.
//!
//! To generate code you would need to instantiate at least the following classes:
//!
//! - \ref CodeHolder - to hold code during code generation.
//! - \ref BaseEmitter - to emit code into \ref CodeHolder.
-//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated
-//! code in executable memory. \ref Target can be customized by inheriting from
-//! it.
+//! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated code in executable memory. \ref
+//! Target can be customized by inheriting from it.
//!
//! There are also other core classes that are important:
//!
-//! - \ref Environment - describes where the code will run. Environment brings
-//! the concept of target triples or tuples into AsmJit, which means that users
-//! can specify target architecture, platform, and ABI.
-//! - \ref Type - encapsulates lightweight type functionality that can be used
-//! to describe primitive and vector types. Types are used by higher level
-//! utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
-//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information
-//! and features described by \ref BaseFeatures.
+//! - \ref Environment - describes where the code will run. Environment brings the concept of target triples or
+//! tuples into AsmJit, which means that users can specify target architecture, platform, and ABI.
+//! - \ref TypeId - encapsulates lightweight type functionality that can be used to describe primitive and vector
+//! types. Types are used by higher level utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
+//! - \ref CpuInfo - encapsulates CPU information - stores both CPU information and CPU features described by \ref
+//! CpuFeatures.
//!
//! AsmJit also provides global constants:
//!
//! - \ref Globals - namespace that provides global constants.
//! - \ref ByteOrder - byte-order constants and functionality.
//!
-//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot
-//! be used to generate code.
+//! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
//!
//! ### CodeHolder & Emitters
//!
@@ -529,8 +476,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the
-//! following emitters that offer various levels of abstraction:
+//! The example above used \ref x86::Assembler as an emitter. AsmJit provides the following emitters that offer various
+//! levels of abstraction:
//!
//! - \ref asmjit_assembler - Low-level emitter that emits directly to \ref CodeBuffer.
//! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list.
@@ -538,30 +485,25 @@ namespace asmjit {
//!
//! ### Targets and JitRuntime
//!
-//! AsmJit's \ref Target is an interface that provides basic target abstraction.
-//! At the moment AsmJit provides only one implementation called \ref JitRuntime,
-//! which as the name suggests provides JIT code target and execution runtime.
-//! \ref JitRuntime provides all the necessary stuff to implement a simple JIT
-//! compiler with basic memory management. It only provides \ref JitRuntime::add()
-//! and \ref JitRuntime::release() functions that are used to either add code
-//! to the runtime or release it. \ref JitRuntime doesn't do any decisions on
-//! when the code should be released, the decision is up to the developer.
+//! AsmJit's \ref Target is an interface that provides basic target abstraction. At the moment AsmJit provides only
+//! one implementation called \ref JitRuntime, which as the name suggests provides JIT code target and execution
+//! runtime. \ref JitRuntime provides all the necessary stuff to implement a simple JIT compiler with basic memory
+//! management. It only provides \ref JitRuntime::add() and \ref JitRuntime::release() functions that are used to
+//! either add code to the runtime or release it. \ref JitRuntime doesn't do any decisions on when the code should be
+//! released, the decision is up to the developer.
//!
//! See more at \ref asmjit_virtual_memory group.
//!
//! ### More About Environment
//!
-//! In the previous example the \ref Environment is retrieved from \ref JitRuntime.
-//! It's logical as \ref JitRuntime always returns an \ref Environment that is
-//! compatible with the host. For example if your application runs in 64-bit mode
-//! the \ref Environment returned will use \ref Environment::kArchX64 architecture
-//! in contrast to \ref Environment::kArchX86, which will be used in 32-bit mode on
-//! any X86 platform.
+//! In the previous example the \ref Environment is retrieved from \ref JitRuntime. It's logical as \ref JitRuntime
+//! always returns an \ref Environment that is compatible with the host. For example if your application runs on X86_64
+//! CPU the \ref Environment returned will use \ref Arch::kX64 architecture in contrast to \ref Arch::kX86, which will
+//! be used in 32-bit mode on an X86 target.
//!
-//! AsmJit allows to setup the \ref Environment manually and to select a different
-//! architecture and ABI when necessary. So let's do something else this time, let's
-//! always generate a 32-bit code and print its binary representation. To do that, we
-//! can create our own \ref Environment and initialize it to \ref Environment::kArchX86.
+//! AsmJit allows to setup the \ref Environment manually and to select a different architecture and ABI when necessary.
+//! So let's do something else this time, let's always generate a 32-bit code and print its binary representation. To
+//! do that, we can create our own \ref Environment and initialize it to \ref Arch::kX86.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -574,7 +516,7 @@ namespace asmjit {
//!
//! // Create a custom environment initialized to 32-bit X86 architecture.
//! Environment env;
-//! env.setArch(Environment::kArchX86);
+//! env.setArch(Arch::kX86);
//!
//! CodeHolder code; // Create a CodeHolder.
//! code.init(env); // Initialize CodeHolder with custom environment.
@@ -612,46 +554,37 @@ namespace asmjit {
//!
//! ### Explicit Code Relocation
//!
-//! In addition to \ref Environment, \ref CodeHolder can be configured to
-//! specify a base-address (or a virtual base-address in a linker terminology),
-//! which could be static (useful when you know the location where the target's
-//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by
-//! default and relocates the code held by \ref CodeHolder to a user provided
-//! address on-demand. To be able to relocate to a user provided address it needs
-//! to store some information about relocations, which is represented by \ref
-//! RelocEntry. Relocation entries are only required if you call external functions
-//! from the generated code that cannot be encoded by using a 32-bit displacement
-//! (64-bit displacements are not provided by aby supported architecture).
-//!
-//! There is also a concept called \ref LabelLink - label link is a lightweight
-//! data structure that doesn't have any identifier and is stored in \ref LabelEntry
-//! as a single-linked list. Label link represents either unbound yet used label
-//! and cross-sections links (only relevant to code that uses multiple sections).
-//! Since crossing sections is something that cannot be resolved immediately these
-//! links persist until offsets of these sections are assigned and until
-//! \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end
-//! up with code that has unresolved label links after flattening. You can verify
-//! it by calling \ref CodeHolder::hasUnresolvedLinks(), which inspects the value
-//! returned by \ref CodeHolder::unresolvedLinkCount().
-//!
-//! AsmJit can flatten code that uses multiple sections by assigning each section
-//! an incrementing offset that respects its alignment. Use \ref CodeHolder::flatten()
-//! to do that. After the sections are flattened their offsets and virtual-sizes
-//! are adjusted to respect each section's buffer size and alignment. The \ref
-//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating
-//! the code held by \ref CodeHolder. You can also flatten your code manually by
-//! iterating over all sections and calculating their offsets (relative to base)
-//! by your own algorithm. In that case \ref CodeHolder::flatten() should not be
-//! called, however, \ref CodeHolder::resolveUnresolvedLinks() should be.
-//!
-//! The example below shows how to use a built-in virtual memory allocator
-//! \ref JitAllocator instead of using \ref JitRuntime (just in case you want
-//! to use your own memory management) and how to relocate the generated code
-//! into your own memory block - you can use your own virtual memory allocator
-//! if you prefer that, but that's OS specific and not covered by the documentation.
-//!
-//! The following code is similar to the previous one, but implements a function
-//! working in both 32-bit and 64-bit environments:
+//! In addition to \ref Environment, \ref CodeHolder can be configured to specify a base-address (or a virtual base
+//! address in a linker terminology), which could be static (useful when you know the location where the target's
+//! machine code will be) or dynamic. AsmJit assumes dynamic base-address by default and relocates the code held by
+//! \ref CodeHolder to a user provided address on-demand. To be able to relocate to a user provided address it needs
+//! to store some information about relocations, which is represented by \ref RelocEntry. Relocation entries are only
+//! required if you call external functions from the generated code that cannot be encoded by using a 32-bit
+//! displacement (64-bit displacements are not provided by aby supported architecture).
+//!
+//! There is also a concept called \ref LabelLink - label link is a lightweight data structure that doesn't have any
+//! identifier and is stored in \ref LabelEntry as a single-linked list. Label link represents either unbound yet used
+//! label and cross-sections links (only relevant to code that uses multiple sections). Since crossing sections is
+//! something that cannot be resolved immediately these links persist until offsets of these sections are assigned and
+//! until \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end up with code that has
+//! unresolved label links after flattening. You can verify it by calling \ref CodeHolder::hasUnresolvedLinks(), which
+//! inspects the value returned by \ref CodeHolder::unresolvedLinkCount().
+//!
+//! AsmJit can flatten code that uses multiple sections by assigning each section an incrementing offset that respects
+//! its alignment. Use \ref CodeHolder::flatten() to do that. After the sections are flattened their offsets and
+//! virtual sizes are adjusted to respect each section's buffer size and alignment. The \ref
+//! CodeHolder::resolveUnresolvedLinks() function must be called before relocating the code held by \ref CodeHolder.
+//! You can also flatten your code manually by iterating over all sections and calculating their offsets (relative to
+//! base) by your own algorithm. In that case \ref CodeHolder::flatten() should not be called, however,
+//! \ref CodeHolder::resolveUnresolvedLinks() should be.
+//!
+//! The example below shows how to use a built-in virtual memory allocator \ref JitAllocator instead of using \ref
+//! JitRuntime (just in case you want to use your own memory management) and how to relocate the generated code
+//! into your own memory block - you can use your own virtual memory allocator if you prefer that, but that's OS
+//! specific and not covered by the documentation.
+//!
+//! The following code is similar to the previous one, but implements a function working in both 32-bit and 64-bit
+//! environments:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -663,7 +596,7 @@ namespace asmjit {
//!
//! int main() {
//! // Create a custom environment that matches the current host environment.
-//! Environment env = hostEnvironment();
+//! Environment env = Environment::host();
//!
//! CodeHolder code; // Create a CodeHolder.
//! code.init(env); // Initialize CodeHolder with environment.
@@ -752,7 +685,7 @@ namespace asmjit {
//! // memcpy((uint8_t*)p + section->offset(),
//! // section->data(),
//! // section->bufferSize());
-//! code.copyFlattenedData(p, codeSize, CodeHolder::kCopyPadSectionBuffer);
+//! code.copyFlattenedData(p, codeSize, CopySectionFlags::kPadSectionBuffer);
//!
//! // Execute the generated function.
//! int inA[4] = { 4, 3, 2, 1 };
@@ -774,18 +707,19 @@ namespace asmjit {
//! }
//! ```
//!
-//! If you know the base-address in advance (before the code generation) it can
-//! be passed as a second argument to \ref CodeHolder::init(). In that case the
-//! Assembler will know the absolute position of each instruction and would be
-//! able to use it during instruction encoding to prevent relocations where
-//! possible. The following example shows how to configure the base address:
+//! If you know the base-address in advance (before the code generation) it can be passed as a second argument to
+//! \ref CodeHolder::init(). In that case the Assembler will know the absolute position of each instruction and
+//! would be able to use it during instruction encoding to prevent relocations where possible. The following example
+//! shows how to configure the base address:
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void initializeCodeHolder(CodeHolder& code) {
-//! Environment env = hostEnvironment();
+//! Environment env = Environment::host();
//! uint64_t baseAddress = uint64_t(0x1234);
//!
//! // initialize CodeHolder with environment and custom base address.
@@ -795,16 +729,16 @@ namespace asmjit {
//!
//! ### Label Offsets and Links
//!
-//! When a label that is not yet bound is used by the Assembler, it creates a
-//! \ref LabelLink, which is then added to a \ref LabelEntry. These links are
-//! also created if a label is used in a different section than in which it
-//! was bound. Let's examine some functions that can be used to check whether
-//! there are any unresolved links.
+//! When a label that is not yet bound is used by the Assembler, it creates a \ref LabelLink, which is then added to
+//! a \ref LabelEntry. These links are also created if a label is used in a different section than in which it was
+//! bound. Let's examine some functions that can be used to check whether there are any unresolved links.
//!
//! ```
//! #include <asmjit/core.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void labelLinksExample(CodeHolder& code, const Label& label) {
//! // Tests whether the `label` is bound.
//! bool isBound = code.isLabelBound(label);
@@ -819,16 +753,17 @@ namespace asmjit {
//! }
//! ```
//!
-//! There is no function that would return the number of unbound labels as this
-//! is completely unimportant from CodeHolder's perspective. If a label is not
-//! used then it doesn't matter whether it's bound or not, only actually used
-//! labels matter. After a Label is bound it's possible to query its offset
-//! offset relative to the start of the section where it was bound:
+//! There is no function that would return the number of unbound labels as this is completely unimportant from
+//! CodeHolder's perspective. If a label is not used then it doesn't matter whether it's bound or not, only actually
+//! used labels matter. After a Label is bound it's possible to query its offset offset relative to the start of the
+//! section where it was bound:
//!
//! ```
//! #include <asmjit/core.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void labelOffsetExample(CodeHolder& code, const Label& label) {
//! // Label offset is known after it's bound. The offset provided is relative
//! // to the start of the section, see below for alternative. If the given
@@ -848,15 +783,16 @@ namespace asmjit {
//!
//! ### Sections
//!
-//! AsmJit allows to create multiple sections within the same \ref CodeHolder.
-//! A test-case [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
-//! can be used as a reference point although the following example should
-//! also provide a useful insight:
+//! AsmJit allows to create multiple sections within the same \ref CodeHolder. A test-case
+//! [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
+//! can be used as a reference point although the following example should also provide a useful insight:
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! void sectionsExample(CodeHolder& code) {
//! // Text section is always provided as the first section.
//! Section* text = code.textSection(); // or code.sectionById(0);
@@ -864,11 +800,11 @@ namespace asmjit {
//! // To create another section use CodeHolder::newSection().
//! Section* data;
//! Error err = code.newSection(&data,
-//! ".data", // Section name
-//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
-//! 0, // Section flags, see Section::Flags.
-//! 8, // Section alignment, must be power of 2.
-//! 0); // Section order value (optional, default 0).
+//! ".data", // Section name
+//! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
+//! SectionFlags::kNone, // Section flags, see SectionFlags.
+//! 8, // Section alignment, must be power of 2.
+//! 0); // Section order value (optional, default 0).
//!
//! // When you switch sections in Assembler, Builder, or Compiler the cursor
//! // will always move to the end of that section. When you create an Assembler
@@ -893,17 +829,17 @@ namespace asmjit {
//! }
//! ```
//!
-//! The last line in the example above shows that a LabelLink would be created
-//! even for bound labels that cross sections. In this case a referenced label
-//! was bound in another section, which means that the link couldn't be resolved
-//! at that moment. If your code uses sections, but you wish AsmJit to flatten
-//! these sections (you don't plan to flatten them manually) then there is an
-//! API for that.
+//! The last line in the example above shows that a LabelLink would be created even for bound labels that cross
+//! sections. In this case a referenced label was bound in another section, which means that the link couldn't be
+//! resolved at that moment. If your code uses sections, but you wish AsmJit to flatten these sections (you don't
+//! plan to flatten them manually) then there is an API for that.
//!
//! ```
//! #include <asmjit/x86.h>
//! #include <stdio.h>
//!
+//! using namespace asmjit;
+//!
//! // ... (continuing the previous example) ...
//! void sectionsExampleContinued(CodeHolder& code) {
//! // Suppose we have some code that contains multiple sections and
@@ -938,18 +874,14 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_assembler]
-// ============================================================================
//! \defgroup asmjit_assembler Assembler
//! \brief Assembler interface and operands.
//!
//! ### Overview
//!
-//! AsmJit's Assembler is used to emit machine code directly into a \ref
-//! CodeBuffer. In general, code generation with assembler requires the knowledge
-//! of the following:
+//! AsmJit's Assembler is used to emit machine code directly into a \ref CodeBuffer. In general, code generation
+//! with assembler requires the knowledge of the following:
//!
//! - \ref BaseAssembler and architecture-specific assemblers:
//! - \ref x86::Assembler - Assembler specific to X86 architecture
@@ -961,76 +893,58 @@ namespace asmjit {
//! - \ref Imm - Immediate (value) operand.
//! - \ref Label - Label operand.
//!
-//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot
-//! be used to generate code.
+//! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
//!
//! ### Operand Basics
//!
-//! Let's start with operands. \ref Operand is a data structure that defines a
-//! data layout of any operand. It can be inherited, but any class inheriting
-//! it cannot add any members to it, only the existing layout can be reused.
-//! AsmJit allows to construct operands dynamically, to store them, and to query
-//! a complete information about them at run-time. Operands are small (always 16
-//! bytes per \ref Operand) and can be copied and passed by value. Please never
-//! allocate individual operands dynamically by using a `new` keyword - it would
-//! work, but then you would have to be responsible for deleting such operands.
-//! In AsmJit operands are always part of some other data structures like \ref
-//! InstNode, which is part of \ref asmjit_builder tool.
-//!
-//! Operands contain only identifiers, but not pointers to any code-generation data.
-//! For example \ref Label operand only provides label identifier, but not a pointer
-//! to \ref LabelEntry structure. In AsmJit such IDs are used to link stuff together
-//! without having to deal with pointers.
-//!
-//! AsmJit's operands all inherit from a base class called \ref Operand. Operands
-//! have the following properties that are commonly accessible by getters and setters:
-//!
-//! - \ref Operand - Base operand, which only provides accessors that are common
-//! to all operand types.
-//! - \ref BaseReg - Describes either physical or virtual register. Physical
-//! registers have id that matches the target's machine id directly whereas
-//! virtual registers must be allocated into physical registers by a register
+//! Let's start with operands. \ref Operand is a data structure that defines a data layout of any operand. It can be
+//! inherited, but any class inheriting it cannot add any members to it, only the existing layout can be reused.
+//! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them
+//! at run-time. Operands are small (always 16 bytes per \ref Operand) and can be copied and passed by value. Please
+//! never allocate individual operands dynamically by using a `new` keyword - it would work, but then you would have
+//! to be responsible for deleting such operands. In AsmJit operands are always part of some other data structures
+//! like \ref InstNode, which is part of \ref asmjit_builder tool.
+//!
+//! Operands contain only identifiers, but not pointers to any code-generation data. For example \ref Label operand
+//! only provides label identifier, but not a pointer to \ref LabelEntry structure. In AsmJit such IDs are used to
+//! link stuff together without having to deal with pointers.
+//!
+//! AsmJit's operands all inherit from a base class called \ref Operand. Operands have the following properties that
+//! are commonly accessible by getters and setters:
+//!
+//! - \ref Operand - Base operand, which only provides accessors that are common to all operand types.
+//! - \ref BaseReg - Describes either physical or virtual register. Physical registers have id that matches the
+//! target's machine id directly whereas virtual registers must be allocated into physical registers by a register
//! allocator pass. Register operand provides:
-//! - Register Type - Unique id that describes each possible register provided
-//! by the target architecture - for example X86 backend provides \ref
-//! x86::Reg::RegType, which defines all variations of general purpose registers
-//! (GPB-LO, GPB-HI, GPW, GPD, and GPQ) and all types of other registers like K,
-//! MM, BND, XMM, YMM, and ZMM.
-//! - Register Group - Groups multiple register types under a single group - for
-//! example all general-purpose registers (of all sizes) on X86 are part of
-//! \ref x86::Reg::kGroupGp and all SIMD registers (XMM, YMM, ZMM) are part
-//! of \ref x86::Reg::kGroupVec.
-//! - Register Size - Contains the size of the register in bytes. If the size
-//! depends on the mode (32-bit vs 64-bit) then generally the higher size is
-//! used (for example RIP register has size 8 by default).
+//! - Register Type (\ref RegType) - Unique id that describes each possible register provided by the target
+//! architecture - for example X86 backend provides general purpose registers (GPB-LO, GPB-HI, GPW, GPD, and GPQ)
+//! and all types of other registers like K, MM, BND, XMM, YMM, ZMM, and TMM.
+//! - Register Group (\ref RegGroup) - Groups multiple register types under a single group - for example all
+//! general-purpose registers (of all sizes) on X86 are part of \ref RegGroup::kGp and all SIMD registers
+//! (XMM, YMM, ZMM) are part of \ref RegGroup::kVec.
+//! - Register Size - Contains the size of the register in bytes. If the size depends on the mode (32-bit vs
+//! 64-bit) then generally the higher size is used (for example RIP register has size 8 by default).
//! - Register Id - Contains physical or virtual id of the register.
//! - \ref BaseMem - Used to reference a memory location. Memory operand provides:
//! - Base Register - A base register type and id (physical or virtual).
//! - Index Register - An index register type and id (physical or virtual).
-//! - Offset - Displacement or absolute address to be referenced (32-bit if base
-//! register is used and 64-bit if base register is not used).
-//! - Flags that can describe various architecture dependent information (like
-//! scale and segment-override on X86).
-//! - \ref Imm - Immediate values are usually part of instructions (encoded within
-//! the instruction itself) or data.
-//! - \ref Label - used to reference a location in code or data. Labels must be
-//! created by the \ref BaseEmitter or by \ref CodeHolder. Each label has its
-//! unique id per \ref CodeHolder instance.
+//! - Offset - Displacement or absolute address to be referenced (32-bit if base register is used and 64-bit if
+//! base register is not used).
+//! - Flags that can describe various architecture dependent information (like scale and segment-override on X86).
+//! - \ref Imm - Immediate values are usually part of instructions (encoded within the instruction itself) or data.
+//! - \ref Label - used to reference a location in code or data. Labels must be created by the \ref BaseEmitter or
+//! by \ref CodeHolder. Each label has its unique id per \ref CodeHolder instance.
//!
//! ### Operand Manipulation
//!
-//! AsmJit allows to construct operands dynamically, to store them, and to query
-//! a complete information about them at run-time. Operands are small (always 16
-//! bytes per `Operand`) and should be always copied (by value) if you intend to
-//! store them (don't create operands by using `new` keyword, it's not recommended).
-//! Operands are safe to be passed to `memcpy()` and `memset()`, which becomes
-//! handy when working with arrays of operands. If you set all members of an \ref
-//! Operand to zero the operand would become NONE operand, which is the same as a
-//! default constructed Operand.
+//! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them at
+//! run-time. Operands are small (always 16 bytes per `Operand`) and should be always copied (by value) if you intend
+//! to store them (don't create operands by using `new` keyword, it's not recommended). Operands are safe to be passed
+//! to `memcpy()` and `memset()`, which becomes handy when working with arrays of operands. If you set all members of
+//! an \ref Operand to zero the operand would become NONE operand, which is the same as a default constructed Operand.
//!
-//! The example below illustrates how operands can be used and modified even
-//! without using any other code generation classes. The example uses X86
-//! architecture-specific operands.
+//! The example below illustrates how operands can be used and modified even without using any other code generation
+//! classes. The example uses X86 architecture-specific operands.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1050,7 +964,7 @@ namespace asmjit {
//! // Constructs [src + idx] memory address - referencing [rax + r10].
//! x86::Mem m = x86::ptr(src, idx);
//!
-//! // Examine `m`: Returns `x86::Reg::kTypeGpq`.
+//! // Examine `m`: Returns `RegType::kX86_Gpq`.
//! m.indexType();
//! // Examine `m`: Returns 10 (`r10`).
//! m.indexId();
@@ -1088,23 +1002,20 @@ namespace asmjit {
//! }
//! ```
//!
-//! Some operands have to be created explicitly by emitters. For example labels
-//! must be created by \ref BaseEmitter::newLabel(), which creates a label entry
-//! and returns a \ref Label operand with the id that refers to it. Such label
-//! then can be used by emitters.
+//! Some operands have to be created explicitly by emitters. For example labels must be created by \ref
+//! BaseEmitter::newLabel(), which creates a label entry and returns a \ref Label operand with the id that refers
+//! to it. Such label then can be used by emitters.
//!
//! ### Memory Operands
//!
-//! Some architectures like X86 provide a complex memory addressing model that
-//! allows to encode addresses having a BASE register, INDEX register with a
-//! possible scale (left shift), and displacement (called offset in AsmJit).
-//! Memory address on X86 can also specify memory segment (segment-override in
-//! X86 terminology) and some instructions (gather / scatter) require INDEX to
-//! be a \ref x86::Vec register instead of a general-purpose register.
+//! Some architectures like X86 provide a complex memory addressing model that allows to encode addresses having a
+//! BASE register, INDEX register with a possible scale (left shift), and displacement (called offset in AsmJit).
+//! Memory address on X86 can also specify memory segment (segment-override in X86 terminology) and some instructions
+//! (gather / scatter) require INDEX to be a \ref x86::Vec register instead of a general-purpose register.
//!
-//! AsmJit allows to encode and work with all forms of addresses mentioned and
-//! implemented by X86. In addition, it also allows to construct absolute 64-bit
-//! memory address operands, which is only allowed in one form of 'mov' instruction.
+//! AsmJit allows to encode and work with all forms of addresses mentioned and implemented by X86. In addition, it
+//! also allows to construct absolute 64-bit memory address operands, which is only allowed in one form of 'mov'
+//! instruction.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1147,9 +1058,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! Memory operands can optionally contain memory size. This is required by
-//! instructions where the memory size cannot be deduced from other operands,
-//! like `inc` and `dec` on X86:
+//! Memory operands can optionally contain memory size. This is required by instructions where the memory size cannot
+//! be deduced from other operands, like `inc` and `dec` on X86:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -1233,34 +1143,26 @@ namespace asmjit {
//!
//! - \ref x86::Assembler provides many X86/X64 examples.
-// ============================================================================
-// [Documentation - asmjit_builder]
-// ============================================================================
//! \defgroup asmjit_builder Builder
//! \brief Builder interface, nodes, and passes.
//!
//! ### Overview
//!
-//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters
-//! that emit into a representation that allows further processing. The code
-//! stored in such representation is completely safe to be patched, simplified,
-//! reordered, obfuscated, removed, injected, analyzed, or processed some other
-//! way. Each instruction, label, directive, or other building block is stored
-//! as \ref BaseNode (or derived class like \ref InstNode or \ref LabelNode)
-//! and contains all the information necessary to pass that node later to the
-//! assembler.
-//!
-//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface.
-//! It was designed to provide a maximum compatibility with the existing \ref
-//! BaseAssembler emitter so users can move from assembler to builder when needed,
+//! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters that emit into a representation that
+//! allows further processing. The code stored in such representation is completely safe to be patched, simplified,
+//! reordered, obfuscated, removed, injected, analyzed, or processed some other way. Each instruction, label,
+//! directive, or other building block is stored as \ref BaseNode (or derived class like \ref InstNode or \ref
+//! LabelNode) and contains all the information necessary to pass that node later to the assembler.
+//!
+//! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface. It was designed to provide a maximum
+//! compatibility with the existing \ref BaseAssembler emitter so users can move from assembler to builder when needed,
//! for example to implement post-processing, which is not possible with Assembler.
//!
//! ### Builder Nodes
//!
-//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate
-//! representation based on nodes, however, it allows to serialize to \ref BaseAssembler
-//! when the code is ready to be encoded.
+//! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate representation based on nodes,
+//! however, it allows to serialize to \ref BaseAssembler when the code is ready to be encoded.
//!
//! There are multiple node types used by both \ref BaseBuilder and \ref BaseCompiler :
//!
@@ -1273,16 +1175,13 @@ namespace asmjit {
//! - Data nodes:
//! - \ref EmbedDataNode - Represents data.
//! - \ref EmbedLabelNode - Represents \ref Label address embedded as data.
-//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels
-//! embedded in data.
+//! - \ref EmbedLabelDeltaNode - Represents a difference of two labels embedded in data.
//! - \ref ConstPoolNode - Represents a constant pool data embedded as data.
//!
//! - Informative nodes:
-//! - \ref CommentNode - Represents a comment string, doesn't affect code
-//! generation.
-//! - \ref SentinelNode - A marker that can be used to remember certain
-//! position in code or data, doesn't affect code generation. Used by
-//! \ref FuncNode to mark the end of a function.
+//! - \ref CommentNode - Represents a comment string, doesn't affect code generation.
+//! - \ref SentinelNode - A marker that can be used to remember certain position in code or data, doesn't affect
+//! code generation. Used by \ref FuncNode to mark the end of a function.
//!
//! - Other nodes are provided by \ref asmjit_compiler infrastructure.
//!
@@ -1290,47 +1189,38 @@ namespace asmjit {
//!
//! - \ref x86::Builder provides many X86/X64 examples.
-// ============================================================================
-// [Documentation - asmjit_compiler]
-// ============================================================================
//! \defgroup asmjit_compiler Compiler
//! \brief Compiler interface.
//!
//! ### Overview
//!
-//! \ref BaseCompiler is a high-level interface built on top of \ref BaseBuilder
-//! interface, which provides register allocation and support for defining and
-//! invoking functions. At the moment it's the easiest way of generating code
-//! in AsmJit as most architecture and OS specifics is properly abstracted and
-//! handled by AsmJit automatically. However, abstractions also mean restrictions,
-//! which means that \ref BaseCompiler has more limitations than \ref BaseAssembler
-//! or \ref BaseBuilder.
-//!
-//! Since \ref BaseCompiler provides register allocation it also establishes the
-//! concept of functions - a function in Compiler sense is a unit in which virtual
-//! registers are allocated into physical registers by the register allocator.
-//! In addition, it enables to use such virtual registers in function invocations.
-//!
-//! \ref BaseCompiler automatically handles function calling conventions. It's
-//! still architecture dependent, but makes the code generation much easies.
-//! Functions are essential; the first-step to generate some code is to define a
-//! signature of the function to be generated (before generating the function body
-//! itself). Function arguments and return value(s) are handled by assigning
-//! virtual registers to them. Similarly, function calls are handled the same way.
+//! \ref BaseCompiler is a high-level interface, which provides register allocation and support for defining and
+//! invoking functions, built on top of \ref BaseBuilder interface At the moment it's the easiest way of generating
+//! code in AsmJit as most architecture and OS specifics is properly abstracted and handled by AsmJit automatically.
+//! However, abstractions also mean restrictions, which means that \ref BaseCompiler has more limitations than \ref
+//! BaseAssembler or \ref BaseBuilder.
+//!
+//! Since \ref BaseCompiler provides register allocation it also establishes the concept of functions - a function
+//! in Compiler sense is a unit in which virtual registers are allocated into physical registers by the register
+//! allocator. In addition, it enables to use such virtual registers in function invocations.
+//!
+//! \ref BaseCompiler automatically handles function calling conventions. It's still architecture dependent, but
+//! makes the code generation much easies. Functions are essential; the first-step to generate some code is to define
+//! a signature of the function to be generated (before generating the function body itself). Function arguments and
+//! return value(s) are handled by assigning virtual registers to them. Similarly, function calls are handled the same
+//! way.
//!
//! ### Compiler Nodes
//!
-//! \ref BaseCompiler adds some nodes that are required for function generation
-//! and invocation:
+//! \ref BaseCompiler adds some nodes that are required for function generation and invocation:
//!
//! - \ref FuncNode - Represents a function definition.
//! - \ref FuncRetNode - Represents a function return.
//! - \ref InvokeNode - Represents a function invocation.
//!
-//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically
-//! adds an architecture-dependent register allocator pass to the list of passes
-//! when attached to \ref CodeHolder.
+//! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically adds an architecture-dependent
+//! register allocator pass to the list of passes when attached to \ref CodeHolder.
//!
//! ### Compiler Examples
//!
@@ -1338,134 +1228,110 @@ namespace asmjit {
//!
//! ### Compiler Tips
//!
-//! Users of AsmJit have done mistakes in the past, this section should provide
-//! some useful tips for beginners:
+//! Users of AsmJit have done mistakes in the past, this section should provide some useful tips for beginners:
//!
-//! - Virtual registers in compiler are bound to a single function. At the
-//! moment the implementation doesn't care whether a single virtual register
-//! is used in multiple functions, but it sees it as two independent virtual
-//! registers in that case. This means that virtual registers cannot be used
-//! to implement global variables. Global variables are basically memory
-//! addresses which functions can read from and write to, and they have to
-//! be implemented in the same way.
+//! - Virtual registers in compiler are bound to a single function. At the moment the implementation doesn't
+//! care whether a single virtual register is used in multiple functions, but it sees it as two independent
+//! virtual registers in that case. This means that virtual registers cannot be used to implement global
+//! variables. Global variables are basically memory addresses which functions can read from and write to,
+//! and they have to be implemented in the same way.
//!
-//! - Compiler provides a useful debugging functionality, which can be turned
-//! on through \ref FormatOptions::Flags. Use \ref Logger::addFlags() to
-//! turn on additional logging features when using Compiler.
+//! - Compiler provides a useful debugging functionality, which can be turned on through \ref FormatFlags. Use
+//! \ref Logger::addFlags() to turn on additional logging features when using Compiler.
-// ============================================================================
-// [Documentation - asmjit_function]
-// ============================================================================
//! \defgroup asmjit_function Function
//! \brief Function definitions.
//!
//! ### Overview
//!
-//! AsmJit provides functionality that can be used to define function signatures
-//! and to calculate automatically optimal function frame that can be used directly
-//! by a prolog and epilog insertion. This feature was exclusive to AsmJit's Compiler
-//! for a very long time, but was abstracted out and is now available for all users
-//! regardless of the emitter they use. The following use cases are possible:
+//! AsmJit provides functionality that can be used to define function signatures and to calculate automatically
+//! optimal function frame that can be used directly by a prolog and epilog insertion. This feature was exclusive
+//! to AsmJit's Compiler for a very long time, but was abstracted out and is now available for all users regardless
+//! of the emitter they use. The following use cases are possible:
//!
-//! - Calculate function frame before the function is generated - this is the
-//! only way available to \ref BaseAssembler users and it will be described
-//! in this section.
+//! - Calculate function frame before the function is generated - this is the only way available to \ref
+//! BaseAssembler users and it will be described in this section.
//!
-//! - Calculate function frame after the function is generated - this way is
-//! generally used by \ref BaseBuilder and \ref BaseCompiler emitters and
-//! this way is generally described in \ref asmjit_compiler section.
+//! - Calculate function frame after the function is generated - this way is generally used by \ref BaseBuilder
+//! and \ref BaseCompiler emitters and this way is generally described in \ref asmjit_compiler section.
//!
//! The following concepts are used to describe and create functions in AsmJit:
//!
-//! - \ref Type::Id - Type-id is an 8-bit value that describes a platform
-//! independent type as we know from C/C++. It provides abstractions for
-//! most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`,
-//! `double`, and all possible vector types to match ISAs up to AVX512.
-//! \ref Type::Id was introduced originally for \ref asmjit_compiler, but
-//! it's now used by \ref FuncSignature as well.
-//!
-//! - \ref CallConv - Describes a calling convention - this class contains
-//! instructions to assign registers and stack addresses to function
-//! arguments and return value(s), but doesn't specify any function
-//! signature itself. Calling conventions are architecture and OS dependent.
-//!
-//! - \ref FuncSignature - Describes a function signature, for example
-//! `int func(int, int)`. FuncSignature contains a function calling convention
-//! id, return value type, and function arguments. The signature itself is
-//! platform independent and uses \ref Type::Id to describe types of function
-//! arguments and function return value(s).
-//!
-//! - \ref FuncDetail - Architecture and ABI dependent information that describes
-//! \ref CallConv and expanded \ref FuncSignature. Each function argument and
-//! return value is represented as \ref FuncValue that contains the original
-//! \ref Type::Id enriched with additional information that specifies whether
-//! the value is passed or returned by register (and which register) or by
-//! stack. Each value also contains some other metadata that provide additional
-//! information required to handle it properly (for example whether a vector is
-//! passed indirectly by a pointer as required by WIN64 calling convention).
-//!
-//! - \ref FuncFrame - Contains information about the function frame that can
-//! be used by prolog/epilog inserter (PEI). Holds call stack size size and
-//! alignment, local stack size and alignment, and various attributes that
-//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't
-//! know anything about function's arguments or return values, it hold only
-//! information necessary to create a valid and ABI conforming function prologs
-//! and epilogs.
-//!
-//! - \ref FuncArgsAssignment - A helper class that can be used to reassign
-//! function arguments into user specified registers. It's architecture and
-//! ABI dependent mapping from function arguments described by \ref CallConv
+//! - \ref TypeId - Type-id is an 8-bit value that describes a platform independent type as we know from C/C++.
+//! It provides abstractions for most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`, `double`,
+//! and all possible vector types to match ISAs up to AVX512. \ref TypeId was introduced originally for \ref
+//! asmjit_compiler, but it's now used by \ref FuncSignature as well.
+//!
+//! - \ref CallConv - Describes a calling convention - this class contains instructions to assign registers and
+//! stack addresses to function arguments and return value(s), but doesn't specify any function signature itself.
+//! Calling conventions are architecture and OS dependent.
+//!
+//! - \ref FuncSignature - Describes a function signature, for example `int func(int, int)`. FuncSignature contains
+//! a function calling convention id, return value type, and function arguments. The signature itself is platform
+//! independent and uses \ref TypeId to describe types of function arguments and function return value(s).
+//!
+//! - \ref FuncDetail - Architecture and ABI dependent information that describes \ref CallConv and expanded \ref
+//! FuncSignature. Each function argument and return value is represented as \ref FuncValue that contains the
+//! original \ref TypeId enriched with additional information that specifies whether the value is passed or
+//! returned by register (and which register) or by stack. Each value also contains some other metadata that
+//! provide additional information required to handle it properly (for example whether a vector is passed
+//! indirectly by a pointer as required by WIN64 calling convention).
+//!
+//! - \ref FuncFrame - Contains information about the function frame that can be used by prolog/epilog inserter
+//! (PEI). Holds call stack size size and alignment, local stack size and alignment, and various attributes that
+//! describe how prolog and epilog should be constructed. `FuncFrame` doesn't know anything about function's
+//! arguments or return values, it hold only information necessary to create a valid and ABI conforming function
+//! prologs and epilogs.
+//!
+//! - \ref FuncArgsAssignment - A helper class that can be used to reassign function arguments into user specified
+//! registers. It's architecture and ABI dependent mapping from function arguments described by \ref CallConv
//! and \ref FuncDetail into registers specified by the user.
//!
-//! It's a lot of concepts where each represents one step in a function frame
-//! calculation. It can be used to create function prologs, epilogs, and also
-//! to calculate information necessary to perform function calls.
+//! It's a lot of concepts where each represents one step in a function frame calculation. It can be used to create
+//! function prologs, epilogs, and also to calculate information necessary to perform function calls.
-// ============================================================================
-// [Documentation - asmjit_logging]
-// ============================================================================
//! \defgroup asmjit_logging Logging
//! \brief Logging and formatting.
//!
//! ### Overview
//!
-//! The initial phase of a project that generates machine code is not always smooth.
-//! Failure cases are common not just at the beginning phase, but also during the
-//! development or refactoring. AsmJit provides logging functionality to address
-//! this issue. AsmJit does already a good job with function overloading to prevent
-//! from emitting unencodable instructions, but it can't prevent from emitting machine
-//! code that is correct at instruction level, but doesn't work when it's executed as
-//! a whole. Logging has always been an important part of AsmJit's infrastructure and
-//! looking at logs can sometimes reveal code generation issues quickly.
+//! The initial phase of a project that generates machine code is not always smooth. Failure cases are common not just
+//! at the beginning phase, but also during the development or refactoring. AsmJit provides logging functionality to
+//! address this issue. AsmJit does already a good job with function overloading to prevent from emitting unencodable
+//! instructions, but it can't prevent from emitting machine code that is correct at instruction level, but doesn't
+//! work when it's executed asa whole. Logging has always been an important part of AsmJit's infrastructure and looking
+//! at logs can sometimes reveal code generation issues quickly.
//!
//! AsmJit provides API for logging and formatting:
-//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters
-//! that inherit from \ref BaseEmitter.
-//! - \ref FormatOptions - Formatting options that can change how instructions and
-//! operands are formatted.
-//! - \ref Formatter - A namespace that provides functions that can format input
-//! data like \ref Operand, \ref BaseReg, \ref Label, and \ref BaseNode into
-//! \ref String.
+//!
+//! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters that inherit from \ref BaseEmitter.
+//!
+//! - \ref FormatOptions - Formatting options that can change how instructions and operands are formatted.
+//!
+//! - \ref Formatter - A namespace that provides functions that can format input data like \ref Operand, \ref BaseReg,
+//! \ref Label, and \ref BaseNode into \ref String.
//!
//! AsmJit's \ref Logger serves the following purposes:
+//!
//! - Provides a basic foundation for logging.
-//! - Abstract class leaving the implementation on users. The following built-in
-//! implementations are provided for simplicity:
+//!
+//! - Abstract class leaving the implementation on users. The following built-in implementations are provided for
+//! simplicity:
+//!
//! - \ref FileLogger implements logging into a standard `FILE` stream.
//! - \ref StringLogger serializes all logs into a \ref String instance.
//!
-//! AsmJit's \ref FormatOptions provides the following to customize the formatting of
-//! instructions and operands through:
-//! - \ref FormatOptions::Flags
-//! - \ref FormatOptions::IndentationType
+//! AsmJit's \ref FormatOptions provides the following to customize the formatting of instructions and operands through:
+//!
+//! - \ref FormatFlags
+//! - \ref FormatIndentationGroup
//!
//! ### Logging
//!
-//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it
-//! to all attached emitters automatically. The example below illustrates how to
-//! use \ref FileLogger that outputs to standard output:
+//! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it to all attached emitters
+//! automatically. The example below illustrates how to use \ref FileLogger that outputs to standard output:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1486,8 +1352,8 @@ namespace asmjit {
//! }
//! ```
//!
-//! If output to FILE stream is not desired it's possible to use \ref StringLogger,
-//! which concatenates everything into a multi-line string:
+//! If output to FILE stream is not desired it's possible to use \ref StringLogger, which concatenates everything
+//! into a multi-line string:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1520,11 +1386,10 @@ namespace asmjit {
//!
//! ### Formatting
//!
-//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref
-//! Logger. Formatting is public and can be used by AsmJit users as well. The
-//! most important thing to know regarding formatting is that \ref Formatter
-//! always appends to the output string, so it can be used to build complex
-//! strings without having to concatenate intermediate strings.
+//! AsmJit uses \ref Formatter to format inputs that are then passed to \ref Logger. Formatting is public and can be
+//! used by AsmJit users as well. The most important thing to know regarding formatting is that \ref Formatter always
+//! appends to the output string, so it can be used to build complex strings without having to concatenate
+//! intermediate strings.
//!
//! The first example illustrates how to format operands:
//!
@@ -1534,12 +1399,12 @@ namespace asmjit {
//!
//! using namespace asmjit;
//!
-//! void logOperand(uint32_t arch, const Operand_& op) {
+//! void logOperand(Arch arch, const Operand_& op) {
//! // The emitter is optional (named labels and virtual registers need it).
//! BaseEmitter* emitter = nullptr;
//!
//! // No flags by default.
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! StringTmp<128> sb;
//! Formatter::formatOperand(sb, formatFlags, emitter, arch, op);
@@ -1552,7 +1417,7 @@ namespace asmjit {
//! // Architecture is not part of operand, it must be passed explicitly.
//! // Format flags. We pass it explicitly also to 'logOperand' to make
//! // compatible with what AsmJit normally does.
-//! uint32_t arch = Environment::kArchX64;
+//! Arch arch = Arch::kX64;
//!
//! log(arch, rax); // Prints 'rax'.
//! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
@@ -1571,12 +1436,12 @@ namespace asmjit {
//! using namespace asmjit;
//!
//! template<typename... Args>
-//! void logInstruction(uint32_t arch, const BaseInst& inst, Args&&... args) {
+//! void logInstruction(Arch arch, const BaseInst& inst, Args&&... args) {
//! // The emitter is optional (named labels and virtual registers need it).
//! BaseEmitter* emitter = nullptr;
//!
//! // No flags by default.
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! // The formatter expects operands in an array.
//! Operand_ operands { std::forward<Args>(args)... };
@@ -1593,7 +1458,7 @@ namespace asmjit {
//! // Architecture is not part of operand, it must be passed explicitly.
//! // Format flags. We pass it explicitly also to 'logOperand' to make
//! // compatible with what AsmJit normally does.
-//! uint32_t arch = Environment::kArchX64;
+//! Arch arch = Arch::kX64;
//!
//! // Prints 'mov rax, rcx'.
//! logInstruction(arch, BaseInst(Inst::kIdMov), rax, rcx);
@@ -1606,19 +1471,19 @@ namespace asmjit {
//! // BaseInst abstracts instruction id, instruction options, and extraReg.
//! // Prints 'lock add [rax], rcx'.
//! logInstruction(arch,
-//! BaseInst(Inst::kIdAdd, Inst::kOptionLock),
+//! BaseInst(Inst::kIdAdd, InstOptions::kX86_Lock),
//! x86::ptr(rax), rcx);
//!
//! // Similarly an extra register (like AVX-512 selector) can be used.
//! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'.
//! logInstruction(arch,
-//! BaseInst(Inst::kIdAdd, Inst::kOptionZMask, k2),
+//! BaseInst(Inst::kIdAdd, InstOptions::kX86_ZMask, k2),
//! zmm0, zmm1, ptr(rax));
//! }
//! ```
//!
-//! And finally, the example below illustrates how to use a built-in function
-//! to format the content of \ref BaseBuilder, which consists of nodes:
+//! And finally, the example below illustrates how to use a built-in function to format the content of
+//! \ref BaseBuilder, which consists of nodes:
//!
//! ```
//! #include <asmjit/core.h>
@@ -1627,7 +1492,7 @@ namespace asmjit {
//! using namespace asmjit;
//!
//! void formattingExample(BaseBuilder* builder) {
-//! uint32_t formatFlags = FormatOptions::kNoFlags;
+//! FormatFlags formatFlags = FormatFlags::kNone;
//!
//! // This also shows how temporary strings can be used.
//! StringTmp<512> sb;
@@ -1644,40 +1509,30 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_error_handling]
-// ============================================================================
//! \defgroup asmjit_error_handling Error Handling
//! \brief Error handling.
//!
//! ### Overview
//!
-//! AsmJit uses error codes to represent and return errors. Every function that
-//! can fail returns an \ref Error code. Exceptions are never thrown by AsmJit
-//! itself even in extreme conditions like out-of-memory, but it's possible to
-//! override \ref ErrorHandler::handleError() to throw, in that case no error
-//! will be returned and exception will be thrown instead. All functions where
-//! this can happen are not marked `noexcept`.
+//! AsmJit uses error codes to represent and return errors. Every function that can fail returns an \ref Error code.
+//! Exceptions are never thrown by AsmJit itself even in extreme conditions like out-of-memory, but it's possible to
+//! override \ref ErrorHandler::handleError() to throw, in that case no error will be returned and exception will be
+//! thrown instead. All functions where this can happen are not marked `noexcept`.
//!
-//! Errors should never be ignored, however, checking errors after each AsmJit
-//! API call would simply overcomplicate the whole code generation experience.
-//! \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
+//! Errors should never be ignored, however, checking errors after each AsmJit API call would simply overcomplicate
+//! the whole code generation experience. \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
//! to customize how errors can be handled:
//!
//! - Record the error and continue (the way how the error is user-implemented).
-//! - Throw an exception. AsmJit doesn't use exceptions and is completely
-//! exception-safe, but it's perfectly legal to throw an exception from
-//! the error handler.
-//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler,
-//! Builder and Compiler to a consistent state before calling \ref
-//! ErrorHandler::handleError(), so `longjmp()` can be used without issues to
-//! cancel the code-generation if an error occurred. This method can be used if
-//! exception handling in your project is turned off and you still want some
-//! comfort. In most cases it should be safe as AsmJit uses \ref Zone memory
-//! and the ownership of memory it allocates always ends with the instance that
-//! allocated it. If using this approach please never jump outside the life-time
-//! of \ref CodeHolder and \ref BaseEmitter.
+//! - Throw an exception. AsmJit doesn't use exceptions and is completely exception-safe, but it's perfectly legal
+//! to throw an exception from the error handler.
+//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, Builder and Compiler to a
+//! consistent state before calling \ref ErrorHandler::handleError(), so `longjmp()` can be used without issues
+//! to cancel the code-generation if an error occurred. This method can be used if exception handling in your
+//! project is turned off and you still want some comfort. In most cases it should be safe as AsmJit uses \ref
+//! Zone memory and the ownership of memory it allocates always ends with the instance that allocated it. If
+//! using this approach please never jump outside the life-time of \ref CodeHolder and \ref BaseEmitter.
//!
//! ### Using ErrorHandler
//!
@@ -1719,69 +1574,56 @@ namespace asmjit {
//! - See \ref Error that lists error codes that AsmJit uses.
//! - See \ref ErrorHandler for more details about error handling.
-// ============================================================================
-// [Documentation - asmjit_instruction_db]
-// ============================================================================
//! \defgroup asmjit_instruction_db Instruction DB
//! \brief Instruction database (introspection, read/write, validation, ...).
//!
//! ### Overview
//!
-//! AsmJit provides a public instruction database that can be used to query
-//! information about a complete instruction. The instruction database requires
-//! the knowledge of the following:
+//! AsmJit provides a public instruction database that can be used to query information about a complete instruction.
+//! The instruction database requires the knowledge of the following:
+//!
+//! - \ref BaseInst - Base instruction that contains instruction id, options, and a possible extra-register that
+//! represents either REP prefix counter or AVX-512 selector (mask).
//!
-//! - \ref BaseInst - Base instruction that contains instruction id, options,
-//! and a possible extra-register that represents either REP prefix counter
-//! or AVX-512 selector (mask).
//! - \ref Operand - Represents operands of an instruction.
//!
//! Each instruction can be then queried for the following information:
//!
-//! - \ref InstRWInfo - Read/write information of instruction and its oprands.
-//! - \ref OpRWInfo - Read/write information of a single operand, part of
-//! \ref InstRWInfo data structure.
-//! - \ref BaseFeatures - CPU features required to execute the instruction.
+//! - \ref InstRWInfo - Read/write information of instruction and its oprands (includes \ref OpRWInfo).
+//!
+//! - \ref CpuFeatures - CPU features required to execute the instruction.
//!
-//! In addition to query functionality AsmJit is also able to validate whether
-//! an instruction and its operands are valid. This is useful for making sure
-//! that what user tries to emit is correct and it can be also used by other
+//! In addition to query functionality AsmJit is also able to validate whether an instruction and its operands are
+//! valid. This is useful for making sure that what user tries to emit is correct and it can be also used by other
//! projects that parse user input, like AsmTK project.
//!
//! ### Query API
//!
-//! The instruction query API is provided by \ref InstAPI namespace. The
-//! following queries are possible:
+//! The instruction query API is provided by \ref InstAPI namespace. The following queries are possible:
//!
-//! - \ref InstAPI::queryRWInfo() - queries read/write information of the
-//! given instruction and its operands. Includes also CPU flags read/written.
+//! - \ref InstAPI::queryRWInfo() - queries read/write information of the given instruction and its operands.
+//! Includes also CPU flags read/written.
//!
-//! - \ref InstAPI::queryFeatures() - queries CPU features that are required
-//! to execute the given instruction. A full instruction with operands must
-//! be given as some architectures like X86 may require different features
-//! for the same instruction based on its operands.
+//! - \ref InstAPI::queryFeatures() - queries CPU features that are required to execute the given instruction. A full
+//! instruction with operands must be given as some architectures like X86 may require different features for the
+//! same instruction based on its operands.
//!
-//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_instinfo.cpp">asmjit_test_x86_instinfo.cpp</a>
+//! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_instinfo.cpp">asmjit_test_instinfo.cpp</a>
//! can be also used as a reference about accessing instruction information.
//!
//! ### Validation API
//!
-//! The instruction validation API is provided by \ref InstAPI namespace in the
-//! similar fashion like the Query API, however, validation can also be turned
-//! on at \ref BaseEmitter level. The following is possible:
+//! The instruction validation API is provided by \ref InstAPI namespace in the similar fashion like the Query API,
+//! however, validation can also be turned on at \ref BaseEmitter level. The following is possible:
//!
-//! - \ref InstAPI::validate() - low-level instruction validation function
-//! that is used internally by emitters if strict validation is enabled.
+//! - \ref InstAPI::validate() - low-level instruction validation function that is used internally by emitters
+//! if strict validation is enabled.
//!
-//! - \ref BaseEmitter::addValidationOptions() - can be used to enable
-//! validation at emitter level, see \ref BaseEmitter::ValidationOptions.
+//! - \ref BaseEmitter::addDiagnosticOptions() - can be used to enable validation at emitter level, see \ref
+//! DiagnosticOptions.
-// ============================================================================
-// [Documentation - asmjit_virtual_memory]
-// ============================================================================
-
//! \defgroup asmjit_virtual_memory Virtual Memory
//! \brief Virtual memory management.
//!
@@ -1789,53 +1631,42 @@ namespace asmjit {
//!
//! AsmJit's virtual memory management is divided into two main categories:
//!
-//! - Low level API that provides cross-platform abstractions for virtual
-//! memory allocation. Implemented in \ref VirtMem namespace.
-//! - High level API that makes it very easy to store generated code for
-//! execution. See \ref JitRuntime, which is used by many examples for its
-//! simplicity and easy integration with \ref CodeHolder. There is also
-//! \ref JitAllocator, which lays somewhere between RAW memory allocation
-//! and \ref JitRuntime.
+//! - Low level API that provides cross-platform abstractions for virtual memory allocation. Implemented in
+//! \ref VirtMem namespace.
+//!
+//! - High level API that makes it very easy to store generated code for execution. See \ref JitRuntime, which is
+//! used by many examples for its simplicity and easy integration with \ref CodeHolder. There is also \ref
+//! JitAllocator, which lays somewhere between RAW memory allocation and \ref JitRuntime.
-// ============================================================================
-// [Documentation - asmjit_zone_memory]
-// ============================================================================
//! \defgroup asmjit_zone Zone Memory
//! \brief Zone memory allocator and containers.
//!
//! ### Overview
//!
-//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate
-//! most of the data it uses. It's a fast allocator that allows AsmJit to allocate
-//! a lot of small data structures fast and without `malloc()` overhead. Since
-//! code generators and all related classes are usually short-lived this approach
-//! decreases memory usage and fragmentation as arena-based allocators always
-//! allocate larger blocks of memory, which are then split into smaller chunks.
-//!
-//! Another advantage of zone memory allocation is that since the whole library
-//! uses this strategy it's very easy to deallocate everything that a particular
-//! instance is holding by simply releasing the memory the allocator holds. This
-//! improves destruction time of such objects as there is no destruction at all.
-//! Long-lived objects just reset its data in destructor or in their reset()
-//! member function for a future reuse. For this purpose all containers in AsmJit
-//! are also zone allocated.
+//! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate most of the data it uses. It's a
+//! fast allocator that allows AsmJit to allocate a lot of small data structures fast and without `malloc()` overhead.
+//! Since code generators and all related classes are usually short-lived this approach decreases memory usage and
+//! fragmentation as arena-based allocators always allocate larger blocks of memory, which are then split into smaller
+//! chunks.
+//!
+//! Another advantage of zone memory allocation is that since the whole library uses this strategy it's very easy to
+//! deallocate everything that a particular instance is holding by simply releasing the memory the allocator holds.
+//! This improves destruction time of such objects as there is no destruction at all. Long-lived objects just reset
+//! its data in destructor or in their reset() member function for a future reuse. For this purpose all containers in
+//! AsmJit are also zone allocated.
//!
//! ### Zone Allocation
//!
-//! - \ref Zone - Incremental zone memory allocator with minimum features. It
-//! can only allocate memory without the possibility to return it back to
-//! the allocator.
+//! - \ref Zone - Incremental zone memory allocator with minimum features. It can only allocate memory without the
+//! possibility to return it back to the allocator.
//!
-//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage.
-//! If the allocation requests fit the static storage allocated then there
-//! will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
-//! otherwise it would act as \ref Zone with one preallocated block on the
-//! stack.
+//! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage. If the allocation requests fit the
+//! static storage allocated then there will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
+//! otherwise it would act as \ref Zone with one preallocated block on the stack.
//!
-//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability
-//! of returning memory to the allocator. Such memory is stored in a pool for
-//! later reuse.
+//! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability of returning memory to the allocator.
+//! Such memory is stored in a pool for later reuse.
//!
//! ### Zone Allocated Containers
//!
@@ -1849,11 +1680,10 @@ namespace asmjit {
//!
//! ### Using Zone Allocated Containers
//!
-//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very
-//! similar to `std::vector`, but the implementation doesn't use exceptions and
-//! uses the mentioned \ref ZoneAllocator for performance reasons. You don't have
-//! to worry about allocations as you should not need to add items to AsmJit's
-//! data structures directly as there should be API for all required operations.
+//! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very similar to `std::vector`, but the
+//! implementation doesn't use exceptions and uses the mentioned \ref ZoneAllocator for performance reasons. You don't
+//! have to worry about allocations as you should not need to add items to AsmJit's data structures directly as there
+//! should be API for all required operations.
//!
//! The following APIs in \ref CodeHolder returns \ref ZoneVector reference:
//!
@@ -1875,10 +1705,9 @@ namespace asmjit {
//! }
//! ```
//!
-//! \ref ZoneVector has overloaded array access operator to make it possible
-//! to access its elements through operator[]. Some standard functions like
-//! \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data()
-//! are provided as well. Vectors are also iterable through a range-based for loop:
+//! \ref ZoneVector has overloaded array access operator to make it possible to access its elements through operator[].
+//! Some standard functions like \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data() are
+//! provided as well. Vectors are also iterable through a range-based for loop:
//!
//! ```
//! using namespace asmjit;
@@ -1895,15 +1724,13 @@ namespace asmjit {
//!
//! ### Design Considerations
//!
-//! Zone-allocated containers do not store the allocator within the container.
-//! This decision was made to reduce the footprint of such containers as AsmJit
-//! tooling, especially Compiler's register allocation, may use many instances
+//! Zone-allocated containers do not store the allocator within the container. This decision was made to reduce the
+//! footprint of such containers as AsmJit tooling, especially Compiler's register allocation, may use many instances
//! of such containers to perform code analysis and register allocation.
//!
-//! For example to append an item into a \ref ZoneVector it's required to pass
-//! the allocator as the first argument, so it can be used in case that the
-//! vector needs a reallocation. Such function also returns an error, which
-//! must be propagated to the caller.
+//! For example to append an item into a \ref ZoneVector it's required to pass the allocator as the first argument,
+//! so it can be used in case that the vector needs a reallocation. Such function also returns an error, which must
+//! be propagated to the caller.
//!
//! ```
//! using namespace asmjit
@@ -1927,10 +1754,9 @@ namespace asmjit {
//! }
//! ```
//!
-//! Containers like \ref ZoneVector also provide a functionality to reserve a
-//! certain number of items before any items are added to it. This approach is
-//! used internally in most places as it allows to prepare space for data that
-//! will be added to some container before the data itself was created.
+//! Containers like \ref ZoneVector also provide a functionality to reserve a certain number of items before any items
+//! are added to it. This approach is used internally in most places as it allows to prepare space for data that will
+//! be added to some container before the data itself was created.
//!
//! ```
//! using namespace asmjit
@@ -1948,60 +1774,44 @@ namespace asmjit {
//! }
//! ```
-// ============================================================================
-// [Documentation - asmjit_utilities]
-// ============================================================================
//! \defgroup asmjit_utilities Utilities
//! \brief Utility classes and functions.
//!
//! ### Overview
//!
-//! AsmJit uses and provides utility classes and functions, that can be used
-//! with AsmJit. The functionality can be divided into the following topics:
+//! AsmJit uses and provides utility classes and functions, that can be used with AsmJit. The functionality can be
+//! divided into the following topics:
//!
//! ### String Functionality
//!
-//! - \ref String - AsmJit's string container, which is used internally
-//! and which doesn't use exceptions and has a stable layout, which is
-//! not dependent on C++ standard library.
-//! - \ref StringTmp - String that can have base storage allocated on
-//! stack. The amount of storage on stack can be specified as a template
-//! parameter.
+//! - \ref String - AsmJit's string container, which is used internally and which doesn't use exceptions and has
+//! a stable layout, which is not dependent on C++ standard library.
+//!
+//! - \ref StringTmp - String that can have base storage allocated on stack. The amount of storage on stack can
+//! be specified as a template parameter.
+//!
//! - \ref FixedString - Fixed string container limited up to N characters.
//!
//! ### Code Generation Utilities
//!
-//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also
-//! available to users that may find use of it.
+//! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also available to users that may find use of it.
//!
//! ### Support Functionality Used by AsmJit
//!
-//! - \ref Support namespace provides many other utility functions and
-//! classes that are used by AsmJit, and made public.
+//! - \ref Support namespace provides many other utility functions and classes that are used by AsmJit, and made
+//! public.
-// ============================================================================
-// [Documentation - asmjit_<arch> backends]
-// ============================================================================
//! \defgroup asmjit_x86 X86 Backend
//! \brief X86/X64 backend.
-// ============================================================================
-// [Documentation - asmjit_ra]
-// ============================================================================
//! \cond INTERNAL
//! \defgroup asmjit_ra RA
//! \brief Register allocator internals.
//! \endcond
-} // {asmjit}
-
-// ============================================================================
-// [Core Headers]
-// ============================================================================
-
#include "asmjit-scope-begin.h"
#include "core/archtraits.h"
#include "core/assembler.h"
@@ -2010,11 +1820,9 @@ namespace asmjit {
#include "core/compiler.h"
#include "core/constpool.h"
#include "core/cpuinfo.h"
-#include "core/datatypes.h"
#include "core/emitter.h"
#include "core/environment.h"
#include "core/errorhandler.h"
-#include "core/features.h"
#include "core/formatter.h"
#include "core/func.h"
#include "core/globals.h"
@@ -2038,23 +1846,4 @@ namespace asmjit {
#include "core/zonevector.h"
#include "asmjit-scope-end.h"
-// ============================================================================
-// [Deprecated]
-// ============================================================================
-
-#ifndef ASMJIT_NO_DEPRECATED
-namespace asmjit {
-
-#ifndef ASMJIT_NO_COMPILER
-ASMJIT_DEPRECATED("Use InvokeNode instead of FuncCallNode")
-typedef InvokeNode FuncCallNode;
-#endif // !ASMJIT_NO_COMPILER
-
-#ifndef ASMJIT_NO_LOGGING
-namespace Logging { using namespace Formatter; }
-#endif //! ASMJIT_NO_LOGGING
-
-} // {asmjit}
-#endif // !ASMJIT_NO_DEPRECATED
-
#endif // ASMJIT_CORE_H_INCLUDED
diff --git a/src/asmjit/core/api-build_p.h b/src/asmjit/core/api-build_p.h
index db37ca7..6eca971 100644
--- a/src/asmjit/core/api-build_p.h
+++ b/src/asmjit/core/api-build_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_API_BUILD_P_H_INCLUDED
#define ASMJIT_CORE_API_BUILD_P_H_INCLUDED
@@ -47,10 +29,6 @@
#include <windows.h>
#endif
-// ============================================================================
-// [asmjit::Build - Globals - Build-Only]
-// ============================================================================
-
#include "./api-config.h"
#if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) && !defined(__clang__)
diff --git a/src/asmjit/core/api-config.h b/src/asmjit/core/api-config.h
index c3f1080..7407c57 100644
--- a/src/asmjit/core/api-config.h
+++ b/src/asmjit/core/api-config.h
@@ -1,48 +1,59 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_API_CONFIG_H_INCLUDED
#define ASMJIT_CORE_API_CONFIG_H_INCLUDED
-// ============================================================================
-// [asmjit::Version]
-// ============================================================================
+// AsmJit Library & ABI Version
+// ============================
//! \addtogroup asmjit_core
//! \{
//! AsmJit library version in `(Major << 16) | (Minor << 8) | (Patch)` format.
-#define ASMJIT_LIBRARY_VERSION 0x010400 /* 1.4.0 */
+#define ASMJIT_LIBRARY_VERSION 0x010800 /* 1.8.0 */
+
+//! \def ASMJIT_ABI_NAMESPACE
+//!
+//! AsmJit ABI namespace is an inline namespace within \ref asmjit namespace.
+//!
+//! It's used to make sure that when user links to an incompatible version of AsmJit, it won't link. It has also some
+//! additional properties as well. When `ASMJIT_ABI_NAMESPACE` is defined by the user it would override the AsmJit
+//! default, which makes it possible to use use multiple AsmJit libraries within a single project, totally controlled
+//! by the users. This is useful especially in cases in which some of such library comes from a third party.
+#ifndef ASMJIT_ABI_NAMESPACE
+ #define ASMJIT_ABI_NAMESPACE _abi_1_8
+#endif
//! \}
-// ============================================================================
-// [asmjit::Build - Documentation]
-// ============================================================================
+// Global Dependencies
+// ===================
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h> // We really want std types as globals, not under 'std' namespace.
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <iterator>
+#include <limits>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
+ #include <pthread.h>
+#endif
+
+// Build Options
+// =============
-// NOTE: Doxygen cannot document macros that are not defined, that's why we have
-// to define them and then undefine them, so it won't use the macros with its
-// own preprocessor.
+// NOTE: Doxygen cannot document macros that are not defined, that's why we have to define them and then undefine
+// them immediately, so it won't use the macros with its own preprocessor.
#ifdef _DOXYGEN
namespace asmjit {
@@ -80,10 +91,10 @@ namespace asmjit {
//! Disables \ref asmjit_compiler functionality completely.
#define ASMJIT_NO_COMPILER
-//! Disables JIT memory management and \ref JitRuntime.
+//! Disables JIT memory management and \ref asmjit::JitRuntime.
#define ASMJIT_NO_JIT
-//! Disables \ref Logger and \ref Formatter.
+//! Disables \ref asmjit::Logger and \ref asmjit::Formatter.
#define ASMJIT_NO_LOGGING
//! Disables everything that contains text.
@@ -116,33 +127,6 @@ namespace asmjit {
} // {asmjit}
#endif // _DOXYGEN
-// ============================================================================
-// [asmjit::Dependencies]
-// ============================================================================
-
-// We really want std-types as globals.
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <iterator>
-#include <limits>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
- #include <pthread.h>
-#endif
-
-
-// ============================================================================
-// [asmjit::Options]
-// ============================================================================
-
// ASMJIT_NO_BUILDER implies ASMJIT_NO_COMPILER.
#if defined(ASMJIT_NO_BUILDER) && !defined(ASMJIT_NO_COMPILER)
#define ASMJIT_NO_COMPILER
@@ -150,37 +134,17 @@ namespace asmjit {
// Prevent compile-time errors caused by misconfiguration.
#if defined(ASMJIT_NO_TEXT) && !defined(ASMJIT_NO_LOGGING)
- #pragma "ASMJIT_NO_TEXT can only be defined when ASMJIT_NO_LOGGING is defined."
+ #pragma message("'ASMJIT_NO_TEXT' can only be defined when 'ASMJIT_NO_LOGGING' is defined.")
#undef ASMJIT_NO_TEXT
#endif
#if defined(ASMJIT_NO_INTROSPECTION) && !defined(ASMJIT_NO_COMPILER)
- #pragma message("ASMJIT_NO_INTROSPECTION can only be defined when ASMJIT_NO_COMPILER is defined")
+ #pragma message("'ASMJIT_NO_INTROSPECTION' can only be defined when 'ASMJIT_NO_COMPILER' is defined")
#undef ASMJIT_NO_INTROSPECTION
#endif
-// ============================================================================
-// [asmjit::Build - Globals - Deprecated]
-// ============================================================================
-
-#ifndef ASMJIT_NO_DEPRECATED
- #if defined(ASMJIT_BUILD_EMBED) || defined(ASMJIT_BUILD_STATIC)
- #if defined(ASMJIT_BUILD_EMBED)
- #pragma message("'ASMJIT_BUILD_EMBED' is deprecated, use 'ASMJIT_STATIC'")
- #endif
- #if defined(ASMJIT_BUILD_STATIC)
- #pragma message("'ASMJIT_BUILD_STATIC' is deprecated, use 'ASMJIT_STATIC'")
- #endif
-
- #if !defined(ASMJIT_STATIC)
- #define ASMJIT_STATIC
- #endif
- #endif
-#endif // !ASMJIT_NO_DEPRECATED
-
-// ============================================================================
-// [asmjit::Build - Globals - Build Mode]
-// ============================================================================
+// Build Mode
+// ==========
// Detect ASMJIT_BUILD_DEBUG and ASMJIT_BUILD_RELEASE if not defined.
#if !defined(ASMJIT_BUILD_DEBUG) && !defined(ASMJIT_BUILD_RELEASE)
@@ -191,9 +155,8 @@ namespace asmjit {
#endif
#endif
-// ============================================================================
-// [asmjit::Build - Globals - Target Architecture Information]
-// ============================================================================
+// Target Architecture Detection
+// =============================
#if defined(_M_X64) || defined(__x86_64__)
#define ASMJIT_ARCH_X86 64
@@ -239,19 +202,15 @@ namespace asmjit {
#define ASMJIT_ARCH_BE 0
#endif
-// ============================================================================
-// [asmjit::Build - Globals - Backends]
-// ============================================================================
-
#if defined(ASMJIT_NO_FOREIGN)
#if !ASMJIT_ARCH_X86 && !defined(ASMJIT_NO_X86)
#define ASMJIT_NO_X86
#endif
#endif
-// ============================================================================
-// [asmjit::Build - Globals - C++ Compiler and Features Detection]
-// ============================================================================
+
+// C++ Compiler and Features Detection
+// ===================================
#define ASMJIT_CXX_GNU 0
#define ASMJIT_CXX_MAKE_VER(MAJOR, MINOR) ((MAJOR) * 1000 + (MINOR))
@@ -293,9 +252,12 @@ namespace asmjit {
#define ASMJIT_CXX_HAS_ATTRIBUTE(NAME, CHECK) (!(!(CHECK)))
#endif
-// ============================================================================
-// [asmjit::Build - Globals - API Decorators & Language Extensions]
-// ============================================================================
+// API Decorators & C++ Extensions
+// ===============================
+
+//! \def ASMJIT_API
+//!
+//! A decorator that is used to decorate API that AsmJit exports when built as a shared library.
// API (Export / Import).
#if !defined(ASMJIT_STATIC)
@@ -324,12 +286,12 @@ namespace asmjit {
#define ASMJIT_VARAPI extern ASMJIT_API
#endif
-// This is basically a workaround. When using MSVC and marking class as DLL
-// export everything gets exported, which is unwanted in most projects. MSVC
-// automatically exports typeinfo and vtable if at least one symbol of the
-// 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 decorated with "visibility(default)" (i.e. ASMJIT_API).
+//! \def ASMJIT_VIRTAPI
+//!
+//! This is basically a workaround. When using MSVC and marking class as DLL export everything gets exported, which
+//! is unwanted in most projects. MSVC automatically exports typeinfo and vtable if at least one symbol of the 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 decorated with "visibility(default)" (i.e. ASMJIT_API).
#if !defined(_WIN32) && defined(__GNUC__)
#define ASMJIT_VIRTAPI ASMJIT_API
#else
@@ -338,11 +300,11 @@ namespace asmjit {
// Function attributes.
#if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__)
- #define ASMJIT_INLINE inline __attribute__((__always_inline__))
+ #define ASMJIT_FORCE_INLINE inline __attribute__((__always_inline__))
#elif !defined(ASMJIT_BUILD_DEBUG) && defined(_MSC_VER)
- #define ASMJIT_INLINE __forceinline
+ #define ASMJIT_FORCE_INLINE __forceinline
#else
- #define ASMJIT_INLINE inline
+ #define ASMJIT_FORCE_INLINE inline
#endif
#if defined(__GNUC__)
@@ -401,6 +363,17 @@ namespace asmjit {
#define ASMJIT_MAY_ALIAS
#endif
+//! \def ASMJIT_MAYBE_UNUSED
+//!
+//! Expands to `[[maybe_unused]]` if supported or a compiler attribute instead.
+#if __cplusplus >= 201703L
+ #define ASMJIT_MAYBE_UNUSED [[maybe_unused]]
+#elif defined(__GNUC__)
+ #define ASMJIT_MAYBE_UNUSED __attribute__((unused))
+#else
+ #define ASMJIT_MAYBE_UNUSED
+#endif
+
//! \def ASMJIT_LIKELY(...)
//!
//! Condition is likely to be taken (mostly error handling and edge cases).
@@ -457,49 +430,51 @@ namespace asmjit {
#define ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF
#endif
-// ============================================================================
-// [asmjit::Build - Globals - Begin-Namespace / End-Namespace]
-// ============================================================================
+// Begin-Namespace & End-Namespace Macros
+// ======================================
-#if defined(__clang__)
+#if defined _DOXYGEN
+ #define ASMJIT_BEGIN_NAMESPACE namespace asmjit {
+ #define ASMJIT_END_NAMESPACE }
+#elif defined(__clang__)
#define ASMJIT_BEGIN_NAMESPACE \
- namespace asmjit { \
+ namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wconstant-logical-operand\"") \
_Pragma("clang diagnostic ignored \"-Wunnamed-type-template-args\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("clang diagnostic pop") \
- }
+ }}
#elif defined(__GNUC__) && __GNUC__ == 4
#define ASMJIT_BEGIN_NAMESPACE \
- namespace asmjit { \
+ namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("GCC diagnostic pop") \
- }
+ }}
#elif defined(__GNUC__) && __GNUC__ >= 8
#define ASMJIT_BEGIN_NAMESPACE \
- namespace asmjit { \
+ namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"")
#define ASMJIT_END_NAMESPACE \
_Pragma("GCC diagnostic pop") \
- }
+ }}
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#define ASMJIT_BEGIN_NAMESPACE \
- namespace asmjit { \
+ namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE { \
__pragma(warning(push)) \
__pragma(warning(disable: 4127)) /* conditional expression is const */ \
__pragma(warning(disable: 4201)) /* nameless struct/union */
#define ASMJIT_END_NAMESPACE \
__pragma(warning(pop)) \
- }
+ }}
#endif
#if !defined(ASMJIT_BEGIN_NAMESPACE) && !defined(ASMJIT_END_NAMESPACE)
- #define ASMJIT_BEGIN_NAMESPACE namespace asmjit {
- #define ASMJIT_END_NAMESPACE }
+ #define ASMJIT_BEGIN_NAMESPACE namespace asmjit { inline namespace ASMJIT_ABI_NAMESPACE {
+ #define ASMJIT_END_NAMESPACE }}
#endif
#define ASMJIT_BEGIN_SUB_NAMESPACE(NAMESPACE) \
@@ -510,9 +485,8 @@ namespace asmjit {
} \
ASMJIT_END_NAMESPACE
-// ============================================================================
-// [asmjit::Build - Globals - Utilities]
-// ============================================================================
+// C++ Utilities
+// =============
#define ASMJIT_NONCOPYABLE(Type) \
Type(const Type& other) = delete; \
@@ -523,11 +497,71 @@ namespace asmjit {
Type(const Type& other) = delete; \
Type& operator=(const Type& other) = delete;
-// ============================================================================
-// [asmjit::Build - Globals - Cleanup]
-// ============================================================================
+//! \def ASMJIT_DEFINE_ENUM_FLAGS(T)
+//!
+//! Defines bit operations for enumeration flags.
+#ifdef _DOXYGEN
+ #define ASMJIT_DEFINE_ENUM_FLAGS(T)
+#else
+ #define ASMJIT_DEFINE_ENUM_FLAGS(T) \
+ static ASMJIT_FORCE_INLINE constexpr T operator~(T a) noexcept { \
+ return T(~(std::underlying_type<T>::type)(a)); \
+ } \
+ \
+ static ASMJIT_FORCE_INLINE constexpr T operator|(T a, T b) noexcept { \
+ return T((std::underlying_type<T>::type)(a) | \
+ (std::underlying_type<T>::type)(b)); \
+ } \
+ static ASMJIT_FORCE_INLINE constexpr T operator&(T a, T b) noexcept { \
+ return T((std::underlying_type<T>::type)(a) & \
+ (std::underlying_type<T>::type)(b)); \
+ } \
+ static ASMJIT_FORCE_INLINE constexpr T operator^(T a, T b) noexcept { \
+ return T((std::underlying_type<T>::type)(a) ^ \
+ (std::underlying_type<T>::type)(b)); \
+ } \
+ \
+ static ASMJIT_FORCE_INLINE T& operator|=(T& a, T b) noexcept { \
+ a = T((std::underlying_type<T>::type)(a) | \
+ (std::underlying_type<T>::type)(b)); \
+ return a; \
+ } \
+ static ASMJIT_FORCE_INLINE T& operator&=(T& a, T b) noexcept { \
+ a = T((std::underlying_type<T>::type)(a) & \
+ (std::underlying_type<T>::type)(b)); \
+ return a; \
+ } \
+ static ASMJIT_FORCE_INLINE T& operator^=(T& a, T b) noexcept { \
+ a = T((std::underlying_type<T>::type)(a) ^ \
+ (std::underlying_type<T>::type)(b)); \
+ return a; \
+ }
+#endif
+
+//! \def ASMJIT_DEFINE_ENUM_COMPARE(T)
+//!
+//! Defines comparison operations for enumeration flags.
+#ifdef _DOXYGEN
+ #define ASMJIT_DEFINE_ENUM_COMPARE(T)
+#else
+ #define ASMJIT_DEFINE_ENUM_COMPARE(T) \
+ static ASMJIT_FORCE_INLINE bool operator<(T a, T b) noexcept { \
+ return (std::underlying_type<T>::type)(a) < (std::underlying_type<T>::type)(b); \
+ } \
+ static ASMJIT_FORCE_INLINE bool operator<=(T a, T b) noexcept { \
+ return (std::underlying_type<T>::type)(a) <= (std::underlying_type<T>::type)(b); \
+ } \
+ static ASMJIT_FORCE_INLINE bool operator>(T a, T b) noexcept { \
+ return (std::underlying_type<T>::type)(a) > (std::underlying_type<T>::type)(b); \
+ } \
+ static ASMJIT_FORCE_INLINE bool operator>=(T a, T b) noexcept { \
+ return (std::underlying_type<T>::type)(a) >= (std::underlying_type<T>::type)(b); \
+ }
+#endif
+
+// Cleanup Api-Config Specific Macros
+// ==================================
-// Cleanup definitions that are only used within this header file.
#undef ASMJIT_CXX_GNU
#undef ASMJIT_CXX_MAKE_VER
diff --git a/src/asmjit/core/archcommons.h b/src/asmjit/core/archcommons.h
index fda2451..88b6069 100644
--- a/src/asmjit/core/archcommons.h
+++ b/src/asmjit/core/archcommons.h
@@ -1,106 +1,82 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
#define ASMJIT_CORE_ARCHCOMMONS_H_INCLUDED
-// This file provides architecture-specific classes that are required in the
-// core library. For example Imm operand allows to be created from arm::Shift
-// in a const-expr way, so the arm::Shift must be provided. So this header
-// file provides everything architecture-specific that is used by the Core API.
+// This file provides architecture-specific classes that are required in the core library. For example Imm operand
+// allows to be created from arm::Shift in a const-expr way, so the arm::Shift must be provided. So this header file
+// provides everything architecture-specific that is used by the Core API.
#include "../core/globals.h"
-// ============================================================================
-// [asmjit::arm]
-// ============================================================================
-
ASMJIT_BEGIN_SUB_NAMESPACE(arm)
//! \addtogroup asmjit_arm
//! \{
+//! Shift operation predicate (ARM) describes either SHIFT or EXTEND operation.
+//!
+//! \note The constants are AsmJit specific. The first 5 values describe real constants on ARM32 and AArch64 hardware,
+//! however, the addition constants that describe extend modes are specific to AsmJit and would be translated to the
+//! AArch64 specific constants by the assembler.
+enum class ShiftOp {
+ //! Shift left logical operation (default).
+ //!
+ //! Available to all ARM architectures.
+ kLSL = 0x00u,
+
+ //! Shift right logical operation.
+ //!
+ //! Available to all ARM architectures.
+ kLSR = 0x01u,
+
+ //! Shift right arithmetic operation.
+ //!
+ //! Available to all ARM architectures.
+ kASR = 0x02u,
+
+ //! Rotate right operation.
+ //!
+ //! \note Not available in AArch64 mode.
+ kROR = 0x03u,
+
+ //! Rotate right with carry operation (encoded as `kShiftROR` with zero).
+ //!
+ //! \note Not available in AArch64 mode.
+ kRRX = 0x04u,
+
+ //! Shift left by filling low order bits with ones.
+ kMSL = 0x05u,
+
+ //! UXTN extend register operation (AArch64 only).
+ kUXTB = 0x06u,
+ //! UXTH extend register operation (AArch64 only).
+ kUXTH = 0x07u,
+ //! UXTW extend register operation (AArch64 only).
+ kUXTW = 0x08u,
+ //! UXTX extend register operation (AArch64 only).
+ kUXTX = 0x09u,
+
+ //! SXTB extend register operation (AArch64 only).
+ kSXTB = 0x0Au,
+ //! SXTH extend register operation (AArch64 only).
+ kSXTH = 0x0Bu,
+ //! SXTW extend register operation (AArch64 only).
+ kSXTW = 0x0Cu,
+ //! SXTX extend register operation (AArch64 only).
+ kSXTX = 0x0Du
+
+ // NOTE: 0xE and 0xF are used by memory operand to specify POST|PRE offset mode.
+};
+
//! Represents ARM immediate shift operation type and value.
class Shift {
public:
- //! Operation predicate (ARM) describes either SHIFT or EXTEND operation.
- //!
- //! \note The constants are AsmJit specific. The first 5 values describe real
- //! constants on ARM32 and AArch64 hardware, however, the addition constants
- //! that describe extend modes are specific to AsmJit and would be translated
- //! to the AArch64 specific constants by the assembler.
- enum Op : uint32_t {
- //! Shift left logical operation (default).
- //!
- //! Available to all ARM architectures.
- kOpLSL = 0x00u,
-
- //! Shift right logical operation.
- //!
- //! Available to all ARM architectures.
- kOpLSR = 0x01u,
-
- //! Shift right arithmetic operation.
- //!
- //! Available to all ARM architectures.
- kOpASR = 0x02u,
-
- //! Rotate right operation.
- //!
- //! \note Not available in AArch64 mode.
- kOpROR = 0x03u,
-
- //! Rotate right with carry operation (encoded as `kShiftROR` with zero).
- //!
- //! \note Not available in AArch64 mode.
- kOpRRX = 0x04u,
-
- //! Shift left by filling low order bits with ones.
- kOpMSL = 0x05u,
-
- //! UXTN extend register operation (AArch64 only).
- kOpUXTB = 0x06u,
- //! UXTH extend register operation (AArch64 only).
- kOpUXTH = 0x07u,
- //! UXTW extend register operation (AArch64 only).
- kOpUXTW = 0x08u,
- //! UXTX extend register operation (AArch64 only).
- kOpUXTX = 0x09u,
-
- //! SXTB extend register operation (AArch64 only).
- kOpSXTB = 0x0Au,
- //! SXTH extend register operation (AArch64 only).
- kOpSXTH = 0x0Bu,
- //! SXTW extend register operation (AArch64 only).
- kOpSXTW = 0x0Cu,
- //! SXTX extend register operation (AArch64 only).
- kOpSXTX = 0x0Du
-
- // NOTE: 0xE and 0xF are used by memory operand to specify POST|PRE offset mode.
- };
-
//! Shift operation.
- uint32_t _op;
+ ShiftOp _op;
//! Shift Value.
uint32_t _value;
@@ -111,51 +87,51 @@ public:
constexpr Shift(const Shift& other) noexcept = default;
//! Constructs Shift from operation `op` and shift `value`.
- constexpr Shift(uint32_t op, uint32_t value) noexcept
+ constexpr Shift(ShiftOp op, uint32_t value) noexcept
: _op(op),
_value(value) {}
//! Returns the shift operation.
- constexpr uint32_t op() const noexcept { return _op; }
+ constexpr ShiftOp op() const noexcept { return _op; }
+ //! Sets shift operation to `op`.
+ inline void setOp(ShiftOp op) noexcept { _op = op; }
+
//! Returns the shift smount.
constexpr uint32_t value() const noexcept { return _value; }
-
- //! Sets shift operation to `op`.
- inline void setOp(uint32_t op) noexcept { _op = op; }
//! Sets shift amount to `value`.
inline void setValue(uint32_t value) noexcept { _value = value; }
};
//! Constructs a `LSL #value` shift (logical shift left).
-static constexpr Shift lsl(uint32_t value) noexcept { return Shift(Shift::kOpLSL, value); }
+static constexpr Shift lsl(uint32_t value) noexcept { return Shift(ShiftOp::kLSL, value); }
//! Constructs a `LSR #value` shift (logical shift right).
-static constexpr Shift lsr(uint32_t value) noexcept { return Shift(Shift::kOpLSR, value); }
+static constexpr Shift lsr(uint32_t value) noexcept { return Shift(ShiftOp::kLSR, value); }
//! Constructs a `ASR #value` shift (arithmetic shift right).
-static constexpr Shift asr(uint32_t value) noexcept { return Shift(Shift::kOpASR, value); }
+static constexpr Shift asr(uint32_t value) noexcept { return Shift(ShiftOp::kASR, value); }
//! Constructs a `ROR #value` shift (rotate right).
-static constexpr Shift ror(uint32_t value) noexcept { return Shift(Shift::kOpROR, value); }
+static constexpr Shift ror(uint32_t value) noexcept { return Shift(ShiftOp::kROR, value); }
//! Constructs a `RRX` shift (rotate with carry by 1).
-static constexpr Shift rrx() noexcept { return Shift(Shift::kOpRRX, 0); }
+static constexpr Shift rrx() noexcept { return Shift(ShiftOp::kRRX, 0); }
//! Constructs a `MSL #value` shift (logical shift left filling ones).
-static constexpr Shift msl(uint32_t value) noexcept { return Shift(Shift::kOpMSL, value); }
+static constexpr Shift msl(uint32_t value) noexcept { return Shift(ShiftOp::kMSL, value); }
//! Constructs a `UXTB #value` extend and shift (unsigned byte extend).
-static constexpr Shift uxtb(uint32_t value) noexcept { return Shift(Shift::kOpUXTB, value); }
+static constexpr Shift uxtb(uint32_t value) noexcept { return Shift(ShiftOp::kUXTB, value); }
//! Constructs a `UXTH #value` extend and shift (unsigned hword extend).
-static constexpr Shift uxth(uint32_t value) noexcept { return Shift(Shift::kOpUXTH, value); }
+static constexpr Shift uxth(uint32_t value) noexcept { return Shift(ShiftOp::kUXTH, value); }
//! Constructs a `UXTW #value` extend and shift (unsigned word extend).
-static constexpr Shift uxtw(uint32_t value) noexcept { return Shift(Shift::kOpUXTW, value); }
+static constexpr Shift uxtw(uint32_t value) noexcept { return Shift(ShiftOp::kUXTW, value); }
//! Constructs a `UXTX #value` extend and shift (unsigned dword extend).
-static constexpr Shift uxtx(uint32_t value) noexcept { return Shift(Shift::kOpUXTX, value); }
+static constexpr Shift uxtx(uint32_t value) noexcept { return Shift(ShiftOp::kUXTX, value); }
//! Constructs a `SXTB #value` extend and shift (signed byte extend).
-static constexpr Shift sxtb(uint32_t value) noexcept { return Shift(Shift::kOpSXTB, value); }
+static constexpr Shift sxtb(uint32_t value) noexcept { return Shift(ShiftOp::kSXTB, value); }
//! Constructs a `SXTH #value` extend and shift (signed hword extend).
-static constexpr Shift sxth(uint32_t value) noexcept { return Shift(Shift::kOpSXTH, value); }
+static constexpr Shift sxth(uint32_t value) noexcept { return Shift(ShiftOp::kSXTH, value); }
//! Constructs a `SXTW #value` extend and shift (signed word extend).
-static constexpr Shift sxtw(uint32_t value) noexcept { return Shift(Shift::kOpSXTW, value); }
+static constexpr Shift sxtw(uint32_t value) noexcept { return Shift(ShiftOp::kSXTW, value); }
//! Constructs a `SXTX #value` extend and shift (signed dword extend).
-static constexpr Shift sxtx(uint32_t value) noexcept { return Shift(Shift::kOpSXTX, value); }
+static constexpr Shift sxtx(uint32_t value) noexcept { return Shift(ShiftOp::kSXTX, value); }
//! \}
diff --git a/src/asmjit/core/archtraits.cpp b/src/asmjit/core/archtraits.cpp
index 6c50bb1..8b79ee2 100644
--- a/src/asmjit/core/archtraits.cpp
+++ b/src/asmjit/core/archtraits.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/archtraits.h"
@@ -35,10 +17,6 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ArchTraits]
-// ============================================================================
-
static const constexpr ArchTraits noArchTraits = {
// SP/FP/LR/PC.
0xFF, 0xFF, 0xFF, 0xFF,
@@ -53,27 +31,38 @@ static const constexpr ArchTraits noArchTraits = {
0, 0,
// ISA features [Gp, Vec, Other0, Other1].
- { 0, 0, 0, 0},
+ {{
+ InstHints::kNoHints,
+ InstHints::kNoHints,
+ InstHints::kNoHints,
+ InstHints::kNoHints
+ }},
// RegTypeToSignature.
- { { 0 } },
+ #define V(index) { OperandSignature(0) }
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
// RegTypeToTypeId.
- { 0 },
+ #define V(index) TypeId::kVoid
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
// TypeIdToRegType.
- { 0 },
+ #define V(index) RegType::kNone
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
+ #undef V
// Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
{
- ISAWordNameId::kByte,
- ISAWordNameId::kHalf,
- ISAWordNameId::kWord,
- ISAWordNameId::kQuad
+ ArchTypeNameId::kByte,
+ ArchTypeNameId::kHalf,
+ ArchTypeNameId::kWord,
+ ArchTypeNameId::kQuad
}
};
-ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount] = {
+ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1] = {
// No architecture.
noArchTraits,
@@ -111,63 +100,60 @@ ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount] = {
noArchTraits
};
-// ============================================================================
-// [asmjit::ArchUtils]
-// ============================================================================
-
-ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept {
+ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept {
const ArchTraits& archTraits = ArchTraits::byArch(arch);
+ // TODO: Remove this, should never be used like this.
// Passed RegType instead of TypeId?
- if (typeId <= BaseReg::kTypeMax)
- typeId = archTraits.regTypeToTypeId(typeId);
+ if (uint32_t(typeId) <= uint32_t(RegType::kMaxValue))
+ typeId = archTraits.regTypeToTypeId(RegType(uint32_t(typeId)));
- if (ASMJIT_UNLIKELY(!Type::isValid(typeId)))
+ if (ASMJIT_UNLIKELY(!TypeUtils::isValid(typeId)))
return DebugUtils::errored(kErrorInvalidTypeId);
// First normalize architecture dependent types.
- if (Type::isAbstract(typeId)) {
+ if (TypeUtils::isAbstract(typeId)) {
bool is32Bit = Environment::is32Bit(arch);
- if (typeId == Type::kIdIntPtr)
- typeId = is32Bit ? Type::kIdI32 : Type::kIdI64;
+ if (typeId == TypeId::kIntPtr)
+ typeId = is32Bit ? TypeId::kInt32 : TypeId::kInt64;
else
- typeId = is32Bit ? Type::kIdU32 : Type::kIdU64;
+ typeId = is32Bit ? TypeId::kUInt32 : TypeId::kUInt64;
}
// Type size helps to construct all groups of registers.
// TypeId is invalid if the size is zero.
- uint32_t size = Type::sizeOf(typeId);
+ uint32_t size = TypeUtils::sizeOf(typeId);
if (ASMJIT_UNLIKELY(!size))
return DebugUtils::errored(kErrorInvalidTypeId);
- if (ASMJIT_UNLIKELY(typeId == Type::kIdF80))
+ if (ASMJIT_UNLIKELY(typeId == TypeId::kFloat80))
return DebugUtils::errored(kErrorInvalidUseOfF80);
- uint32_t regType = 0;
- if (typeId >= Type::_kIdBaseStart && typeId < Type::_kIdVec32Start) {
- regType = archTraits._typeIdToRegType[typeId - Type::_kIdBaseStart];
- if (!regType) {
- if (typeId == Type::kIdI64 || typeId == Type::kIdU64)
+ RegType regType = RegType::kNone;
+ if (TypeUtils::isBetween(typeId, TypeId::_kBaseStart, TypeId::_kVec32Start)) {
+ regType = archTraits._typeIdToRegType[uint32_t(typeId) - uint32_t(TypeId::_kBaseStart)];
+ if (regType == RegType::kNone) {
+ if (typeId == TypeId::kInt64 || typeId == TypeId::kUInt64)
return DebugUtils::errored(kErrorInvalidUseOfGpq);
else
return DebugUtils::errored(kErrorInvalidTypeId);
}
}
else {
- if (size <= 8 && archTraits._regInfo[BaseReg::kTypeVec64].isValid())
- regType = BaseReg::kTypeVec64;
- else if (size <= 16 && archTraits._regInfo[BaseReg::kTypeVec128].isValid())
- regType = BaseReg::kTypeVec128;
- else if (size == 32 && archTraits._regInfo[BaseReg::kTypeVec256].isValid())
- regType = BaseReg::kTypeVec256;
- else if (archTraits._regInfo[BaseReg::kTypeVec512].isValid())
- regType = BaseReg::kTypeVec512;
+ if (size <= 8 && archTraits._regSignature[RegType::kVec64].isValid())
+ regType = RegType::kVec64;
+ else if (size <= 16 && archTraits._regSignature[RegType::kVec128].isValid())
+ regType = RegType::kVec128;
+ else if (size == 32 && archTraits._regSignature[RegType::kVec256].isValid())
+ regType = RegType::kVec256;
+ else if (archTraits._regSignature[RegType::kVec512].isValid())
+ regType = RegType::kVec512;
else
return DebugUtils::errored(kErrorInvalidTypeId);
}
*typeIdOut = typeId;
- regInfoOut->reset(archTraits.regTypeToSignature(regType));
+ *regSignatureOut = archTraits.regTypeToSignature(regType);
return kErrorOk;
}
diff --git a/src/asmjit/core/archtraits.h b/src/asmjit/core/archtraits.h
index 43ef10f..4d05c11 100644
--- a/src/asmjit/core/archtraits.h
+++ b/src/asmjit/core/archtraits.h
@@ -1,31 +1,13 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
#define ASMJIT_CORE_ARCHTRAITS_H_INCLUDED
-#include "../core/environment.h"
#include "../core/operand.h"
+#include "../core/support.h"
#include "../core/type.h"
ASMJIT_BEGIN_NAMESPACE
@@ -33,8 +15,98 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
+//! Instruction set architecture (ISA).
+enum class Arch : uint8_t {
+ //! Unknown or uninitialized ISA.
+ kUnknown = 0,
+
+ //! 32-bit X86 ISA.
+ kX86 = 1,
+ //! 64-bit X86 ISA also known as X64, X86_64, and AMD64.
+ kX64 = 2,
+
+ //! 32-bit RISC-V ISA.
+ kRISCV32 = 3,
+ //! 64-bit RISC-V ISA.
+ kRISCV64 = 4,
+
+ //! 32-bit ARM ISA (little endian).
+ kARM = 5,
+ //! 64-bit ARM ISA in (little endian).
+ kAArch64 = 6,
+ //! 32-bit ARM ISA in Thumb mode (little endian).
+ kThumb = 7,
+
+ // 8 is not used at the moment, even numbers are 64-bit architectures.
+
+ //! 32-bit MIPS ISA in (little endian).
+ kMIPS32_LE = 9,
+ //! 64-bit MIPS ISA in (little endian).
+ kMIPS64_LE = 10,
+
+ //! 32-bit ARM ISA (big endian).
+ kARM_BE = 11,
+ //! 64-bit ARM ISA in (big endian).
+ kAArch64_BE = 12,
+ //! 32-bit ARM ISA in Thumb mode (big endian).
+ kThumb_BE = 13,
+
+ // 14 is not used at the moment, even numbers are 64-bit architectures.
+
+ //! 32-bit MIPS ISA in (big endian).
+ kMIPS32_BE = 15,
+ //! 64-bit MIPS ISA in (big endian).
+ kMIPS64_BE = 16,
+
+ //! Maximum value of `Arch`.
+ kMaxValue = kMIPS64_BE,
+
+ //! Mask used by 32-bit ISAs (odd are 32-bit, even are 64-bit).
+ k32BitMask = 0x01,
+ //! First big-endian architecture.
+ kBigEndian = kARM_BE,
+
+ //! ISA detected at compile-time (ISA of the host).
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#else
+ ASMJIT_ARCH_X86 == 32 ? kX86 :
+ ASMJIT_ARCH_X86 == 64 ? kX64 :
+
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kARM :
+ ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kARM_BE :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kAArch64 :
+ ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kAArch64_BE :
+
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kMIPS32_LE :
+ ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kMIPS32_BE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kMIPS64_LE :
+ ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kMIPS64_BE :
+
+ kUnknown
+#endif
+};
+
+//! Sub-architecture.
+enum class SubArch : uint8_t {
+ //! Unknown or uninitialized architecture sub-type.
+ kUnknown = 0,
+
+ //! Maximum value of `SubArch`.
+ kMaxValue = kUnknown,
+
+ //! Sub-architecture detected at compile-time (sub-architecture of the host).
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#else
+ kUnknown
+#endif
+};
+
//! Identifier used to represent names of different data types across architectures.
-enum class ISAWordNameId : uint8_t {
+enum class ArchTypeNameId : uint8_t {
//! Describes 'db' (X86/X86_64 convention, always 8-bit quantity).
kDB = 0,
//! Describes 'dw' (X86/X86_64 convention, always 16-bit word).
@@ -64,23 +136,33 @@ enum class ISAWordNameId : uint8_t {
//! Describes 'quad' (64-bit word).
kQuad,
- //! Maximum value.
+ //! Maximum value of `ArchTypeNameId`.
kMaxValue = kQuad
};
-// ============================================================================
-// [asmjit::ArchTraits]
-// ============================================================================
+//! Instruction feature hints for each register group provided by \ref ArchTraits.
+//!
+//! Instruction feature hints describe miscellaneous instructions provided by the architecture that can be used by
+//! register allocator to make certain things simpler - like register swaps or emitting register push/pop sequences.
+//!
+//! \remarks Instruction feature hints are only defined for register groups that can be used with \ref
+//! asmjit_compiler infrastructure. Register groups that are not managed by Compiler are not provided by
+//! \ref ArchTraits and cannot be queried.
+enum class InstHints : uint8_t {
+ //! No feature hints.
+ kNoHints = 0,
+
+ //! Architecture supports a register swap by using a single instructio.
+ kRegSwap = 0x01u,
+ //! Architecture provides push/pop instructions.
+ kPushPop = 0x02u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(InstHints)
//! Architecture traits used by Function API and Compiler's register allocator.
struct ArchTraits {
- //! ISA features for each register group.
- enum IsaFeatures : uint32_t {
- //! ISA features a register swap by using a single instruction.
- kIsaFeatureSwap = 0x01u,
- //! ISA features a push/pop like instruction for this register group.
- kIsaFeaturePushPop = 0x02u,
- };
+ //! \name Members
+ //! \{
//! Stack pointer register id.
uint8_t _spRegId;
@@ -101,84 +183,69 @@ struct ArchTraits {
//! Maximum addressable offset on stack depending on specific instruction.
uint32_t _maxStackOffset;
- //! Flags for each virtual register group (always covers GP and Vec groups).
- uint8_t _isaFlags[BaseReg::kGroupVirt];
+ //! Flags for each virtual register group.
+ Support::Array<InstHints, Globals::kNumVirtGroups> _instHints;
- //! Maps register type into a signature, that provides group, size and can
- //! be used to construct register operands.
- RegInfo _regInfo[BaseReg::kTypeMax + 1];
- //! Maps a register to type-id, see \ref Type::Id.
- uint8_t _regTypeToTypeId[BaseReg::kTypeMax + 1];
- //! Maps base TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref Type::Id.
- uint8_t _typeIdToRegType[32];
+ //! Maps register type into a signature, that provides group, size and can be used to construct register operands.
+ Support::Array<OperandSignature, uint32_t(RegType::kMaxValue) + 1> _regSignature;
+ //! Maps a register to type-id, see \ref TypeId.
+ Support::Array<TypeId, uint32_t(RegType::kMaxValue) + 1> _regTypeToTypeId;
+ //! Maps scalar TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref TypeId.
+ Support::Array<RegType, 32> _typeIdToRegType;
//! Word name identifiers of 8-bit, 16-bit, 32-biit, and 64-bit quantities that appear in formatted text.
- ISAWordNameId _isaWordNameIdTable[4];
+ ArchTypeNameId _typeNameIdTable[4];
- //! Resets all members to zeros.
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! \}
//! \name Accessors
//! \{
//! Returns stack pointer register id.
- inline constexpr uint32_t spRegId() const noexcept { return _spRegId; }
+ inline uint32_t spRegId() const noexcept { return _spRegId; }
//! Returns stack frame register id.
- inline constexpr uint32_t fpRegId() const noexcept { return _fpRegId; }
+ inline uint32_t fpRegId() const noexcept { return _fpRegId; }
//! Returns link register id, if the architecture provides it.
- inline constexpr uint32_t linkRegId() const noexcept { return _linkRegId; }
+ inline uint32_t linkRegId() const noexcept { return _linkRegId; }
//! Returns instruction pointer register id, if the architecture provides it.
- inline constexpr uint32_t ipRegId() const noexcept { return _ipRegId; }
+ inline uint32_t ipRegId() const noexcept { return _ipRegId; }
//! Returns a hardware stack alignment requirement.
//!
- //! \note This is a hardware constraint. Architectures that don't constrain
- //! it would return the lowest alignment (1), however, some architectures may
- //! constrain the alignment, for example AArch64 requires 16-byte alignment.
- inline constexpr uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
+ //! \note This is a hardware constraint. Architectures that don't constrain it would return the lowest alignment
+ //! (1), however, some architectures may constrain the alignment, for example AArch64 requires 16-byte alignment.
+ inline uint32_t hwStackAlignment() const noexcept { return _hwStackAlignment; }
- //! Tests whether the architecture provides link register, which is used across
- //! function calls. If the link register is not provided then a function call
- //! pushes the return address on stack (X86/X64).
- inline constexpr bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
+ //! Tests whether the architecture provides link register, which is used across function calls. If the link
+ //! register is not provided then a function call pushes the return address on stack (X86/X64).
+ inline bool hasLinkReg() const noexcept { return _linkRegId != BaseReg::kIdBad; }
//! Returns minimum addressable offset on stack guaranteed for all instructions.
- inline constexpr uint32_t minStackOffset() const noexcept { return _minStackOffset; }
+ inline uint32_t minStackOffset() const noexcept { return _minStackOffset; }
//! Returns maximum addressable offset on stack depending on specific instruction.
- inline constexpr uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
+ inline uint32_t maxStackOffset() const noexcept { return _maxStackOffset; }
//! Returns ISA flags of the given register `group`.
- inline constexpr uint32_t isaFlags(uint32_t group) const noexcept { return _isaFlags[group]; }
+ inline InstHints instFeatureHints(RegGroup group) const noexcept { return _instHints[group]; }
//! Tests whether the given register `group` has the given `flag` set.
- inline constexpr bool hasIsaFlag(uint32_t group, uint32_t flag) const noexcept { return (_isaFlags[group] & flag) != 0; }
+ inline bool hasInstHint(RegGroup group, InstHints feature) const noexcept { return Support::test(_instHints[group], feature); }
//! Tests whether the ISA provides register swap instruction for the given register `group`.
- inline constexpr bool hasSwap(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeatureSwap); }
+ inline bool hasInstRegSwap(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kRegSwap); }
//! Tests whether the ISA provides push/pop instructions for the given register `group`.
- inline constexpr bool hasPushPop(uint32_t group) const noexcept { return hasIsaFlag(group, kIsaFeaturePushPop); }
+ inline bool hasInstPushPop(RegGroup group) const noexcept { return hasInstHint(group, InstHints::kPushPop); }
- inline uint32_t hasRegType(uint32_t rType) const noexcept {
- return rType <= BaseReg::kTypeMax && _regInfo[rType].signature() != 0;
+ inline bool hasRegType(RegType type) const noexcept {
+ return type <= RegType::kMaxValue && _regSignature[type].isValid();
}
- inline uint32_t regTypeToSignature(uint32_t rType) const noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return _regInfo[rType].signature();
- }
-
- inline uint32_t regTypeToGroup(uint32_t rType) const noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return _regInfo[rType].group();
- }
-
- inline uint32_t regTypeToSize(uint32_t rType) const noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return _regInfo[rType].size();
- }
-
- inline uint32_t regTypeToTypeId(uint32_t rType) const noexcept {
- ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
- return _regTypeToTypeId[rType];
- }
+ //! Returns an operand signature from the given register `type` of this architecture.
+ inline OperandSignature regTypeToSignature(RegType type) const noexcept { return _regSignature[type]; }
+ //! Returns a register from the given register `type` of this architecture.
+ inline RegGroup regTypeToGroup(RegType type) const noexcept { return _regSignature[type].regGroup(); }
+ //! Returns a register size the given register `type` of this architecture.
+ inline uint32_t regTypeToSize(RegType type) const noexcept { return _regSignature[type].size(); }
+ //! Returns a corresponding `TypeId` from the given register `type` of this architecture.
+ inline TypeId regTypeToTypeId(RegType type) const noexcept { return _regTypeToTypeId[type]; }
//! Returns a table of ISA word names that appear in formatted text. Word names are ISA dependent.
//!
@@ -187,10 +254,10 @@ struct ArchTraits {
//! - [1] 16-bits
//! - [2] 32-bits
//! - [3] 64-bits
- inline const ISAWordNameId* isaWordNameIdTable() const noexcept { return _isaWordNameIdTable; }
+ inline const ArchTypeNameId* typeNameIdTable() const noexcept { return _typeNameIdTable; }
- //! Returns an ISA word name identifier of the given `index`, see \ref isaWordNameIdTable() for more details.
- inline ISAWordNameId isaWordNameId(uint32_t index) const noexcept { return _isaWordNameIdTable[index]; }
+ //! Returns an ISA word name identifier of the given `index`, see \ref typeNameIdTable() for more details.
+ inline ArchTypeNameId typeNameIdByIndex(uint32_t index) const noexcept { return _typeNameIdTable[index]; }
//! \}
@@ -198,23 +265,21 @@ struct ArchTraits {
//! \{
//! Returns a const reference to `ArchTraits` for the given architecture `arch`.
- static inline const ArchTraits& byArch(uint32_t arch) noexcept;
+ static inline const ArchTraits& byArch(Arch arch) noexcept;
//! \}
};
-ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount];
-
-inline const ArchTraits& ArchTraits::byArch(uint32_t arch) noexcept { return _archTraits[arch & ~Environment::kArchBigEndianMask]; }
+ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1];
-// ============================================================================
-// [asmjit::ArchUtils]
-// ============================================================================
+//! \cond
+inline const ArchTraits& ArchTraits::byArch(Arch arch) noexcept { return _archTraits[uint32_t(arch)]; }
+//! \endcond
//! Architecture utilities.
namespace ArchUtils {
-ASMJIT_API Error typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfo) noexcept;
+ASMJIT_API Error typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept;
} // {ArchUtils}
diff --git a/src/asmjit/core/assembler.cpp b/src/asmjit/core/assembler.cpp
index 6f9fe00..ea223a3 100644
--- a/src/asmjit/core/assembler.cpp
+++ b/src/asmjit/core/assembler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/assembler.h"
@@ -32,18 +14,16 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::BaseAssembler - Construction / Destruction]
-// ============================================================================
+// BaseAssembler - Construction & Destruction
+// ==========================================
BaseAssembler::BaseAssembler() noexcept
- : BaseEmitter(kTypeAssembler) {}
+ : BaseEmitter(EmitterType::kAssembler) {}
BaseAssembler::~BaseAssembler() noexcept {}
-// ============================================================================
-// [asmjit::BaseAssembler - Buffer Management]
-// ============================================================================
+// BaseAssembler - Buffer Management
+// =================================
Error BaseAssembler::setOffset(size_t offset) {
if (ASMJIT_UNLIKELY(!_code))
@@ -57,9 +37,8 @@ Error BaseAssembler::setOffset(size_t offset) {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseAssembler - Section Management]
-// ============================================================================
+// BaseAssembler - Section Management
+// ==================================
static void BaseAssembler_initSection(BaseAssembler* self, Section* section) noexcept {
uint8_t* p = section->_buffer._data;
@@ -86,9 +65,8 @@ Error BaseAssembler::section(Section* section) {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseAssembler - Label Management]
-// ============================================================================
+// BaseAssembler - Label Management
+// ================================
Label BaseAssembler::newLabel() {
uint32_t labelId = Globals::kInvalidId;
@@ -103,7 +81,7 @@ Label BaseAssembler::newLabel() {
return Label(labelId);
}
-Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) {
+Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
uint32_t labelId = Globals::kInvalidId;
if (ASMJIT_LIKELY(_code)) {
LabelEntry* le;
@@ -134,9 +112,8 @@ Error BaseAssembler::bind(const Label& label) {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseAssembler - Embed]
-// ============================================================================
+// BaseAssembler - Embed
+// =====================
Error BaseAssembler::embed(const void* data, size_t dataSize) {
if (ASMJIT_UNLIKELY(!_code))
@@ -154,7 +131,7 @@ Error BaseAssembler::embed(const void* data, size_t dataSize) {
#ifndef ASMJIT_NO_LOGGING
if (_logger) {
StringTmp<512> sb;
- Formatter::formatData(sb, _logger->flags(), arch(), Type::kIdU8, data, dataSize, 1);
+ Formatter::formatData(sb, _logger->flags(), arch(), TypeId::kUInt8, data, dataSize, 1);
sb.append('\n');
_logger->log(sb);
}
@@ -163,17 +140,17 @@ Error BaseAssembler::embed(const void* data, size_t dataSize) {
return kErrorOk;
}
-Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) {
- uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
- uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
+Error BaseAssembler::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
+ uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize());
+ TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta);
- if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId)))
+ if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId)))
return reportError(DebugUtils::errored(kErrorInvalidArgument));
if (itemCount == 0 || repeatCount == 0)
return kErrorOk;
- uint32_t typeSize = Type::sizeOf(finalTypeId);
+ uint32_t typeSize = TypeUtils::sizeOf(finalTypeId);
Support::FastUInt8 of = 0;
size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
@@ -203,16 +180,16 @@ Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t it
}
#ifndef ASMJIT_NO_LOGGING
-static const uint8_t dataTypeIdBySize[9] = {
- Type::kIdVoid, // [0] (invalid)
- Type::kIdU8, // [1] (uint8_t)
- Type::kIdU16, // [2] (uint16_t)
- Type::kIdVoid, // [3] (invalid)
- Type::kIdU32, // [4] (uint32_t)
- Type::kIdVoid, // [5] (invalid)
- Type::kIdVoid, // [6] (invalid)
- Type::kIdVoid, // [7] (invalid)
- Type::kIdU64 // [8] (uint64_t)
+static const TypeId dataTypeIdBySize[9] = {
+ TypeId::kVoid, // [0] (invalid)
+ TypeId::kUInt8, // [1] (uint8_t)
+ TypeId::kUInt16, // [2] (uint16_t)
+ TypeId::kVoid, // [3] (invalid)
+ TypeId::kUInt32, // [4] (uint32_t)
+ TypeId::kVoid, // [5] (invalid)
+ TypeId::kVoid, // [6] (invalid)
+ TypeId::kVoid, // [7] (invalid)
+ TypeId::kUInt64 // [8] (uint64_t)
};
#endif
@@ -223,7 +200,7 @@ Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
if (ASMJIT_UNLIKELY(!isLabelValid(label)))
return reportError(DebugUtils::errored(kErrorInvalidLabel));
- ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
+ ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment())));
ASMJIT_PROPAGATE(bind(label));
size_t size = pool.size();
@@ -282,13 +259,13 @@ Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) {
sb.append('.');
Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
sb.append(' ');
- Formatter::formatLabel(sb, 0, this, label.id());
+ Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id());
sb.append('\n');
_logger->log(sb);
}
#endif
- Error err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs);
+ Error err = _code->newRelocEntry(&re, RelocType::kRelToAbs);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
@@ -343,9 +320,9 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
sb.append('.');
Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
sb.append(" (");
- Formatter::formatLabel(sb, 0, this, label.id());
+ Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id());
sb.append(" - ");
- Formatter::formatLabel(sb, 0, this, base.id());
+ Formatter::formatLabel(sb, FormatFlags::kNone, this, base.id());
sb.append(")\n");
_logger->log(sb);
}
@@ -358,7 +335,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
}
else {
RelocEntry* re;
- Error err = _code->newRelocEntry(&re, RelocEntry::kTypeExpression);
+ Error err = _code->newRelocEntry(&re, RelocType::kExpression);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
@@ -367,7 +344,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
return reportError(DebugUtils::errored(kErrorOutOfMemory));
exp->reset();
- exp->opType = Expression::kOpSub;
+ exp->opType = ExpressionOpType::kSub;
exp->setValueAsLabel(0, labelEntry);
exp->setValueAsLabel(1, baseEntry);
@@ -383,19 +360,18 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseAssembler - Comment]
-// ============================================================================
+// BaseAssembler - Comment
+// =======================
Error BaseAssembler::comment(const char* data, size_t size) {
- if (!hasEmitterFlag(kFlagLogComments)) {
- if (!hasEmitterFlag(kFlagAttached))
+ if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
+ if (!hasEmitterFlag(EmitterFlags::kAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
return kErrorOk;
}
#ifndef ASMJIT_NO_LOGGING
- // Logger cannot be NULL if `kFlagLogComments` is set.
+ // Logger cannot be NULL if `EmitterFlags::kLogComments` is set.
ASMJIT_ASSERT(_logger != nullptr);
_logger->log(data, size);
@@ -407,9 +383,8 @@ Error BaseAssembler::comment(const char* data, size_t size) {
#endif
}
-// ============================================================================
-// [asmjit::BaseAssembler - Events]
-// ============================================================================
+// BaseAssembler - Events
+// ======================
Error BaseAssembler::onAttach(CodeHolder* code) noexcept {
ASMJIT_PROPAGATE(Base::onAttach(code));
diff --git a/src/asmjit/core/assembler.h b/src/asmjit/core/assembler.h
index c0da819..7ea2505 100644
--- a/src/asmjit/core/assembler.h
+++ b/src/asmjit/core/assembler.h
@@ -1,31 +1,12 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ASSEMBLER_H_INCLUDED
#define ASMJIT_CORE_ASSEMBLER_H_INCLUDED
#include "../core/codeholder.h"
-#include "../core/datatypes.h"
#include "../core/emitter.h"
#include "../core/operand.h"
@@ -34,10 +15,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_assembler
//! \{
-// ============================================================================
-// [asmjit::BaseAssembler]
-// ============================================================================
-
//! Base assembler.
//!
//! This is a base class that provides interface used by architecture specific
@@ -112,7 +89,7 @@ public:
//! \{
ASMJIT_API Label newLabel() override;
- ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override;
+ ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) override;
ASMJIT_API Error bind(const Label& label) override;
//! \}
@@ -121,7 +98,7 @@ public:
//! \{
ASMJIT_API Error embed(const void* data, size_t dataSize) override;
- ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) override;
+ ASMJIT_API Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) override;
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override;
diff --git a/src/asmjit/core/builder.cpp b/src/asmjit/core/builder.cpp
index ad89f1d..108a8b0 100644
--- a/src/asmjit/core/builder.cpp
+++ b/src/asmjit/core/builder.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_BUILDER
@@ -33,9 +15,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::PostponedErrorHandler (Internal)]
-// ============================================================================
+// PostponedErrorHandler (Internal)
+// ================================
//! Postponed error handler that never throws. Used as a temporal error handler
//! to run passes. If error occurs, the caller is notified and will call the
@@ -50,9 +31,8 @@ public:
StringTmp<128> _message;
};
-// ============================================================================
-// [asmjit::BaseBuilder - Utilities]
-// ============================================================================
+// BaseBuilder - Utilities
+// =======================
static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
for (Pass* pass : self->_passes)
@@ -60,12 +40,11 @@ static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
self->_passes.reset();
}
-// ============================================================================
-// [asmjit::BaseBuilder - Construction / Destruction]
-// ============================================================================
+// BaseBuilder - Construction & Destruction
+// ========================================
BaseBuilder::BaseBuilder() noexcept
- : BaseEmitter(kTypeBuilder),
+ : BaseEmitter(EmitterType::kBuilder),
_codeZone(32768 - Zone::kBlockOverhead),
_dataZone(16384 - Zone::kBlockOverhead),
_passZone(65536 - Zone::kBlockOverhead),
@@ -75,11 +54,10 @@ BaseBuilder::~BaseBuilder() noexcept {
BaseBuilder_deletePasses(this);
}
-// ============================================================================
-// [asmjit::BaseBuilder - Node Management]
-// ============================================================================
+// BaseBuilder - Node Management
+// =============================
-Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount) {
+Error BaseBuilder::newInstNode(InstNode** out, InstId instId, InstOptions instOptions, uint32_t opCount) {
uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
@@ -92,28 +70,28 @@ Error BaseBuilder::_newInstNode(InstNode** out, uint32_t instId, uint32_t instOp
}
-Error BaseBuilder::_newLabelNode(LabelNode** out) {
+Error BaseBuilder::newLabelNode(LabelNode** out) {
*out = nullptr;
ASMJIT_PROPAGATE(_newNodeT<LabelNode>(out));
return registerLabelNode(*out);
}
-Error BaseBuilder::_newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment) {
+Error BaseBuilder::newAlignNode(AlignNode** out, AlignMode alignMode, uint32_t alignment) {
*out = nullptr;
return _newNodeT<AlignNode>(out, alignMode, alignment);
}
-Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) {
+Error BaseBuilder::newEmbedDataNode(EmbedDataNode** out, TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
*out = nullptr;
- uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
- uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
+ uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize());
+ TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta);
- if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId)))
+ if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId)))
return reportError(DebugUtils::errored(kErrorInvalidArgument));
- uint32_t typeSize = Type::sizeOf(finalTypeId);
+ uint32_t typeSize = TypeUtils::sizeOf(finalTypeId);
Support::FastUInt8 of = 0;
size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
@@ -123,7 +101,7 @@ Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const
EmbedDataNode* node;
ASMJIT_PROPAGATE(_newNodeT<EmbedDataNode>(&node));
- node->_embed._typeId = uint8_t(typeId);
+ node->_embed._typeId = typeId;
node->_embed._typeSize = uint8_t(typeSize);
node->_itemCount = itemCount;
node->_repeatCount = repeatCount;
@@ -143,14 +121,14 @@ Error BaseBuilder::_newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const
return kErrorOk;
}
-Error BaseBuilder::_newConstPoolNode(ConstPoolNode** out) {
+Error BaseBuilder::newConstPoolNode(ConstPoolNode** out) {
*out = nullptr;
ASMJIT_PROPAGATE(_newNodeT<ConstPoolNode>(out));
return registerLabelNode(*out);
}
-Error BaseBuilder::_newCommentNode(CommentNode** out, const char* data, size_t size) {
+Error BaseBuilder::newCommentNode(CommentNode** out, const char* data, size_t size) {
*out = nullptr;
if (data) {
@@ -198,7 +176,7 @@ BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
_lastNode = node;
}
- node->addFlags(BaseNode::kFlagIsActive);
+ node->addFlags(NodeFlags::kIsActive);
if (node->isSection())
_dirtySectionLinks = true;
@@ -219,7 +197,7 @@ BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
node->_prev = prev;
node->_next = next;
- node->addFlags(BaseNode::kFlagIsActive);
+ node->addFlags(NodeFlags::kIsActive);
if (node->isSection())
_dirtySectionLinks = true;
@@ -246,7 +224,7 @@ BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
node->_prev = prev;
node->_next = next;
- node->addFlags(BaseNode::kFlagIsActive);
+ node->addFlags(NodeFlags::kIsActive);
if (node->isSection())
_dirtySectionLinks = true;
@@ -278,7 +256,7 @@ BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
node->_prev = nullptr;
node->_next = nullptr;
- node->clearFlags(BaseNode::kFlagIsActive);
+ node->clearFlags(NodeFlags::kIsActive);
if (node->isSection())
_dirtySectionLinks = true;
@@ -319,7 +297,7 @@ void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
node->_prev = nullptr;
node->_next = nullptr;
- node->clearFlags(BaseNode::kFlagIsActive);
+ node->clearFlags(NodeFlags::kIsActive);
didRemoveSection |= uint32_t(node->isSection());
if (_cursor == node)
@@ -340,9 +318,8 @@ BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept {
return old;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Section]
-// ============================================================================
+// BaseBuilder - Sections
+// ======================
Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) {
*out = nullptr;
@@ -424,9 +401,8 @@ void BaseBuilder::updateSectionLinks() noexcept {
_dirtySectionLinks = false;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Labels]
-// ============================================================================
+// BaseBuilder - Labels
+// ====================
Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) {
*out = nullptr;
@@ -500,7 +476,7 @@ Label BaseBuilder::newLabel() {
return Label(labelId);
}
-Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) {
+Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
uint32_t labelId = Globals::kInvalidId;
LabelEntry* le;
@@ -521,9 +497,8 @@ Error BaseBuilder::bind(const Label& label) {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Passes]
-// ============================================================================
+// BaseBuilder - Passes
+// ====================
ASMJIT_FAVOR_SIZE Pass* BaseBuilder::passByName(const char* name) const noexcept {
for (Pass* pass : _passes)
@@ -603,21 +578,20 @@ Error BaseBuilder::runPasses() {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Emit]
-// ============================================================================
+// BaseBuilder - Emit
+// ==================
-Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt);
- uint32_t options = instOptions() | forcedInstOptions();
+ InstOptions options = instOptions() | forcedInstOptions();
- if (options & BaseInst::kOptionReserved) {
+ if (Support::test(options, InstOptions::kReserved)) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
#ifndef ASMJIT_NO_VALIDATION
// Strict validation.
- if (hasValidationOption(kValidationOptionIntermediate)) {
+ if (hasDiagnosticOption(DiagnosticOptions::kValidateIntermediate)) {
Operand_ opArray[Globals::kMaxOpCount];
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
@@ -631,8 +605,8 @@ Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1
}
#endif
- // Clear options that should never be part of `InstNode`.
- options &= ~BaseInst::kOptionReserved;
+ // Clear instruction options that should never be part of a regular instruction.
+ options &= ~InstOptions::kReserved;
}
uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
@@ -666,42 +640,40 @@ Error BaseBuilder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Align]
-// ============================================================================
+// BaseBuilder - Align
+// ===================
-Error BaseBuilder::align(uint32_t alignMode, uint32_t alignment) {
+Error BaseBuilder::align(AlignMode alignMode, uint32_t alignment) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
AlignNode* node;
- ASMJIT_PROPAGATE(_newAlignNode(&node, alignMode, alignment));
+ ASMJIT_PROPAGATE(newAlignNode(&node, alignMode, alignment));
addNode(node);
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Embed]
-// ============================================================================
+// BaseBuilder - Embed
+// ===================
Error BaseBuilder::embed(const void* data, size_t dataSize) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, data, dataSize));
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, data, dataSize));
addNode(node);
return kErrorOk;
}
-Error BaseBuilder::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t itemRepeat) {
+Error BaseBuilder::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t itemRepeat) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
addNode(node);
return kErrorOk;
@@ -714,23 +686,22 @@ Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
if (!isLabelValid(label))
return reportError(DebugUtils::errored(kErrorInvalidLabel));
- ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment())));
+ ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment())));
ASMJIT_PROPAGATE(bind(label));
EmbedDataNode* node;
- ASMJIT_PROPAGATE(_newEmbedDataNode(&node, Type::kIdU8, nullptr, pool.size()));
+ ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, nullptr, pool.size()));
pool.fill(node->data());
addNode(node);
return kErrorOk;
}
-// EmbedLabel / EmbedLabelDelta
-// ----------------------------
+// BaseBuilder - EmbedLabel & EmbedLabelDelta
+// ==========================================
//
-// If dataSize is zero it means that the size is the same as target register
-// width, however, if it's provided we really want to validate whether it's
-// within the possible range.
+// If dataSize is zero it means that the size is the same as target register width, however,
+// if it's provided we really want to validate whether it's within the possible range.
static inline bool BaseBuilder_checkDataSize(size_t dataSize) noexcept {
return !dataSize || (Support::isPowerOf2(dataSize) && dataSize <= 8);
@@ -764,24 +735,22 @@ Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Comment]
-// ============================================================================
+// BaseBuilder - Comment
+// =====================
Error BaseBuilder::comment(const char* data, size_t size) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
CommentNode* node;
- ASMJIT_PROPAGATE(_newCommentNode(&node, data, size));
+ ASMJIT_PROPAGATE(newCommentNode(&node, data, size));
addNode(node);
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Serialize]
-// ============================================================================
+// BaseBuilder - SerializeTo
+// =========================
Error BaseBuilder::serializeTo(BaseEmitter* dst) {
Error err = kErrorOk;
@@ -796,7 +765,7 @@ Error BaseBuilder::serializeTo(BaseEmitter* dst) {
InstNode* node = node_->as<InstNode>();
// NOTE: Inlined to remove one additional call per instruction.
- dst->setInstOptions(node->instOptions());
+ dst->setInstOptions(node->options());
dst->setExtraReg(node->extraReg());
const Operand_* op = node->operands();
@@ -862,9 +831,8 @@ Error BaseBuilder::serializeTo(BaseEmitter* dst) {
return err;
}
-// ============================================================================
-// [asmjit::BaseBuilder - Events]
-// ============================================================================
+// BaseBuilder - Events
+// ====================
Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
ASMJIT_PROPAGATE(Base::onAttach(code));
@@ -883,7 +851,7 @@ Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
_cursor = initialSection;
_firstNode = initialSection;
_lastNode = initialSection;
- initialSection->setFlags(BaseNode::kFlagIsActive);
+ initialSection->setFlags(NodeFlags::kIsActive);
return kErrorOk;
}
@@ -898,8 +866,7 @@ Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
_dataZone.reset();
_passZone.reset();
- _nodeFlags = 0;
-
+ _nodeFlags = NodeFlags::kNone;
_cursor = nullptr;
_firstNode = nullptr;
_lastNode = nullptr;
@@ -907,9 +874,8 @@ Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
return Base::onDetach(code);
}
-// ============================================================================
-// [asmjit::Pass - Construction / Destruction]
-// ============================================================================
+// Pass - Construction & Destruction
+// =================================
Pass::Pass(const char* name) noexcept
: _name(name) {}
diff --git a/src/asmjit/core/builder.h b/src/asmjit/core/builder.h
index 317bda1..545471d 100644
--- a/src/asmjit/core/builder.h
+++ b/src/asmjit/core/builder.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_BUILDER_H_INCLUDED
#define ASMJIT_CORE_BUILDER_H_INCLUDED
@@ -44,10 +26,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_builder
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class BaseBuilder;
class Pass;
@@ -63,21 +41,88 @@ class CommentNode;
class SentinelNode;
class LabelDeltaNode;
-// Only used by Compiler infrastructure.
-class JumpAnnotation;
+//! Type of node used by \ref BaseBuilder and \ref BaseCompiler.
+enum class NodeType : uint8_t {
+ //! Invalid node (internal, don't use).
+ kNone = 0,
+
+ // [BaseBuilder]
+
+ //! Node is \ref InstNode or \ref InstExNode.
+ kInst = 1,
+ //! Node is \ref SectionNode.
+ kSection = 2,
+ //! Node is \ref LabelNode.
+ kLabel = 3,
+ //! Node is \ref AlignNode.
+ kAlign = 4,
+ //! Node is \ref EmbedDataNode.
+ kEmbedData = 5,
+ //! Node is \ref EmbedLabelNode.
+ kEmbedLabel = 6,
+ //! Node is \ref EmbedLabelDeltaNode.
+ kEmbedLabelDelta = 7,
+ //! Node is \ref ConstPoolNode.
+ kConstPool = 8,
+ //! Node is \ref CommentNode.
+ kComment = 9,
+ //! Node is \ref SentinelNode.
+ kSentinel = 10,
+
+ // [BaseCompiler]
+
+ //! Node is \ref JumpNode (acts as InstNode).
+ kJump = 15,
+ //! Node is \ref FuncNode (acts as LabelNode).
+ kFunc = 16,
+ //! Node is \ref FuncRetNode (acts as InstNode).
+ kFuncRet = 17,
+ //! Node is \ref InvokeNode (acts as InstNode).
+ kInvoke = 18,
+
+ // [UserDefined]
+
+ //! First id of a user-defined node.
+ kUser = 32
+};
-// ============================================================================
-// [asmjit::BaseBuilder]
-// ============================================================================
+//! Node flags, specify what the node is and/or does.
+enum class NodeFlags : uint8_t {
+ //! No flags.
+ kNone = 0,
+ //! Node is code that can be executed (instruction, label, align, etc...).
+ kIsCode = 0x01u,
+ //! Node is data that cannot be executed (data, const-pool, etc...).
+ kIsData = 0x02u,
+ //! Node is informative, can be removed and ignored.
+ kIsInformative = 0x04u,
+ //! Node can be safely removed if unreachable.
+ kIsRemovable = 0x08u,
+ //! Node does nothing when executed (label, align, explicit nop).
+ kHasNoEffect = 0x10u,
+ //! Node is an instruction or acts as it.
+ kActsAsInst = 0x20u,
+ //! Node is a label or acts as it.
+ kActsAsLabel = 0x40u,
+ //! Node is active (part of the code).
+ kIsActive = 0x80u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(NodeFlags)
+
+//! Type of the sentinel (purery informative purpose).
+enum class SentinelType : uint8_t {
+ //! Type of the sentinel is not known.
+ kUnknown = 0u,
+ //! This is a sentinel used at the end of \ref FuncNode.
+ kFuncEnd = 1u
+};
//! Builder interface.
//!
-//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler
-//! replacement in case pre-processing or post-processing of the generated code
-//! is required. The code can be modified during or after code generation. Pre
-//! or post processing can be done manually or through a \ref Pass object. \ref
-//! BaseBuilder stores the emitted code as a double-linked list of nodes, which
-//! allows O(1) insertion and removal during processing.
+//! `BaseBuilder` interface was designed to be used as a \ref BaseAssembler replacement in case pre-processing or
+//! post-processing of the generated code is required. The code can be modified during or after code generation.
+//! Pre processing or post processing can be done manually or through a \ref Pass object. \ref BaseBuilder stores
+//! the emitted code as a double-linked list of nodes, which allows O(1) insertion and removal during processing.
//!
//! Check out architecture specific builders for more details and examples:
//!
@@ -87,6 +132,9 @@ public:
ASMJIT_NONCOPYABLE(BaseBuilder)
typedef BaseEmitter Base;
+ //! \name Members
+ //! \{
+
//! Base zone used to allocate nodes and passes.
Zone _codeZone;
//! Data zone used to allocate data and names.
@@ -111,10 +159,12 @@ public:
BaseNode* _lastNode = nullptr;
//! Flags assigned to each new node.
- uint32_t _nodeFlags = 0;
+ NodeFlags _nodeFlags = NodeFlags::kNone;
//! The sections links are dirty (used internally).
bool _dirtySectionLinks = false;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -133,14 +183,13 @@ public:
//! Returns the last node.
inline BaseNode* lastNode() const noexcept { return _lastNode; }
- //! Allocates and instantiates a new node of type `T` and returns its instance.
- //! If the allocation fails `nullptr` is returned.
+ //! Allocates and instantiates a new node of type `T` and returns its instance. If the allocation fails `nullptr`
+ //! is returned.
//!
//! The template argument `T` must be a type that is extends \ref BaseNode.
//!
- //! \remarks The pointer returned (if non-null) is owned by the Builder or
- //! Compiler. When the Builder/Compiler is destroyed it destroys all nodes
- //! it created so no manual memory management is required.
+ //! \remarks The pointer returned (if non-null) is owned by the Builder or Compiler. When the Builder/Compiler
+ //! is destroyed it destroys all nodes it created so no manual memory management is required.
template<typename T, typename... Args>
inline Error _newNodeT(T** out, Args&&... args) {
*out = _allocator.newT<T>(this, std::forward<Args>(args)...);
@@ -150,17 +199,17 @@ public:
}
//! Creates a new \ref InstNode.
- ASMJIT_API Error _newInstNode(InstNode** out, uint32_t instId, uint32_t instOptions, uint32_t opCount);
+ ASMJIT_API Error newInstNode(InstNode** out, InstId instId, InstOptions instOptions, uint32_t opCount);
//! Creates a new \ref LabelNode.
- ASMJIT_API Error _newLabelNode(LabelNode** out);
+ ASMJIT_API Error newLabelNode(LabelNode** out);
//! Creates a new \ref AlignNode.
- ASMJIT_API Error _newAlignNode(AlignNode** out, uint32_t alignMode, uint32_t alignment);
+ ASMJIT_API Error newAlignNode(AlignNode** out, AlignMode alignMode, uint32_t alignment);
//! Creates a new \ref EmbedDataNode.
- ASMJIT_API Error _newEmbedDataNode(EmbedDataNode** out, uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1);
+ ASMJIT_API Error newEmbedDataNode(EmbedDataNode** out, TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1);
//! Creates a new \ref ConstPoolNode.
- ASMJIT_API Error _newConstPoolNode(ConstPoolNode** out);
+ ASMJIT_API Error newConstPoolNode(ConstPoolNode** out);
//! Creates a new \ref CommentNode.
- ASMJIT_API Error _newCommentNode(CommentNode** out, const char* data, size_t size);
+ ASMJIT_API Error newCommentNode(CommentNode** out, const char* data, size_t size);
//! Adds `node` after the current and sets the current node to the given `node`.
ASMJIT_API BaseNode* addNode(BaseNode* node) noexcept;
@@ -175,11 +224,9 @@ public:
//! Returns the cursor.
//!
- //! When the Builder/Compiler is created it automatically creates a '.text'
- //! \ref SectionNode, which will be the initial one. When instructions are
- //! added they are always added after the cursor and the cursor is changed
- //! to be that newly added node. Use `setCursor()` to change where new nodes
- //! are inserted.
+ //! When the Builder/Compiler is created it automatically creates a '.text' \ref SectionNode, which will be the
+ //! initial one. When instructions are added they are always added after the cursor and the cursor is changed
+ //! to be that newly added node. Use `setCursor()` to change where new nodes are inserted.
inline BaseNode* cursor() const noexcept {
return _cursor;
}
@@ -189,8 +236,8 @@ public:
//! Sets the current node without returning the previous node.
//!
- //! Only use this function if you are concerned about performance and want
- //! this inlined (for example if you set the cursor in a loop, etc...).
+ //! Only use this function if you are concerned about performance and want this inlined (for example if you set
+ //! the cursor in a loop, etc...).
inline void _setCursor(BaseNode* node) noexcept {
_cursor = node;
}
@@ -202,8 +249,8 @@ public:
//! Returns a vector of SectionNode objects.
//!
- //! \note If a section of some id is not associated with the Builder/Compiler
- //! it would be null, so always check for nulls if you iterate over the vector.
+ //! \note If a section of some id is not associated with the Builder/Compiler it would be null, so always check
+ //! for nulls if you iterate over the vector.
inline const ZoneVector<SectionNode*>& sectionNodes() const noexcept {
return _sectionNodes;
}
@@ -215,15 +262,14 @@ public:
//! Returns or creates a `SectionNode` that matches the given `sectionId`.
//!
- //! \remarks This function will either get the existing `SectionNode` or create
- //! it in case it wasn't created before. You can check whether a section has a
- //! registered `SectionNode` by using `BaseBuilder::hasRegisteredSectionNode()`.
+ //! \remarks This function will either get the existing `SectionNode` or create it in case it wasn't created before.
+ //! You can check whether a section has a registered `SectionNode` by using `BaseBuilder::hasRegisteredSectionNode()`.
ASMJIT_API Error sectionNodeOf(SectionNode** out, uint32_t sectionId);
ASMJIT_API Error section(Section* section) override;
- //! Returns whether the section links of active section nodes are dirty. You can
- //! update these links by calling `updateSectionLinks()` in such case.
+ //! Returns whether the section links of active section nodes are dirty. You can update these links by calling
+ //! `updateSectionLinks()` in such case.
inline bool hasDirtySectionLinks() const noexcept { return _dirtySectionLinks; }
//! Updates links of all active section nodes.
@@ -236,8 +282,8 @@ public:
//! Returns a vector of \ref LabelNode nodes.
//!
- //! \note If a label of some id is not associated with the Builder/Compiler
- //! it would be null, so always check for nulls if you iterate over the vector.
+ //! \note If a label of some id is not associated with the Builder/Compiler it would be null, so always check for
+ //! nulls if you iterate over the vector.
inline const ZoneVector<LabelNode*>& labelNodes() const noexcept { return _labelNodes; }
//! Tests whether the `LabelNode` of the given `labelId` was registered.
@@ -252,9 +298,8 @@ public:
//! Gets or creates a \ref LabelNode that matches the given `labelId`.
//!
- //! \remarks This function will either get the existing `LabelNode` or create
- //! it in case it wasn't created before. You can check whether a label has a
- //! registered `LabelNode` by calling \ref BaseBuilder::hasRegisteredLabelNode().
+ //! \remarks This function will either get the existing `LabelNode` or create it in case it wasn't created before.
+ //! You can check whether a label has a registered `LabelNode` by calling \ref BaseBuilder::hasRegisteredLabelNode().
ASMJIT_API Error labelNodeOf(LabelNode** out, uint32_t labelId);
//! \overload
@@ -264,13 +309,12 @@ public:
//! Registers this \ref LabelNode (internal).
//!
- //! This function is used internally to register a newly created `LabelNode`
- //! with this instance of Builder/Compiler. Use \ref labelNodeOf() functions
- //! to get back \ref LabelNode from a label or its identifier.
+ //! This function is used internally to register a newly created `LabelNode` with this instance of Builder/Compiler.
+ //! Use \ref labelNodeOf() functions to get back \ref LabelNode from a label or its identifier.
ASMJIT_API Error registerLabelNode(LabelNode* node);
ASMJIT_API Label newLabel() override;
- ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override;
+ ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) override;
ASMJIT_API Error bind(const Label& label) override;
//! \}
@@ -281,14 +325,13 @@ public:
//! Returns a vector of `Pass` instances that will be executed by `runPasses()`.
inline const ZoneVector<Pass*>& passes() const noexcept { return _passes; }
- //! Allocates and instantiates a new pass of type `T` and returns its instance.
- //! If the allocation fails `nullptr` is returned.
+ //! Allocates and instantiates a new pass of type `T` and returns its instance. If the allocation fails `nullptr` is
+ //! returned.
//!
//! The template argument `T` must be a type that is extends \ref Pass.
//!
- //! \remarks The pointer returned (if non-null) is owned by the Builder or
- //! Compiler. When the Builder/Compiler is destroyed it destroys all passes
- //! it created so no manual memory management is required.
+ //! \remarks The pointer returned (if non-null) is owned by the Builder or Compiler. When the Builder/Compiler is
+ //! destroyed it destroys all passes it created so no manual memory management is required.
template<typename T>
inline T* newPassT() noexcept { return _codeZone.newT<T>(); }
@@ -319,14 +362,14 @@ public:
//! \name Emit
//! \{
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
+ ASMJIT_API Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
//! \}
//! \name Align
//! \{
- ASMJIT_API Error align(uint32_t alignMode, uint32_t alignment) override;
+ ASMJIT_API Error align(AlignMode alignMode, uint32_t alignment) override;
//! \}
@@ -334,7 +377,7 @@ public:
//! \{
ASMJIT_API Error embed(const void* data, size_t dataSize) override;
- ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t count, size_t repeat = 1) override;
+ ASMJIT_API Error embedDataArray(TypeId typeId, const void* data, size_t count, size_t repeat = 1) override;
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override;
@@ -354,9 +397,8 @@ public:
//! Serializes everything the given emitter `dst`.
//!
- //! Although not explicitly required the emitter will most probably be of
- //! Assembler type. The reason is that there is no known use of serializing
- //! nodes held by Builder/Compiler into another Builder-like emitter.
+ //! Although not explicitly required the emitter will most probably be of Assembler type. The reason is that
+ //! there is no known use of serializing nodes held by Builder/Compiler into another Builder-like emitter.
ASMJIT_API Error serializeTo(BaseEmitter* dst);
//! \}
@@ -368,37 +410,21 @@ public:
ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use serializeTo() instead, serialize() is now also an instruction.")
- inline Error serialize(BaseEmitter* dst) {
- return serializeTo(dst);
- }
-
-#ifndef ASMJIT_NO_LOGGING
- ASMJIT_DEPRECATED("Use Formatter::formatNodeList(sb, formatFlags, builder)")
- inline Error dump(String& sb, uint32_t formatFlags = 0) const noexcept {
- return Formatter::formatNodeList(sb, formatFlags, this);
- }
-#endif // !ASMJIT_NO_LOGGING
-#endif // !ASMJIT_NO_DEPRECATED
};
-// ============================================================================
-// [asmjit::BaseNode]
-// ============================================================================
-
//! Base node.
//!
-//! Every node represents a building-block used by \ref BaseBuilder. It can
-//! be instruction, data, label, comment, directive, or any other high-level
-//! representation that can be transformed to the building blocks mentioned.
-//! Every class that inherits \ref BaseBuilder can define its own high-level
-//! nodes that can be later lowered to basic nodes like instructions.
+//! Every node represents a building-block used by \ref BaseBuilder. It can be instruction, data, label, comment,
+//! directive, or any other high-level representation that can be transformed to the building blocks mentioned.
+//! Every class that inherits \ref BaseBuilder can define its own high-level nodes that can be later lowered to
+//! basic nodes like instructions.
class BaseNode {
public:
ASMJIT_NONCOPYABLE(BaseNode)
+ //! \name Members
+ //! \{
+
union {
struct {
//! Previous node.
@@ -412,22 +438,34 @@ public:
//! Data shared between all types of nodes.
struct AnyData {
- //! Node type, see \ref NodeType.
- uint8_t _nodeType;
- //! Node flags, see \ref Flags.
- uint8_t _nodeFlags;
+ //! Node type.
+ NodeType _nodeType;
+ //! Node flags.
+ NodeFlags _nodeFlags;
//! Not used by BaseNode.
uint8_t _reserved0;
//! Not used by BaseNode.
uint8_t _reserved1;
};
+ //! Data used by \ref AlignNode.
+ struct AlignData {
+ //! Node type.
+ NodeType _nodeType;
+ //! Node flags.
+ NodeFlags _nodeFlags;
+ //! Align mode.
+ AlignMode _alignMode;
+ //! Not used by AlignNode.
+ uint8_t _reserved;
+ };
+
//! Data used by \ref InstNode.
struct InstData {
- //! Node type, see \ref NodeType.
- uint8_t _nodeType;
- //! Node flags, see \ref Flags.
- uint8_t _nodeFlags;
+ //! Node type.
+ NodeType _nodeType;
+ //! Node flags.
+ NodeFlags _nodeFlags;
//! Instruction operands count (used).
uint8_t _opCount;
//! Instruction operands capacity (allocated).
@@ -436,24 +474,24 @@ public:
//! Data used by \ref EmbedDataNode.
struct EmbedData {
- //! Node type, see \ref NodeType.
- uint8_t _nodeType;
- //! Node flags, see \ref Flags.
- uint8_t _nodeFlags;
- //! Type id, see \ref Type::Id.
- uint8_t _typeId;
+ //! Node type.
+ NodeType _nodeType;
+ //! Node flags.
+ NodeFlags _nodeFlags;
+ //! Type id.
+ TypeId _typeId;
//! Size of `_typeId`.
uint8_t _typeSize;
};
//! Data used by \ref SentinelNode.
struct SentinelData {
- //! Node type, see \ref NodeType.
- uint8_t _nodeType;
- //! Node flags, see \ref Flags.
- uint8_t _nodeFlags;
+ //! Node type.
+ NodeType _nodeType;
+ //! Node flags.
+ NodeFlags _nodeFlags;
//! Sentinel type.
- uint8_t _sentinelType;
+ SentinelType _sentinelType;
//! Not used by BaseNode.
uint8_t _reserved1;
};
@@ -462,6 +500,8 @@ public:
union {
//! Data useful by any node type.
AnyData _any;
+ //! Data specific to \ref AlignNode.
+ AlignData _alignData;
//! Data specific to \ref InstNode.
InstData _inst;
//! Data specific to \ref EmbedDataNode.
@@ -487,84 +527,17 @@ public:
//! Inline comment/annotation or nullptr if not used.
const char* _inlineComment;
- //! Type of `BaseNode`.
- enum NodeType : uint32_t {
- //! Invalid node (internal, don't use).
- kNodeNone = 0,
-
- // [BaseBuilder]
-
- //! Node is \ref InstNode or \ref InstExNode.
- kNodeInst = 1,
- //! Node is \ref SectionNode.
- kNodeSection = 2,
- //! Node is \ref LabelNode.
- kNodeLabel = 3,
- //! Node is \ref AlignNode.
- kNodeAlign = 4,
- //! Node is \ref EmbedDataNode.
- kNodeEmbedData = 5,
- //! Node is \ref EmbedLabelNode.
- kNodeEmbedLabel = 6,
- //! Node is \ref EmbedLabelDeltaNode.
- kNodeEmbedLabelDelta = 7,
- //! Node is \ref ConstPoolNode.
- kNodeConstPool = 8,
- //! Node is \ref CommentNode.
- kNodeComment = 9,
- //! Node is \ref SentinelNode.
- kNodeSentinel = 10,
-
- // [BaseCompiler]
-
- //! Node is \ref JumpNode (acts as InstNode).
- kNodeJump = 15,
- //! Node is \ref FuncNode (acts as LabelNode).
- kNodeFunc = 16,
- //! Node is \ref FuncRetNode (acts as InstNode).
- kNodeFuncRet = 17,
- //! Node is \ref InvokeNode (acts as InstNode).
- kNodeInvoke = 18,
-
- // [UserDefined]
-
- //! First id of a user-defined node.
- kNodeUser = 32,
-
-#ifndef ASMJIT_NO_DEPRECATED
- kNodeFuncCall = kNodeInvoke
-#endif // !ASMJIT_NO_DEPRECATED
- };
-
- //! Node flags, specify what the node is and/or does.
- enum Flags : uint32_t {
- //! Node is code that can be executed (instruction, label, align, etc...).
- kFlagIsCode = 0x01u,
- //! Node is data that cannot be executed (data, const-pool, etc...).
- kFlagIsData = 0x02u,
- //! Node is informative, can be removed and ignored.
- kFlagIsInformative = 0x04u,
- //! Node can be safely removed if unreachable.
- kFlagIsRemovable = 0x08u,
- //! Node does nothing when executed (label, align, explicit nop).
- kFlagHasNoEffect = 0x10u,
- //! Node is an instruction or acts as it.
- kFlagActsAsInst = 0x20u,
- //! Node is a label or acts as it.
- kFlagActsAsLabel = 0x40u,
- //! Node is active (part of the code).
- kFlagIsActive = 0x80u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
//! Creates a new `BaseNode` - always use `BaseBuilder` to allocate nodes.
- ASMJIT_INLINE BaseNode(BaseBuilder* cb, uint32_t type, uint32_t flags = 0) noexcept {
+ inline BaseNode(BaseBuilder* cb, NodeType nodeType, NodeFlags nodeFlags = NodeFlags::kNone) noexcept {
_prev = nullptr;
_next = nullptr;
- _any._nodeType = uint8_t(type);
- _any._nodeFlags = uint8_t(flags | cb->_nodeFlags);
+ _any._nodeType = nodeType;
+ _any._nodeFlags = nodeFlags | cb->_nodeFlags;
_any._reserved0 = 0;
_any._reserved1 = 0;
_position = 0;
@@ -593,71 +566,65 @@ public:
inline BaseNode* next() const noexcept { return _next; }
//! Returns the type of the node, see `NodeType`.
- inline uint32_t type() const noexcept { return _any._nodeType; }
+ inline NodeType type() const noexcept { return _any._nodeType; }
//! Sets the type of the node, see `NodeType` (internal).
//!
- //! \remarks You should never set a type of a node to anything else than the
- //! initial value. This function is only provided for users that use custom
- //! nodes and need to change the type either during construction or later.
- inline void setType(uint32_t type) noexcept { _any._nodeType = uint8_t(type); }
+ //! \remarks You should never set a type of a node to anything else than the initial value. This function is only
+ //! provided for users that use custom nodes and need to change the type either during construction or later.
+ inline void setType(NodeType type) noexcept { _any._nodeType = type; }
//! Tests whether this node is either `InstNode` or extends it.
- inline bool isInst() const noexcept { return hasFlag(kFlagActsAsInst); }
+ inline bool isInst() const noexcept { return hasFlag(NodeFlags::kActsAsInst); }
//! Tests whether this node is `SectionNode`.
- inline bool isSection() const noexcept { return type() == kNodeSection; }
+ inline bool isSection() const noexcept { return type() == NodeType::kSection; }
//! Tests whether this node is either `LabelNode` or extends it.
- inline bool isLabel() const noexcept { return hasFlag(kFlagActsAsLabel); }
+ inline bool isLabel() const noexcept { return hasFlag(NodeFlags::kActsAsLabel); }
//! Tests whether this node is `AlignNode`.
- inline bool isAlign() const noexcept { return type() == kNodeAlign; }
+ inline bool isAlign() const noexcept { return type() == NodeType::kAlign; }
//! Tests whether this node is `EmbedDataNode`.
- inline bool isEmbedData() const noexcept { return type() == kNodeEmbedData; }
+ inline bool isEmbedData() const noexcept { return type() == NodeType::kEmbedData; }
//! Tests whether this node is `EmbedLabelNode`.
- inline bool isEmbedLabel() const noexcept { return type() == kNodeEmbedLabel; }
+ inline bool isEmbedLabel() const noexcept { return type() == NodeType::kEmbedLabel; }
//! Tests whether this node is `EmbedLabelDeltaNode`.
- inline bool isEmbedLabelDelta() const noexcept { return type() == kNodeEmbedLabelDelta; }
+ inline bool isEmbedLabelDelta() const noexcept { return type() == NodeType::kEmbedLabelDelta; }
//! Tests whether this node is `ConstPoolNode`.
- inline bool isConstPool() const noexcept { return type() == kNodeConstPool; }
+ inline bool isConstPool() const noexcept { return type() == NodeType::kConstPool; }
//! Tests whether this node is `CommentNode`.
- inline bool isComment() const noexcept { return type() == kNodeComment; }
+ inline bool isComment() const noexcept { return type() == NodeType::kComment; }
//! Tests whether this node is `SentinelNode`.
- inline bool isSentinel() const noexcept { return type() == kNodeSentinel; }
+ inline bool isSentinel() const noexcept { return type() == NodeType::kSentinel; }
//! Tests whether this node is `FuncNode`.
- inline bool isFunc() const noexcept { return type() == kNodeFunc; }
+ inline bool isFunc() const noexcept { return type() == NodeType::kFunc; }
//! Tests whether this node is `FuncRetNode`.
- inline bool isFuncRet() const noexcept { return type() == kNodeFuncRet; }
+ inline bool isFuncRet() const noexcept { return type() == NodeType::kFuncRet; }
//! Tests whether this node is `InvokeNode`.
- inline bool isInvoke() const noexcept { return type() == kNodeInvoke; }
+ inline bool isInvoke() const noexcept { return type() == NodeType::kInvoke; }
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use isInvoke")
- inline bool isFuncCall() const noexcept { return isInvoke(); }
-#endif // !ASMJIT_NO_DEPRECATED
-
- //! Returns the node flags, see \ref Flags.
- inline uint32_t flags() const noexcept { return _any._nodeFlags; }
+ //! Returns the node flags.
+ inline NodeFlags flags() const noexcept { return _any._nodeFlags; }
//! Tests whether the node has the given `flag` set.
- inline bool hasFlag(uint32_t flag) const noexcept { return (uint32_t(_any._nodeFlags) & flag) != 0; }
+ inline bool hasFlag(NodeFlags flag) const noexcept { return Support::test(_any._nodeFlags, flag); }
//! Replaces node flags with `flags`.
- inline void setFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(flags); }
+ inline void setFlags(NodeFlags flags) noexcept { _any._nodeFlags = flags; }
//! Adds the given `flags` to node flags.
- inline void addFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(_any._nodeFlags | flags); }
+ inline void addFlags(NodeFlags flags) noexcept { _any._nodeFlags |= flags; }
//! Clears the given `flags` from node flags.
- inline void clearFlags(uint32_t flags) noexcept { _any._nodeFlags = uint8_t(_any._nodeFlags & (flags ^ 0xFF)); }
+ inline void clearFlags(NodeFlags flags) noexcept { _any._nodeFlags &= ~flags; }
//! Tests whether the node is code that can be executed.
- inline bool isCode() const noexcept { return hasFlag(kFlagIsCode); }
+ inline bool isCode() const noexcept { return hasFlag(NodeFlags::kIsCode); }
//! Tests whether the node is data that cannot be executed.
- inline bool isData() const noexcept { return hasFlag(kFlagIsData); }
+ inline bool isData() const noexcept { return hasFlag(NodeFlags::kIsData); }
//! Tests whether the node is informative only (is never encoded like comment, etc...).
- inline bool isInformative() const noexcept { return hasFlag(kFlagIsInformative); }
+ inline bool isInformative() const noexcept { return hasFlag(NodeFlags::kIsInformative); }
//! Tests whether the node is removable if it's in an unreachable code block.
- inline bool isRemovable() const noexcept { return hasFlag(kFlagIsRemovable); }
+ inline bool isRemovable() const noexcept { return hasFlag(NodeFlags::kIsRemovable); }
//! Tests whether the node has no effect when executed (label, .align, nop, ...).
- inline bool hasNoEffect() const noexcept { return hasFlag(kFlagHasNoEffect); }
+ inline bool hasNoEffect() const noexcept { return hasFlag(NodeFlags::kHasNoEffect); }
//! Tests whether the node is part of the code.
- inline bool isActive() const noexcept { return hasFlag(kFlagIsActive); }
+ inline bool isActive() const noexcept { return hasFlag(NodeFlags::kIsActive); }
//! Tests whether the node has a position assigned.
//!
@@ -667,20 +634,18 @@ public:
inline uint32_t position() const noexcept { return _position; }
//! Sets node position.
//!
- //! Node position is a 32-bit unsigned integer that is used by Compiler to
- //! track where the node is relatively to the start of the function. It doesn't
- //! describe a byte position in a binary, instead it's just a pseudo position
+ //! Node position is a 32-bit unsigned integer that is used by Compiler to track where the node is relatively to
+ //! the start of the function. It doesn't describe a byte position in a binary, instead it's just a pseudo position
//! used by liveness analysis and other tools around Compiler.
//!
- //! If you don't use Compiler then you may use `position()` and `setPosition()`
- //! freely for your own purposes if the 32-bit value limit is okay for you.
+ //! If you don't use Compiler then you may use `position()` and `setPosition()` freely for your own purposes if
+ //! the 32-bit value limit is okay for you.
inline void setPosition(uint32_t position) noexcept { _position = position; }
//! Returns user data casted to `T*`.
//!
- //! User data is decicated to be used only by AsmJit users and not touched
- //! by the library. The data has a pointer size so you can either store a
- //! pointer or `intptr_t` value through `setUserDataAsIntPtr()`.
+ //! User data is decicated to be used only by AsmJit users and not touched by the library. The data has a pointer
+ //! size so you can either store a pointer or `intptr_t` value through `setUserDataAsIntPtr()`.
template<typename T>
inline T* userDataAsPtr() const noexcept { return static_cast<T*>(_userDataPtr); }
//! Returns user data casted to `int64_t`.
@@ -722,10 +687,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::InstNode]
-// ============================================================================
-
//! Instruction node.
//!
//! Wraps an instruction with its options and operands.
@@ -733,25 +694,34 @@ class InstNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(InstNode)
+ //! \name Constants
+ //! \{
+
enum : uint32_t {
- //! Count of embedded operands per `InstNode` that are always allocated as
- //! a part of the instruction. Minimum embedded operands is 4, but in 32-bit
- //! more pointers are smaller and we can embed 5. The rest (up to 6 operands)
+ //! Count of embedded operands per `InstNode` that are always allocated as a part of the instruction. Minimum
+ //! embedded operands is 4, but in 32-bit more pointers are smaller and we can embed 5. The rest (up to 6 operands)
//! is always stored in `InstExNode`.
kBaseOpCapacity = uint32_t((128 - sizeof(BaseNode) - sizeof(BaseInst)) / sizeof(Operand_))
};
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! Base instruction data.
BaseInst _baseInst;
//! First 4 or 5 operands (indexed from 0).
Operand_ _opArray[kBaseOpCapacity];
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `InstNode` instance.
- ASMJIT_INLINE InstNode(BaseBuilder* cb, uint32_t instId, uint32_t options, uint32_t opCount, uint32_t opCapacity = kBaseOpCapacity) noexcept
- : BaseNode(cb, kNodeInst, kFlagIsCode | kFlagIsRemovable | kFlagActsAsInst),
+ inline InstNode(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCount, uint32_t opCapacity = kBaseOpCapacity) noexcept
+ : BaseNode(cb, NodeType::kInst, NodeFlags::kIsCode | NodeFlags::kIsRemovable | NodeFlags::kActsAsInst),
_baseInst(instId, options) {
_inst._opCapacity = uint8_t(opCapacity);
_inst._opCount = uint8_t(opCount);
@@ -767,25 +737,38 @@ public:
//! \}
- //! \name Accessors
+ //! \name Instruction Object
//! \{
inline BaseInst& baseInst() noexcept { return _baseInst; }
inline const BaseInst& baseInst() const noexcept { return _baseInst; }
+ //! \}
+
+ //! \name Instruction Id
+ //! \{
+
//! Returns the instruction id, see `BaseInst::Id`.
- inline uint32_t id() const noexcept { return _baseInst.id(); }
+ inline InstId id() const noexcept { return _baseInst.id(); }
//! Sets the instruction id to `id`, see `BaseInst::Id`.
- inline void setId(uint32_t id) noexcept { _baseInst.setId(id); }
+ inline void setId(InstId id) noexcept { _baseInst.setId(id); }
+
+ //! \}
- //! Returns instruction options.
- inline uint32_t instOptions() const noexcept { return _baseInst.options(); }
- //! Sets instruction options.
- inline void setInstOptions(uint32_t options) noexcept { _baseInst.setOptions(options); }
- //! Adds instruction options.
- inline void addInstOptions(uint32_t options) noexcept { _baseInst.addOptions(options); }
- //! Clears instruction options.
- inline void clearInstOptions(uint32_t options) noexcept { _baseInst.clearOptions(options); }
+ //! \name Instruction Options
+ //! \{
+
+ inline InstOptions options() const noexcept { return _baseInst.options(); }
+ inline bool hasOption(InstOptions option) const noexcept { return _baseInst.hasOption(option); }
+ inline void setOptions(InstOptions options) noexcept { _baseInst.setOptions(options); }
+ inline void addOptions(InstOptions options) noexcept { _baseInst.addOptions(options); }
+ inline void clearOptions(InstOptions options) noexcept { _baseInst.clearOptions(options); }
+ inline void resetOptions() noexcept { _baseInst.resetOptions(); }
+
+ //! \}
+
+ //! \name Extra Register
+ //! \{
//! Tests whether the node has an extra register operand.
inline bool hasExtraReg() const noexcept { return _baseInst.hasExtraReg(); }
@@ -800,6 +783,11 @@ public:
//! Resets extra register operand.
inline void resetExtraReg() noexcept { _baseInst.resetExtraReg(); }
+ //! \}
+
+ //! \name Instruction Operands
+ //! \{
+
//! Returns operand count.
inline uint32_t opCount() const noexcept { return _inst._opCount; }
//! Returns operand capacity.
@@ -848,19 +836,19 @@ public:
//! \name Utilities
//! \{
- inline bool hasOpType(uint32_t opType) const noexcept {
+ inline bool hasOpType(OperandType opType) const noexcept {
for (uint32_t i = 0, count = opCount(); i < count; i++)
if (_opArray[i].opType() == opType)
return true;
return false;
}
- inline bool hasRegOp() const noexcept { return hasOpType(Operand::kOpReg); }
- inline bool hasMemOp() const noexcept { return hasOpType(Operand::kOpMem); }
- inline bool hasImmOp() const noexcept { return hasOpType(Operand::kOpImm); }
- inline bool hasLabelOp() const noexcept { return hasOpType(Operand::kOpLabel); }
+ inline bool hasRegOp() const noexcept { return hasOpType(OperandType::kReg); }
+ inline bool hasMemOp() const noexcept { return hasOpType(OperandType::kMem); }
+ inline bool hasImmOp() const noexcept { return hasOpType(OperandType::kImm); }
+ inline bool hasLabelOp() const noexcept { return hasOpType(OperandType::kLabel); }
- inline uint32_t indexOfOpType(uint32_t opType) const noexcept {
+ inline uint32_t indexOfOpType(OperandType opType) const noexcept {
uint32_t i = 0;
uint32_t count = opCount();
@@ -873,9 +861,9 @@ public:
return i;
}
- inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(Operand::kOpMem); }
- inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(Operand::kOpImm); }
- inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(Operand::kOpLabel); }
+ inline uint32_t indexOfMemOp() const noexcept { return indexOfOpType(OperandType::kMem); }
+ inline uint32_t indexOfImmOp() const noexcept { return indexOfOpType(OperandType::kImm); }
+ inline uint32_t indexOfLabelOp() const noexcept { return indexOfOpType(OperandType::kLabel); }
//! \}
@@ -886,7 +874,7 @@ public:
inline uint32_t* _getRewriteArray() noexcept { return &_baseInst._extraReg._id; }
inline const uint32_t* _getRewriteArray() const noexcept { return &_baseInst._extraReg._id; }
- ASMJIT_INLINE uint32_t getRewriteIndex(const uint32_t* id) const noexcept {
+ inline uint32_t getRewriteIndex(const uint32_t* id) const noexcept {
const uint32_t* array = _getRewriteArray();
ASMJIT_ASSERT(array <= id);
@@ -896,7 +884,7 @@ public:
return uint32_t(index);
}
- ASMJIT_INLINE void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept {
+ inline void rewriteIdAtIndex(uint32_t index, uint32_t id) noexcept {
uint32_t* array = _getRewriteArray();
array[index] = id;
}
@@ -921,58 +909,59 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::InstExNode]
-// ============================================================================
-
//! Instruction node with maximum number of operands.
//!
-//! This node is created automatically by Builder/Compiler in case that the
-//! required number of operands exceeds the default capacity of `InstNode`.
+//! This node is created automatically by Builder/Compiler in case that the required number of operands exceeds
+//! the default capacity of `InstNode`.
class InstExNode : public InstNode {
public:
ASMJIT_NONCOPYABLE(InstExNode)
+ //! \name Members
+ //! \{
+
//! Continued `_opArray[]` to hold up to `kMaxOpCount` operands.
Operand_ _opArrayEx[Globals::kMaxOpCount - kBaseOpCapacity];
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `InstExNode` instance.
- inline InstExNode(BaseBuilder* cb, uint32_t instId, uint32_t options, uint32_t opCapacity = Globals::kMaxOpCount) noexcept
+ inline InstExNode(BaseBuilder* cb, InstId instId, InstOptions options, uint32_t opCapacity = Globals::kMaxOpCount) noexcept
: InstNode(cb, instId, options, opCapacity) {}
//! \}
};
-// ============================================================================
-// [asmjit::SectionNode]
-// ============================================================================
-
//! Section node.
class SectionNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(SectionNode)
+ //! \name Members
+ //! \{
+
//! Section id.
uint32_t _id;
//! Next section node that follows this section.
//!
- //! This link is only valid when the section is active (is part of the code)
- //! and when `Builder::hasDirtySectionLinks()` returns `false`. If you intend
- //! to use this field you should always call `Builder::updateSectionLinks()`
- //! before you do so.
+ //! This link is only valid when the section is active (is part of the code) and when `Builder::hasDirtySectionLinks()`
+ //! returns `false`. If you intend to use this field you should always call `Builder::updateSectionLinks()` before you
+ //! do so.
SectionNode* _nextSection;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `SectionNode` instance.
- inline SectionNode(BaseBuilder* cb, uint32_t id = 0) noexcept
- : BaseNode(cb, kNodeSection, kFlagHasNoEffect),
- _id(id),
+ inline SectionNode(BaseBuilder* cb, uint32_t secionId = 0) noexcept
+ : BaseNode(cb, NodeType::kSection, NodeFlags::kHasNoEffect),
+ _id(secionId),
_nextSection(nullptr) {}
//! \}
@@ -986,24 +975,25 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::LabelNode]
-// ============================================================================
-
//! Label node.
class LabelNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(LabelNode)
+ //! \name Members
+ //! \{
+
//! Label identifier.
uint32_t _labelId;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `LabelNode` instance.
inline LabelNode(BaseBuilder* cb, uint32_t labelId = 0) noexcept
- : BaseNode(cb, kNodeLabel, kFlagHasNoEffect | kFlagActsAsLabel),
+ : BaseNode(cb, NodeType::kLabel, NodeFlags::kHasNoEffect | NodeFlags::kActsAsLabel),
_labelId(labelId) {}
//! \}
@@ -1017,17 +1007,8 @@ public:
inline uint32_t labelId() const noexcept { return _labelId; }
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use labelId() instead")
- inline uint32_t id() const noexcept { return labelId(); }
-#endif // !ASMJIT_NO_DEPRECATED
};
-// ============================================================================
-// [asmjit::AlignNode]
-// ============================================================================
-
//! Align directive (BaseBuilder).
//!
//! Wraps `.align` directive.
@@ -1035,19 +1016,24 @@ class AlignNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(AlignNode)
- //! Align mode, see `AlignMode`.
- uint32_t _alignMode;
+ //! \name Members
+ //! \{
+
//! Alignment (in bytes).
uint32_t _alignment;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `AlignNode` instance.
- inline AlignNode(BaseBuilder* cb, uint32_t alignMode, uint32_t alignment) noexcept
- : BaseNode(cb, kNodeAlign, kFlagIsCode | kFlagHasNoEffect),
- _alignMode(alignMode),
- _alignment(alignment) {}
+ inline AlignNode(BaseBuilder* cb, AlignMode alignMode, uint32_t alignment) noexcept
+ : BaseNode(cb, NodeType::kAlign, NodeFlags::kIsCode | NodeFlags::kHasNoEffect) {
+
+ _alignData._alignMode = alignMode;
+ _alignment = alignment;
+ }
//! \}
@@ -1055,9 +1041,9 @@ public:
//! \{
//! Returns align mode.
- inline uint32_t alignMode() const noexcept { return _alignMode; }
+ inline AlignMode alignMode() const noexcept { return _alignData._alignMode; }
//! Sets align mode to `alignMode`.
- inline void setAlignMode(uint32_t alignMode) noexcept { _alignMode = alignMode; }
+ inline void setAlignMode(AlignMode alignMode) noexcept { _alignData._alignMode = alignMode; }
//! Returns align offset in bytes.
inline uint32_t alignment() const noexcept { return _alignment; }
@@ -1067,22 +1053,22 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::EmbedDataNode]
-// ============================================================================
-
//! Embed data node.
//!
-//! Wraps `.data` directive. The node contains data that will be placed at the
-//! node's position in the assembler stream. The data is considered to be RAW;
-//! no analysis nor byte-order conversion is performed on RAW data.
+//! Wraps `.data` directive. The node contains data that will be placed at the node's position in the assembler
+//! stream. The data is considered to be RAW; no analysis nor byte-order conversion is performed on RAW data.
class EmbedDataNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(EmbedDataNode)
+ //! \cond INTERNAL
enum : uint32_t {
kInlineBufferSize = 128 - (sizeof(BaseNode) + sizeof(size_t) * 2)
};
+ //! \endcond
+
+ //! \name Members
+ //! \{
size_t _itemCount;
size_t _repeatCount;
@@ -1092,15 +1078,17 @@ public:
uint8_t _inlineData[kInlineBufferSize];
};
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedDataNode` instance.
inline EmbedDataNode(BaseBuilder* cb) noexcept
- : BaseNode(cb, kNodeEmbedData, kFlagIsData),
+ : BaseNode(cb, NodeType::kEmbedData, NodeFlags::kIsData),
_itemCount(0),
_repeatCount(0) {
- _embed._typeId = uint8_t(Type::kIdU8),
+ _embed._typeId = TypeId::kUInt8;
_embed._typeSize = uint8_t(1);
memset(_inlineData, 0, kInlineBufferSize);
}
@@ -1110,8 +1098,8 @@ public:
//! \name Accessors
//! \{
- //! Returns \ref Type::Id of the data.
- inline uint32_t typeId() const noexcept { return _embed._typeId; }
+ //! Returns data type as \ref TypeId.
+ inline TypeId typeId() const noexcept { return _embed._typeId; }
//! Returns the size of a single data element.
inline uint32_t typeSize() const noexcept { return _embed._typeSize; }
@@ -1140,24 +1128,25 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::EmbedLabelNode]
-// ============================================================================
-
//! Label data node.
class EmbedLabelNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(EmbedLabelNode)
+ //! \name Members
+ //! \{
+
uint32_t _labelId;
uint32_t _dataSize;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedLabelNode` instance.
inline EmbedLabelNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t dataSize = 0) noexcept
- : BaseNode(cb, kNodeEmbedLabel, kFlagIsData),
+ : BaseNode(cb, NodeType::kEmbedLabel, NodeFlags::kIsData),
_labelId(labelId),
_dataSize(dataSize) {}
@@ -1182,32 +1171,28 @@ public:
inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use labelId() instead")
- inline uint32_t id() const noexcept { return labelId(); }
-#endif // !ASMJIT_NO_DEPRECATED
};
-// ============================================================================
-// [asmjit::EmbedLabelDeltaNode]
-// ============================================================================
-
//! Label data node.
class EmbedLabelDeltaNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(EmbedLabelDeltaNode)
+ //! \name Members
+ //! \{
+
uint32_t _labelId;
uint32_t _baseLabelId;
uint32_t _dataSize;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `EmbedLabelDeltaNode` instance.
inline EmbedLabelDeltaNode(BaseBuilder* cb, uint32_t labelId = 0, uint32_t baseLabelId = 0, uint32_t dataSize = 0) noexcept
- : BaseNode(cb, kNodeEmbedLabelDelta, kFlagIsData),
+ : BaseNode(cb, NodeType::kEmbedLabelDelta, NodeFlags::kIsData),
_labelId(labelId),
_baseLabelId(baseLabelId),
_dataSize(dataSize) {}
@@ -1243,33 +1228,20 @@ public:
inline void setDataSize(uint32_t dataSize) noexcept { _dataSize = dataSize; }
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use labelId() instead")
- inline uint32_t id() const noexcept { return labelId(); }
-
- ASMJIT_DEPRECATED("Use setLabelId() instead")
- inline void setId(uint32_t id) noexcept { setLabelId(id); }
-
- ASMJIT_DEPRECATED("Use baseLabelId() instead")
- inline uint32_t baseId() const noexcept { return baseLabelId(); }
-
- ASMJIT_DEPRECATED("Use setBaseLabelId() instead")
- inline void setBaseId(uint32_t id) noexcept { setBaseLabelId(id); }
-#endif // !ASMJIT_NO_DEPRECATED
};
-// ============================================================================
-// [asmjit::ConstPoolNode]
-// ============================================================================
-
//! A node that wraps `ConstPool`.
class ConstPoolNode : public LabelNode {
public:
ASMJIT_NONCOPYABLE(ConstPoolNode)
+ //! \name Members
+ //! \{
+
ConstPool _constPool;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -1278,9 +1250,9 @@ public:
: LabelNode(cb, id),
_constPool(&cb->_codeZone) {
- setType(kNodeConstPool);
- addFlags(kFlagIsData);
- clearFlags(kFlagIsCode | kFlagHasNoEffect);
+ setType(NodeType::kConstPool);
+ addFlags(NodeFlags::kIsData);
+ clearFlags(NodeFlags::kIsCode | NodeFlags::kHasNoEffect);
}
//! \}
@@ -1313,10 +1285,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::CommentNode]
-// ============================================================================
-
//! Comment node.
class CommentNode : public BaseNode {
public:
@@ -1327,41 +1295,29 @@ public:
//! Creates a new `CommentNode` instance.
inline CommentNode(BaseBuilder* cb, const char* comment) noexcept
- : BaseNode(cb, kNodeComment, kFlagIsInformative | kFlagHasNoEffect | kFlagIsRemovable) {
+ : BaseNode(cb, NodeType::kComment, NodeFlags::kIsInformative | NodeFlags::kHasNoEffect | NodeFlags::kIsRemovable) {
_inlineComment = comment;
}
//! \}
};
-// ============================================================================
-// [asmjit::SentinelNode]
-// ============================================================================
-
//! Sentinel node.
//!
-//! Sentinel is a marker that is completely ignored by the code builder. It's
-//! used to remember a position in a code as it never gets removed by any pass.
+//! Sentinel is a marker that is completely ignored by the code builder. It's used to remember a position in a code
+//! as it never gets removed by any pass.
class SentinelNode : public BaseNode {
public:
ASMJIT_NONCOPYABLE(SentinelNode)
- //! Type of the sentinel (purery informative purpose).
- enum SentinelType : uint32_t {
- //! Type of the sentinel is not known.
- kSentinelUnknown = 0u,
- //! This is a sentinel used at the end of \ref FuncNode.
- kSentinelFuncEnd = 1u
- };
-
//! \name Construction & Destruction
//! \{
//! Creates a new `SentinelNode` instance.
- inline SentinelNode(BaseBuilder* cb, uint32_t sentinelType = kSentinelUnknown) noexcept
- : BaseNode(cb, kNodeSentinel, kFlagIsInformative | kFlagHasNoEffect) {
+ inline SentinelNode(BaseBuilder* cb, SentinelType sentinelType = SentinelType::kUnknown) noexcept
+ : BaseNode(cb, NodeType::kSentinel, NodeFlags::kIsInformative | NodeFlags::kHasNoEffect) {
- _sentinel._sentinelType = uint8_t(sentinelType);
+ _sentinel._sentinelType = sentinelType;
}
//! \}
@@ -1370,33 +1326,34 @@ public:
//! \{
//! Returns the type of the sentinel.
- inline uint32_t sentinelType() const noexcept {
+ inline SentinelType sentinelType() const noexcept {
return _sentinel._sentinelType;
}
//! Sets the type of the sentinel.
- inline void setSentinelType(uint32_t type) noexcept {
- _sentinel._sentinelType = uint8_t(type);
+ inline void setSentinelType(SentinelType type) noexcept {
+ _sentinel._sentinelType = type;
}
//! \}
};
-// ============================================================================
-// [asmjit::Pass]
-// ============================================================================
-
//! Pass can be used to implement code transformations, analysis, and lowering.
class ASMJIT_VIRTAPI Pass {
public:
ASMJIT_BASE_CLASS(Pass)
ASMJIT_NONCOPYABLE(Pass)
+ //! \name Members
+ //! \{
+
//! BaseBuilder this pass is assigned to.
BaseBuilder* _cb = nullptr;
//! Name of the pass.
const char* _name = nullptr;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -1420,8 +1377,8 @@ public:
//! Processes the code stored in Builder or Compiler.
//!
- //! This is the only function that is called by the `BaseBuilder` to process
- //! the code. It passes `zone`, which will be reset after the `run()` finishes.
+ //! This is the only function that is called by the `BaseBuilder` to process the code. It passes `zone`,
+ //! which will be reset after the `run()` finishes.
virtual Error run(Zone* zone, Logger* logger) = 0;
//! \}
diff --git a/src/asmjit/core/codebuffer.h b/src/asmjit/core/codebuffer.h
index 76c86b1..4946e7a 100644
--- a/src/asmjit/core/codebuffer.h
+++ b/src/asmjit/core/codebuffer.h
@@ -1,42 +1,35 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_CODEBUFFER_H_INCLUDED
#define ASMJIT_CORE_CODEBUFFER_H_INCLUDED
#include "../core/globals.h"
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::CodeBuffer]
-// ============================================================================
+//! Flags used by \ref CodeBuffer.
+enum class CodeBufferFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+ //! Buffer is external (not allocated by asmjit).
+ kIsExternal = 0x00000001u,
+ //! Buffer is fixed (cannot be reallocated).
+ kIsFixed = 0x00000002u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(CodeBufferFlags)
//! Code or data buffer.
struct CodeBuffer {
+ //! \name Members
+ //! \{
+
//! The content of the buffer (data).
uint8_t* _data;
//! Number of bytes of `data` used.
@@ -44,15 +37,9 @@ struct CodeBuffer {
//! Buffer capacity (in bytes).
size_t _capacity;
//! Buffer flags.
- uint32_t _flags;
+ CodeBufferFlags _flags;
- //! Code buffer flags.
- enum Flags : uint32_t {
- //! Buffer is external (not allocated by asmjit).
- kFlagIsExternal = 0x00000001u,
- //! Buffer is fixed (cannot be reallocated).
- kFlagIsFixed = 0x00000002u
- };
+ //! \}
//! \name Overloaded Operators
//! \{
@@ -73,20 +60,20 @@ struct CodeBuffer {
//! \name Accessors
//! \{
- //! Returns code buffer flags, see \ref Flags.
- inline uint32_t flags() const noexcept { return _flags; }
+ //! Returns code buffer flags.
+ inline CodeBufferFlags flags() const noexcept { return _flags; }
//! Tests whether the code buffer has the given `flag` set.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasFlag(CodeBufferFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Tests whether this code buffer has a fixed size.
//!
//! Fixed size means that the code buffer is fixed and cannot grow.
- inline bool isFixed() const noexcept { return hasFlag(kFlagIsFixed); }
+ inline bool isFixed() const noexcept { return hasFlag(CodeBufferFlags::kIsFixed); }
//! Tests whether the data in this code buffer is external.
//!
//! External data can only be provided by users, it's never used by AsmJit.
- inline bool isExternal() const noexcept { return hasFlag(kFlagIsExternal); }
+ inline bool isExternal() const noexcept { return hasFlag(CodeBufferFlags::kIsExternal); }
//! Tests whether the data in this code buffer is allocated (non-null).
inline bool isAllocated() const noexcept { return _data != nullptr; }
diff --git a/src/asmjit/core/codeholder.cpp b/src/asmjit/core/codeholder.cpp
index 3c4154e..f446801 100644
--- a/src/asmjit/core/codeholder.cpp
+++ b/src/asmjit/core/codeholder.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/assembler.h"
@@ -32,9 +14,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [Globals]
-// ============================================================================
+// Globals
+// =======
static const char CodeHolder_addrTabName[] = ".addrtab";
@@ -43,31 +24,30 @@ static inline uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcep
return (m << 6) | (o << 3) | rm;
}
-// ============================================================================
-// [asmjit::LabelLinkIterator]
-// ============================================================================
+// LabelLinkIterator
+// =================
class LabelLinkIterator {
public:
- ASMJIT_INLINE LabelLinkIterator(LabelEntry* le) noexcept { reset(le); }
+ inline LabelLinkIterator(LabelEntry* le) noexcept { reset(le); }
- ASMJIT_INLINE explicit operator bool() const noexcept { return isValid(); }
- ASMJIT_INLINE bool isValid() const noexcept { return _link != nullptr; }
+ inline explicit operator bool() const noexcept { return isValid(); }
+ inline bool isValid() const noexcept { return _link != nullptr; }
- ASMJIT_INLINE LabelLink* link() const noexcept { return _link; }
- ASMJIT_INLINE LabelLink* operator->() const noexcept { return _link; }
+ inline LabelLink* link() const noexcept { return _link; }
+ inline LabelLink* operator->() const noexcept { return _link; }
- ASMJIT_INLINE void reset(LabelEntry* le) noexcept {
+ inline void reset(LabelEntry* le) noexcept {
_pPrev = &le->_links;
_link = *_pPrev;
}
- ASMJIT_INLINE void next() noexcept {
+ inline void next() noexcept {
_pPrev = &_link->next;
_link = *_pPrev;
}
- ASMJIT_INLINE void resolveAndNext(CodeHolder* code) noexcept {
+ inline void resolveAndNext(CodeHolder* code) noexcept {
LabelLink* linkToDelete = _link;
_link = _link->next;
@@ -81,11 +61,10 @@ public:
LabelLink* _link;
};
-// ============================================================================
-// [asmjit::CodeHolder - Utilities]
-// ============================================================================
+// CodeHolder - Utilities
+// ======================
-static void CodeHolder_resetInternal(CodeHolder* self, uint32_t resetPolicy) noexcept {
+static void CodeHolder_resetInternal(CodeHolder* self, ResetPolicy resetPolicy) noexcept {
uint32_t i;
const ZoneVector<BaseEmitter*>& emitters = self->emitters();
@@ -134,27 +113,25 @@ static void CodeHolder_onSettingsUpdated(CodeHolder* self) noexcept {
}
}
-// ============================================================================
-// [asmjit::CodeHolder - Construction / Destruction]
-// ============================================================================
+// CodeHolder - Construction & Destruction
+// =======================================
-CodeHolder::CodeHolder() noexcept
+CodeHolder::CodeHolder(const Support::Temporary* temporary) noexcept
: _environment(),
_baseAddress(Globals::kNoBaseAddress),
_logger(nullptr),
_errorHandler(nullptr),
- _zone(16384 - Zone::kBlockOverhead),
+ _zone(16384 - Zone::kBlockOverhead, 1, temporary),
_allocator(&_zone),
_unresolvedLinkCount(0),
_addressTableSection(nullptr) {}
CodeHolder::~CodeHolder() noexcept {
- CodeHolder_resetInternal(this, Globals::kResetHard);
+ CodeHolder_resetInternal(this, ResetPolicy::kHard);
}
-// ============================================================================
-// [asmjit::CodeHolder - Init / Reset]
-// ============================================================================
+// CodeHolder - Init & Reset
+// =========================
inline void CodeHolder_setSectionDefaultName(
Section* section,
@@ -179,7 +156,7 @@ Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noe
if (err == kErrorOk) {
Section* section = _allocator.allocZeroedT<Section>();
if (ASMJIT_LIKELY(section)) {
- section->_flags = Section::kFlagExec | Section::kFlagConst;
+ section->_flags = SectionFlags::kExecutable | SectionFlags::kReadOnly;
CodeHolder_setSectionDefaultName(section, '.', 't', 'e', 'x', 't');
_sections.appendUnsafe(section);
_sectionsByOrder.appendUnsafe(section);
@@ -200,13 +177,12 @@ Error CodeHolder::init(const Environment& environment, uint64_t baseAddress) noe
}
}
-void CodeHolder::reset(uint32_t resetPolicy) noexcept {
+void CodeHolder::reset(ResetPolicy resetPolicy) noexcept {
CodeHolder_resetInternal(this, resetPolicy);
}
-// ============================================================================
-// [asmjit::CodeHolder - Attach / Detach]
-// ============================================================================
+// CodeHolder - Attach / Detach
+// ============================
Error CodeHolder::attach(BaseEmitter* emitter) noexcept {
// Catch a possible misuse of the API.
@@ -214,8 +190,8 @@ Error CodeHolder::attach(BaseEmitter* emitter) noexcept {
return DebugUtils::errored(kErrorInvalidArgument);
// Invalid emitter, this should not be possible.
- uint32_t type = emitter->emitterType();
- if (ASMJIT_UNLIKELY(type == BaseEmitter::kTypeNone || type >= BaseEmitter::kTypeCount))
+ EmitterType type = emitter->emitterType();
+ if (ASMJIT_UNLIKELY(type == EmitterType::kNone || uint32_t(type) > uint32_t(EmitterType::kMaxValue)))
return DebugUtils::errored(kErrorInvalidState);
// This is suspicious, but don't fail if `emitter` is already attached
@@ -261,9 +237,8 @@ Error CodeHolder::detach(BaseEmitter* emitter) noexcept {
return err;
}
-// ============================================================================
-// [asmjit::CodeHolder - Logging]
-// ============================================================================
+// CodeHolder - Logging
+// ====================
void CodeHolder::setLogger(Logger* logger) noexcept {
#ifndef ASMJIT_NO_LOGGING
@@ -274,18 +249,16 @@ void CodeHolder::setLogger(Logger* logger) noexcept {
#endif
}
-// ============================================================================
-// [asmjit::CodeHolder - Error Handling]
-// ============================================================================
+// CodeHolder - Error Handling
+// ===========================
void CodeHolder::setErrorHandler(ErrorHandler* errorHandler) noexcept {
_errorHandler = errorHandler;
CodeHolder_onSettingsUpdated(this);
}
-// ============================================================================
-// [asmjit::CodeHolder - Code Buffer]
-// ============================================================================
+// CodeHolder - Code Buffer
+// ========================
static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept {
uint8_t* oldData = cb->_data;
@@ -368,11 +341,10 @@ Error CodeHolder::reserveBuffer(CodeBuffer* cb, size_t n) noexcept {
return CodeHolder_reserveInternal(this, cb, n);
}
-// ============================================================================
-// [asmjit::CodeHolder - Sections]
-// ============================================================================
+// CodeHolder - Sections
+// =====================
-Error CodeHolder::newSection(Section** sectionOut, const char* name, size_t nameSize, uint32_t flags, uint32_t alignment, int32_t order) noexcept {
+Error CodeHolder::newSection(Section** sectionOut, const char* name, size_t nameSize, SectionFlags flags, uint32_t alignment, int32_t order) noexcept {
*sectionOut = nullptr;
if (nameSize == SIZE_MAX)
@@ -435,7 +407,12 @@ Section* CodeHolder::ensureAddressTableSection() noexcept {
if (_addressTableSection)
return _addressTableSection;
- newSection(&_addressTableSection, CodeHolder_addrTabName, sizeof(CodeHolder_addrTabName) - 1, 0, _environment.registerSize(), std::numeric_limits<int32_t>::max());
+ newSection(&_addressTableSection,
+ CodeHolder_addrTabName,
+ sizeof(CodeHolder_addrTabName) - 1,
+ SectionFlags::kNone,
+ _environment.registerSize(),
+ std::numeric_limits<int32_t>::max());
return _addressTableSection;
}
@@ -458,9 +435,8 @@ Error CodeHolder::addAddressToAddressTable(uint64_t address) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::CodeHolder - Labels / Symbols]
-// ============================================================================
+// CodeHolder - Labels & Symbols
+// =============================
//! Only used to lookup a label from `_namedLabels`.
class LabelByName {
@@ -547,32 +523,66 @@ Error CodeHolder::newLabelEntry(LabelEntry** entryOut) noexcept {
return kErrorOk;
}
-Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId) noexcept {
+Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, LabelType type, uint32_t parentId) noexcept {
*entryOut = nullptr;
uint32_t hashCode = CodeHolder_hashNameAndGetSize(name, nameSize);
- if (ASMJIT_UNLIKELY(nameSize == 0))
- return DebugUtils::errored(kErrorInvalidLabelName);
+ if (ASMJIT_UNLIKELY(nameSize == 0)) {
+ if (type == LabelType::kAnonymous)
+ return newLabelEntry(entryOut);
+ else
+ return DebugUtils::errored(kErrorInvalidLabelName);
+ }
if (ASMJIT_UNLIKELY(nameSize > Globals::kMaxLabelNameSize))
return DebugUtils::errored(kErrorLabelNameTooLong);
switch (type) {
- case Label::kTypeLocal:
+ case LabelType::kAnonymous: {
+ // Anonymous labels cannot have a parent (or more specifically, parent is useless here).
+ if (ASMJIT_UNLIKELY(parentId != Globals::kInvalidId))
+ return DebugUtils::errored(kErrorInvalidParentLabel);
+
+ uint32_t labelId = _labelEntries.size();
+ if (ASMJIT_UNLIKELY(labelId == Globals::kInvalidId))
+ return DebugUtils::errored(kErrorTooManyLabels);
+
+ ASMJIT_PROPAGATE(_labelEntries.willGrow(&_allocator));
+ LabelEntry* le = _allocator.allocZeroedT<LabelEntry>();
+
+ if (ASMJIT_UNLIKELY(!le))
+ return DebugUtils::errored(kErrorOutOfMemory);
+
+ // NOTE: This LabelEntry has a name, but we leave its hashCode as zero as it's anonymous.
+ le->_setId(labelId);
+ le->_parentId = Globals::kInvalidId;
+ le->_offset = 0;
+ ASMJIT_PROPAGATE(le->_name.setData(&_zone, name, nameSize));
+
+ _labelEntries.appendUnsafe(le);
+
+ *entryOut = le;
+ return kErrorOk;
+ }
+
+ case LabelType::kLocal: {
if (ASMJIT_UNLIKELY(parentId >= _labelEntries.size()))
return DebugUtils::errored(kErrorInvalidParentLabel);
hashCode ^= parentId;
break;
+ }
- case Label::kTypeGlobal:
- case Label::kTypeExternal:
+ case LabelType::kGlobal:
+ case LabelType::kExternal: {
if (ASMJIT_UNLIKELY(parentId != Globals::kInvalidId))
- return DebugUtils::errored(kErrorNonLocalLabelCannotHaveParent);
+ return DebugUtils::errored(kErrorInvalidParentLabel);
break;
+ }
- default:
+ default: {
return DebugUtils::errored(kErrorInvalidArgument);
+ }
}
// Don't allow to insert duplicates. Local labels allow duplicates that have
@@ -596,7 +606,7 @@ Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, si
le->_hashCode = hashCode;
le->_setId(labelId);
- le->_type = uint8_t(type);
+ le->_type = type;
le->_parentId = parentId;
le->_offset = 0;
ASMJIT_PROPAGATE(le->_name.setData(&_zone, name, nameSize));
@@ -733,11 +743,10 @@ ASMJIT_API Error CodeHolder::bindLabel(const Label& label, uint32_t toSectionId,
return err;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Relocations]
-// ============================================================================
+// CodeHolder - Relocations
+// ========================
-Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept {
+Error CodeHolder::newRelocEntry(RelocEntry** dst, RelocType relocType) noexcept {
ASMJIT_PROPAGATE(_relocations.willGrow(&_allocator));
uint32_t relocId = _relocations.size();
@@ -749,7 +758,7 @@ Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept {
return DebugUtils::errored(kErrorOutOfMemory);
re->_id = relocId;
- re->_relocType = uint8_t(relocType);
+ re->_relocType = relocType;
re->_sourceSectionId = Globals::kInvalidId;
re->_targetSectionId = Globals::kInvalidId;
_relocations.appendUnsafe(re);
@@ -758,26 +767,25 @@ Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Expression Evaluation]
-// ============================================================================
+// CodeHolder - Expression Evaluation
+// ==================================
static Error CodeHolder_evaluateExpression(CodeHolder* self, Expression* exp, uint64_t* out) noexcept {
uint64_t value[2];
for (size_t i = 0; i < 2; i++) {
uint64_t v;
switch (exp->valueType[i]) {
- case Expression::kValueNone: {
+ case ExpressionValueType::kNone: {
v = 0;
break;
}
- case Expression::kValueConstant: {
+ case ExpressionValueType::kConstant: {
v = exp->value[i].constant;
break;
}
- case Expression::kValueLabel: {
+ case ExpressionValueType::kLabel: {
LabelEntry* le = exp->value[i].label;
if (!le->isBound())
return DebugUtils::errored(kErrorExpressionLabelNotBound);
@@ -785,7 +793,7 @@ static Error CodeHolder_evaluateExpression(CodeHolder* self, Expression* exp, ui
break;
}
- case Expression::kValueExpression: {
+ case ExpressionValueType::kExpression: {
Expression* nested = exp->value[i].expression;
ASMJIT_PROPAGATE(CodeHolder_evaluateExpression(self, nested, &v));
break;
@@ -803,27 +811,27 @@ static Error CodeHolder_evaluateExpression(CodeHolder* self, Expression* exp, ui
uint64_t& b = value[1];
switch (exp->opType) {
- case Expression::kOpAdd:
+ case ExpressionOpType::kAdd:
result = a + b;
break;
- case Expression::kOpSub:
+ case ExpressionOpType::kSub:
result = a - b;
break;
- case Expression::kOpMul:
+ case ExpressionOpType::kMul:
result = a * b;
break;
- case Expression::kOpSll:
+ case ExpressionOpType::kSll:
result = (b > 63) ? uint64_t(0) : uint64_t(a << b);
break;
- case Expression::kOpSrl:
+ case ExpressionOpType::kSrl:
result = (b > 63) ? uint64_t(0) : uint64_t(a >> b);
break;
- case Expression::kOpSra:
+ case ExpressionOpType::kSra:
result = Support::sar(a, Support::min<uint64_t>(b, 63));
break;
@@ -835,9 +843,8 @@ static Error CodeHolder_evaluateExpression(CodeHolder* self, Expression* exp, ui
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Utilities]
-// ============================================================================
+// CodeHolder - Utilities
+// ======================
Error CodeHolder::flatten() noexcept {
uint64_t offset = 0;
@@ -917,7 +924,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
// Relocate all recorded locations.
for (const RelocEntry* re : _relocations) {
// Possibly deleted or optimized-out entry.
- if (re->relocType() == RelocEntry::kTypeNone)
+ if (re->relocType() == RelocType::kNone)
continue;
Section* sourceSection = sectionById(re->sourceSectionId());
@@ -940,17 +947,17 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
size_t valueOffset = size_t(re->sourceOffset()) + re->format().valueOffset();
switch (re->relocType()) {
- case RelocEntry::kTypeExpression: {
+ case RelocType::kExpression: {
Expression* expression = (Expression*)(uintptr_t(value));
ASMJIT_PROPAGATE(CodeHolder_evaluateExpression(this, expression, &value));
break;
}
- case RelocEntry::kTypeAbsToAbs: {
+ case RelocType::kAbsToAbs: {
break;
}
- case RelocEntry::kTypeRelToAbs: {
+ case RelocType::kRelToAbs: {
// Value is currently a relative offset from the start of its section.
// We have to convert it to an absolute offset (including base address).
if (ASMJIT_UNLIKELY(!targetSection))
@@ -961,14 +968,14 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
break;
}
- case RelocEntry::kTypeAbsToRel: {
+ case RelocType::kAbsToRel: {
value -= baseAddress + sectionOffset + sourceOffset + regionSize;
if (addressSize > 4 && !Support::isInt32(int64_t(value)))
return DebugUtils::errored(kErrorRelocOffsetOutOfRange);
break;
}
- case RelocEntry::kTypeX64AddressEntry: {
+ case RelocType::kX64AddressEntry: {
if (re->format().valueSize() != 4 || valueOffset < 2)
return DebugUtils::errored(kErrorInvalidRelocEntry);
@@ -1055,7 +1062,7 @@ Error CodeHolder::relocateToBase(uint64_t baseAddress) noexcept {
return kErrorOk;
}
-Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions) noexcept {
+Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, CopySectionFlags copyFlags) noexcept {
if (ASMJIT_UNLIKELY(!isSectionValid(sectionId)))
return DebugUtils::errored(kErrorInvalidSection);
@@ -1067,7 +1074,7 @@ Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId,
memcpy(dst, section->data(), bufferSize);
- if (bufferSize < dstSize && (copyOptions & kCopyPadSectionBuffer)) {
+ if (bufferSize < dstSize && Support::test(copyFlags, CopySectionFlags::kPadSectionBuffer)) {
size_t paddingSize = dstSize - bufferSize;
memset(static_cast<uint8_t*>(dst) + bufferSize, 0, paddingSize);
}
@@ -1075,7 +1082,7 @@ Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId,
return kErrorOk;
}
-Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions) noexcept {
+Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, CopySectionFlags copyFlags) noexcept {
size_t end = 0;
for (Section* section : _sectionsByOrder) {
if (section->offset() > dstSize)
@@ -1091,7 +1098,7 @@ Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOpti
size_t paddingSize = 0;
memcpy(dstTarget, section->data(), bufferSize);
- if ((copyOptions & kCopyPadSectionBuffer) && bufferSize < section->virtualSize()) {
+ if (Support::test(copyFlags, CopySectionFlags::kPadSectionBuffer) && bufferSize < section->virtualSize()) {
paddingSize = Support::min<size_t>(dstSize - offset, size_t(section->virtualSize())) - bufferSize;
memset(dstTarget + bufferSize, 0, paddingSize);
}
@@ -1099,16 +1106,15 @@ Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOpti
end = Support::max(end, offset + bufferSize + paddingSize);
}
- if (end < dstSize && (copyOptions & kCopyPadTargetBuffer)) {
+ if (end < dstSize && Support::test(copyFlags, CopySectionFlags::kPadTargetBuffer)) {
memset(static_cast<uint8_t*>(dst) + end, 0, dstSize - end);
}
return kErrorOk;
}
-// ============================================================================
-// [asmjit::CodeHolder - Unit]
-// ============================================================================
+// CodeHolder - Tests
+// ==================
#if defined(ASMJIT_TEST)
UNIT(code_holder) {
@@ -1116,34 +1122,33 @@ UNIT(code_holder) {
INFO("Verifying CodeHolder::init()");
Environment env;
- env.init(Environment::kArchX86);
+ env.init(Arch::kX86);
code.init(env);
- EXPECT(code.arch() == Environment::kArchX86);
+ EXPECT(code.arch() == Arch::kX86);
INFO("Verifying named labels");
LabelEntry* le;
- EXPECT(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, Label::kTypeGlobal) == kErrorOk);
+ EXPECT(code.newNamedLabelEntry(&le, "NamedLabel", SIZE_MAX, LabelType::kGlobal) == kErrorOk);
EXPECT(strcmp(le->name(), "NamedLabel") == 0);
EXPECT(code.labelIdByName("NamedLabel") == le->id());
INFO("Verifying section ordering");
Section* section1;
- EXPECT(code.newSection(&section1, "high-priority", SIZE_MAX, 0, 1, -1) == kErrorOk);
+ EXPECT(code.newSection(&section1, "high-priority", SIZE_MAX, SectionFlags::kNone, 1, -1) == kErrorOk);
EXPECT(code.sections()[1] == section1);
EXPECT(code.sectionsByOrder()[0] == section1);
Section* section0;
- EXPECT(code.newSection(&section0, "higher-priority", SIZE_MAX, 0, 1, -2) == kErrorOk);
+ EXPECT(code.newSection(&section0, "higher-priority", SIZE_MAX, SectionFlags::kNone, 1, -2) == kErrorOk);
EXPECT(code.sections()[2] == section0);
EXPECT(code.sectionsByOrder()[0] == section0);
EXPECT(code.sectionsByOrder()[1] == section1);
Section* section3;
- EXPECT(code.newSection(&section3, "low-priority", SIZE_MAX, 0, 1, 2) == kErrorOk);
+ EXPECT(code.newSection(&section3, "low-priority", SIZE_MAX, SectionFlags::kNone, 1, 2) == kErrorOk);
EXPECT(code.sections()[3] == section3);
EXPECT(code.sectionsByOrder()[3] == section3);
-
}
#endif
diff --git a/src/asmjit/core/codeholder.h b/src/asmjit/core/codeholder.h
index 2a6ee49..b6257f2 100644
--- a/src/asmjit/core/codeholder.h
+++ b/src/asmjit/core/codeholder.h
@@ -1,32 +1,13 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_CODEHOLDER_H_INCLUDED
#define ASMJIT_CORE_CODEHOLDER_H_INCLUDED
#include "../core/archtraits.h"
#include "../core/codebuffer.h"
-#include "../core/datatypes.h"
#include "../core/errorhandler.h"
#include "../core/operand.h"
#include "../core/string.h"
@@ -43,65 +24,41 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class BaseEmitter;
class CodeHolder;
class LabelEntry;
class Logger;
-// ============================================================================
-// [asmjit::AlignMode]
-// ============================================================================
-
-//! Align mode.
-enum AlignMode : uint32_t {
- //! Align executable code.
- kAlignCode = 0,
- //! Align non-executable code.
- kAlignData = 1,
- //! Align by a sequence of zeros.
- kAlignZero = 2,
- //! Count of alignment modes.
- kAlignCount = 3
+//! Operator type that can be used within an \ref Expression.
+enum class ExpressionOpType : uint8_t {
+ //! Addition.
+ kAdd = 0,
+ //! Subtraction.
+ kSub = 1,
+ //! Multiplication
+ kMul = 2,
+ //! Logical left shift.
+ kSll = 3,
+ //! Logical right shift.
+ kSrl = 4,
+ //! Arithmetic right shift.
+ kSra = 5
};
-// ============================================================================
-// [asmjit::Expression]
-// ============================================================================
+//! Value tyoe that can be used within an \ref Expression.
+enum class ExpressionValueType : uint8_t {
+ //! No value or invalid.
+ kNone = 0,
+ //! Value is 64-bit unsigned integer (constant).
+ kConstant = 1,
+ //! Value is \ref LabelEntry, which references a \ref Label.
+ kLabel = 2,
+ //! Value is \ref Expression
+ kExpression = 3
+};
//! Expression node that can reference constants, labels, and another expressions.
struct Expression {
- //! Operation type.
- enum OpType : uint8_t {
- //! Addition.
- kOpAdd = 0,
- //! Subtraction.
- kOpSub = 1,
- //! Multiplication
- kOpMul = 2,
- //! Logical left shift.
- kOpSll = 3,
- //! Logical right shift.
- kOpSrl = 4,
- //! Arithmetic right shift.
- kOpSra = 5
- };
-
- //! Type of \ref Value.
- enum ValueType : uint8_t {
- //! No value or invalid.
- kValueNone = 0,
- //! Value is 64-bit unsigned integer (constant).
- kValueConstant = 1,
- //! Value is \ref LabelEntry, which references a \ref Label.
- kValueLabel = 2,
- //! Value is \ref Expression
- kValueExpression = 3
- };
-
//! Expression value.
union Value {
//! Constant.
@@ -112,50 +69,93 @@ struct Expression {
LabelEntry* label;
};
+ //! \name Members
+ //! \{
+
//! Operation type.
- uint8_t opType;
+ ExpressionOpType opType;
//! Value types of \ref value.
- uint8_t valueType[2];
+ ExpressionValueType valueType[2];
//! Reserved for future use, should be initialized to zero.
uint8_t reserved[5];
//! Expression left and right values.
Value value[2];
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
//! Resets the whole expression.
//!
- //! Changes both values to \ref kValueNone.
+ //! Changes both values to \ref ExpressionValueType::kNone.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
- //! Sets the value type at `index` to \ref kValueConstant and its content to `constant`.
+ //! Sets the value type at `index` to \ref ExpressionValueType::kConstant and its content to `constant`.
inline void setValueAsConstant(size_t index, uint64_t constant) noexcept {
- valueType[index] = kValueConstant;
+ valueType[index] = ExpressionValueType::kConstant;
value[index].constant = constant;
}
- //! Sets the value type at `index` to \ref kValueLabel and its content to `labelEntry`.
+ //! Sets the value type at `index` to \ref ExpressionValueType::kLabel and its content to `labelEntry`.
inline void setValueAsLabel(size_t index, LabelEntry* labelEntry) noexcept {
- valueType[index] = kValueLabel;
+ valueType[index] = ExpressionValueType::kLabel;
value[index].label = labelEntry;
}
- //! Sets the value type at `index` to \ref kValueExpression and its content to `expression`.
+ //! Sets the value type at `index` to \ref ExpressionValueType::kExpression and its content to `expression`.
inline void setValueAsExpression(size_t index, Expression* expression) noexcept {
- valueType[index] = kValueLabel;
+ valueType[index] = ExpressionValueType::kExpression;
value[index].expression = expression;
}
+
+ //! \}
};
-// ============================================================================
-// [asmjit::Section]
-// ============================================================================
+//! Section flags, used by \ref Section.
+enum class SectionFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+ //! Executable (.text sections).
+ kExecutable = 0x00000001u,
+ //! Read-only (.text and .data sections).
+ kReadOnly = 0x00000002u,
+ //! Zero initialized by the loader (BSS).
+ kZeroInitialized = 0x00000004u,
+ //! Info / comment flag.
+ kComment = 0x00000008u,
+ //! Section created implicitly, can be deleted by \ref Target.
+ kImplicit = 0x80000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(SectionFlags)
+
+//! Flags that can be used with \ref CodeHolder::copySectionData() and \ref CodeHolder::copyFlattenedData().
+enum class CopySectionFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
+ //! If virtual size of a section is greater than the size of its \ref CodeBuffer then all bytes between the buffer
+ //! size and virtual size will be zeroed. If this option is not set then those bytes would be left as is, which
+ //! means that if the user didn't initialize them they would have a previous content, which may be unwanted.
+ kPadSectionBuffer = 0x00000001u,
+
+ //! Clears the target buffer if the flattened data is less than the destination size. This option works
+ //! only with \ref CodeHolder::copyFlattenedData() as it processes multiple sections. It is ignored by
+ //! \ref CodeHolder::copySectionData().
+ kPadTargetBuffer = 0x00000002u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(CopySectionFlags)
//! Section entry.
class Section {
public:
+ //! \name Members
+ //! \{
+
//! Section id.
uint32_t _id;
//! Section flags.
- uint32_t _flags;
+ SectionFlags _flags;
//! Section alignment requirements (0 if no requirements).
uint32_t _alignment;
//! Order (lower value means higher priority).
@@ -169,19 +169,7 @@ public:
//! Code or data buffer.
CodeBuffer _buffer;
- //! Section flags.
- enum Flags : uint32_t {
- //! Executable (.text sections).
- kFlagExec = 0x00000001u,
- //! Read-only (.text and .data sections).
- kFlagConst = 0x00000002u,
- //! Zero initialized by the loader (BSS).
- kFlagZero = 0x00000004u,
- //! Info / comment flag.
- kFlagInfo = 0x00000008u,
- //! Section created implicitly and can be deleted by \ref Target.
- kFlagImplicit = 0x80000000u
- };
+ //! \}
//! \name Accessors
//! \{
@@ -196,14 +184,14 @@ public:
//! \overload
inline const uint8_t* data() const noexcept { return _buffer.data(); }
- //! Returns the section flags, see \ref Flags.
- inline uint32_t flags() const noexcept { return _flags; }
+ //! Returns the section flags.
+ inline SectionFlags flags() const noexcept { return _flags; }
//! Tests whether the section has the given `flag`.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasFlag(SectionFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Adds `flags` to the section flags.
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ inline void addFlags(SectionFlags flags) noexcept { _flags |= flags; }
//! Removes `flags` from the section flags.
- inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
+ inline void clearFlags(SectionFlags flags) noexcept { _flags &= ~flags; }
//! Returns the minimum section alignment
inline uint32_t alignment() const noexcept { return _alignment; }
@@ -220,9 +208,8 @@ public:
//! Returns the virtual size of the section.
//!
- //! Virtual size is initially zero and is never changed by AsmJit. It's normal
- //! if virtual size is smaller than size returned by `bufferSize()` as the buffer
- //! stores real data emitted by assemblers or appended by users.
+ //! Virtual size is initially zero and is never changed by AsmJit. It's normal if virtual size is smaller than
+ //! size returned by `bufferSize()` as the buffer stores real data emitted by assemblers or appended by users.
//!
//! Use `realSize()` to get the real and final size of this section.
inline uint64_t virtualSize() const noexcept { return _virtualSize; }
@@ -242,16 +229,71 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::OffsetFormat]
-// ============================================================================
+//! Entry in an address table.
+class AddressTableEntry : public ZoneTreeNodeT<AddressTableEntry> {
+public:
+ ASMJIT_NONCOPYABLE(AddressTableEntry)
+
+ //! \name Members
+ //! \{
-//! Provides information about formatting offsets, absolute addresses, or their
-//! parts. Offset format is used by both \ref RelocEntry and \ref LabelLink.
-//!
-//! The illustration above describes the relation of region size and offset size.
-//! Region size is the size of the whole unit whereas offset size is the size of
-//! the unit that will be patched.
+ //! Address.
+ uint64_t _address;
+ //! Slot.
+ uint32_t _slot;
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ inline explicit AddressTableEntry(uint64_t address) noexcept
+ : _address(address),
+ _slot(0xFFFFFFFFu) {}
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ inline uint64_t address() const noexcept { return _address; }
+ inline uint32_t slot() const noexcept { return _slot; }
+
+ inline bool hasAssignedSlot() const noexcept { return _slot != 0xFFFFFFFFu; }
+
+ inline bool operator<(const AddressTableEntry& other) const noexcept { return _address < other._address; }
+ inline bool operator>(const AddressTableEntry& other) const noexcept { return _address > other._address; }
+
+ inline bool operator<(uint64_t queryAddress) const noexcept { return _address < queryAddress; }
+ inline bool operator>(uint64_t queryAddress) const noexcept { return _address > queryAddress; }
+
+ //! \}
+};
+
+//! Offset format type, used by \ref OffsetFormat.
+enum class OffsetType : uint8_t {
+ //! A value having `_immBitCount` bits and shifted by `_immBitShift`.
+ //!
+ //! This offset type is sufficient for many targets that store offset as a continuous set bits within an
+ //! instruction word / sequence of bytes.
+ kCommon = 0,
+
+ // AArch64 Specific Offset Formats
+ // -------------------------------
+
+ //! AARCH64 ADR format of `[.|immlo:2|.....|immhi:19|.....]`.
+ kAArch64_ADR,
+
+ //! AARCH64 ADRP format of `[.|immlo:2|.....|immhi:19|.....]` (4kB pages).
+ kAArch64_ADRP,
+
+ //! Maximum value of `OffsetFormatType`.
+ kMaxValue = kAArch64_ADRP
+};
+
+//! Provides information about formatting offsets, absolute addresses, or their parts. Offset format is used by both
+//! \ref RelocEntry and \ref LabelLink. The illustration below describes the relation of region size and offset size.
+//! Region size is the size of the whole unit whereas offset size is the size of the unit that will be patched.
//!
//! ```
//! +-> Code buffer | The subject of the relocation (region) |
@@ -274,77 +316,64 @@ public:
//! (ImmBitCount) +- ImmBitShift
//! ```
struct OffsetFormat {
- //! Type of the displacement.
- uint8_t _type;
+ //! \name Members
+ //! \{
+
+ //! Type of the offset.
+ OffsetType _type;
//! Encoding flags.
uint8_t _flags;
- //! Size of the region (in bytes) containing the offset value, if the offset
- //! value is part of an instruction, otherwise it would be the same as
- //! `_valueSize`.
+ //! Size of the region (in bytes) containing the offset value, if the offset value is part of an instruction,
+ //! otherwise it would be the same as `_valueSize`.
uint8_t _regionSize;
//! Size of the offset value, in bytes (1, 2, 4, or 8).
uint8_t _valueSize;
- //! Offset of the offset value, in bytes, relative to the start of the region
- //! or data. Value offset would be zero if both region size and value size are
- //! equal.
+ //! Offset of the offset value, in bytes, relative to the start of the region or data. Value offset would be
+ //! zero if both region size and value size are equal.
uint8_t _valueOffset;
- //! Size of the displacement immediate value in bits.
+ //! Size of the offset immediate value in bits.
uint8_t _immBitCount;
- //! Shift of the displacement immediate value in bits in the target word.
+ //! Shift of the offset immediate value in bits in the target word.
uint8_t _immBitShift;
- //! Number of least significant bits to discard before writing the immediate
- //! to the destination. All discarded bits must be zero otherwise the value
- //! is invalid.
+ //! Number of least significant bits to discard before writing the immediate to the destination. All discarded
+ //! bits must be zero otherwise the value is invalid.
uint8_t _immDiscardLsb;
- //! Type of the displacement.
- enum Type : uint8_t {
- //! A value having `_immBitCount` bits and shifted by `_immBitShift`.
- //!
- //! This displacement type is sufficient for both X86/X64 and many other
- //! architectures that store displacement as continuous bits within a machine
- //! word.
- kTypeCommon = 0,
- //! AARCH64 ADR format of `[.|immlo:2|.....|immhi:19|.....]`.
- kTypeAArch64_ADR,
- //! AARCH64 ADRP format of `[.|immlo:2|.....|immhi:19|.....]` (4kB pages).
- kTypeAArch64_ADRP,
-
- //! Count of displacement types.
- kTypeCount
- };
+ //! \}
- //! Returns the type of the displacement.
- inline uint32_t type() const noexcept { return _type; }
+ //! \name Accessors
+ //! \{
+
+ //! Returns the type of the offset.
+ inline OffsetType type() const noexcept { return _type; }
//! Returns flags.
inline uint32_t flags() const noexcept { return _flags; }
- //! Returns the size of the region/instruction where the displacement is encoded.
+ //! Returns the size of the region/instruction where the offset is encoded.
inline uint32_t regionSize() const noexcept { return _regionSize; }
- //! Returns the the offset of the word relative to the start of the region
- //! where the displacement is.
+ //! Returns the the offset of the word relative to the start of the region where the offset is.
inline uint32_t valueOffset() const noexcept { return _valueOffset; }
- //! Returns the size of the data-type (word) that contains the displacement, in bytes.
+ //! Returns the size of the data-type (word) that contains the offset, in bytes.
inline uint32_t valueSize() const noexcept { return _valueSize; }
- //! Returns the count of bits of the displacement value in the data it's stored in.
+ //! Returns the count of bits of the offset value in the data it's stored in.
inline uint32_t immBitCount() const noexcept { return _immBitCount; }
- //! Returns the bit-shift of the displacement value in the data it's stored in.
+ //! Returns the bit-shift of the offset value in the data it's stored in.
inline uint32_t immBitShift() const noexcept { return _immBitShift; }
- //! Returns the number of least significant bits of the displacement value,
- //! that must be zero and that are not part of the encoded data.
+ //! Returns the number of least significant bits of the offset value, that must be zero and that are not part of
+ //! the encoded data.
inline uint32_t immDiscardLsb() const noexcept { return _immDiscardLsb; }
//! Resets this offset format to a simple data value of `dataSize` bytes.
//!
- //! The region will be the same size as data and immediate bits would correspond
- //! to `dataSize * 8`. There will be no immediate bit shift or discarded bits.
+ //! The region will be the same size as data and immediate bits would correspond to `dataSize * 8`. There will be
+ //! no immediate bit shift or discarded bits.
inline void resetToDataValue(size_t dataSize) noexcept {
ASMJIT_ASSERT(dataSize <= 8u);
- _type = uint8_t(kTypeCommon);
+ _type = OffsetType::kCommon;
_flags = uint8_t(0);
_regionSize = uint8_t(dataSize);
_valueSize = uint8_t(dataSize);
@@ -354,13 +383,13 @@ struct OffsetFormat {
_immDiscardLsb = uint8_t(0);
}
- inline void resetToImmValue(uint32_t type, size_t valueSize, uint32_t immBitShift, uint32_t immBitCount, uint32_t immDiscardLsb) noexcept {
+ inline void resetToImmValue(OffsetType type, size_t valueSize, uint32_t immBitShift, uint32_t immBitCount, uint32_t immDiscardLsb) noexcept {
ASMJIT_ASSERT(valueSize <= 8u);
ASMJIT_ASSERT(immBitShift < valueSize * 8u);
ASMJIT_ASSERT(immBitCount <= 64u);
ASMJIT_ASSERT(immDiscardLsb <= 64u);
- _type = uint8_t(type);
+ _type = type;
_flags = uint8_t(0);
_regionSize = uint8_t(valueSize);
_valueSize = uint8_t(valueSize);
@@ -379,18 +408,35 @@ struct OffsetFormat {
_regionSize = uint8_t(leadingSize + trailingSize + _valueSize);
_valueOffset = uint8_t(leadingSize);
}
+
+ //! \}
};
-// ============================================================================
-// [asmjit::RelocEntry]
-// ============================================================================
+//! Relocation type.
+enum class RelocType : uint32_t {
+ //! None/deleted (no relocation).
+ kNone = 0,
+ //! Expression evaluation, `_payload` is pointer to `Expression`.
+ kExpression = 1,
+ //! Relocate absolute to absolute.
+ kAbsToAbs = 2,
+ //! Relocate relative to absolute.
+ kRelToAbs = 3,
+ //! Relocate absolute to relative.
+ kAbsToRel = 4,
+ //! Relocate absolute to relative or use trampoline.
+ kX64AddressEntry = 5
+};
//! Relocation entry.
struct RelocEntry {
+ //! \name Members
+ //! \{
+
//! Relocation id.
uint32_t _id;
//! Type of the relocation.
- uint32_t _relocType;
+ RelocType _relocType;
//! Format of the relocated value.
OffsetFormat _format;
//! Source section id.
@@ -402,28 +448,14 @@ struct RelocEntry {
//! Payload (target offset, target address, expression, etc).
uint64_t _payload;
- //! Relocation type.
- enum RelocType : uint32_t {
- //! None/deleted (no relocation).
- kTypeNone = 0,
- //! Expression evaluation, `_payload` is pointer to `Expression`.
- kTypeExpression = 1,
- //! Relocate absolute to absolute.
- kTypeAbsToAbs = 2,
- //! Relocate relative to absolute.
- kTypeRelToAbs = 3,
- //! Relocate absolute to relative.
- kTypeAbsToRel = 4,
- //! Relocate absolute to relative or use trampoline.
- kTypeX64AddressEntry = 5
- };
+ //! \}
//! \name Accessors
//! \{
inline uint32_t id() const noexcept { return _id; }
- inline uint32_t relocType() const noexcept { return _relocType; }
+ inline RelocType relocType() const noexcept { return _relocType; }
inline const OffsetFormat& format() const noexcept { return _format; }
inline uint32_t sourceSectionId() const noexcept { return _sourceSectionId; }
@@ -439,9 +471,20 @@ struct RelocEntry {
//! \}
};
-// ============================================================================
-// [asmjit::LabelLink]
-// ============================================================================
+//! Type of the \ref Label.
+enum class LabelType : uint8_t {
+ //! Anonymous label that can optionally have a name, which is only used for debugging purposes.
+ kAnonymous = 0,
+ //! Local label (always has parentId).
+ kLocal = 1,
+ //! Global label (never has parentId).
+ kGlobal = 2,
+ //! External label (references an external symbol).
+ kExternal = 3,
+
+ //! Maximum value of `LabelType`.
+ kMaxValue = kExternal
+};
//! Data structure used to link either unbound labels or cross-section links.
struct LabelLink {
@@ -459,41 +502,43 @@ struct LabelLink {
OffsetFormat format;
};
-// ============================================================================
-// [asmjit::LabelEntry]
-// ============================================================================
-
//! Label entry.
//!
//! Contains the following properties:
-//! * Label id - This is the only thing that is set to the `Label` operand.
-//! * Label name - Optional, used mostly to create executables and libraries.
-//! * Label type - Type of the label, default `Label::kTypeAnonymous`.
-//! * Label parent id - Derived from many assemblers that allow to define a
-//! local label that falls under a global label. This allows to define
-//! many labels of the same name that have different parent (global) label.
-//! * Offset - offset of the label bound by `Assembler`.
-//! * Links - single-linked list that contains locations of code that has
-//! to be patched when the label gets bound. Every use of unbound label
-//! adds one link to `_links` list.
-//! * HVal - Hash value of label's name and optionally parentId.
-//! * HashNext - Hash-table implementation detail.
+//! - Label id - This is the only thing that is set to the `Label` operand.
+//! - Label name - Optional, used mostly to create executables and libraries.
+//! - Label type - Type of the label, default `LabelType::kAnonymous`.
+//! - Label parent id - Derived from many assemblers that allow to define a local label that falls under a global
+//! label. This allows to define many labels of the same name that have different parent (global) label.
+//! - Offset - offset of the label bound by `Assembler`.
+//! - Links - single-linked list that contains locations of code that has to be patched when the label gets bound.
+//! Every use of unbound label adds one link to `_links` list.
+//! - HVal - Hash value of label's name and optionally parentId.
+//! - HashNext - Hash-table implementation detail.
class LabelEntry : public ZoneHashNode {
public:
- // Let's round the size of `LabelEntry` to 64 bytes (as `ZoneAllocator` has
- // granularity of 32 bytes anyway). This gives `_name` the remaining space,
- // which is should be 16 bytes on 64-bit and 28 bytes on 32-bit architectures.
+ //! \name Constants
+ //! \{
+
enum : uint32_t {
- kStaticNameSize =
- 64 - (sizeof(ZoneHashNode) + 8 + sizeof(Section*) + sizeof(size_t) + sizeof(LabelLink*))
+ //! SSO size of \ref _name.
+ //!
+ //! \cond INTERNAL
+ //! Let's round the size of `LabelEntry` to 64 bytes (as `ZoneAllocator` has granularity of 32 bytes anyway). This
+ //! gives `_name` the remaining space, which is should be 16 bytes on 64-bit and 28 bytes on 32-bit architectures.
+ //! \endcond
+ kStaticNameSize = 64 - (sizeof(ZoneHashNode) + 8 + sizeof(Section*) + sizeof(size_t) + sizeof(LabelLink*))
};
- //! Label type, see `Label::LabelType`.
- uint8_t _type;
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ //! Type of the label.
+ LabelType _type;
//! Must be zero.
- uint8_t _flags;
- //! Reserved.
- uint16_t _reserved16;
+ uint8_t _reserved[3];
//! Label parent id or zero.
uint32_t _parentId;
//! Label offset relative to the start of the `_section`.
@@ -505,22 +550,21 @@ public:
//! Label name.
ZoneString<kStaticNameSize> _name;
+ //! \}
+
//! \name Accessors
//! \{
- // NOTE: Label id is stored in `_customData`, which is provided by ZoneHashNode
- // to fill a padding that a C++ compiler targeting 64-bit CPU will add to align
- // the structure to 64-bits.
+ // NOTE: Label id is stored in `_customData`, which is provided by ZoneHashNode to fill a padding that a C++
+ // compiler targeting 64-bit CPU will add to align the structure to 64-bits.
//! Returns label id.
inline uint32_t id() const noexcept { return _customData; }
//! Sets label id (internal, used only by `CodeHolder`).
inline void _setId(uint32_t id) noexcept { _customData = id; }
- //! Returns label type, see `Label::LabelType`.
- inline uint32_t type() const noexcept { return _type; }
- //! Returns label flags, returns 0 at the moment.
- inline uint32_t flags() const noexcept { return _flags; }
+ //! Returns label type.
+ inline LabelType type() const noexcept { return _type; }
//! Tests whether the label has a parent label.
inline bool hasParent() const noexcept { return _parentId != Globals::kInvalidId; }
@@ -537,15 +581,13 @@ public:
//! Returns the label's name.
//!
- //! \note Local labels will return their local name without their parent
- //! part, for example ".L1".
+ //! \note Local labels will return their local name without their parent part, for example ".L1".
inline const char* name() const noexcept { return _name.data(); }
//! Returns size of label's name.
//!
- //! \note Label name is always null terminated, so you can use `strlen()` to
- //! get it, however, it's also cached in `LabelEntry` itself, so if you want
- //! to know the size the fastest way is to call `LabelEntry::nameSize()`.
+ //! \note Label name is always null terminated, so you can use `strlen()` to get it, however, it's also cached in
+ //! `LabelEntry` itself, so if you want to know the size the fastest way is to call `LabelEntry::nameSize()`.
inline uint32_t nameSize() const noexcept { return _name.size(); }
//! Returns links associated with this label.
@@ -561,71 +603,38 @@ public:
//! Returns the hash-value of label's name and its parent label (if any).
//!
- //! Label hash is calculated as `HASH(Name) ^ ParentId`. The hash function
- //! is implemented in `Support::hashString()` and `Support::hashRound()`.
+ //! Label hash is calculated as `HASH(Name) ^ ParentId`. The hash function is implemented in `Support::hashString()`
+ //! and `Support::hashRound()`.
inline uint32_t hashCode() const noexcept { return _hashCode; }
//! \}
};
-// ============================================================================
-// [asmjit::AddressTableEntry]
-// ============================================================================
-
-//! Entry in an address table.
-class AddressTableEntry : public ZoneTreeNodeT<AddressTableEntry> {
-public:
- ASMJIT_NONCOPYABLE(AddressTableEntry)
-
- //! Address.
- uint64_t _address;
- //! Slot.
- uint32_t _slot;
-
- //! \name Construction & Destruction
- //! \{
-
- inline explicit AddressTableEntry(uint64_t address) noexcept
- : _address(address),
- _slot(0xFFFFFFFFu) {}
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- inline uint64_t address() const noexcept { return _address; }
- inline uint32_t slot() const noexcept { return _slot; }
-
- inline bool hasAssignedSlot() const noexcept { return _slot != 0xFFFFFFFFu; }
-
- inline bool operator<(const AddressTableEntry& other) const noexcept { return _address < other._address; }
- inline bool operator>(const AddressTableEntry& other) const noexcept { return _address > other._address; }
-
- inline bool operator<(uint64_t queryAddress) const noexcept { return _address < queryAddress; }
- inline bool operator>(uint64_t queryAddress) const noexcept { return _address > queryAddress; }
-
- //! \}
-};
-
-// ============================================================================
-// [asmjit::CodeHolder]
-// ============================================================================
-
-//! Contains basic information about the target architecture and its options.
+//! Holds assembled code and data (including sections, labels, and relocation information).
+//!
+//! CodeHolder connects emitters with their targets. It provides them interface that can be used to query information
+//! about the target environment (architecture, etc...) and API to create labels, sections, relocations, and to write
+//! data to a \ref CodeBuffer, which is always part of \ref Section. More than one emitter can be attached to a single
+//! CodeHolder instance at a time, which is used in practice
+//!
+//! CodeHolder provides interface for all emitter types. Assemblers use CodeHolder to write into \ref CodeBuffer, and
+//! higher level emitters like Builder and Compiler use CodeHolder to manage labels and sections so higher level code
+//! can be serialized to Assembler by \ref BaseEmitter::finalize() and \ref BaseBuilder::serializeTo().
//!
-//! In addition, it holds assembled code & data (including sections, labels, and
-//! relocation information). `CodeHolder` can store both binary and intermediate
-//! representation of assembly, which can be generated by \ref BaseAssembler,
-//! \ref BaseBuilder, and \ref BaseCompiler
+//! In order to use CodeHolder, it must be first initialized by \ref init(). After the CodeHolder has been successfully
+//! initialized it can be used to hold assembled code, sections, labels, relocations, and to attach / detach code
+//! emitters. After the end of code generation it can be used to query physical locations of labels and to relocate
+//! the assembled code into the right address.
//!
-//! \note `CodeHolder` has an ability to attach an \ref ErrorHandler, however,
-//! the error handler is not triggered by `CodeHolder` itself, it's instead
-//! propagated to all emitters that attach to it.
+//! \note \ref CodeHolder has an ability to attach an \ref ErrorHandler, however, the error handler is not triggered
+//! by \ref CodeHolder itself, it's instead propagated to all emitters that attach to it.
class CodeHolder {
public:
ASMJIT_NONCOPYABLE(CodeHolder)
+ //! \name Members
+ //! \{
+
//! Environment information.
Environment _environment;
//! Base address or \ref Globals::kNoBaseAddress.
@@ -661,31 +670,22 @@ public:
//! Address table entries.
ZoneTree<AddressTableEntry> _addressTableEntries;
- //! Options that can be used with \ref copySectionData() and \ref copyFlattenedData().
- enum CopyOptions : uint32_t {
- //! If virtual size of a section is greater than the size of its \ref CodeBuffer
- //! then all bytes between the buffer size and virtual size will be zeroed.
- //! If this option is not set then those bytes would be left as is, which
- //! means that if the user didn't initialize them they would have a previous
- //! content, which may be unwanted.
- kCopyPadSectionBuffer = 0x00000001u,
-
-#ifndef ASMJIT_NO_DEPRECATED
- kCopyWithPadding = kCopyPadSectionBuffer,
-#endif // !ASMJIT_NO_DEPRECATED
-
- //! Zeroes the target buffer if the flattened data is less than the destination
- //! size. This option works only with \ref copyFlattenedData() as it processes
- //! multiple sections. It is ignored by \ref copySectionData().
- kCopyPadTargetBuffer = 0x00000002u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
//! Creates an uninitialized CodeHolder (you must init() it before it can be used).
- ASMJIT_API CodeHolder() noexcept;
- //! Destroys the CodeHolder.
+ //!
+ //! An optional `temporary` argument can be used to initialize the first block of \ref Zone that the CodeHolder
+ //! uses into a temporary memory provided by the user.
+ ASMJIT_API explicit CodeHolder(const Support::Temporary* temporary = nullptr) noexcept;
+
+ //! \overload
+ inline explicit CodeHolder(const Support::Temporary& temporary) noexcept
+ : CodeHolder(&temporary) {}
+
+ //! Destroys the CodeHolder and frees all resources it has allocated.
ASMJIT_API ~CodeHolder() noexcept;
//! Tests whether the `CodeHolder` has been initialized.
@@ -693,10 +693,10 @@ public:
//! Emitters can be only attached to initialized `CodeHolder` instances.
inline bool isInitialized() const noexcept { return _environment.isInitialized(); }
- //! Initializes CodeHolder to hold code described by code `info`.
+ //! Initializes CodeHolder to hold code described by the given `environment` and `baseAddress`.
ASMJIT_API Error init(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept;
//! Detaches all code-generators attached and resets the `CodeHolder`.
- ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept;
+ ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
//! \}
@@ -715,10 +715,9 @@ public:
//! Returns the allocator that the `CodeHolder` uses.
//!
- //! \note This should be only used for AsmJit's purposes. Code holder uses
- //! arena allocator to allocate everything, so anything allocated through
- //! this allocator will be invalidated by \ref CodeHolder::reset() or by
- //! CodeHolder's destructor.
+ //! \note This should be only used for AsmJit's purposes. Code holder uses arena allocator to allocate everything,
+ //! so anything allocated through this allocator will be invalidated by \ref CodeHolder::reset() or by CodeHolder's
+ //! destructor.
inline ZoneAllocator* allocator() const noexcept { return const_cast<ZoneAllocator*>(&_allocator); }
//! \}
@@ -726,13 +725,13 @@ public:
//! \name Code & Architecture
//! \{
- //! Returns the target environment information, see \ref Environment.
+ //! Returns the target environment information.
inline const Environment& environment() const noexcept { return _environment; }
//! Returns the target architecture.
- inline uint32_t arch() const noexcept { return environment().arch(); }
+ inline Arch arch() const noexcept { return environment().arch(); }
//! Returns the target sub-architecture.
- inline uint32_t subArch() const noexcept { return environment().subArch(); }
+ inline SubArch subArch() const noexcept { return environment().subArch(); }
//! Tests whether a static base-address is set.
inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
@@ -752,7 +751,7 @@ public:
//! \name Logging
//! \{
- //! Returns the attached logger, see \ref Logger.
+ //! Returns the attached logger.
inline Logger* logger() const noexcept { return _logger; }
//! Attaches a `logger` to CodeHolder and propagates it to all attached emitters.
ASMJIT_API void setLogger(Logger* logger) noexcept;
@@ -778,14 +777,12 @@ public:
//! Makes sure that at least `n` bytes can be added to CodeHolder's buffer `cb`.
//!
- //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the
- //! behavior of the function is undefined.
+ //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the behavior of the function is undefined.
ASMJIT_API Error growBuffer(CodeBuffer* cb, size_t n) noexcept;
//! Reserves the size of `cb` to at least `n` bytes.
//!
- //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the
- //! behavior of the function is undefined.
+ //! \note The buffer `cb` must be managed by `CodeHolder` - otherwise the behavior of the function is undefined.
ASMJIT_API Error reserveBuffer(CodeBuffer* cb, size_t n) noexcept;
//! \}
@@ -806,7 +803,7 @@ public:
//! Creates a new section and return its pointer in `sectionOut`.
//!
//! Returns `Error`, does not report a possible error to `ErrorHandler`.
- ASMJIT_API Error newSection(Section** sectionOut, const char* name, size_t nameSize = SIZE_MAX, uint32_t flags = 0, uint32_t alignment = 1, int32_t order = 0) noexcept;
+ ASMJIT_API Error newSection(Section** sectionOut, const char* name, size_t nameSize = SIZE_MAX, SectionFlags flags = SectionFlags::kNone, uint32_t alignment = 1, int32_t order = 0) noexcept;
//! Returns a section entry of the given index.
inline Section* sectionById(uint32_t sectionId) const noexcept { return _sections[sectionId]; }
@@ -838,14 +835,12 @@ public:
//! Used to add an address to an address table.
//!
- //! This implicitly calls `ensureAddressTableSection()` and then creates
- //! `AddressTableEntry` that is inserted to `_addressTableEntries`. If the
- //! address already exists this operation does nothing as the same addresses
+ //! This implicitly calls `ensureAddressTableSection()` and then creates `AddressTableEntry` that is inserted
+ //! to `_addressTableEntries`. If the address already exists this operation does nothing as the same addresses
//! use the same slot.
//!
- //! This function should be considered internal as it's used by assemblers to
- //! insert an absolute address into the address table. Inserting address into
- //! address table without creating a particula relocation entry makes no sense.
+ //! This function should be considered internal as it's used by assemblers to insert an absolute address into the
+ //! address table. Inserting address into address table without creating a particula relocation entry makes no sense.
ASMJIT_API Error addAddressToAddressTable(uint64_t address) noexcept;
//! \}
@@ -893,8 +888,8 @@ public:
//! Returns offset of a `Label` by its `labelId`.
//!
- //! The offset returned is relative to the start of the section. Zero offset
- //! is returned for unbound labels, which is their initial offset value.
+ //! The offset returned is relative to the start of the section. Zero offset is returned for unbound labels,
+ //! which is their initial offset value.
inline uint64_t labelOffset(uint32_t labelId) const noexcept {
ASMJIT_ASSERT(isLabelValid(labelId));
return _labelEntries[labelId]->offset();
@@ -907,9 +902,8 @@ public:
//! Returns offset of a label by it's `labelId` relative to the base offset.
//!
- //! \remarks The offset of the section where the label is bound must be valid
- //! in order to use this function, otherwise the value returned will not be
- //! reliable.
+ //! \remarks The offset of the section where the label is bound must be valid in order to use this function,
+ //! otherwise the value returned will not be reliable.
inline uint64_t labelOffsetFromBase(uint32_t labelId) const noexcept {
ASMJIT_ASSERT(isLabelValid(labelId));
const LabelEntry* le = _labelEntries[labelId];
@@ -930,20 +924,18 @@ public:
//!
//! \param entryOut Where to store the created \ref LabelEntry.
//! \param name The name of the label.
- //! \param nameSize The length of `name` argument, or `SIZE_MAX` if `name` is
- //! a null terminated string, which means that the `CodeHolder` will
- //! use `strlen()` to determine the length.
- //! \param type The type of the label to create, see \ref Label::LabelType.
- //! \param parentId Parent id of a local label, otherwise it must be
- //! \ref Globals::kInvalidId.
+ //! \param nameSize The length of `name` argument, or `SIZE_MAX` if `name` is a null terminated string, which
+ //! means that the `CodeHolder` will use `strlen()` to determine the length.
+ //! \param type The type of the label to create, see \ref LabelType.
+ //! \param parentId Parent id of a local label, otherwise it must be \ref Globals::kInvalidId.
+ //! \retval Always returns \ref Error, does not report a possible error to the attached \ref ErrorHandler.
//!
- //! \retval Always returns \ref Error, does not report a possible error to
- //! the attached \ref ErrorHandler.
- //!
- //! AsmJit has a support for local labels (\ref Label::kTypeLocal) which
- //! require a parent label id (parentId). The names of local labels can
- //! conflict with names of other local labels that have a different parent.
- ASMJIT_API Error newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId = Globals::kInvalidId) noexcept;
+ //! AsmJit has a support for local labels (\ref LabelType::kLocal) which require a parent label id (parentId).
+ //! The names of local labels can conflict with names of other local labels that have a different parent. In
+ //! addition, AsmJit supports named anonymous labels, which are useful only for debugging purposes as the
+ //! anonymous name will have a name, which will be formatted, but the label itself cannot be queried by such
+ //! name.
+ ASMJIT_API Error newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, LabelType type, uint32_t parentId = Globals::kInvalidId) noexcept;
//! Returns a label by name.
//!
@@ -968,10 +960,9 @@ public:
//! Returns `null` if the allocation failed.
ASMJIT_API LabelLink* newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept;
- //! Resolves cross-section links (`LabelLink`) associated with each label that
- //! was used as a destination in code of a different section. It's only useful
- //! to people that use multiple sections as it will do nothing if the code only
- //! contains a single section in which cross-section links are not possible.
+ //! Resolves cross-section links (`LabelLink`) associated with each label that was used as a destination in code
+ //! of a different section. It's only useful to people that use multiple sections as it will do nothing if the code
+ //! only contains a single section in which cross-section links are not possible.
ASMJIT_API Error resolveUnresolvedLinks() noexcept;
//! Binds a label to a given `sectionId` and `offset` (relative to start of the section).
@@ -995,7 +986,7 @@ public:
//! Creates a new relocation entry of type `relocType`.
//!
//! Additional fields can be set after the relocation entry was created.
- ASMJIT_API Error newRelocEntry(RelocEntry** dst, uint32_t relocType) noexcept;
+ ASMJIT_API Error newRelocEntry(RelocEntry** dst, RelocType relocType) noexcept;
//! \}
@@ -1009,49 +1000,29 @@ public:
//! Returns computed the size of code & data of all sections.
//!
- //! \note All sections will be iterated over and the code size returned
- //! would represent the minimum code size of all combined sections after
- //! applying minimum alignment. Code size may decrease after calling
- //! `flatten()` and `relocateToBase()`.
+ //! \note All sections will be iterated over and the code size returned would represent the minimum code size of
+ //! all combined sections after applying minimum alignment. Code size may decrease after calling `flatten()` and
+ //! `relocateToBase()`.
ASMJIT_API size_t codeSize() const noexcept;
//! Relocates the code to the given `baseAddress`.
//!
- //! \param baseAddress Absolute base address where the code will be relocated
- //! to. Please note that nothing is copied to such base address, it's just an
- //! absolute value used by the relocator to resolve all stored relocations.
+ //! \param baseAddress Absolute base address where the code will be relocated to. Please note that nothing is
+ //! copied to such base address, it's just an absolute value used by the relocator to resolve all stored relocations.
//!
//! \note This should never be called more than once.
ASMJIT_API Error relocateToBase(uint64_t baseAddress) noexcept;
//! Copies a single section into `dst`.
- ASMJIT_API Error copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions = 0) noexcept;
+ ASMJIT_API Error copySectionData(void* dst, size_t dstSize, uint32_t sectionId, CopySectionFlags copyFlags = CopySectionFlags::kNone) noexcept;
//! Copies all sections into `dst`.
//!
- //! This should only be used if the data was flattened and there are no gaps
- //! between the sections. The `dstSize` is always checked and the copy will
- //! never write anything outside the provided buffer.
- ASMJIT_API Error copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions = 0) noexcept;
+ //! This should only be used if the data was flattened and there are no gaps between the sections. The `dstSize`
+ //! is always checked and the copy will never write anything outside the provided buffer.
+ ASMJIT_API Error copyFlattenedData(void* dst, size_t dstSize, CopySectionFlags copyFlags = CopySectionFlags::kNone) noexcept;
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use 'CodeHolder::init(const Environment& environment, uint64_t baseAddress)' instead")
- inline Error init(const CodeInfo& codeInfo) noexcept { return init(codeInfo._environment, codeInfo._baseAddress); }
-
- ASMJIT_DEPRECATED("Use nevironment() instead")
- inline CodeInfo codeInfo() const noexcept { return CodeInfo(_environment, _baseAddress); }
-
- ASMJIT_DEPRECATED("Use BaseEmitter::encodingOptions() - this function always returns zero")
- inline uint32_t emitterOptions() const noexcept { return 0; }
-
- ASMJIT_DEPRECATED("Use BaseEmitter::addEncodingOptions() - this function does nothing")
- inline void addEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); }
-
- ASMJIT_DEPRECATED("Use BaseEmitter::clearEncodingOptions() - this function does nothing")
- inline void clearEmitterOptions(uint32_t options) noexcept { DebugUtils::unused(options); }
-#endif // !ASMJIT_NO_DEPRECATED
};
//! \}
diff --git a/src/asmjit/core/codewriter.cpp b/src/asmjit/core/codewriter.cpp
index 6097c0e..772146e 100644
--- a/src/asmjit/core/codewriter.cpp
+++ b/src/asmjit/core/codewriter.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/codeholder.h"
@@ -50,13 +32,13 @@ bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const Offs
return false;
switch (format.type()) {
- case OffsetFormat::kTypeCommon: {
+ case OffsetType::kCommon: {
*dst = (uint32_t(offset32) & Support::lsbMask<uint32_t>(bitCount)) << bitShift;
return true;
}
- case OffsetFormat::kTypeAArch64_ADR:
- case OffsetFormat::kTypeAArch64_ADRP: {
+ case OffsetType::kAArch64_ADR:
+ case OffsetType::kAArch64_ADRP: {
// Sanity checks.
if (format.valueSize() != 4 || bitCount != 21 || bitShift != 5)
return false;
@@ -91,7 +73,7 @@ bool CodeWriterUtils::encodeOffset64(uint64_t* dst, int64_t offset64, const Offs
return false;
switch (format.type()) {
- case OffsetFormat::kTypeCommon: {
+ case OffsetType::kCommon: {
*dst = (uint64_t(offset64) & Support::lsbMask<uint64_t>(bitCount)) << format.immBitShift();
return true;
}
diff --git a/src/asmjit/core/codewriter_p.h b/src/asmjit/core/codewriter_p.h
index 61c9101..8b120bd 100644
--- a/src/asmjit/core/codewriter_p.h
+++ b/src/asmjit/core/codewriter_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED
#define ASMJIT_CORE_CODEBUFFERWRITER_P_H_INCLUDED
@@ -34,25 +16,17 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_assembler
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
struct OffsetFormat;
-// ============================================================================
-// [asmjit::CodeWriter]
-// ============================================================================
-
//! Helper that is used to write into a \ref CodeBuffer held by \ref BaseAssembler.
class CodeWriter {
public:
uint8_t* _cursor;
- ASMJIT_INLINE explicit CodeWriter(BaseAssembler* a) noexcept
+ ASMJIT_FORCE_INLINE explicit CodeWriter(BaseAssembler* a) noexcept
: _cursor(a->_bufferPtr) {}
- ASMJIT_INLINE Error ensureSpace(BaseAssembler* a, size_t n) noexcept {
+ ASMJIT_FORCE_INLINE Error ensureSpace(BaseAssembler* a, size_t n) noexcept {
size_t remainingSpace = (size_t)(a->_bufferEnd - _cursor);
if (ASMJIT_UNLIKELY(remainingSpace < n)) {
CodeBuffer& buffer = a->_section->_buffer;
@@ -64,24 +38,24 @@ public:
return kErrorOk;
}
- ASMJIT_INLINE uint8_t* cursor() const noexcept { return _cursor; }
- ASMJIT_INLINE void setCursor(uint8_t* cursor) noexcept { _cursor = cursor; }
- ASMJIT_INLINE void advance(size_t n) noexcept { _cursor += n; }
+ ASMJIT_FORCE_INLINE uint8_t* cursor() const noexcept { return _cursor; }
+ ASMJIT_FORCE_INLINE void setCursor(uint8_t* cursor) noexcept { _cursor = cursor; }
+ ASMJIT_FORCE_INLINE void advance(size_t n) noexcept { _cursor += n; }
- ASMJIT_INLINE size_t offsetFrom(uint8_t* from) const noexcept {
+ ASMJIT_FORCE_INLINE size_t offsetFrom(uint8_t* from) const noexcept {
ASMJIT_ASSERT(_cursor >= from);
return (size_t)(_cursor - from);
}
template<typename T>
- ASMJIT_INLINE void emit8(T val) noexcept {
+ ASMJIT_FORCE_INLINE void emit8(T val) noexcept {
typedef typename std::make_unsigned<T>::type U;
_cursor[0] = uint8_t(U(val) & U(0xFF));
_cursor++;
}
template<typename T, typename Y>
- ASMJIT_INLINE void emit8If(T val, Y cond) noexcept {
+ ASMJIT_FORCE_INLINE void emit8If(T val, Y cond) noexcept {
typedef typename std::make_unsigned<T>::type U;
ASMJIT_ASSERT(size_t(cond) <= 1u);
@@ -90,41 +64,41 @@ public:
}
template<typename T>
- ASMJIT_INLINE void emit16uLE(T val) noexcept {
+ ASMJIT_FORCE_INLINE void emit16uLE(T val) noexcept {
typedef typename std::make_unsigned<T>::type U;
Support::writeU16uLE(_cursor, uint32_t(U(val) & 0xFFFFu));
_cursor += 2;
}
template<typename T>
- ASMJIT_INLINE void emit16uBE(T val) noexcept {
+ ASMJIT_FORCE_INLINE void emit16uBE(T val) noexcept {
typedef typename std::make_unsigned<T>::type U;
Support::writeU16uBE(_cursor, uint32_t(U(val) & 0xFFFFu));
_cursor += 2;
}
template<typename T>
- ASMJIT_INLINE void emit32uLE(T val) noexcept {
+ ASMJIT_FORCE_INLINE void emit32uLE(T val) noexcept {
typedef typename std::make_unsigned<T>::type U;
Support::writeU32uLE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu));
_cursor += 4;
}
template<typename T>
- ASMJIT_INLINE void emit32uBE(T val) noexcept {
+ ASMJIT_FORCE_INLINE void emit32uBE(T val) noexcept {
typedef typename std::make_unsigned<T>::type U;
Support::writeU32uBE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu));
_cursor += 4;
}
- ASMJIT_INLINE void emitData(const void* data, size_t size) noexcept {
+ ASMJIT_FORCE_INLINE void emitData(const void* data, size_t size) noexcept {
ASMJIT_ASSERT(size != 0);
memcpy(_cursor, data, size);
_cursor += size;
}
template<typename T>
- ASMJIT_INLINE void emitValueLE(const T& value, size_t size) noexcept {
+ ASMJIT_FORCE_INLINE void emitValueLE(const T& value, size_t size) noexcept {
typedef typename std::make_unsigned<T>::type U;
ASMJIT_ASSERT(size <= sizeof(T));
@@ -137,7 +111,7 @@ public:
}
template<typename T>
- ASMJIT_INLINE void emitValueBE(const T& value, size_t size) noexcept {
+ ASMJIT_FORCE_INLINE void emitValueBE(const T& value, size_t size) noexcept {
typedef typename std::make_unsigned<T>::type U;
ASMJIT_ASSERT(size <= sizeof(T));
@@ -149,13 +123,13 @@ public:
_cursor += size;
}
- ASMJIT_INLINE void emitZeros(size_t size) noexcept {
+ ASMJIT_FORCE_INLINE void emitZeros(size_t size) noexcept {
ASMJIT_ASSERT(size != 0);
memset(_cursor, 0, size);
_cursor += size;
}
- ASMJIT_INLINE void remove8(uint8_t* where) noexcept {
+ ASMJIT_FORCE_INLINE void remove8(uint8_t* where) noexcept {
ASMJIT_ASSERT(where < _cursor);
uint8_t* p = where;
@@ -165,7 +139,7 @@ public:
}
template<typename T>
- ASMJIT_INLINE void insert8(uint8_t* where, T val) noexcept {
+ ASMJIT_FORCE_INLINE void insert8(uint8_t* where, T val) noexcept {
uint8_t* p = _cursor;
while (p != where) {
@@ -177,7 +151,7 @@ public:
_cursor++;
}
- ASMJIT_INLINE void done(BaseAssembler* a) noexcept {
+ ASMJIT_FORCE_INLINE void done(BaseAssembler* a) noexcept {
CodeBuffer& buffer = a->_section->_buffer;
size_t newSize = (size_t)(_cursor - a->_bufferData);
ASMJIT_ASSERT(newSize <= buffer.capacity());
@@ -187,10 +161,7 @@ public:
}
};
-// ============================================================================
-// [asmjit::CodeWriterUtils]
-// ============================================================================
-
+//! Code writer utilities.
namespace CodeWriterUtils {
bool encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept;
diff --git a/src/asmjit/core/compiler.cpp b/src/asmjit/core/compiler.cpp
index 6bd889f..bfa84f3 100644
--- a/src/asmjit/core/compiler.cpp
+++ b/src/asmjit/core/compiler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_COMPILER
@@ -35,11 +17,11 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::GlobalConstPoolPass]
-// ============================================================================
+// GlobalConstPoolPass
+// ===================
class GlobalConstPoolPass : public Pass {
+public:
typedef Pass Base;
public:
ASMJIT_NONCOPYABLE(GlobalConstPoolPass)
@@ -51,53 +33,50 @@ public:
// Flush the global constant pool.
BaseCompiler* compiler = static_cast<BaseCompiler*>(_cb);
- if (compiler->_globalConstPool) {
- compiler->addAfter(compiler->_globalConstPool, compiler->lastNode());
- compiler->_globalConstPool = nullptr;
+ ConstPoolNode* globalConstPool = compiler->_constPools[uint32_t(ConstPoolScope::kGlobal)];
+
+ if (globalConstPool) {
+ compiler->addAfter(globalConstPool, compiler->lastNode());
+ compiler->_constPools[uint32_t(ConstPoolScope::kGlobal)] = nullptr;
}
return kErrorOk;
}
};
-// ============================================================================
-// [asmjit::BaseCompiler - Construction / Destruction]
-// ============================================================================
+// BaseCompiler - Construction & Destruction
+// =========================================
BaseCompiler::BaseCompiler() noexcept
: BaseBuilder(),
_func(nullptr),
_vRegZone(4096 - Zone::kBlockOverhead),
_vRegArray(),
- _localConstPool(nullptr),
- _globalConstPool(nullptr) {
-
- _emitterType = uint8_t(kTypeCompiler);
- _validationFlags = uint8_t(InstAPI::kValidationFlagVirtRegs);
+ _constPools { nullptr, nullptr } {
+ _emitterType = EmitterType::kCompiler;
+ _validationFlags = ValidationFlags::kEnableVirtRegs;
}
BaseCompiler::~BaseCompiler() noexcept {}
-// ============================================================================
-// [asmjit::BaseCompiler - Function Management]
-// ============================================================================
+// BaseCompiler - Function Management
+// ==================================
-Error BaseCompiler::_newFuncNode(FuncNode** out, const FuncSignature& signature) {
+Error BaseCompiler::newFuncNode(FuncNode** out, const FuncSignature& signature) {
*out = nullptr;
// Create FuncNode together with all the required surrounding nodes.
FuncNode* funcNode;
ASMJIT_PROPAGATE(_newNodeT<FuncNode>(&funcNode));
- ASMJIT_PROPAGATE(_newLabelNode(&funcNode->_exitNode));
- ASMJIT_PROPAGATE(_newNodeT<SentinelNode>(&funcNode->_end, SentinelNode::kSentinelFuncEnd));
+ ASMJIT_PROPAGATE(newLabelNode(&funcNode->_exitNode));
+ ASMJIT_PROPAGATE(_newNodeT<SentinelNode>(&funcNode->_end, SentinelType::kFuncEnd));
// Initialize the function's detail info.
Error err = funcNode->detail().init(signature, environment());
if (ASMJIT_UNLIKELY(err))
return reportError(err);
- // If the Target guarantees greater stack alignment than required by the
- // calling convention then override it as we can prevent having to perform
- // dynamic stack alignment
+ // If the Target guarantees greater stack alignment than required by the calling convention
+ // then override it as we can prevent having to perform dynamic stack alignment
uint32_t environmentStackAlignment = _environment.stackAlignment();
if (funcNode->_funcDetail._callConv.naturalStackAlignment() < environmentStackAlignment)
@@ -123,13 +102,13 @@ Error BaseCompiler::_newFuncNode(FuncNode** out, const FuncSignature& signature)
return kErrorOk;
}
-Error BaseCompiler::_addFuncNode(FuncNode** out, const FuncSignature& signature) {
- ASMJIT_PROPAGATE(_newFuncNode(out, signature));
+Error BaseCompiler::addFuncNode(FuncNode** out, const FuncSignature& signature) {
+ ASMJIT_PROPAGATE(newFuncNode(out, signature));
addFunc(*out);
return kErrorOk;
}
-Error BaseCompiler::_newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
+Error BaseCompiler::newFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
uint32_t opCount = !o1.isNone() ? 2u : !o0.isNone() ? 1u : 0u;
FuncRetNode* node;
@@ -143,8 +122,8 @@ Error BaseCompiler::_newRetNode(FuncRetNode** out, const Operand_& o0, const Ope
return kErrorOk;
}
-Error BaseCompiler::_addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
- ASMJIT_PROPAGATE(_newRetNode(out, o0, o1));
+Error BaseCompiler::addFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
+ ASMJIT_PROPAGATE(newFuncRetNode(out, o0, o1));
addNode(*out);
return kErrorOk;
}
@@ -169,10 +148,11 @@ Error BaseCompiler::endFunc() {
return reportError(DebugUtils::errored(kErrorInvalidState));
// Add the local constant pool at the end of the function (if exists).
- if (_localConstPool) {
+ ConstPoolNode* localConstPool = _constPools[uint32_t(ConstPoolScope::kLocal)];
+ if (localConstPool) {
setCursor(func->endNode()->prev());
- addNode(_localConstPool);
- _localConstPool = nullptr;
+ addNode(localConstPool);
+ _constPools[uint32_t(ConstPoolScope::kLocal)] = nullptr;
}
// Mark as finished.
@@ -184,28 +164,12 @@ Error BaseCompiler::endFunc() {
return kErrorOk;
}
-Error BaseCompiler::_setArg(size_t argIndex, size_t valueIndex, const BaseReg& r) {
- FuncNode* func = _func;
-
- if (ASMJIT_UNLIKELY(!func))
- return reportError(DebugUtils::errored(kErrorInvalidState));
-
- if (ASMJIT_UNLIKELY(!isVirtRegValid(r)))
- return reportError(DebugUtils::errored(kErrorInvalidVirtId));
-
- VirtReg* vReg = virtRegByReg(r);
- func->setArg(argIndex, valueIndex, vReg);
-
- return kErrorOk;
-}
-
-// ============================================================================
-// [asmjit::BaseCompiler - Function Invocation]
-// ============================================================================
+// BaseCompiler - Function Invocation
+// ==================================
-Error BaseCompiler::_newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
+Error BaseCompiler::newInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature) {
InvokeNode* node;
- ASMJIT_PROPAGATE(_newNodeT<InvokeNode>(&node, instId, 0u));
+ ASMJIT_PROPAGATE(_newNodeT<InvokeNode>(&node, instId, InstOptions::kNone));
node->setOpCount(1);
node->setOp(0, o0);
@@ -228,15 +192,14 @@ Error BaseCompiler::_newInvokeNode(InvokeNode** out, uint32_t instId, const Oper
return kErrorOk;
}
-Error BaseCompiler::_addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
- ASMJIT_PROPAGATE(_newInvokeNode(out, instId, o0, signature));
+Error BaseCompiler::addInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature) {
+ ASMJIT_PROPAGATE(newInvokeNode(out, instId, o0, signature));
addNode(*out);
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseCompiler - Virtual Registers]
-// ============================================================================
+// BaseCompiler - Virtual Registers
+// ================================
static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) {
uint32_t index = unsigned(Operand::virtIdToIndex(vReg->_id));
@@ -248,7 +211,7 @@ static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) {
vReg->_name.setData(&self->_dataZone, buf, unsigned(size));
}
-Error BaseCompiler::newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name) {
+Error BaseCompiler::newVirtReg(VirtReg** out, TypeId typeId, OperandSignature signature, const char* name) {
*out = nullptr;
uint32_t index = _vRegArray.size();
@@ -262,10 +225,10 @@ Error BaseCompiler::newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signatur
if (ASMJIT_UNLIKELY(!vReg))
return reportError(DebugUtils::errored(kErrorOutOfMemory));
- uint32_t size = Type::sizeOf(typeId);
+ uint32_t size = TypeUtils::sizeOf(typeId);
uint32_t alignment = Support::min<uint32_t>(size, 64);
- vReg = new(vReg) VirtReg(Operand::indexToVirtId(index), signature, size, alignment, typeId);
+ vReg = new(vReg) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId);
#ifndef ASMJIT_NO_LOGGING
if (name && name[0] != '\0')
@@ -282,22 +245,22 @@ Error BaseCompiler::newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signatur
return kErrorOk;
}
-Error BaseCompiler::_newReg(BaseReg* out, uint32_t typeId, const char* name) {
- RegInfo regInfo;
+Error BaseCompiler::_newReg(BaseReg* out, TypeId typeId, const char* name) {
+ OperandSignature regSignature;
out->reset();
- Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, &regInfo);
+ Error err = ArchUtils::typeIdToRegSignature(arch(), typeId, &typeId, &regSignature);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
VirtReg* vReg;
- ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name));
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regSignature, name));
- out->_initReg(regInfo.signature(), vReg->id());
+ out->_initReg(regSignature, vReg->id());
return kErrorOk;
}
-Error BaseCompiler::_newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...) {
+Error BaseCompiler::_newRegFmt(BaseReg* out, TypeId typeId, const char* fmt, ...) {
va_list ap;
StringTmp<256> sb;
@@ -311,75 +274,72 @@ Error BaseCompiler::_newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, .
Error BaseCompiler::_newReg(BaseReg* out, const BaseReg& ref, const char* name) {
out->reset();
- RegInfo regInfo;
- uint32_t typeId;
+ OperandSignature regSignature;
+ TypeId typeId;
if (isVirtRegValid(ref)) {
VirtReg* vRef = virtRegByReg(ref);
typeId = vRef->typeId();
- // NOTE: It's possible to cast one register type to another if it's the
- // same register group. However, VirtReg always contains the TypeId that
- // was used to create the register. This means that in some cases we may
- // end up having different size of `ref` and `vRef`. In such case we
- // adjust the TypeId to match the `ref` register type instead of the
- // original register type, which should be the expected behavior.
- uint32_t typeSize = Type::sizeOf(typeId);
+ // NOTE: It's possible to cast one register type to another if it's the same register group. However, VirtReg
+ // always contains the TypeId that was used to create the register. This means that in some cases we may end
+ // up having different size of `ref` and `vRef`. In such case we adjust the TypeId to match the `ref` register
+ // type instead of the original register type, which should be the expected behavior.
+ uint32_t typeSize = TypeUtils::sizeOf(typeId);
uint32_t refSize = ref.size();
if (typeSize != refSize) {
- if (Type::isInt(typeId)) {
+ if (TypeUtils::isInt(typeId)) {
// GP register - change TypeId to match `ref`, but keep sign of `vRef`.
switch (refSize) {
- case 1: typeId = Type::kIdI8 | (typeId & 1); break;
- case 2: typeId = Type::kIdI16 | (typeId & 1); break;
- case 4: typeId = Type::kIdI32 | (typeId & 1); break;
- case 8: typeId = Type::kIdI64 | (typeId & 1); break;
- default: typeId = Type::kIdVoid; break;
+ case 1: typeId = TypeId(uint32_t(TypeId::kInt8 ) | (uint32_t(typeId) & 1)); break;
+ case 2: typeId = TypeId(uint32_t(TypeId::kInt16) | (uint32_t(typeId) & 1)); break;
+ case 4: typeId = TypeId(uint32_t(TypeId::kInt32) | (uint32_t(typeId) & 1)); break;
+ case 8: typeId = TypeId(uint32_t(TypeId::kInt64) | (uint32_t(typeId) & 1)); break;
+ default: typeId = TypeId::kVoid; break;
}
}
- else if (Type::isMmx(typeId)) {
+ else if (TypeUtils::isMmx(typeId)) {
// MMX register - always use 64-bit.
- typeId = Type::kIdMmx64;
+ typeId = TypeId::kMmx64;
}
- else if (Type::isMask(typeId)) {
+ else if (TypeUtils::isMask(typeId)) {
// Mask register - change TypeId to match `ref` size.
switch (refSize) {
- case 1: typeId = Type::kIdMask8; break;
- case 2: typeId = Type::kIdMask16; break;
- case 4: typeId = Type::kIdMask32; break;
- case 8: typeId = Type::kIdMask64; break;
- default: typeId = Type::kIdVoid; break;
+ case 1: typeId = TypeId::kMask8; break;
+ case 2: typeId = TypeId::kMask16; break;
+ case 4: typeId = TypeId::kMask32; break;
+ case 8: typeId = TypeId::kMask64; break;
+ default: typeId = TypeId::kVoid; break;
}
}
else {
- // VEC register - change TypeId to match `ref` size, keep vector metadata.
- uint32_t elementTypeId = Type::baseOf(typeId);
-
+ // Vector register - change TypeId to match `ref` size, keep vector metadata.
+ TypeId scalarTypeId = TypeUtils::scalarOf(typeId);
switch (refSize) {
- case 16: typeId = Type::_kIdVec128Start + (elementTypeId - Type::kIdI8); break;
- case 32: typeId = Type::_kIdVec256Start + (elementTypeId - Type::kIdI8); break;
- case 64: typeId = Type::_kIdVec512Start + (elementTypeId - Type::kIdI8); break;
- default: typeId = Type::kIdVoid; break;
+ case 16: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec128Start); break;
+ case 32: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec256Start); break;
+ case 64: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec512Start); break;
+ default: typeId = TypeId::kVoid; break;
}
}
- if (typeId == Type::kIdVoid)
+ if (typeId == TypeId::kVoid)
return reportError(DebugUtils::errored(kErrorInvalidState));
}
}
else {
- typeId = ref.type();
+ typeId = ArchTraits::byArch(arch()).regTypeToTypeId(ref.type());
}
- Error err = ArchUtils::typeIdToRegInfo(arch(), typeId, &typeId, &regInfo);
+ Error err = ArchUtils::typeIdToRegSignature(arch(), typeId, &typeId, &regSignature);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
VirtReg* vReg;
- ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regInfo.signature(), name));
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regSignature, name));
- out->_initReg(regInfo.signature(), vReg->id());
+ out->_initReg(regSignature, vReg->id());
return kErrorOk;
}
@@ -410,14 +370,17 @@ Error BaseCompiler::_newStack(BaseMem* out, uint32_t size, uint32_t alignment, c
alignment = 64;
VirtReg* vReg;
- ASMJIT_PROPAGATE(newVirtReg(&vReg, 0, 0, name));
+ ASMJIT_PROPAGATE(newVirtReg(&vReg, TypeId::kVoid, OperandSignature(0), name));
vReg->_virtSize = size;
vReg->_isStack = true;
vReg->_alignment = uint8_t(alignment);
// Set the memory operand to GPD/GPQ and its id to VirtReg.
- *out = BaseMem(BaseMem::Decomposed { _gpRegInfo.type(), vReg->id(), BaseReg::kTypeNone, 0, 0, 0, BaseMem::kSignatureMemRegHomeFlag });
+ *out = BaseMem(OperandSignature::fromOpType(OperandType::kMem) |
+ OperandSignature::fromMemBaseType(_gpSignature.regType()) |
+ OperandSignature::fromBits(OperandSignature::kMemRegHomeFlag),
+ vReg->id(), 0, 0);
return kErrorOk;
}
@@ -438,9 +401,8 @@ Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t new
if (newAlignment)
vReg->_alignment = uint8_t(newAlignment);
- // This is required if the RAPass is already running. There is a chance that
- // a stack-slot has been already allocated and in that case it has to be
- // updated as well, otherwise we would allocate wrong amount of memory.
+ // This is required if the RAPass is already running. There is a chance that a stack-slot has been already
+ // allocated and in that case it has to be updated as well, otherwise we would allocate wrong amount of memory.
RAWorkReg* workReg = vReg->_workReg;
if (workReg && workReg->_stackSlot) {
workReg->_stackSlot->_size = vReg->_virtSize;
@@ -450,37 +412,26 @@ Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t new
return kErrorOk;
}
-Error BaseCompiler::_newConst(BaseMem* out, uint32_t scope, const void* data, size_t size) {
+Error BaseCompiler::_newConst(BaseMem* out, ConstPoolScope scope, const void* data, size_t size) {
out->reset();
- ConstPoolNode** pPool;
- if (scope == ConstPool::kScopeLocal)
- pPool = &_localConstPool;
- else if (scope == ConstPool::kScopeGlobal)
- pPool = &_globalConstPool;
- else
+ if (uint32_t(scope) > 1)
return reportError(DebugUtils::errored(kErrorInvalidArgument));
- if (!*pPool)
- ASMJIT_PROPAGATE(_newConstPoolNode(pPool));
+ if (!_constPools[uint32_t(scope)])
+ ASMJIT_PROPAGATE(newConstPoolNode(&_constPools[uint32_t(scope)]));
- ConstPoolNode* pool = *pPool;
+ ConstPoolNode* pool = _constPools[uint32_t(scope)];
size_t off;
Error err = pool->add(data, size, off);
if (ASMJIT_UNLIKELY(err))
return reportError(err);
- *out = BaseMem(BaseMem::Decomposed {
- Label::kLabelTag, // Base type.
- pool->labelId(), // Base id.
- 0, // Index type.
- 0, // Index id.
- int32_t(off), // Offset.
- uint32_t(size), // Size.
- 0 // Flags.
- });
-
+ *out = BaseMem(OperandSignature::fromOpType(OperandType::kMem) |
+ OperandSignature::fromMemBaseType(RegType::kLabelTag) |
+ OperandSignature::fromSize(uint32_t(size)),
+ pool->labelId(), 0, int32_t(off));
return kErrorOk;
}
@@ -505,11 +456,10 @@ void BaseCompiler::rename(const BaseReg& reg, const char* fmt, ...) {
}
}
-// ============================================================================
-// [asmjit::BaseCompiler - Jump Annotations]
-// ============================================================================
+// BaseCompiler - Jump Annotations
+// ===============================
-Error BaseCompiler::newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation) {
+Error BaseCompiler::newJumpNode(JumpNode** out, InstId instId, InstOptions instOptions, const Operand_& o0, JumpAnnotation* annotation) {
JumpNode* node = _allocator.allocT<JumpNode>();
uint32_t opCount = 1;
@@ -524,8 +474,8 @@ Error BaseCompiler::newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOp
return kErrorOk;
}
-Error BaseCompiler::emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation) {
- uint32_t options = instOptions() | forcedInstOptions();
+Error BaseCompiler::emitAnnotatedJump(InstId instId, const Operand_& o0, JumpAnnotation* annotation) {
+ InstOptions options = instOptions() | forcedInstOptions();
RegOnly extra = extraReg();
const char* comment = inlineComment();
@@ -562,16 +512,15 @@ JumpAnnotation* BaseCompiler::newJumpAnnotation() {
return jumpAnnotation;
}
-// ============================================================================
-// [asmjit::BaseCompiler - Events]
-// ============================================================================
+// BaseCompiler - Events
+// =====================
Error BaseCompiler::onAttach(CodeHolder* code) noexcept {
ASMJIT_PROPAGATE(Base::onAttach(code));
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
- uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
- _gpRegInfo.setSignature(archTraits.regTypeToSignature(nativeRegType));
+ RegType nativeRegType = Environment::is32Bit(code->arch()) ? RegType::kGp32 : RegType::kGp64;
+ _gpSignature = archTraits.regTypeToSignature(nativeRegType);
Error err = addPassT<GlobalConstPoolPass>();
if (ASMJIT_UNLIKELY(err)) {
@@ -584,8 +533,8 @@ Error BaseCompiler::onAttach(CodeHolder* code) noexcept {
Error BaseCompiler::onDetach(CodeHolder* code) noexcept {
_func = nullptr;
- _localConstPool = nullptr;
- _globalConstPool = nullptr;
+ _constPools[uint32_t(ConstPoolScope::kLocal)] = nullptr;
+ _constPools[uint32_t(ConstPoolScope::kGlobal)] = nullptr;
_vRegArray.reset();
_vRegZone.reset();
@@ -593,32 +542,30 @@ Error BaseCompiler::onDetach(CodeHolder* code) noexcept {
return Base::onDetach(code);
}
-// ============================================================================
-// [asmjit::FuncPass - Construction / Destruction]
-// ============================================================================
+// FuncPass - Construction & Destruction
+// =====================================
FuncPass::FuncPass(const char* name) noexcept
: Pass(name) {}
-// ============================================================================
-// [asmjit::FuncPass - Run]
-// ============================================================================
+// FuncPass - Run
+// ==============
Error FuncPass::run(Zone* zone, Logger* logger) {
BaseNode* node = cb()->firstNode();
if (!node) return kErrorOk;
do {
- if (node->type() == BaseNode::kNodeFunc) {
+ if (node->type() == NodeType::kFunc) {
FuncNode* func = node->as<FuncNode>();
node = func->endNode();
ASMJIT_PROPAGATE(runOnFunction(zone, logger, func));
}
- // Find a function by skipping all nodes that are not `kNodeFunc`.
+ // Find a function by skipping all nodes that are not `NodeType::kFunc`.
do {
node = node->next();
- } while (node && node->type() != BaseNode::kNodeFunc);
+ } while (node && node->type() != NodeType::kFunc);
} while (node);
return kErrorOk;
diff --git a/src/asmjit/core/compiler.h b/src/asmjit/core/compiler.h
index 4c4cd33..1331e62 100644
--- a/src/asmjit/core/compiler.h
+++ b/src/asmjit/core/compiler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_COMPILER_H_INCLUDED
#define ASMJIT_CORE_COMPILER_H_INCLUDED
@@ -40,10 +22,6 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class JumpAnnotation;
class JumpNode;
class FuncNode;
@@ -53,25 +31,18 @@ class InvokeNode;
//! \addtogroup asmjit_compiler
//! \{
-// ============================================================================
-// [asmjit::BaseCompiler]
-// ============================================================================
-
//! Code emitter that uses virtual registers and performs register allocation.
//!
-//! Compiler is a high-level code-generation tool that provides register
-//! allocation and automatic handling of function calling conventions. It was
-//! primarily designed for merging multiple parts of code into a function
-//! without worrying about registers and function calling conventions.
+//! Compiler is a high-level code-generation tool that provides register allocation and automatic handling of function
+//! calling conventions. It was primarily designed for merging multiple parts of code into a function without worrying
+//! about registers and function calling conventions.
//!
-//! BaseCompiler can be used, with a minimum effort, to handle 32-bit and
-//! 64-bit code generation within a single code base.
+//! BaseCompiler can be used, with a minimum effort, to handle 32-bit and 64-bit code generation within a single code
+//! base.
//!
-//! BaseCompiler is based on BaseBuilder and contains all the features it
-//! provides. It means that the code it stores can be modified (removed, added,
-//! injected) and analyzed. When the code is finalized the compiler can emit
-//! the code into an Assembler to translate the abstract representation into a
-//! machine code.
+//! BaseCompiler is based on BaseBuilder and contains all the features it provides. It means that the code it stores
+//! can be modified (removed, added, injected) and analyzed. When the code is finalized the compiler can emit the code
+//! into an Assembler to translate the abstract representation into a machine code.
//!
//! Check out architecture specific compilers for more details and examples:
//!
@@ -81,6 +52,9 @@ public:
ASMJIT_NONCOPYABLE(BaseCompiler)
typedef BaseBuilder Base;
+ //! \name Members
+ //! \{
+
//! Current function.
FuncNode* _func;
//! Allocates `VirtReg` objects.
@@ -90,10 +64,12 @@ public:
//! Stores jump annotations.
ZoneVector<JumpAnnotation*> _jumpAnnotations;
- //! Local constant pool, flushed at the end of each function.
- ConstPoolNode* _localConstPool;
- //! Global constant pool, flushed by `finalize()`.
- ConstPoolNode* _globalConstPool;
+ //! Local and global constant pools.
+ //!
+ //! Local constant pool is flushed with each function, global constant pool is flushed only by \ref finalize().
+ ConstPoolNode* _constPools[2];
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -108,31 +84,31 @@ public:
//! \name Function Management
//! \{
- //! Returns the current function.
- inline FuncNode* func() const noexcept { return _func; }
-
//! Creates a new \ref FuncNode.
- ASMJIT_API Error _newFuncNode(FuncNode** out, const FuncSignature& signature);
- //! Creates a new \ref FuncNode adds it to the compiler.
- ASMJIT_API Error _addFuncNode(FuncNode** out, const FuncSignature& signature);
+ ASMJIT_API Error newFuncNode(FuncNode** out, const FuncSignature& signature);
+ //! Creates a new \ref FuncNode adds it to the instruction stream.
+ ASMJIT_API Error addFuncNode(FuncNode** out, const FuncSignature& signature);
//! Creates a new \ref FuncRetNode.
- ASMJIT_API Error _newRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
- //! Creates a new \ref FuncRetNode and adds it to the compiler.
- ASMJIT_API Error _addRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
+ ASMJIT_API Error newFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
+ //! Creates a new \ref FuncRetNode and adds it to the instruction stream.
+ ASMJIT_API Error addFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1);
+
+ //! Returns the current function.
+ inline FuncNode* func() const noexcept { return _func; }
//! Creates a new \ref FuncNode with the given `signature` and returns it.
inline FuncNode* newFunc(const FuncSignature& signature) {
FuncNode* node;
- _newFuncNode(&node, signature);
+ newFuncNode(&node, signature);
return node;
}
- //! Creates a new \ref FuncNode with the given `signature`, adds it to the
- //! compiler by using the \ref addFunc(FuncNode*) overload, and returns it.
+ //! Creates a new \ref FuncNode with the given `signature`, adds it to the instruction stream by using
+ //! the \ref addFunc(FuncNode*) overload, and returns it.
inline FuncNode* addFunc(const FuncSignature& signature) {
FuncNode* node;
- _addFuncNode(&node, signature);
+ addFuncNode(&node, signature);
return node;
}
@@ -141,23 +117,21 @@ public:
//! Emits a sentinel that marks the end of the current function.
ASMJIT_API Error endFunc();
- ASMJIT_API Error _setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg);
+#if !defined(ASMJIT_NO_DEPRECATED)
+ inline Error _setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg);
//! Sets a function argument at `argIndex` to `reg`.
+ ASMJIT_DEPRECATED("Setting arguments through Compiler is deprecated, use FuncNode->setArg() instead")
inline Error setArg(size_t argIndex, const BaseReg& reg) { return _setArg(argIndex, 0, reg); }
+
//! Sets a function argument at `argIndex` at `valueIndex` to `reg`.
+ ASMJIT_DEPRECATED("Setting arguments through Compiler is deprecated, use FuncNode->setArg() instead")
inline Error setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) { return _setArg(argIndex, valueIndex, reg); }
+#endif
- inline FuncRetNode* newRet(const Operand_& o0, const Operand_& o1) {
+ inline Error addRet(const Operand_& o0, const Operand_& o1) {
FuncRetNode* node;
- _newRetNode(&node, o0, o1);
- return node;
- }
-
- inline FuncRetNode* addRet(const Operand_& o0, const Operand_& o1) {
- FuncRetNode* node;
- _addRetNode(&node, o0, o1);
- return node;
+ return addFuncRetNode(&node, o0, o1);
}
//! \}
@@ -166,23 +140,9 @@ public:
//! \{
//! Creates a new \ref InvokeNode.
- ASMJIT_API Error _newInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature);
- //! Creates a new \ref InvokeNode and adds it to Compiler.
- ASMJIT_API Error _addInvokeNode(InvokeNode** out, uint32_t instId, const Operand_& o0, const FuncSignature& signature);
-
- //! Creates a new `InvokeNode`.
- inline InvokeNode* newCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
- InvokeNode* node;
- _newInvokeNode(&node, instId, o0, signature);
- return node;
- }
-
- //! Adds a new `InvokeNode`.
- inline InvokeNode* addCall(uint32_t instId, const Operand_& o0, const FuncSignature& signature) {
- InvokeNode* node;
- _addInvokeNode(&node, instId, o0, signature);
- return node;
- }
+ ASMJIT_API Error newInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature);
+ //! Creates a new \ref InvokeNode and adds it to the instruction stream.
+ ASMJIT_API Error addInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature);
//! \}
@@ -191,18 +151,17 @@ public:
//! Creates a new virtual register representing the given `typeId` and `signature`.
//!
- //! \note This function is public, but it's not generally recommended to be used
- //! by AsmJit users, use architecture-specific `newReg()` functionality instead
- //! or functions like \ref _newReg() and \ref _newRegFmt().
- ASMJIT_API Error newVirtReg(VirtReg** out, uint32_t typeId, uint32_t signature, const char* name);
+ //! \note This function is public, but it's not generally recommended to be used by AsmJit users, use architecture
+ //! specific `newReg()` functionality instead or functions like \ref _newReg() and \ref _newRegFmt().
+ ASMJIT_API Error newVirtReg(VirtReg** out, TypeId typeId, OperandSignature signature, const char* name);
//! Creates a new virtual register of the given `typeId` and stores it to `out` operand.
- ASMJIT_API Error _newReg(BaseReg* out, uint32_t typeId, const char* name = nullptr);
+ ASMJIT_API Error _newReg(BaseReg* out, TypeId typeId, const char* name = nullptr);
//! Creates a new virtual register of the given `typeId` and stores it to `out` operand.
//!
//! \note This version accepts a snprintf() format `fmt` followed by a variadic arguments.
- ASMJIT_API Error _newRegFmt(BaseReg* out, uint32_t typeId, const char* fmt, ...);
+ ASMJIT_API Error _newRegFmt(BaseReg* out, TypeId typeId, const char* fmt, ...);
//! Creates a new virtual register compatible with the provided reference register `ref`.
ASMJIT_API Error _newReg(BaseReg* out, const BaseReg& ref, const char* name = nullptr);
@@ -233,9 +192,8 @@ public:
//! Returns \ref VirtReg associated with the given virtual register `index`.
//!
- //! \note This is not the same as virtual register id. The conversion between
- //! id and its index is implemented by \ref Operand_::virtIdToIndex() and \ref
- //! Operand_::indexToVirtId() functions.
+ //! \note This is not the same as virtual register id. The conversion between id and its index is implemented
+ //! by \ref Operand_::virtIdToIndex() and \ref Operand_::indexToVirtId() functions.
inline VirtReg* virtRegByIndex(uint32_t index) const noexcept { return _vRegArray[index]; }
//! Returns an array of all virtual registers managed by the Compiler.
@@ -262,11 +220,11 @@ public:
//! \name Constants
//! \{
- //! Creates a new constant of the given `scope` (see \ref ConstPool::Scope).
+ //! Creates a new constant of the given `scope` (see \ref ConstPoolScope).
//!
- //! This function adds a constant of the given `size` to the built-in \ref
- //! ConstPool and stores the reference to that constant to the `out` operand.
- ASMJIT_API Error _newConst(BaseMem* out, uint32_t scope, const void* data, size_t size);
+ //! This function adds a constant of the given `size` to the built-in \ref ConstPool and stores the reference to that
+ //! constant to the `out` operand.
+ ASMJIT_API Error _newConst(BaseMem* out, ConstPoolScope scope, const void* data, size_t size);
//! \}
@@ -285,23 +243,15 @@ public:
return _jumpAnnotations;
}
- ASMJIT_API Error newJumpNode(JumpNode** out, uint32_t instId, uint32_t instOptions, const Operand_& o0, JumpAnnotation* annotation);
- ASMJIT_API Error emitAnnotatedJump(uint32_t instId, const Operand_& o0, JumpAnnotation* annotation);
+ ASMJIT_API Error newJumpNode(JumpNode** out, InstId instId, InstOptions instOptions, const Operand_& o0, JumpAnnotation* annotation);
+ ASMJIT_API Error emitAnnotatedJump(InstId instId, const Operand_& o0, JumpAnnotation* annotation);
- //! Returns a new `JumpAnnotation` instance, which can be used to aggregate
- //! possible targets of a jump where the target is not a label, for example
- //! to implement jump tables.
+ //! Returns a new `JumpAnnotation` instance, which can be used to aggregate possible targets of a jump where the
+ //! target is not a label, for example to implement jump tables.
ASMJIT_API JumpAnnotation* newJumpAnnotation();
//! \}
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("alloc() has no effect, it will be removed in the future")
- inline void alloc(BaseReg&) {}
- ASMJIT_DEPRECATED("spill() has no effect, it will be removed in the future")
- inline void spill(BaseReg&) {}
-#endif // !ASMJIT_NO_DEPRECATED
-
//! \name Events
//! \{
@@ -311,22 +261,19 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::JumpAnnotation]
-// ============================================================================
-
//! Jump annotation used to annotate jumps.
//!
-//! \ref BaseCompiler allows to emit jumps where the target is either register
-//! or memory operand. Such jumps cannot be trivially inspected, so instead of
-//! doing heuristics AsmJit allows to annotate such jumps with possible targets.
-//! Register allocator then use the annotation to construct control-flow, which
-//! is then used by liveness analysis and other tools to prepare ground for
-//! register allocation.
+//! \ref BaseCompiler allows to emit jumps where the target is either register or memory operand. Such jumps cannot be
+//! trivially inspected, so instead of doing heuristics AsmJit allows to annotate such jumps with possible targets.
+//! Register allocator then uses the annotation to construct control-flow, which is then used by liveness analysis and
+//! other tools to prepare ground for register allocation.
class JumpAnnotation {
public:
ASMJIT_NONCOPYABLE(JumpAnnotation)
+ //! \name Members
+ //! \{
+
//! Compiler that owns this JumpAnnotation.
BaseCompiler* _compiler;
//! Annotation identifier.
@@ -334,10 +281,20 @@ public:
//! Vector of label identifiers, see \ref labelIds().
ZoneVector<uint32_t> _labelIds;
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
inline JumpAnnotation(BaseCompiler* compiler, uint32_t annotationId) noexcept
: _compiler(compiler),
_annotationId(annotationId) {}
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
//! Returns the compiler that owns this JumpAnnotation.
inline BaseCompiler* compiler() const noexcept { return _compiler; }
//! Returns the annotation id.
@@ -350,35 +307,42 @@ public:
//! Tests whether the given `labelId` is a target of this JumpAnnotation.
inline bool hasLabelId(uint32_t labelId) const noexcept { return _labelIds.contains(labelId); }
+ //! \}
+
+ //! \name Annotation Building API
+ //! \{
+
//! Adds the `label` to the list of targets of this JumpAnnotation.
inline Error addLabel(const Label& label) noexcept { return addLabelId(label.id()); }
//! Adds the `labelId` to the list of targets of this JumpAnnotation.
inline Error addLabelId(uint32_t labelId) noexcept { return _labelIds.append(&_compiler->_allocator, labelId); }
-};
-// ============================================================================
-// [asmjit::JumpNode]
-// ============================================================================
+ //! \}
+};
//! Jump instruction with \ref JumpAnnotation.
//!
-//! \note This node should be only used to represent jump where the jump target
-//! cannot be deduced by examining instruction operands. For example if the jump
-//! target is register or memory location. This pattern is often used to perform
-//! indirect jumps that use jump table, e.g. to implement `switch{}` statement.
+//! \note This node should be only used to represent jump where the jump target cannot be deduced by examining
+//! instruction operands. For example if the jump target is register or memory location. This pattern is often
+//! used to perform indirect jumps that use jump table, e.g. to implement `switch{}` statement.
class JumpNode : public InstNode {
public:
ASMJIT_NONCOPYABLE(JumpNode)
+ //! \name Members
+ //! \{
+
JumpAnnotation* _annotation;
+ //! \}
+
//! \name Construction & Destruction
//! \{
- ASMJIT_INLINE JumpNode(BaseCompiler* cc, uint32_t instId, uint32_t options, uint32_t opCount, JumpAnnotation* annotation) noexcept
+ inline JumpNode(BaseCompiler* cc, InstId instId, InstOptions options, uint32_t opCount, JumpAnnotation* annotation) noexcept
: InstNode(cc, instId, options, opCount, kBaseOpCapacity),
_annotation(annotation) {
- setType(kNodeJump);
+ setType(NodeType::kJump);
}
//! \}
@@ -396,31 +360,24 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::FuncNode]
-// ============================================================================
-
//! Function node represents a function used by \ref BaseCompiler.
//!
//! A function is composed of the following:
//!
-//! - Function entry, \ref FuncNode acts as a label, so the entry is implicit.
-//! To get the entry, simply use \ref FuncNode::label(), which is the same
-//! as \ref LabelNode::label().
+//! - Function entry, \ref FuncNode acts as a label, so the entry is implicit. To get the entry, simply use
+//! \ref FuncNode::label(), which is the same as \ref LabelNode::label().
//!
-//! - Function exit, which is represented by \ref FuncNode::exitNode(). A
-//! helper function \ref FuncNode::exitLabel() exists and returns an exit
-//! label instead of node.
+//! - Function exit, which is represented by \ref FuncNode::exitNode(). A helper function
+//! \ref FuncNode::exitLabel() exists and returns an exit label instead of node.
//!
-//! - Function \ref FuncNode::endNode() sentinel. This node marks the end of
-//! a function - there should be no code that belongs to the function after
-//! this node, but the Compiler doesn't enforce that at the moment.
+//! - Function \ref FuncNode::endNode() sentinel. This node marks the end of a function - there should be no
+//! code that belongs to the function after this node, but the Compiler doesn't enforce that at the moment.
//!
//! - Function detail, see \ref FuncNode::detail().
//!
//! - Function frame, see \ref FuncNode::frame().
//!
-//! - Function arguments mapped to virtual registers, see \ref FuncNode::args().
+//! - Function arguments mapped to virtual registers, see \ref FuncNode::argPacks().
//!
//! In a node list, the function and its body looks like the following:
//!
@@ -439,29 +396,30 @@ public:
//! [...] - Anything after the function.
//! \endcode
//!
-//! When a function is added to the compiler by \ref BaseCompiler::addFunc() it
-//! actually inserts 3 nodes (FuncNode, ExitLabel, and FuncEnd) and sets the
-//! current cursor to be FuncNode. When \ref BaseCompiler::endFunc() is called
-//! the cursor is set to FuncEnd. This guarantees that user can use ExitLabel
-//! as a marker after additional code or data can be placed, and it's a common
-//! practice.
+//! When a function is added to the instruction stream by \ref BaseCompiler::addFunc() it actually inserts 3 nodes
+//! (FuncNode, ExitLabel, and FuncEnd) and sets the current cursor to be FuncNode. When \ref BaseCompiler::endFunc()
+//! is called the cursor is set to FuncEnd. This guarantees that user can use ExitLabel as a marker after additional
+//! code or data can be placed, which is a common practice.
class FuncNode : public LabelNode {
public:
ASMJIT_NONCOPYABLE(FuncNode)
//! Arguments pack.
struct ArgPack {
- VirtReg* _data[Globals::kMaxValuePack];
+ RegOnly _data[Globals::kMaxValuePack];
inline void reset() noexcept {
for (size_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++)
- _data[valueIndex] = nullptr;
+ _data[valueIndex].reset();
}
- inline VirtReg*& operator[](size_t valueIndex) noexcept { return _data[valueIndex]; }
- inline VirtReg* const& operator[](size_t valueIndex) const noexcept { return _data[valueIndex]; }
+ inline RegOnly& operator[](size_t valueIndex) noexcept { return _data[valueIndex]; }
+ inline const RegOnly& operator[](size_t valueIndex) const noexcept { return _data[valueIndex]; }
};
+ //! \name Members
+ //! \{
+
//! Function detail.
FuncDetail _funcDetail;
//! Function frame.
@@ -470,24 +428,25 @@ public:
LabelNode* _exitNode;
//! Function end (sentinel).
SentinelNode* _end;
-
//! Argument packs.
ArgPack* _args;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `FuncNode` instance.
//!
- //! Always use `BaseCompiler::addFunc()` to create `FuncNode`.
- ASMJIT_INLINE FuncNode(BaseBuilder* cb) noexcept
+ //! Always use `BaseCompiler::addFunc()` to create a new `FuncNode`.
+ inline FuncNode(BaseBuilder* cb) noexcept
: LabelNode(cb),
_funcDetail(),
_frame(),
_exitNode(nullptr),
_end(nullptr),
_args(nullptr) {
- setType(kNodeFunc);
+ setType(NodeType::kFunc);
}
//! \}
@@ -500,12 +459,12 @@ public:
//! Returns function exit label.
inline Label exitLabel() const noexcept { return _exitNode->label(); }
- //! Returns "End of Func" sentinel.
+ //! Returns "End of Func" sentinel node.
inline SentinelNode* endNode() const noexcept { return _end; }
- //! Returns function declaration.
+ //! Returns function detail.
inline FuncDetail& detail() noexcept { return _funcDetail; }
- //! Returns function declaration.
+ //! Returns function detail.
inline const FuncDetail& detail() const noexcept { return _funcDetail; }
//! Returns function frame.
@@ -513,14 +472,19 @@ public:
//! Returns function frame.
inline const FuncFrame& frame() const noexcept { return _frame; }
- //! Tests whether the function has a return value.
- inline bool hasRet() const noexcept { return _funcDetail.hasRet(); }
+ //! Returns function attributes.
+ inline FuncAttributes attributes() const noexcept { return _frame.attributes(); }
+ //! Adds `attrs` to the function attributes.
+ inline void addAttributes(FuncAttributes attrs) noexcept { _frame.addAttributes(attrs); }
+
//! Returns arguments count.
inline uint32_t argCount() const noexcept { return _funcDetail.argCount(); }
-
//! Returns argument packs.
inline ArgPack* argPacks() const noexcept { return _args; }
+ //! Tests whether the function has a return value.
+ inline bool hasRet() const noexcept { return _funcDetail.hasRet(); }
+
//! Returns argument pack at `argIndex`.
inline ArgPack& argPack(size_t argIndex) const noexcept {
ASMJIT_ASSERT(argIndex < argCount());
@@ -528,15 +492,27 @@ public:
}
//! Sets argument at `argIndex`.
- inline void setArg(size_t argIndex, VirtReg* vReg) noexcept {
+ inline void setArg(size_t argIndex, const BaseReg& vReg) noexcept {
+ ASMJIT_ASSERT(argIndex < argCount());
+ _args[argIndex][0].init(vReg);
+ }
+
+ //! \overload
+ inline void setArg(size_t argIndex, const RegOnly& vReg) noexcept {
ASMJIT_ASSERT(argIndex < argCount());
- _args[argIndex][0] = vReg;
+ _args[argIndex][0].init(vReg);
}
//! Sets argument at `argIndex` and `valueIndex`.
- inline void setArg(size_t argIndex, size_t valueIndex, VirtReg* vReg) noexcept {
+ inline void setArg(size_t argIndex, size_t valueIndex, const BaseReg& vReg) noexcept {
ASMJIT_ASSERT(argIndex < argCount());
- _args[argIndex][valueIndex] = vReg;
+ _args[argIndex][valueIndex].init(vReg);
+ }
+
+ //! \overload
+ inline void setArg(size_t argIndex, size_t valueIndex, const RegOnly& vReg) noexcept {
+ ASMJIT_ASSERT(argIndex < argCount());
+ _args[argIndex][valueIndex].init(vReg);
}
//! Resets argument pack at `argIndex`.
@@ -548,21 +524,12 @@ public:
//! Resets argument pack at `argIndex`.
inline void resetArg(size_t argIndex, size_t valueIndex) noexcept {
ASMJIT_ASSERT(argIndex < argCount());
- _args[argIndex][valueIndex] = nullptr;
+ _args[argIndex][valueIndex].reset();
}
- //! Returns function attributes.
- inline uint32_t attributes() const noexcept { return _frame.attributes(); }
- //! Adds `attrs` to the function attributes.
- inline void addAttributes(uint32_t attrs) noexcept { _frame.addAttributes(attrs); }
-
//! \}
};
-// ============================================================================
-// [asmjit::FuncRetNode]
-// ============================================================================
-
//! Function return, used by \ref BaseCompiler.
class FuncRetNode : public InstNode {
public:
@@ -572,27 +539,21 @@ public:
//! \{
//! Creates a new `FuncRetNode` instance.
- inline FuncRetNode(BaseBuilder* cb) noexcept : InstNode(cb, BaseInst::kIdAbstract, 0, 0) {
- _any._nodeType = kNodeFuncRet;
+ inline FuncRetNode(BaseBuilder* cb) noexcept : InstNode(cb, BaseInst::kIdAbstract, InstOptions::kNone, 0) {
+ _any._nodeType = NodeType::kFuncRet;
}
//! \}
};
-// ============================================================================
-// [asmjit::InvokeNode]
-// ============================================================================
-
//! Function invocation, used by \ref BaseCompiler.
class InvokeNode : public InstNode {
public:
ASMJIT_NONCOPYABLE(InvokeNode)
- //! Operand pack provides multiple operands that can be associated with a
- //! single return value of function argument. Sometimes this is necessary to
- //! express an argument or return value that requires multiple registers, for
- //! example 64-bit value in 32-bit mode or passing / returning homogeneous data
- //! structures.
+ //! Operand pack provides multiple operands that can be associated with a single return value of function
+ //! argument. Sometims this is necessary to express an argument or return value that requires multiple
+ //! registers, for example 64-bit value in 32-bit mode or passing / returning homogeneous data structures.
struct OperandPack {
//! Operands.
Operand_ _data[Globals::kMaxValuePack];
@@ -616,6 +577,9 @@ public:
}
};
+ //! \name Members
+ //! \{
+
//! Function detail.
FuncDetail _funcDetail;
//! Function return value(s).
@@ -623,18 +587,20 @@ public:
//! Function arguments.
OperandPack* _args;
+ //! \}
+
//! \name Construction & Destruction
//! \{
//! Creates a new `InvokeNode` instance.
- inline InvokeNode(BaseBuilder* cb, uint32_t instId, uint32_t options) noexcept
+ inline InvokeNode(BaseBuilder* cb, InstId instId, InstOptions options) noexcept
: InstNode(cb, instId, options, kBaseOpCapacity),
_funcDetail(),
_args(nullptr) {
- setType(kNodeInvoke);
+ setType(NodeType::kInvoke);
_resetOps();
_rets.reset();
- addFlags(kFlagIsRemovable);
+ addFlags(NodeFlags::kIsRemovable);
}
//! \}
@@ -718,10 +684,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::FuncPass]
-// ============================================================================
-
//! Function pass extends \ref Pass with \ref FuncPass::runOnFunction().
class ASMJIT_VIRTAPI FuncPass : public Pass {
public:
@@ -743,7 +705,7 @@ public:
//! \}
- //! \name Run
+ //! \name Pass Interface
//! \{
//! Calls `runOnFunction()` on each `FuncNode` node found.
@@ -755,6 +717,18 @@ public:
//! \}
};
+#if !defined(ASMJIT_NO_DEPRECATED)
+inline Error BaseCompiler::_setArg(size_t argIndex, size_t valueIndex, const BaseReg& reg) {
+ FuncNode* func = _func;
+
+ if (ASMJIT_UNLIKELY(!func))
+ return reportError(DebugUtils::errored(kErrorInvalidState));
+
+ func->setArg(argIndex, valueIndex, reg);
+ return kErrorOk;
+}
+#endif
+
//! \}
ASMJIT_END_NAMESPACE
diff --git a/src/asmjit/core/compilerdefs.h b/src/asmjit/core/compilerdefs.h
index 32f0757..f2e7a4e 100644
--- a/src/asmjit/core/compilerdefs.h
+++ b/src/asmjit/core/compilerdefs.h
@@ -1,63 +1,41 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_COMPILERDEFS_H_INCLUDED
#define ASMJIT_CORE_COMPILERDEFS_H_INCLUDED
#include "../core/api-config.h"
#include "../core/operand.h"
+#include "../core/type.h"
#include "../core/zonestring.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class RAWorkReg;
//! \addtogroup asmjit_compiler
//! \{
-// ============================================================================
-// [asmjit::VirtReg]
-// ============================================================================
-
//! Virtual register data, managed by \ref BaseCompiler.
class VirtReg {
public:
ASMJIT_NONCOPYABLE(VirtReg)
+ //! \name Members
+ //! \{
+
+ //! Virtual register signature.
+ OperandSignature _signature {};
//! Virtual register id.
uint32_t _id = 0;
- //! Virtual register info (signature).
- RegInfo _info = {};
- //! Virtual register size (can be smaller than `regInfo._size`).
+ //! Virtual register size (can be smaller than `_signature._size`).
uint32_t _virtSize = 0;
//! Virtual register alignment (for spilling).
uint8_t _alignment = 0;
//! Type-id.
- uint8_t _typeId = 0;
+ TypeId _typeId = TypeId::kVoid;
//! Virtual register weight for alloc/spill decisions.
uint8_t _weight = 1;
//! True if this is a fixed register, never reallocated.
@@ -69,24 +47,23 @@ public:
//! Virtual register name (user provided or automatically generated).
ZoneString<16> _name {};
- // -------------------------------------------------------------------------
- // The following members are used exclusively by RAPass. They are initialized
- // when the VirtReg is created to NULL pointers and then changed during RAPass
- // execution. RAPass sets them back to NULL before it returns.
- // -------------------------------------------------------------------------
+ // The following members are used exclusively by RAPass. They are initialized when the VirtReg is created to
+ // null pointers and then changed during RAPass execution. RAPass sets them back to NULL before it returns.
//! Reference to `RAWorkReg`, used during register allocation.
RAWorkReg* _workReg = nullptr;
+ //! \}
+
//! \name Construction & Destruction
//! \{
- inline VirtReg(uint32_t id, uint32_t signature, uint32_t virtSize, uint32_t alignment, uint32_t typeId) noexcept
- : _id(id),
- _info { signature },
+ inline VirtReg(const OperandSignature& signature, uint32_t id, uint32_t virtSize, uint32_t alignment, TypeId typeId) noexcept
+ : _signature(signature),
+ _id(id),
_virtSize(virtSize),
_alignment(uint8_t(alignment)),
- _typeId(uint8_t(typeId)),
+ _typeId(typeId),
_isFixed(false),
_isStack(false),
_reserved(0) {}
@@ -104,56 +81,50 @@ public:
//! Returns the size of the virtual register name.
inline uint32_t nameSize() const noexcept { return _name.size(); }
- //! Returns a register information that wraps the register signature.
- inline const RegInfo& info() const noexcept { return _info; }
+ //! Returns a register signature of this virtual register.
+ inline OperandSignature signature() const noexcept { return _signature; }
//! Returns a virtual register type (maps to the physical register type as well).
- inline uint32_t type() const noexcept { return _info.type(); }
+ inline RegType type() const noexcept { return _signature.regType(); }
//! Returns a virtual register group (maps to the physical register group as well).
- inline uint32_t group() const noexcept { return _info.group(); }
+ inline RegGroup group() const noexcept { return _signature.regGroup(); }
//! Returns a real size of the register this virtual register maps to.
//!
- //! For example if this is a 128-bit SIMD register used for a scalar single
- //! precision floating point value then its virtSize would be 4, however, the
- //! `regSize` would still say 16 (128-bits), because it's the smallest size
+ //! For example if this is a 128-bit SIMD register used for a scalar single precision floating point value then
+ //! its virtSize would be 4, however, the `regSize` would still say 16 (128-bits), because it's the smallest size
//! of that register type.
- inline uint32_t regSize() const noexcept { return _info.size(); }
-
- //! Returns a register signature of this virtual register.
- inline uint32_t signature() const noexcept { return _info.signature(); }
+ inline uint32_t regSize() const noexcept { return _signature.size(); }
//! Returns the virtual register size.
//!
- //! The virtual register size describes how many bytes the virtual register
- //! needs to store its content. It can be smaller than the physical register
- //! size, see `regSize()`.
+ //! The virtual register size describes how many bytes the virtual register needs to store its content. It can be
+ //! smaller than the physical register size, see `regSize()`.
inline uint32_t virtSize() const noexcept { return _virtSize; }
//! Returns the virtual register alignment.
inline uint32_t alignment() const noexcept { return _alignment; }
- //! Returns the virtual register type id, see `Type::Id`.
- inline uint32_t typeId() const noexcept { return _typeId; }
+ //! Returns the virtual register type id.
+ inline TypeId typeId() const noexcept { return _typeId; }
- //! Returns the virtual register weight - the register allocator can use it
- //! as explicit hint for alloc/spill decisions.
+ //! Returns the virtual register weight - the register allocator can use it as explicit hint for alloc/spill
+ //! decisions.
inline uint32_t weight() const noexcept { return _weight; }
- //! Sets the virtual register weight (0 to 255) - the register allocator can
- //! use it as explicit hint for alloc/spill decisions and initial bin-packing.
+ //! Sets the virtual register weight (0 to 255) - the register allocator can use it as explicit hint for
+ //! alloc/spill decisions and initial bin-packing.
inline void setWeight(uint32_t weight) noexcept { _weight = uint8_t(weight); }
- //! Returns whether the virtual register is always allocated to a fixed
- //! physical register (and never reallocated).
+ //! Returns whether the virtual register is always allocated to a fixed physical register (and never reallocated).
//!
//! \note This is only used for special purposes and it's mostly internal.
inline bool isFixed() const noexcept { return bool(_isFixed); }
- //! Returns whether the virtual register is indeed a stack that only uses
- //! the virtual register id for making it accessible.
+ //! Tests whether the virtual register is in fact a stack that only uses the virtual register id.
//!
//! \note It's an error if a stack is accessed as a register.
inline bool isStack() const noexcept { return bool(_isStack); }
+ //! Tests whether the virtual register has an associated `RAWorkReg` at the moment.
inline bool hasWorkReg() const noexcept { return _workReg != nullptr; }
inline RAWorkReg* workReg() const noexcept { return _workReg; }
inline void setWorkReg(RAWorkReg* workReg) noexcept { _workReg = workReg; }
diff --git a/src/asmjit/core/constpool.cpp b/src/asmjit/core/constpool.cpp
index 84d7cd3..ad5fe4f 100644
--- a/src/asmjit/core/constpool.cpp
+++ b/src/asmjit/core/constpool.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/constpool.h"
@@ -27,16 +9,14 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ConstPool - Construction / Destruction]
-// ============================================================================
+// ConstPool - Construction & Destruction
+// ======================================
ConstPool::ConstPool(Zone* zone) noexcept { reset(zone); }
ConstPool::~ConstPool() noexcept {}
-// ============================================================================
-// [asmjit::ConstPool - Reset]
-// ============================================================================
+// ConstPool - Reset
+// =================
void ConstPool::reset(Zone* zone) noexcept {
_zone = zone;
@@ -55,11 +35,10 @@ void ConstPool::reset(Zone* zone) noexcept {
_minItemSize = 0;
}
-// ============================================================================
-// [asmjit::ConstPool - Ops]
-// ============================================================================
+// ConstPool - Operations
+// ======================
-static ASMJIT_INLINE ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcept {
+static inline ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcept {
ConstPool::Gap* gap = self->_gapPool;
if (!gap)
return self->_zone->allocT<ConstPool::Gap>();
@@ -68,7 +47,7 @@ static ASMJIT_INLINE ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcep
return gap;
}
-static ASMJIT_INLINE void ConstPool_freeGap(ConstPool* self, ConstPool::Gap* gap) noexcept {
+static inline void ConstPool_freeGap(ConstPool* self, ConstPool::Gap* gap) noexcept {
gap->_next = self->_gapPool;
self->_gapPool = gap;
}
@@ -80,7 +59,11 @@ static void ConstPool_addGap(ConstPool* self, size_t offset, size_t size) noexce
size_t gapIndex;
size_t gapSize;
- if (size >= 16 && Support::isAligned<size_t>(offset, 16)) {
+ if (size >= 32 && Support::isAligned<size_t>(offset, 32)) {
+ gapIndex = ConstPool::kIndex32;
+ gapSize = 32;
+ }
+ else if (size >= 16 && Support::isAligned<size_t>(offset, 16)) {
gapIndex = ConstPool::kIndex16;
gapSize = 16;
}
@@ -101,9 +84,8 @@ static void ConstPool_addGap(ConstPool* self, size_t offset, size_t size) noexce
gapSize = 1;
}
- // We don't have to check for errors here, if this failed nothing really
- // happened (just the gap won't be visible) and it will fail again at
- // place where the same check would generate `kErrorOutOfMemory` error.
+ // We don't have to check for errors here, if this failed nothing really happened (just the gap won't be
+ // visible) and it will fail again at place where the same check would generate `kErrorOutOfMemory` error.
ConstPool::Gap* gap = ConstPool_allocGap(self);
if (!gap)
return;
@@ -122,7 +104,9 @@ static void ConstPool_addGap(ConstPool* self, size_t offset, size_t size) noexce
Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept {
size_t treeIndex;
- if (size == 32)
+ if (size == 64)
+ treeIndex = kIndex64;
+ else if (size == 32)
treeIndex = kIndex32;
else if (size == 16)
treeIndex = kIndex16;
@@ -143,8 +127,7 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
return kErrorOk;
}
- // Before incrementing the current offset try if there is a gap that can
- // be used for the requested data.
+ // Before incrementing the current offset try if there is a gap that can be used for the requested data.
size_t offset = ~size_t(0);
size_t gapIndex = treeIndex;
@@ -172,8 +155,7 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
}
if (offset == ~size_t(0)) {
- // Get how many bytes have to be skipped so the address is aligned accordingly
- // to the 'size'.
+ // Get how many bytes have to be skipped so the address is aligned accordingly to the 'size'.
size_t diff = Support::alignUpDiff<size_t>(_size, size);
if (diff != 0) {
@@ -195,9 +177,8 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
dstOffset = offset;
- // Now create a bunch of shared constants that are based on the data pattern.
- // We stop at size 4, it probably doesn't make sense to split constants down
- // to 1 byte.
+ // Now create a bunch of shared constants that are based on the data pattern. We stop at size 4,
+ // it probably doesn't make sense to split constants down to 1 byte.
size_t pCount = 1;
size_t smallerSize = size;
@@ -226,9 +207,8 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
return kErrorOk;
}
-// ============================================================================
-// [asmjit::ConstPool - Reset]
-// ============================================================================
+// ConstPool - Reset
+// =================
struct ConstPoolFill {
inline ConstPoolFill(uint8_t* dst, size_t dataSize) noexcept :
@@ -255,9 +235,8 @@ void ConstPool::fill(void* dst) const noexcept {
}
}
-// ============================================================================
-// [asmjit::ConstPool - Unit]
-// ============================================================================
+// ConstPool - Tests
+// =================
#if defined(ASMJIT_TEST)
UNIT(const_pool) {
diff --git a/src/asmjit/core/constpool.h b/src/asmjit/core/constpool.h
index fc0e0bc..32b84b1 100644
--- a/src/asmjit/core/constpool.h
+++ b/src/asmjit/core/constpool.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_CONSTPOOL_H_INCLUDED
#define ASMJIT_CORE_CONSTPOOL_H_INCLUDED
@@ -33,23 +15,22 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
-// ============================================================================
-// [asmjit::ConstPool]
-// ============================================================================
+//! Constant pool scope.
+enum class ConstPoolScope : uint32_t {
+ //! Local constant, always embedded right after the current function.
+ kLocal = 0,
+ //! Global constant, embedded at the end of the currently compiled code.
+ kGlobal = 1,
+
+ //! Maximum value of `ConstPoolScope`.
+ kMaxValue = kGlobal
+};
//! Constant pool.
class ConstPool {
public:
ASMJIT_NONCOPYABLE(ConstPool)
- //! Constant pool scope.
- enum Scope : uint32_t {
- //! Local constant, always embedded right after the current function.
- kScopeLocal = 0,
- //! Global constant, embedded at the end of the currently compiled code.
- kScopeGlobal = 1
- };
-
//! \cond INTERNAL
//! Index of a given size in const-pool table.
@@ -60,7 +41,8 @@ public:
kIndex8 = 3,
kIndex16 = 4,
kIndex32 = 5,
- kIndexCount = 6
+ kIndex64 = 6,
+ kIndexCount = 7
};
//! Zone-allocated const-pool gap created by two differently aligned constants.
@@ -193,6 +175,9 @@ public:
//! \endcond
+ //! \name Members
+ //! \{
+
//! Zone allocator.
Zone* _zone;
//! Tree per size.
@@ -209,6 +194,8 @@ public:
//! Minimum item size in the pool.
size_t _minItemSize;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -238,21 +225,18 @@ public:
//! Adds a constant to the constant pool.
//!
- //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes.
- //! The constant is added to the pool only if it doesn't not exist, otherwise
- //! cached value is returned.
+ //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes. The constant is added to the pool only
+ //! if it doesn't not exist, otherwise cached value is returned.
//!
- //! AsmJit is able to subdivide added constants, so for example if you add
- //! 8-byte constant 0x1122334455667788 it will create the following slots:
+ //! AsmJit is able to subdivide added constants, so for example if you add 8-byte constant 0x1122334455667788 it
+ //! will create the following slots:
//!
//! 8-byte: 0x1122334455667788
//! 4-byte: 0x11223344, 0x55667788
//!
- //! The reason is that when combining MMX/SSE/AVX code some patterns are used
- //! frequently. However, AsmJit is not able to reallocate a constant that has
- //! been already added. For example if you try to add 4-byte constant and then
- //! 8-byte constant having the same 4-byte pattern as the previous one, two
- //! independent slots will be generated by the pool.
+ //! The reason is that when combining MMX/SSE/AVX code some patterns are used frequently. However, AsmJit is not
+ //! able to reallocate a constant that has been already added. For example if you try to add 4-byte constant and
+ //! then 8-byte constant having the same 4-byte pattern as the previous one, two independent slots will be used.
ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset) noexcept;
//! Fills the destination with the content of this constant pool.
diff --git a/src/asmjit/core/cpuinfo.cpp b/src/asmjit/core/cpuinfo.cpp
index a281a4a..ef152cd 100644
--- a/src/asmjit/core/cpuinfo.cpp
+++ b/src/asmjit/core/cpuinfo.cpp
@@ -1,28 +1,11 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/cpuinfo.h"
+#include "../core/support.h"
#if !defined(_WIN32)
#include <errno.h>
@@ -30,11 +13,27 @@
#include <unistd.h>
#endif
+// Required by `getauxval()` on Linux.
+#if defined(__linux__)
+ #include <sys/auxv.h>
+#endif
+
+//! Required to detect CPU and features on Apple platforms.
+#if defined(__APPLE__)
+ #include <mach/machine.h>
+ #include <sys/types.h>
+ #include <sys/sysctl.h>
+#endif
+
+// Required by `__cpuidex()` and `_xgetbv()`.
+#if defined(_MSC_VER)
+ #include <intrin.h>
+#endif
+
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::CpuInfo - Detect - CPU NumThreads]
-// ============================================================================
+// CpuInfo - Detect - HW-Thread Count
+// ==================================
#if defined(_WIN32)
static inline uint32_t detectHWThreadCount() noexcept {
@@ -53,37 +52,1103 @@ static inline uint32_t detectHWThreadCount() noexcept {
}
#endif
-// ============================================================================
-// [asmjit::CpuInfo - Detect - CPU Features]
-// ============================================================================
+// CpuInfo - Detect - X86
+// ======================
+
+#if ASMJIT_ARCH_X86
+
+struct cpuid_t { uint32_t eax, ebx, ecx, edx; };
+struct xgetbv_t { uint32_t eax, edx; };
-#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
-namespace x86 { void detectCpu(CpuInfo& cpu) noexcept; }
+// Executes `cpuid` instruction.
+static inline void cpuidQuery(cpuid_t* out, uint32_t inEax, uint32_t inEcx = 0) noexcept {
+#if defined(_MSC_VER)
+ __cpuidex(reinterpret_cast<int*>(out), inEax, inEcx);
+#elif defined(__GNUC__) && ASMJIT_ARCH_X86 == 32
+ __asm__ __volatile__(
+ "mov %%ebx, %%edi\n"
+ "cpuid\n"
+ "xchg %%edi, %%ebx\n" : "=a"(out->eax), "=D"(out->ebx), "=c"(out->ecx), "=d"(out->edx) : "a"(inEax), "c"(inEcx));
+#elif defined(__GNUC__) && ASMJIT_ARCH_X86 == 64
+ __asm__ __volatile__(
+ "mov %%rbx, %%rdi\n"
+ "cpuid\n"
+ "xchg %%rdi, %%rbx\n" : "=a"(out->eax), "=D"(out->ebx), "=c"(out->ecx), "=d"(out->edx) : "a"(inEax), "c"(inEcx));
+#else
+ #error "[asmjit] x86::cpuidQuery() - Unsupported compiler."
#endif
+}
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM
-namespace arm { void detectCpu(CpuInfo& cpu) noexcept; }
+// Executes 'xgetbv' instruction.
+static inline void xgetbvQuery(xgetbv_t* out, uint32_t inEcx) noexcept {
+#if defined(_MSC_VER)
+ uint64_t value = _xgetbv(inEcx);
+ out->eax = uint32_t(value & 0xFFFFFFFFu);
+ out->edx = uint32_t(value >> 32);
+#elif defined(__GNUC__)
+ uint32_t outEax;
+ uint32_t outEdx;
+
+ // Replaced, because the world is not perfect:
+ // __asm__ __volatile__("xgetbv" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
+ __asm__ __volatile__(".byte 0x0F, 0x01, 0xD0" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
+
+ out->eax = outEax;
+ out->edx = outEdx;
+#else
+ out->eax = 0;
+ out->edx = 0;
#endif
+}
+
+// Map a 12-byte vendor string returned by `cpuid` into a `CpuInfo::Vendor` ID.
+static inline void simplifyCpuVendor(CpuInfo& cpu, uint32_t d0, uint32_t d1, uint32_t d2) noexcept {
+ struct Vendor {
+ char normalized[8];
+ union { char text[12]; uint32_t d[3]; };
+ };
+
+ static const Vendor table[] = {
+ { { 'A', 'M', 'D' }, {{ 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' }} },
+ { { 'I', 'N', 'T', 'E', 'L' }, {{ 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' }} },
+ { { 'V', 'I', 'A' }, {{ 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' }} },
+ { { 'V', 'I', 'A' }, {{ 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 }} },
+ { { 'U', 'N', 'K', 'N', 'O', 'W', 'N' }, {{ 0 }} }
+ };
+
+ uint32_t i;
+ for (i = 0; i < ASMJIT_ARRAY_SIZE(table) - 1; i++)
+ if (table[i].d[0] == d0 && table[i].d[1] == d1 && table[i].d[2] == d2)
+ break;
+ memcpy(cpu._vendor.str, table[i].normalized, 8);
+}
+
+static ASMJIT_FAVOR_SIZE void simplifyCpuBrand(char* s) noexcept {
+ char* d = s;
+
+ char c = s[0];
+ char prev = 0;
+
+ // Used to always clear the current character to ensure that the result
+ // doesn't contain garbage after a new null terminator is placed at the end.
+ s[0] = '\0';
+
+ for (;;) {
+ if (!c)
+ break;
+
+ if (!(c == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@'))) {
+ *d++ = c;
+ prev = c;
+ }
+
+ c = *++s;
+ s[0] = '\0';
+ }
+
+ d[0] = '\0';
+}
+
+static ASMJIT_FAVOR_SIZE void detectX86Cpu(CpuInfo& cpu) noexcept {
+ using Support::bitTest;
+
+ cpuid_t regs;
+ xgetbv_t xcr0 { 0, 0 };
+ CpuFeatures::X86& features = cpu.features().x86();
+
+ cpu._wasDetected = true;
+ cpu._maxLogicalProcessors = 1;
+
+ // We are gonna execute CPUID, which was introduced by I486, so it's the requirement.
+ features.add(CpuFeatures::X86::kI486);
+
+ // CPUID EAX=0
+ // -----------
+
+ // Get vendor string/id.
+ cpuidQuery(&regs, 0x0);
+
+ uint32_t maxId = regs.eax;
+ uint32_t maxSubLeafId_0x7 = 0;
+
+ simplifyCpuVendor(cpu, regs.ebx, regs.edx, regs.ecx);
+
+ // CPUID EAX=1
+ // -----------
+
+ if (maxId >= 0x1) {
+ // Get feature flags in ECX/EDX and family/model in EAX.
+ cpuidQuery(&regs, 0x1);
+
+ // Fill family and model fields.
+ uint32_t modelId = (regs.eax >> 4) & 0x0F;
+ uint32_t familyId = (regs.eax >> 8) & 0x0F;
+
+ // Use extended family and model fields.
+ if (familyId == 0x06u || familyId == 0x0Fu)
+ modelId += (((regs.eax >> 16) & 0x0Fu) << 4);
+
+ if (familyId == 0x0Fu)
+ familyId += ((regs.eax >> 20) & 0xFFu);
+
+ cpu._modelId = modelId;
+ cpu._familyId = familyId;
+ cpu._brandId = ((regs.ebx ) & 0xFF);
+ cpu._processorType = ((regs.eax >> 12) & 0x03);
+ cpu._maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
+ cpu._stepping = ((regs.eax ) & 0x0F);
+ cpu._cacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
+
+ features.addIf(bitTest(regs.ecx, 0), CpuFeatures::X86::kSSE3);
+ features.addIf(bitTest(regs.ecx, 1), CpuFeatures::X86::kPCLMULQDQ);
+ features.addIf(bitTest(regs.ecx, 3), CpuFeatures::X86::kMONITOR);
+ features.addIf(bitTest(regs.ecx, 5), CpuFeatures::X86::kVMX);
+ features.addIf(bitTest(regs.ecx, 6), CpuFeatures::X86::kSMX);
+ features.addIf(bitTest(regs.ecx, 9), CpuFeatures::X86::kSSSE3);
+ features.addIf(bitTest(regs.ecx, 13), CpuFeatures::X86::kCMPXCHG16B);
+ features.addIf(bitTest(regs.ecx, 19), CpuFeatures::X86::kSSE4_1);
+ features.addIf(bitTest(regs.ecx, 20), CpuFeatures::X86::kSSE4_2);
+ features.addIf(bitTest(regs.ecx, 22), CpuFeatures::X86::kMOVBE);
+ features.addIf(bitTest(regs.ecx, 23), CpuFeatures::X86::kPOPCNT);
+ features.addIf(bitTest(regs.ecx, 25), CpuFeatures::X86::kAESNI);
+ features.addIf(bitTest(regs.ecx, 26), CpuFeatures::X86::kXSAVE);
+ features.addIf(bitTest(regs.ecx, 27), CpuFeatures::X86::kOSXSAVE);
+ features.addIf(bitTest(regs.ecx, 30), CpuFeatures::X86::kRDRAND);
+ features.addIf(bitTest(regs.edx, 0), CpuFeatures::X86::kFPU);
+ features.addIf(bitTest(regs.edx, 4), CpuFeatures::X86::kRDTSC);
+ features.addIf(bitTest(regs.edx, 5), CpuFeatures::X86::kMSR);
+ features.addIf(bitTest(regs.edx, 8), CpuFeatures::X86::kCMPXCHG8B);
+ features.addIf(bitTest(regs.edx, 15), CpuFeatures::X86::kCMOV);
+ features.addIf(bitTest(regs.edx, 19), CpuFeatures::X86::kCLFLUSH);
+ features.addIf(bitTest(regs.edx, 23), CpuFeatures::X86::kMMX);
+ features.addIf(bitTest(regs.edx, 24), CpuFeatures::X86::kFXSR);
+ features.addIf(bitTest(regs.edx, 25), CpuFeatures::X86::kSSE);
+ features.addIf(bitTest(regs.edx, 25), CpuFeatures::X86::kSSE, CpuFeatures::X86::kSSE2);
+ features.addIf(bitTest(regs.edx, 28), CpuFeatures::X86::kMT);
+
+ // Get the content of XCR0 if supported by the CPU and enabled by the OS.
+ if (features.hasXSAVE() && features.hasOSXSAVE()) {
+ xgetbvQuery(&xcr0, 0);
+ }
+
+ // Detect AVX+.
+ if (bitTest(regs.ecx, 28)) {
+ // - XCR0[2:1] == 11b
+ // XMM & YMM states need to be enabled by OS.
+ if ((xcr0.eax & 0x00000006u) == 0x00000006u) {
+ features.add(CpuFeatures::X86::kAVX);
+ features.addIf(bitTest(regs.ecx, 12), CpuFeatures::X86::kFMA);
+ features.addIf(bitTest(regs.ecx, 29), CpuFeatures::X86::kF16C);
+ }
+ }
+ }
+
+ constexpr uint32_t kXCR0_AMX_Bits = 0x3u << 17;
+ bool amxEnabledByOS = (xcr0.eax & kXCR0_AMX_Bits) == kXCR0_AMX_Bits;
+
+#if defined(__APPLE__)
+ // Apple platform provides on-demand AVX512 support. When an AVX512 instruction is used the first time it results
+ // in #UD, which would cause the thread being promoted to use AVX512 support by the OS in addition to enabling the
+ // necessary bits in XCR0 register.
+ bool avx512EnabledByOS = true;
+#else
+ // - XCR0[2:1] == 11b - XMM/YMM states need to be enabled by OS.
+ // - XCR0[7:5] == 111b - Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by OS.
+ constexpr uint32_t kXCR0_AVX512_Bits = (0x3u << 1) | (0x7u << 5);
+ bool avx512EnabledByOS = (xcr0.eax & kXCR0_AVX512_Bits) == kXCR0_AVX512_Bits;
+#endif
+
+ // CPUID EAX=7 ECX=0
+ // -----------------
+
+ // Detect new features if the processor supports CPUID-07.
+ bool maybeMPX = false;
+
+ if (maxId >= 0x7) {
+ cpuidQuery(&regs, 0x7);
+
+ maybeMPX = bitTest(regs.ebx, 14);
+ maxSubLeafId_0x7 = regs.eax;
+
+ features.addIf(bitTest(regs.ebx, 0), CpuFeatures::X86::kFSGSBASE);
+ features.addIf(bitTest(regs.ebx, 3), CpuFeatures::X86::kBMI);
+ features.addIf(bitTest(regs.ebx, 4), CpuFeatures::X86::kHLE);
+ features.addIf(bitTest(regs.ebx, 7), CpuFeatures::X86::kSMEP);
+ features.addIf(bitTest(regs.ebx, 8), CpuFeatures::X86::kBMI2);
+ features.addIf(bitTest(regs.ebx, 9), CpuFeatures::X86::kERMS);
+ features.addIf(bitTest(regs.ebx, 11), CpuFeatures::X86::kRTM);
+ features.addIf(bitTest(regs.ebx, 18), CpuFeatures::X86::kRDSEED);
+ features.addIf(bitTest(regs.ebx, 19), CpuFeatures::X86::kADX);
+ features.addIf(bitTest(regs.ebx, 20), CpuFeatures::X86::kSMAP);
+ features.addIf(bitTest(regs.ebx, 23), CpuFeatures::X86::kCLFLUSHOPT);
+ features.addIf(bitTest(regs.ebx, 24), CpuFeatures::X86::kCLWB);
+ features.addIf(bitTest(regs.ebx, 29), CpuFeatures::X86::kSHA);
+ features.addIf(bitTest(regs.ecx, 0), CpuFeatures::X86::kPREFETCHWT1);
+ features.addIf(bitTest(regs.ecx, 4), CpuFeatures::X86::kOSPKE);
+ features.addIf(bitTest(regs.ecx, 5), CpuFeatures::X86::kWAITPKG);
+ features.addIf(bitTest(regs.ecx, 7), CpuFeatures::X86::kCET_SS);
+ features.addIf(bitTest(regs.ecx, 8), CpuFeatures::X86::kGFNI);
+ features.addIf(bitTest(regs.ecx, 9), CpuFeatures::X86::kVAES);
+ features.addIf(bitTest(regs.ecx, 10), CpuFeatures::X86::kVPCLMULQDQ);
+ features.addIf(bitTest(regs.ecx, 22), CpuFeatures::X86::kRDPID);
+ features.addIf(bitTest(regs.ecx, 25), CpuFeatures::X86::kCLDEMOTE);
+ features.addIf(bitTest(regs.ecx, 27), CpuFeatures::X86::kMOVDIRI);
+ features.addIf(bitTest(regs.ecx, 28), CpuFeatures::X86::kMOVDIR64B);
+ features.addIf(bitTest(regs.ecx, 29), CpuFeatures::X86::kENQCMD);
+ features.addIf(bitTest(regs.edx, 5), CpuFeatures::X86::kUINTR);
+ features.addIf(bitTest(regs.edx, 14), CpuFeatures::X86::kSERIALIZE);
+ features.addIf(bitTest(regs.edx, 16), CpuFeatures::X86::kTSXLDTRK);
+ features.addIf(bitTest(regs.edx, 18), CpuFeatures::X86::kPCONFIG);
+ features.addIf(bitTest(regs.edx, 20), CpuFeatures::X86::kCET_IBT);
+
+ // Detect 'TSX' - Requires at least one of `HLE` and `RTM` features.
+ if (features.hasHLE() || features.hasRTM())
+ features.add(CpuFeatures::X86::kTSX);
+
+ // Detect 'AVX2' - Requires AVX as well.
+ if (bitTest(regs.ebx, 5) && features.hasAVX())
+ features.add(CpuFeatures::X86::kAVX2);
+
+ // Detect 'AVX512'.
+ if (avx512EnabledByOS && bitTest(regs.ebx, 16)) {
+ features.add(CpuFeatures::X86::kAVX512_F);
+
+ features.addIf(bitTest(regs.ebx, 17), CpuFeatures::X86::kAVX512_DQ);
+ features.addIf(bitTest(regs.ebx, 21), CpuFeatures::X86::kAVX512_IFMA);
+ features.addIf(bitTest(regs.ebx, 26), CpuFeatures::X86::kAVX512_PFI);
+ features.addIf(bitTest(regs.ebx, 27), CpuFeatures::X86::kAVX512_ERI);
+ features.addIf(bitTest(regs.ebx, 28), CpuFeatures::X86::kAVX512_CDI);
+ features.addIf(bitTest(regs.ebx, 30), CpuFeatures::X86::kAVX512_BW);
+ features.addIf(bitTest(regs.ebx, 31), CpuFeatures::X86::kAVX512_VL);
+ features.addIf(bitTest(regs.ecx, 1), CpuFeatures::X86::kAVX512_VBMI);
+ features.addIf(bitTest(regs.ecx, 6), CpuFeatures::X86::kAVX512_VBMI2);
+ features.addIf(bitTest(regs.ecx, 11), CpuFeatures::X86::kAVX512_VNNI);
+ features.addIf(bitTest(regs.ecx, 12), CpuFeatures::X86::kAVX512_BITALG);
+ features.addIf(bitTest(regs.ecx, 14), CpuFeatures::X86::kAVX512_VPOPCNTDQ);
+ features.addIf(bitTest(regs.edx, 2), CpuFeatures::X86::kAVX512_4VNNIW);
+ features.addIf(bitTest(regs.edx, 3), CpuFeatures::X86::kAVX512_4FMAPS);
+ features.addIf(bitTest(regs.edx, 8), CpuFeatures::X86::kAVX512_VP2INTERSECT);
+ features.addIf(bitTest(regs.edx, 23), CpuFeatures::X86::kAVX512_FP16);
+ }
+
+ // Detect 'AMX'.
+ if (amxEnabledByOS) {
+ features.addIf(bitTest(regs.edx, 22), CpuFeatures::X86::kAMX_BF16);
+ features.addIf(bitTest(regs.edx, 24), CpuFeatures::X86::kAMX_TILE);
+ features.addIf(bitTest(regs.edx, 25), CpuFeatures::X86::kAMX_INT8);
+ }
+ }
+
+ // CPUID EAX=7 ECX=1
+ // -----------------
+
+ if (features.hasAVX512_F() && maxSubLeafId_0x7 >= 1) {
+ cpuidQuery(&regs, 0x7, 1);
+
+ features.addIf(bitTest(regs.eax, 3), CpuFeatures::X86::kAVX_VNNI);
+ features.addIf(bitTest(regs.eax, 5), CpuFeatures::X86::kAVX512_BF16);
+ features.addIf(bitTest(regs.eax, 22), CpuFeatures::X86::kHRESET);
+ }
+
+ // CPUID EAX=13 ECX=0
+ // ------------------
+
+ if (maxId >= 0xD) {
+ cpuidQuery(&regs, 0xD, 0);
+
+ // Both CPUID result and XCR0 has to be enabled to have support for MPX.
+ if (((regs.eax & xcr0.eax) & 0x00000018u) == 0x00000018u && maybeMPX)
+ features.add(CpuFeatures::X86::kMPX);
-// ============================================================================
-// [asmjit::CpuInfo - Detect - Static Initializer]
-// ============================================================================
+ cpuidQuery(&regs, 0xD, 1);
+
+ features.addIf(bitTest(regs.eax, 0), CpuFeatures::X86::kXSAVEOPT);
+ features.addIf(bitTest(regs.eax, 1), CpuFeatures::X86::kXSAVEC);
+ features.addIf(bitTest(regs.eax, 3), CpuFeatures::X86::kXSAVES);
+ }
+
+ // CPUID EAX=14 ECX=0
+ // ------------------
+
+ if (maxId >= 0xE) {
+ cpuidQuery(&regs, 0xE, 0);
+
+ features.addIf(bitTest(regs.ebx, 4), CpuFeatures::X86::kPTWRITE);
+ }
+
+ // CPUID EAX=0x80000000...maxId
+ // ----------------------------
+
+ maxId = 0x80000000u;
+ uint32_t i = maxId;
+
+ // The highest EAX that we understand.
+ constexpr uint32_t kHighestProcessedEAX = 0x8000001Fu;
+
+ // Several CPUID calls are required to get the whole branc string. It's easier
+ // to copy one DWORD at a time instead of copying the string a byte by byte.
+ uint32_t* brand = cpu._brand.u32;
+ do {
+ cpuidQuery(&regs, i);
+ switch (i) {
+ case 0x80000000u:
+ maxId = Support::min<uint32_t>(regs.eax, kHighestProcessedEAX);
+ break;
+
+ case 0x80000001u:
+ features.addIf(bitTest(regs.ecx, 0), CpuFeatures::X86::kLAHFSAHF);
+ features.addIf(bitTest(regs.ecx, 2), CpuFeatures::X86::kSVM);
+ features.addIf(bitTest(regs.ecx, 5), CpuFeatures::X86::kLZCNT);
+ features.addIf(bitTest(regs.ecx, 6), CpuFeatures::X86::kSSE4A);
+ features.addIf(bitTest(regs.ecx, 7), CpuFeatures::X86::kMSSE);
+ features.addIf(bitTest(regs.ecx, 8), CpuFeatures::X86::kPREFETCHW);
+ features.addIf(bitTest(regs.ecx, 12), CpuFeatures::X86::kSKINIT);
+ features.addIf(bitTest(regs.ecx, 15), CpuFeatures::X86::kLWP);
+ features.addIf(bitTest(regs.ecx, 21), CpuFeatures::X86::kTBM);
+ features.addIf(bitTest(regs.ecx, 29), CpuFeatures::X86::kMONITORX);
+ features.addIf(bitTest(regs.edx, 20), CpuFeatures::X86::kNX);
+ features.addIf(bitTest(regs.edx, 21), CpuFeatures::X86::kFXSROPT);
+ features.addIf(bitTest(regs.edx, 22), CpuFeatures::X86::kMMX2);
+ features.addIf(bitTest(regs.edx, 27), CpuFeatures::X86::kRDTSCP);
+ features.addIf(bitTest(regs.edx, 29), CpuFeatures::X86::kPREFETCHW);
+ features.addIf(bitTest(regs.edx, 30), CpuFeatures::X86::k3DNOW2, CpuFeatures::X86::kMMX2);
+ features.addIf(bitTest(regs.edx, 31), CpuFeatures::X86::kPREFETCHW);
+
+ if (features.hasAVX()) {
+ features.addIf(bitTest(regs.ecx, 11), CpuFeatures::X86::kXOP);
+ features.addIf(bitTest(regs.ecx, 16), CpuFeatures::X86::kFMA4);
+ }
+
+ // This feature seems to be only supported by AMD.
+ if (cpu.isVendor("AMD")) {
+ features.addIf(bitTest(regs.ecx, 4), CpuFeatures::X86::kALTMOVCR8);
+ }
+ break;
+
+ case 0x80000002u:
+ case 0x80000003u:
+ case 0x80000004u:
+ *brand++ = regs.eax;
+ *brand++ = regs.ebx;
+ *brand++ = regs.ecx;
+ *brand++ = regs.edx;
+
+ // Go directly to the next one we are interested in.
+ if (i == 0x80000004u)
+ i = 0x80000008u - 1;
+ break;
+
+ case 0x80000008u:
+ features.addIf(bitTest(regs.ebx, 0), CpuFeatures::X86::kCLZERO);
+ features.addIf(bitTest(regs.ebx, 0), CpuFeatures::X86::kRDPRU);
+ features.addIf(bitTest(regs.ebx, 8), CpuFeatures::X86::kMCOMMIT);
+ features.addIf(bitTest(regs.ebx, 9), CpuFeatures::X86::kWBNOINVD);
+
+ // Go directly to the next one we are interested in.
+ i = 0x8000001Fu - 1;
+ break;
+
+ case 0x8000001Fu:
+ features.addIf(bitTest(regs.eax, 4), CpuFeatures::X86::kSNP);
+ break;
+ }
+ } while (++i <= maxId);
+
+ // Simplify CPU brand string a bit by removing some unnecessary spaces.
+ simplifyCpuBrand(cpu._brand.str);
+}
+
+#endif // ASMJIT_ARCH_X86
+
+// CpuInfo - Detect - ARM
+// ======================
+
+// The most relevant and accurate information can be found here:
+// https://github.com/llvm-project/llvm/blob/master/lib/Target/AArch64/AArch64.td
+// https://github.com/apple/llvm-project/blob/apple/main/llvm/lib/Target/AArch64/AArch64.td (Apple fork)
+//
+// Other resources:
+// https://en.wikipedia.org/wiki/AArch64
+// https://en.wikipedia.org/wiki/Apple_silicon#List_of_Apple_processors
+// https://developer.arm.com/architectures/learn-the-architecture/understanding-the-armv8-x-extensions/single-page
+
+#if ASMJIT_ARCH_ARM
+
+static inline void populateBaseARMFeatures(CpuInfo& cpu) noexcept {
+#if ASMJIT_ARCH_ARM == 32
+ // No baseline flags at the moment.
+ DebugUtils::unused(cpu);
+#else
+ // AArch64 is based on ARMv8-A and later.
+ cpu.addFeature(CpuFeatures::ARM::kARMv6);
+ cpu.addFeature(CpuFeatures::ARM::kARMv7);
+ cpu.addFeature(CpuFeatures::ARM::kARMv8a);
+
+ // AArch64 comes with these features by default.
+ cpu.addFeature(CpuFeatures::ARM::kVFPv2);
+ cpu.addFeature(CpuFeatures::ARM::kVFPv3);
+ cpu.addFeature(CpuFeatures::ARM::kVFPv4);
+ cpu.addFeature(CpuFeatures::ARM::kASIMD);
+ cpu.addFeature(CpuFeatures::ARM::kIDIVA);
+#endif
+}
+
+// Detects ARM version by macros defined at compile time. This means that AsmJit will report features forced at
+// compile time that should always be provided by the target CPU. This also means that if we don't provide any
+// means to detect CPU features the features reported by AsmJit will at least not report less features than the
+// target it was compiled to.
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void detectARMFeaturesViaCompilerFlags(CpuInfo& cpu) noexcept {
+ DebugUtils::unused(cpu);
+
+#if ASMJIT_ARCH_ARM == 32
+
+ // ARM targets have no baseline at the moment.
+# if defined(__ARM_ARCH_7A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv7);
+# endif
+# if defined(__ARM_ARCH_8A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8a);
+# endif
+
+# if defined(__TARGET_ARCH_THUMB)
+ cpu.addFeature(CpuFeatures::ARM::kTHUMB);
+# if __TARGET_ARCH_THUMB >= 4
+ cpu.addFeature(CpuFeatures::ARM::kTHUMBv2);
+# endif
+# endif
+
+# if defined(__ARM_FEATURE_FMA)
+ cpu.addFeature(CpuFeatures::ARM::kVFPv3);
+ cpu.addFeature(CpuFeatures::ARM::kVFPv4);
+# endif
+
+# if defined(__ARM_NEON)
+ cpu.addFeature(CpuFeatures::ARM::kASIMD);
+# endif
+
+# if defined(__ARM_FEATURE_IDIV) && defined(__TARGET_ARCH_THUMB)
+ cpu.addFeature(CpuFeatures::ARM::kIDIVT);
+#endif
+# if defined(__ARM_FEATURE_IDIV) && !defined(__TARGET_ARCH_THUMB)
+ cpu.addFeature(CpuFeatures::ARM::kIDIVA);
+# endif
+
+#endif
+
+#if defined(__ARM_ARCH_8_1A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_1a);
+#endif
+#if defined(__ARM_ARCH_8_2A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_2a);
+#endif
+#if defined(__ARM_ARCH_8_3A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_3a);
+#endif
+#if defined(__ARM_ARCH_8_4A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_4a);
+#endif
+#if defined(__ARM_ARCH_8_5A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_5a);
+#endif
+#if defined(__ARM_ARCH_8_6A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_6a);
+#endif
+#if defined(__ARM_ARCH_8_7A__)
+ cpu.addFeature(CpuFeatures::ARM::kARMv8_7a);
+#endif
+
+#if defined(__ARM_FEATURE_AES)
+ cpu.addFeature(CpuFeatures::ARM::kAES);
+#endif
+
+#if defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC) && defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
+ cpu.addFeature(CpuFeatures::ARM::kBF16);
+#endif
+
+#if defined(__ARM_FEATURE_CRC32)
+ cpu.addFeature(CpuFeatures::ARM::kCRC32);
+#endif
+
+#if defined(__ARM_FEATURE_CRYPTO)
+ cpu.addFeature(CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+#endif
+
+#if defined(__ARM_FEATURE_DOTPROD)
+ cpu.addFeature(CpuFeatures::ARM::kDOTPROD);
+#endif
+
+#if defined(__ARM_FEATURE_FP16FML) || defined(__ARM_FEATURE_FP16_FML)
+ cpu.addFeature(CpuFeatures::ARM::kFP16FML);
+#endif
+
+#if defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC)
+ cpu.addFeature(CpuFeatures::ARM::kFP16FULL);
+#endif
+
+#if defined(__ARM_FEATURE_FRINT)
+ cpu.addFeature(CpuFeatures::ARM::kFRINT);
+#endif
+
+#if defined(__ARM_FEATURE_JCVT)
+ cpu.addFeature(CpuFeatures::ARM::kFJCVTZS);
+#endif
+
+#if defined(__ARM_FEATURE_MATMUL_INT8)
+ cpu.addFeature(CpuFeatures::ARM::kI8MM);
+#endif
+
+#if defined(__ARM_FEATURE_ATOMICS)
+ cpu.addFeature(CpuFeatures::ARM::kLSE);
+#endif
+
+#if defined(__ARM_FEATURE_MEMORY_TAGGING)
+ cpu.addFeature(CpuFeatures::ARM::kMTE);
+#endif
+
+#if defined(__ARM_FEATURE_QRDMX)
+ cpu.addFeature(CpuFeatures::ARM::kRDM);
+#endif
+
+#if defined(__ARM_FEATURE_RNG)
+ cpu.addFeature(CpuFeatures::ARM::kRNG);
+#endif
+
+#if defined(__ARM_FEATURE_SHA2)
+ cpu.addFeature(CpuFeatures::ARM::kSHA2);
+#endif
+
+#if defined(__ARM_FEATURE_SHA3)
+ cpu.addFeature(CpuFeatures::ARM::kSHA3);
+#endif
+
+#if defined(__ARM_FEATURE_SHA512)
+ cpu.addFeature(CpuFeatures::ARM::kSHA512);
+#endif
+
+#if defined(__ARM_FEATURE_SM3)
+ cpu.addFeature(CpuFeatures::ARM::kSM3);
+#endif
+
+#if defined(__ARM_FEATURE_SM4)
+ cpu.addFeature(CpuFeatures::ARM::kSM4);
+#endif
+
+#if defined(__ARM_FEATURE_SVE) || defined(__ARM_FEATURE_SVE_VECTOR_OPERATORS)
+ cpu.addFeature(CpuFeatures::ARM::kSVE);
+#endif
+
+#if defined(__ARM_FEATURE_SVE_MATMUL_INT8)
+ cpu.addFeature(CpuFeatures::ARM::kSVE_I8MM);
+#endif
+
+#if defined(__ARM_FEATURE_SVE_MATMUL_FP32)
+ cpu.addFeature(CpuFeatures::ARM::kSVE_F32MM);
+#endif
+
+#if defined(__ARM_FEATURE_SVE_MATMUL_FP64)
+ cpu.addFeature(CpuFeatures::ARM::kSVE_F64MM);
+#endif
+
+#if defined(__ARM_FEATURE_SVE2)
+ cpu.addFeature(CpuFeatures::ARM::kSVE2);
+#endif
+
+#if defined(__ARM_FEATURE_SVE2_AES)
+ cpu.addFeature(CpuFeatures::ARM::kSVE2_AES);
+#endif
+
+#if defined(__ARM_FEATURE_SVE2_BITPERM)
+ cpu.addFeature(CpuFeatures::ARM::kSVE2_BITPERM);
+#endif
+
+#if defined(__ARM_FEATURE_SVE2_SHA3)
+ cpu.addFeature(CpuFeatures::ARM::kSVE2_SHA3);
+#endif
+
+#if defined(__ARM_FEATURE_SVE2_SM4)
+ cpu.addFeature(CpuFeatures::ARM::kSVE2_SM4);
+#endif
+
+#if defined(__ARM_FEATURE_TME)
+ cpu.addFeature(CpuFeatures::ARM::kTME);
+#endif
+}
+
+ASMJIT_MAYBE_UNUSED
+static ASMJIT_FAVOR_SIZE void expandARMFeaturesByVersion(CpuInfo& cpu) noexcept {
+ CpuFeatures::ARM& features = cpu.features().arm();
+
+ if (features.hasARMv8_7a()) {
+ features.add(CpuFeatures::ARM::kARMv8_6a);
+ }
+
+ if (features.hasARMv8_6a()) {
+ features.add(CpuFeatures::ARM::kARMv8_5a,
+ CpuFeatures::ARM::kBF16);
+
+ if (features.hasSVE())
+ features.add(CpuFeatures::ARM::kSVE_I8MM);
+ }
+
+ if (features.hasARMv8_5a()) {
+ features.add(CpuFeatures::ARM::kARMv8_4a,
+ CpuFeatures::ARM::kALTNZCV,
+ CpuFeatures::ARM::kBTI,
+ CpuFeatures::ARM::kFRINT,
+ CpuFeatures::ARM::kSB,
+ CpuFeatures::ARM::kSSBS);
+ }
+
+ if (features.hasARMv8_4a()) {
+ features.add(CpuFeatures::ARM::kARMv8_3a,
+ CpuFeatures::ARM::kDIT,
+ CpuFeatures::ARM::kDOTPROD,
+ CpuFeatures::ARM::kFLAGM,
+ CpuFeatures::ARM::kPMU,
+ CpuFeatures::ARM::kRCPC_IMMO);
+ }
+
+ if (features.hasARMv8_3a()) {
+ features.add(CpuFeatures::ARM::kARMv8_2a,
+ CpuFeatures::ARM::kFCMA,
+ CpuFeatures::ARM::kFJCVTZS);
+ }
+
+ if (features.hasARMv8_2a()) {
+ features.add(CpuFeatures::ARM::kARMv8_1a);
+ }
+
+ if (features.hasARMv8_1a()) {
+ features.add(CpuFeatures::ARM::kARMv8a,
+ CpuFeatures::ARM::kCRC32,
+ CpuFeatures::ARM::kLSE,
+ CpuFeatures::ARM::kRDM);
+ }
+
+ if (features.hasARMv8a()) {
+ features.add(CpuFeatures::ARM::kARMv7,
+ CpuFeatures::ARM::kVFPv2,
+ CpuFeatures::ARM::kVFPv3,
+ CpuFeatures::ARM::kVFPv4,
+ CpuFeatures::ARM::kVFP_D32,
+ CpuFeatures::ARM::kASIMD,
+ CpuFeatures::ARM::kIDIVA);
+ }
+}
+
+// CpuInfo - Detect - ARM [Windows]
+// ================================
+
+#if defined(_WIN32)
+struct WinPFPMapping {
+ uint8_t featureId;
+ uint8_t pfpFeatureId;
+};
+
+static ASMJIT_FAVOR_SIZE void detectPFPFeatures(CpuInfo& cpu, const WinPFPMapping* mapping, size_t size) noexcept {
+ for (size_t i = 0; i < size; i++)
+ if (::IsProcessorFeaturePresent(mapping[i].pfpFeatureId))
+ cpu.addFeature(mapping[i].featureId);
+}
+
+//! Detect ARM CPU features on Windows.
+//!
+//! The detection is based on `IsProcessorFeaturePresent()` API call.
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ cpu._wasDetected = true;
+ populateBaseARMFeatures(cpu);
+
+ CpuFeatures::ARM& features = cpu.features().arm();
+
+ // Win32 for ARM requires ARMv7 with DSP extensions, VFPv3, and uses THUMBv2 by default.
+#if ASMJIT_ARCH_ARM == 32
+ features.add(CpuFeatures::ARM::kTHUMB);
+ features.add(CpuFeatures::ARM::kTHUMBv2);
+ features.add(CpuFeatures::ARM::kARMv6);
+ features.add(CpuFeatures::ARM::kARMv7);
+ features.add(CpuFeatures::ARM::kEDSP);
+ features.add(CpuFeatures::ARM::kVFPv2);
+ features.add(CpuFeatures::ARM::kVFPv3);
+#endif
+
+ // Windows for ARM requires ASIMD.
+ features.add(CpuFeatures::ARM::kASIMD);
+
+ // Detect additional CPU features by calling `IsProcessorFeaturePresent()`.
+ static const WinPFPMapping mapping[] = {
+#if ASMJIT_ARCH_ARM == 32
+ { uint8_t(CpuFeatures::ARM::kVFP_D32) , 18 }, // PF_ARM_VFP_32_REGISTERS_AVAILABLE
+ { uint8_t(CpuFeatures::ARM::kIDIVT) , 24 }, // PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE
+ { uint8_t(CpuFeatures::ARM::kVFPv4) , 27 }, // PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE
+ { uint8_t(CpuFeatures::ARM::kARMv8a) , 29 }, // PF_ARM_V8_INSTRUCTIONS_AVAILABLE
+#endif
+ { uint8_t(CpuFeatures::ARM::kAES) , 30 }, // PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE
+ { uint8_t(CpuFeatures::ARM::kCRC32) , 31 }, // PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE
+ { uint8_t(CpuFeatures::ARM::kLSE) , 34 } // PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
+
+ };
+ detectPFPFeatures(cpu, mapping, ASMJIT_ARRAY_SIZE(mapping));
+
+ // Windows provides several instructions under a single flag:
+ if (features.hasAES()) {
+ features.add(CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ }
+
+ expandARMFeaturesByVersion(cpu);
+}
+
+// CpuInfo - Detect - ARM [Linux]
+// ==============================
+
+#elif defined(__linux__)
+
+struct LinuxHWCapMapping {
+ uint8_t featureId;
+ uint8_t hwCapBit;
+};
+
+static ASMJIT_FAVOR_SIZE void detectHWCaps(CpuInfo& cpu, unsigned long type, const LinuxHWCapMapping* mapping, size_t size) noexcept {
+ unsigned long mask = getauxval(type);
+ for (size_t i = 0; i < size; i++)
+ cpu.features().addIf(Support::bitTest(mask, mapping[i].hwCapBit), mapping[i].featureId);
+}
+
+#if ASMJIT_ARCH_ARM == 32
+
+// `AT_HWCAP` provides ARMv7 (and less) related flags.
+static const LinuxHWCapMapping hwCapMapping[] = {
+ { uint8_t(CpuFeatures::ARM::kVFPv2) , 6 }, // HWCAP_VFP
+ { uint8_t(CpuFeatures::ARM::kEDSP) , 7 }, // HWCAP_EDSP
+ { uint8_t(CpuFeatures::ARM::kASIMD) , 12 }, // HWCAP_NEON
+ { uint8_t(CpuFeatures::ARM::kVFPv3) , 13 }, // HWCAP_VFPv3
+ { uint8_t(CpuFeatures::ARM::kVFPv4) , 16 }, // HWCAP_VFPv4
+ { uint8_t(CpuFeatures::ARM::kIDIVA) , 17 }, // HWCAP_IDIVA
+ { uint8_t(CpuFeatures::ARM::kIDIVT) , 18 }, // HWCAP_IDIVT
+ { uint8_t(CpuFeatures::ARM::kVFP_D32) , 19 } // HWCAP_VFPD32
+};
+
+// `AT_HWCAP2` provides ARMv8+ related flags.
+static const LinuxHWCapMapping hwCap2Mapping[] = {
+ { uint8_t(CpuFeatures::ARM::kAES) , 0 }, // HWCAP2_AES
+ { uint8_t(CpuFeatures::ARM::kPMULL) , 1 }, // HWCAP2_PMULL
+ { uint8_t(CpuFeatures::ARM::kSHA1) , 2 }, // HWCAP2_SHA1
+ { uint8_t(CpuFeatures::ARM::kSHA2) , 3 }, // HWCAP2_SHA2
+ { uint8_t(CpuFeatures::ARM::kCRC32) , 4 } // HWCAP2_CRC32
+};
+
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ cpu._wasDetected = true;
+
+ populateBaseARMFeatures(cpu);
+
+ CpuFeatures::ARM& features = cpu.features().arm();
+
+ detectHWCaps(cpu, AT_HWCAP, hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+ detectHWCaps(cpu, AT_HWCAP2, hwCap2Mapping, ASMJIT_ARRAY_SIZE(hwCap2Mapping));
+
+ // VFPv3 implies VFPv2.
+ if (features.hasVFPv3())
+ features.add(CpuFeatures::ARM::kVFPv2);
+
+ // VFPv2 implies ARMv6.
+ if (features.hasVFPv2())
+ features.add(CpuFeatures::ARM::kARMv6);
+
+ // ARMv7 provides VFPv3|ASIMD.
+ if (features.hasVFPv3() || features.hasASIMD())
+ features.add(CpuFeatures::ARM::kARMv7);
+
+ // ARMv8 provives AES, CRC32, PMULL, SHA1, and SHA2.
+ if (features.hasAES() || features.hasCRC32() || features.hasPMULL() || features.hasSHA1() || features.hasSHA2())
+ features.add(CpuFeatures::ARM::kARMv8a);
+}
+
+#else
+
+// `AT_HWCAP` provides ARMv8+ related flags.
+static const LinuxHWCapMapping hwCapMapping[] = {
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 0 }, // HWCAP_FP
+ */
+ { uint8_t(CpuFeatures::ARM::kASIMD) , 1 }, // HWCAP_ASIMD
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 2 }, // HWCAP_EVTSTRM
+ */
+ { uint8_t(CpuFeatures::ARM::kAES) , 3 }, // HWCAP_AES
+ { uint8_t(CpuFeatures::ARM::kPMULL) , 4 }, // HWCAP_PMULL
+ { uint8_t(CpuFeatures::ARM::kSHA1) , 5 }, // HWCAP_SHA1
+ { uint8_t(CpuFeatures::ARM::kSHA2) , 6 }, // HWCAP_SHA2
+ { uint8_t(CpuFeatures::ARM::kCRC32) , 7 }, // HWCAP_CRC32
+ { uint8_t(CpuFeatures::ARM::kLSE) , 8 }, // HWCAP_ATOMICS
+ { uint8_t(CpuFeatures::ARM::kFP16CONV) , 9 }, // HWCAP_FPHP
+ { uint8_t(CpuFeatures::ARM::kFP16FULL) , 10 }, // HWCAP_ASIMDHP
+ { uint8_t(CpuFeatures::ARM::kCPUID) , 11 }, // HWCAP_CPUID
+ { uint8_t(CpuFeatures::ARM::kRDM) , 12 }, // HWCAP_ASIMDRDM
+ { uint8_t(CpuFeatures::ARM::kFJCVTZS) , 13 }, // HWCAP_JSCVT
+ { uint8_t(CpuFeatures::ARM::kFCMA) , 14 }, // HWCAP_FCMA
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 15 }, // HWCAP_LRCPC
+ { uint8_t(CpuFeatures::ARM::k) , 16 }, // HWCAP_DCPOP
+ */
+ { uint8_t(CpuFeatures::ARM::kSHA3) , 17 }, // HWCAP_SHA3
+ { uint8_t(CpuFeatures::ARM::kSM3) , 18 }, // HWCAP_SM3
+ { uint8_t(CpuFeatures::ARM::kSM4) , 19 }, // HWCAP_SM4
+ { uint8_t(CpuFeatures::ARM::kDOTPROD) , 20 }, // HWCAP_ASIMDDP
+ { uint8_t(CpuFeatures::ARM::kSHA512) , 21 }, // HWCAP_SHA512
+ { uint8_t(CpuFeatures::ARM::kSVE) , 22 }, // HWCAP_SVE
+ { uint8_t(CpuFeatures::ARM::kFP16FML) , 23 }, // HWCAP_ASIMDFHM
+ { uint8_t(CpuFeatures::ARM::kDIT) , 24 }, // HWCAP_DIT
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 25 }, // HWCAP_USCAT
+ { uint8_t(CpuFeatures::ARM::k) , 26 }, // HWCAP_ILRCPC
+ */
+ { uint8_t(CpuFeatures::ARM::kFLAGM) , 27 }, // HWCAP_FLAGM
+ { uint8_t(CpuFeatures::ARM::kSSBS) , 28 }, // HWCAP_SSBS
+ { uint8_t(CpuFeatures::ARM::kSB) , 29 } // HWCAP_SB
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 30 }, // HWCAP_PACA
+ { uint8_t(CpuFeatures::ARM::k) , 31 } // HWCAP_PACG
+ */
+};
+
+// `AT_HWCAP2` provides ARMv8+ related flags.
+static const LinuxHWCapMapping hwCapMapping2[] = {
+ /*
+ { uint8_t(CpuFeatures::ARM::k) , 0 }, // HWCAP2_DCPODP
+ */
+ { uint8_t(CpuFeatures::ARM::kSVE2) , 1 }, // HWCAP2_SVE2
+ { uint8_t(CpuFeatures::ARM::kSVE2_AES) , 2 }, // HWCAP2_SVEAES
+ { uint8_t(CpuFeatures::ARM::kSVE_PMULL) , 3 }, // HWCAP2_SVEPMULL
+ { uint8_t(CpuFeatures::ARM::kSVE2_BITPERM), 4 }, // HWCAP2_SVEBITPERM
+ { uint8_t(CpuFeatures::ARM::kSVE2_SHA3) , 5 }, // HWCAP2_SVESHA3
+ { uint8_t(CpuFeatures::ARM::kSVE2_SM4) , 6 }, // HWCAP2_SVESM4
+ { uint8_t(CpuFeatures::ARM::kALTNZCV) , 7 }, // HWCAP2_FLAGM2
+ { uint8_t(CpuFeatures::ARM::kFRINT) , 8 }, // HWCAP2_FRINT
+ { uint8_t(CpuFeatures::ARM::kSVE_I8MM) , 9 }, // HWCAP2_SVEI8MM
+ { uint8_t(CpuFeatures::ARM::kSVE_F32MM) , 10 }, // HWCAP2_SVEF32MM
+ { uint8_t(CpuFeatures::ARM::kSVE_F64MM) , 11 }, // HWCAP2_SVEF64MM
+ { uint8_t(CpuFeatures::ARM::kSVE_BF16) , 12 }, // HWCAP2_SVEBF16
+ { uint8_t(CpuFeatures::ARM::kI8MM) , 13 }, // HWCAP2_I8MM
+ { uint8_t(CpuFeatures::ARM::kBF16) , 14 }, // HWCAP2_BF16
+ { uint8_t(CpuFeatures::ARM::kDGH) , 15 }, // HWCAP2_DGH
+ { uint8_t(CpuFeatures::ARM::kRNG) , 16 }, // HWCAP2_RNG
+ { uint8_t(CpuFeatures::ARM::kBTI) , 17 }, // HWCAP2_BTI
+ { uint8_t(CpuFeatures::ARM::kMTE) , 18 } // HWCAP2_MTE
+};
+
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ cpu._wasDetected = true;
+ populateBaseARMFeatures(cpu);
+
+ detectHWCaps(cpu, AT_HWCAP, hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+ detectHWCaps(cpu, AT_HWCAP2, hwCapMapping2, ASMJIT_ARRAY_SIZE(hwCapMapping2));
+}
+
+#endif
+
+// CpuInfo - Detect - ARM [Apple]
+// ==============================
+
+#elif defined(__APPLE__)
+
+namespace AppleHWId {
+ enum CpuFamily : uint32_t {
+ // Generic ARM.
+ kCpuFamily_ARM_9 = 0xE73283AEu,
+ kCpuFamily_ARM_11 = 0x8FF620D8u,
+ kCpuFamily_ARM_12 = 0xBD1B0AE9u,
+ kCpuFamily_ARM_13 = 0x0CC90E64u,
+ kCpuFamily_ARM_14 = 0x96077EF1u,
+ kCpuFamily_ARM_15 = 0xA8511BCAu,
+
+ // Apple design.
+ kCpuFamily_SWIFT = 0x1E2D6381u,
+ kCpuFamily_CYCLONE = 0x37A09642u,
+ kCpuFamily_TYPHOON = 0x2C91A47Eu,
+ kCpuFamily_TWISTER = 0x92FB37C8u,
+ kCpuFamily_HURRICANE = 0x67CEEE93u,
+ kCpuFamily_MONSOON_MISTRAL = 0xE81E7EF6u,
+ kCpuFamily_VORTEX_TEMPEST = 0x07D34B9Fu,
+ kCpuFamily_LIGHTNING_THUNDER = 0x462504D2u,
+ kCpuFamily_FIRESTORM_ICESTORM = 0x1B588BB3u
+ };
+};
+
+static ASMJIT_FAVOR_SIZE uint32_t queryARMCpuFamilyId() noexcept {
+ uint32_t result = 0;
+ size_t size = sizeof(cpuFamily);
+
+ int res = sysctlbyname("hw.cpufamily", &result, &size, nullptr, 0);
+ if (res != 0)
+ return 0;
+ else
+ return result;
+}
+
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ cpu._wasDetected = true;
+ populateBaseARMFeatures(cpu);
+
+ uint32_t cpuFamilyId = queryARMCpuFamilyId();
+ CpuFeatures::ARM& features = cpu.features().arm();
+
+ switch (cpuFamilyId) {
+ case AppleHWId::kCpuFamily_ARM_9:
+ case AppleHWId::kCpuFamily_ARM_11:
+ case AppleHWId::kCpuFamily_ARM_12:
+ break;
+
+ // ARM Cortex A8.
+ case AppleHWId::kCpuFamily_ARM_13:
+ break;
+
+ // ARM Cortex A9.
+ case AppleHWId::kCpuFamily_ARM_14:
+ break;
+
+ // ARM Cortex A7 - ARMv7k.
+ case AppleHWId::kCpuFamily_ARM_15:
+ features.add(CpuFeatures::ARM::kARMv7);
+ break;
+
+ // Apple A6/A6X - ARMv7s.
+ case AppleHWId::kCpuFamily_SWIFT:
+ features.add(CpuFeatures::ARM::kARMv7);
+ break;
+
+ // Apple A7 - ARMv8.0-A.
+ case AppleHWId::kCpuFamily_CYCLONE:
+ features.add(CpuFeatures::ARM::kARMv8a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ break;
+
+ // Apple A8 - ARMv8.0-A.
+ case AppleHWId::kCpuFamily_TYPHOON:
+ features.add(CpuFeatures::ARM::kARMv8a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ break;
+
+ // Apple A9 - ARMv8.0-A.
+ case AppleHWId::kCpuFamily_TWISTER:
+ features.add(CpuFeatures::ARM::kARMv8a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ break;
+
+ // Apple A10 - ARMv8.1-A.
+ case AppleHWId::kCpuFamily_HURRICANE:
+ features.add(CpuFeatures::ARM::kARMv8_1a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kRDM,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+
+ break;
+
+ // Apple A11 - ARMv8.2-A.
+ case AppleHWId::kCpuFamily_MONSOON_MISTRAL:
+ features.add(CpuFeatures::ARM::kARMv8_2a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kFP16FULL,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ break;
+
+ // Apple A12 - ARMv8.3-A.
+ case AppleHWId::kCpuFamily_VORTEX_TEMPEST:
+ features.add(CpuFeatures::ARM::kARMv8_3a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kFP16FULL,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2);
+ break;
+
+ // Apple A13 - ARMv8.4-A.
+ case AppleHWId::kCpuFamily_LIGHTNING_THUNDER:
+ features.add(CpuFeatures::ARM::kARMv8_4a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kFP16FML,
+ CpuFeatures::ARM::kFP16FULL,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2,
+ CpuFeatures::ARM::kSHA3,
+ CpuFeatures::ARM::kSHA512);
+ break;
+
+ // Apple A14/M1 - ARMv8.5-A.
+ case AppleHWId::kCpuFamily_FIRESTORM_ICESTORM:
+ features.add(CpuFeatures::ARM::kARMv8_4a,
+ CpuFeatures::ARM::kAES,
+ CpuFeatures::ARM::kALTNZCV,
+ CpuFeatures::ARM::kFP16FML,
+ CpuFeatures::ARM::kFP16FULL,
+ CpuFeatures::ARM::kFRINT,
+ CpuFeatures::ARM::kSB,
+ CpuFeatures::ARM::kSHA1,
+ CpuFeatures::ARM::kSHA2,
+ CpuFeatures::ARM::kSHA3,
+ CpuFeatures::ARM::kSHA512,
+ CpuFeatures::ARM::kSSBS);
+ break;
+
+ default:
+ cpu._wasDetected = false;
+ break;
+ }
+
+ expandARMFeaturesByVersion(cpu);
+}
+
+// CpuInfo - Detect - ARM [Unknown]
+// ================================
+
+#else
+
+#if ASMJIT_ARCH_ARM == 64
+ #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with AArch64 CPU)")
+#else
+ #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown OS with ARM CPU)")
+#endif
+
+static ASMJIT_FAVOR_SIZE void detectARMCpu(CpuInfo& cpu) noexcept {
+ populateBaseARMFeatures(cpu);
+ detectARMFeaturesViaCompilerFlags(cpu);
+ expandARMFeaturesByVersion(cpu);
+}
+#endif
+
+#endif
+
+// CpuInfo - Detect - Host
+// =======================
static uint32_t cpuInfoInitialized;
static CpuInfo cpuInfoGlobal(Globals::NoInit);
const CpuInfo& CpuInfo::host() noexcept {
- // This should never cause a problem as the resulting information should
- // always be the same.
+ // This should never cause a problem as the resulting information should always be the same. In the worst case we
+ // would just overwrite it non-atomically.
if (!cpuInfoInitialized) {
CpuInfo cpuInfoLocal;
-#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
- x86::detectCpu(cpuInfoLocal);
-#endif
+ cpuInfoLocal._arch = Arch::kHost;
+ cpuInfoLocal._subArch = SubArch::kHost;
-#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM
- arm::detectCpu(cpuInfoLocal);
+#if ASMJIT_ARCH_X86
+ detectX86Cpu(cpuInfoLocal);
+#elif ASMJIT_ARCH_ARM
+ detectARMCpu(cpuInfoLocal);
+#else
+ #pragma message("[asmjit] Disabling runtime CPU detection - unsupported OS/CPU combination (Unknown CPU)")
#endif
cpuInfoLocal._hwThreadCount = detectHWThreadCount();
diff --git a/src/asmjit/core/cpuinfo.h b/src/asmjit/core/cpuinfo.h
index 83bb8c1..974fb3e 100644
--- a/src/asmjit/core/cpuinfo.h
+++ b/src/asmjit/core/cpuinfo.h
@@ -1,52 +1,679 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_CPUINFO_H_INCLUDED
#define ASMJIT_CORE_CPUINFO_H_INCLUDED
#include "../core/archtraits.h"
-#include "../core/features.h"
+#include "../core/environment.h"
#include "../core/globals.h"
#include "../core/string.h"
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::CpuInfo]
-// ============================================================================
+//! CPU features information.
+//!
+//! Each feature is represented by a single bit in an embedded bit array.
+class CpuFeatures {
+public:
+ //! A word that is used to represents feature bits.
+ typedef Support::BitWord BitWord;
+ //! Iterator that can iterate all CPU features set.
+ typedef Support::BitVectorIterator<BitWord> Iterator;
+
+ //! \name Constants
+ //! \{
+
+ //! \cond INTERNAL
+ enum : uint32_t {
+ kMaxFeatures = 256,
+ kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits
+ };
+ //! \endcond
+
+ //! \}
+
+ //! \name Data
+ //! \{
+
+ //! CPU features data.
+ struct Data {
+ //! \name Members
+ //! \{
+
+ //! Data bits.
+ Support::Array<BitWord, kNumBitWords> _bits;
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ inline bool operator==(const Data& other) noexcept { return eq(other); }
+ inline bool operator!=(const Data& other) noexcept { return !eq(other); }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns true if there are no features set.
+ inline bool empty() const noexcept { return _bits.aggregate<Support::Or>(0) == 0; }
+
+ //! Returns all features as array of bitwords (see \ref Support::BitWord).
+ inline BitWord* bits() noexcept { return _bits.data(); }
+ //! Returns all features as array of bitwords (const).
+ inline const BitWord* bits() const noexcept { return _bits.data(); }
+
+ //! Returns the number of BitWords returned by \ref bits().
+ inline size_t bitWordCount() const noexcept { return kNumBitWords; }
+
+ //! Returns \ref Support::BitVectorIterator, that can be used to iterate over all features efficiently.
+ inline Iterator iterator() const noexcept { return Iterator(_bits.data(), kNumBitWords); }
+
+ //! Tests whether the feature `featureId` is present.
+ template<typename FeatureId>
+ ASMJIT_FORCE_INLINE bool has(const FeatureId& featureId) const noexcept {
+ ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
+
+ uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
+ uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
+
+ return bool((_bits[idx] >> bit) & 0x1);
+ }
+
+ //! Tests whether all features as defined by `other` are present.
+ ASMJIT_FORCE_INLINE bool hasAll(const Data& other) const noexcept {
+ for (uint32_t i = 0; i < kNumBitWords; i++)
+ if ((_bits[i] & other._bits[i]) != other._bits[i])
+ return false;
+ return true;
+ }
+
+ //! \}
+
+ //! \name Manipulation
+ //! \{
+
+ inline void reset() noexcept { _bits.fill(0); }
+
+ //! Adds the given CPU `featureId` to the list of features.
+ template<typename FeatureId>
+ ASMJIT_FORCE_INLINE void add(const FeatureId& featureId) noexcept {
+ ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
+
+ uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
+ uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
+
+ _bits[idx] |= BitWord(1) << bit;
+ }
+
+ template<typename FeatureId, typename... Args>
+ ASMJIT_FORCE_INLINE void add(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ add(featureId);
+ add(std::forward<Args>(otherFeatureIds)...);
+ }
+
+ template<typename FeatureId>
+ ASMJIT_FORCE_INLINE void addIf(bool condition, const FeatureId& featureId) noexcept {
+ ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
+
+ uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
+ uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
+
+ _bits[idx] |= BitWord(condition) << bit;
+ }
+
+ template<typename FeatureId, typename... Args>
+ ASMJIT_FORCE_INLINE void addIf(bool condition, const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ addIf(condition, featureId);
+ addIf(condition, std::forward<Args>(otherFeatureIds)...);
+ }
+
+ //! Removes the given CPU `featureId` from the list of features.
+ template<typename FeatureId>
+ ASMJIT_FORCE_INLINE void remove(const FeatureId& featureId) noexcept {
+ ASMJIT_ASSERT(uint32_t(featureId) < kMaxFeatures);
+
+ uint32_t idx = uint32_t(featureId) / Support::kBitWordSizeInBits;
+ uint32_t bit = uint32_t(featureId) % Support::kBitWordSizeInBits;
+
+ _bits[idx] &= ~(BitWord(1) << bit);
+ }
+
+ template<typename FeatureId, typename... Args>
+ ASMJIT_FORCE_INLINE void remove(const FeatureId& featureId, Args&&... otherFeatureIds) noexcept {
+ remove(featureId);
+ remove(std::forward<Args>(otherFeatureIds)...);
+ }
+
+ //! Tests whether this CPU features data matches `other`.
+ ASMJIT_FORCE_INLINE bool eq(const Data& other) const noexcept { return _bits == other._bits; }
+
+ //! \}
+
+ };
+
+ //! X86 specific features data.
+ struct X86 : public Data {
+ //! X86 CPU feature identifiers.
+ enum Id : uint8_t {
+ // @EnumValuesBegin{"enum": "CpuFeatures::X86"}@
+ kNone, //!< No feature (never set, used internally).
+
+ kMT, //!< CPU has multi-threading capabilities.
+ kNX, //!< CPU has Not-Execute-Bit aka DEP (data-execution prevention).
+ k3DNOW, //!< CPU has 3DNOW (3DNOW base instructions) [AMD].
+ k3DNOW2, //!< CPU has 3DNOW2 (enhanced 3DNOW) [AMD].
+ kADX, //!< CPU has ADX (multi-precision add-carry instruction extensions).
+ kAESNI, //!< CPU has AESNI (AES encode/decode instructions).
+ kALTMOVCR8, //!< CPU has LOCK MOV R<->CR0 (supports `MOV R<->CR8` via `LOCK MOV R<->CR0` in 32-bit mode) [AMD].
+ kAMX_BF16, //!< CPU has AMX_BF16 (advanced matrix extensions - BF16 instructions).
+ kAMX_INT8, //!< CPU has AMX_INT8 (advanced matrix extensions - INT8 instructions).
+ kAMX_TILE, //!< CPU has AMX_TILE (advanced matrix extensions).
+ kAVX, //!< CPU has AVX (advanced vector extensions).
+ kAVX2, //!< CPU has AVX2 (advanced vector extensions 2).
+ kAVX512_4FMAPS, //!< CPU has AVX512_FMAPS (FMA packed single).
+ kAVX512_4VNNIW, //!< CPU has AVX512_VNNIW (vector NN instructions word variable precision).
+ kAVX512_BF16, //!< CPU has AVX512_BF16 (BFLOAT16 support instruction).
+ kAVX512_BITALG, //!< CPU has AVX512_BITALG (VPOPCNT[B|W], VPSHUFBITQMB).
+ kAVX512_BW, //!< CPU has AVX512_BW (packed BYTE|WORD).
+ kAVX512_CDI, //!< CPU has AVX512_CDI (conflict detection).
+ kAVX512_DQ, //!< CPU has AVX512_DQ (packed DWORD|QWORD).
+ kAVX512_ERI, //!< CPU has AVX512_ERI (exponential and reciprocal).
+ kAVX512_F, //!< CPU has AVX512_F (AVX512 foundation).
+ kAVX512_FP16, //!< CPU has AVX512_FP16 (FP16 extensions).
+ kAVX512_IFMA, //!< CPU has AVX512_IFMA (integer fused-multiply-add using 52-bit precision).
+ kAVX512_PFI, //!< CPU has AVX512_PFI (prefetch instructions).
+ kAVX512_VBMI, //!< CPU has AVX512_VBMI (vector byte manipulation).
+ kAVX512_VBMI2, //!< CPU has AVX512_VBMI2 (vector byte manipulation 2).
+ kAVX512_VL, //!< CPU has AVX512_VL (vector length extensions).
+ kAVX512_VNNI, //!< CPU has AVX512_VNNI (vector neural network instructions).
+ kAVX512_VP2INTERSECT, //!< CPU has AVX512_VP2INTERSECT
+ kAVX512_VPOPCNTDQ, //!< CPU has AVX512_VPOPCNTDQ (VPOPCNT[D|Q] instructions).
+ kAVX_VNNI, //!< CPU has AVX_VNNI (VEX encoding of vpdpbusd/vpdpbusds/vpdpwssd/vpdpwssds).
+ kBMI, //!< CPU has BMI (bit manipulation instructions #1).
+ kBMI2, //!< CPU has BMI2 (bit manipulation instructions #2).
+ kCET_IBT, //!< CPU has CET-IBT (indirect branch tracking).
+ kCET_SS, //!< CPU has CET-SS.
+ kCLDEMOTE, //!< CPU has CLDEMOTE (cache line demote).
+ kCLFLUSH, //!< CPU has CLFUSH (Cache Line flush).
+ kCLFLUSHOPT, //!< CPU has CLFUSHOPT (Cache Line flush - optimized).
+ kCLWB, //!< CPU has CLWB.
+ kCLZERO, //!< CPU has CLZERO.
+ kCMOV, //!< CPU has CMOV (CMOV and FCMOV instructions).
+ kCMPXCHG16B, //!< CPU has CMPXCHG16B (compare-exchange 16 bytes) [X86_64].
+ kCMPXCHG8B, //!< CPU has CMPXCHG8B (compare-exchange 8 bytes).
+ kENCLV, //!< CPU has ENCLV.
+ kENQCMD, //!< CPU has ENQCMD (enqueue stores).
+ kERMS, //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
+ kF16C, //!< CPU has F16C.
+ kFMA, //!< CPU has FMA (fused-multiply-add 3 operand form).
+ kFMA4, //!< CPU has FMA4 (fused-multiply-add 4 operand form).
+ kFPU, //!< CPU has FPU (FPU support).
+ kFSGSBASE, //!< CPU has FSGSBASE.
+ kFXSR, //!< CPU has FXSR (FXSAVE/FXRSTOR instructions).
+ kFXSROPT, //!< CPU has FXSROTP (FXSAVE/FXRSTOR is optimized).
+ kGEODE, //!< CPU has GEODE extensions (3DNOW additions).
+ kGFNI, //!< CPU has GFNI (Galois field instructions).
+ kHLE, //!< CPU has HLE.
+ kHRESET, //!< CPU has HRESET.
+ kI486, //!< CPU has I486 features (I486+ support).
+ kLAHFSAHF, //!< CPU has LAHF/SAHF (LAHF/SAHF in 64-bit mode) [X86_64].
+ kLWP, //!< CPU has LWP (lightweight profiling) [AMD].
+ kLZCNT, //!< CPU has LZCNT (LZCNT instruction).
+ kMCOMMIT, //!< CPU has MCOMMIT (MCOMMIT instruction).
+ kMMX, //!< CPU has MMX (MMX base instructions).
+ kMMX2, //!< CPU has MMX2 (MMX extensions or MMX2).
+ kMONITOR, //!< CPU has MONITOR (MONITOR/MWAIT instructions).
+ kMONITORX, //!< CPU has MONITORX (MONITORX/MWAITX instructions).
+ kMOVBE, //!< CPU has MOVBE (move with byte-order swap).
+ kMOVDIR64B, //!< CPU has MOVDIR64B (move 64 bytes as direct store).
+ kMOVDIRI, //!< CPU has MOVDIRI (move dword/qword as direct store).
+ kMPX, //!< CPU has MPX (memory protection extensions).
+ kMSR, //!< CPU has MSR (RDMSR/WRMSR instructions).
+ kMSSE, //!< CPU has MSSE (misaligned SSE support).
+ kOSXSAVE, //!< CPU has OSXSAVE (XSAVE enabled by OS).
+ kOSPKE, //!< CPU has OSPKE (PKE enabled by OS).
+ kPCLMULQDQ, //!< CPU has PCLMULQDQ (packed carry-less multiplication).
+ kPCONFIG, //!< CPU has PCONFIG (PCONFIG instruction).
+ kPOPCNT, //!< CPU has POPCNT (POPCNT instruction).
+ kPREFETCHW, //!< CPU has PREFETCHW.
+ kPREFETCHWT1, //!< CPU has PREFETCHWT1.
+ kPTWRITE, //!< CPU has PTWRITE.
+ kRDPID, //!< CPU has RDPID.
+ kRDPRU, //!< CPU has RDPRU.
+ kRDRAND, //!< CPU has RDRAND.
+ kRDSEED, //!< CPU has RDSEED.
+ kRDTSC, //!< CPU has RDTSC.
+ kRDTSCP, //!< CPU has RDTSCP.
+ kRTM, //!< CPU has RTM.
+ kSERIALIZE, //!< CPU has SERIALIZE.
+ kSHA, //!< CPU has SHA (SHA-1 and SHA-256 instructions).
+ kSKINIT, //!< CPU has SKINIT (SKINIT/STGI instructions) [AMD].
+ kSMAP, //!< CPU has SMAP (supervisor-mode access prevention).
+ kSMEP, //!< CPU has SMEP (supervisor-mode execution prevention).
+ kSMX, //!< CPU has SMX (safer mode extensions).
+ kSNP, //!< CPU has SNP.
+ kSSE, //!< CPU has SSE.
+ kSSE2, //!< CPU has SSE2.
+ kSSE3, //!< CPU has SSE3.
+ kSSE4_1, //!< CPU has SSE4.1.
+ kSSE4_2, //!< CPU has SSE4.2.
+ kSSE4A, //!< CPU has SSE4A [AMD].
+ kSSSE3, //!< CPU has SSSE3.
+ kSVM, //!< CPU has SVM (virtualization) [AMD].
+ kTBM, //!< CPU has TBM (trailing bit manipulation) [AMD].
+ kTSX, //!< CPU has TSX.
+ kTSXLDTRK, //!< CPU has TSXLDTRK.
+ kUINTR, //!< CPU has UINTR (user interrupts).
+ kVAES, //!< CPU has VAES (vector AES 256|512 bit support).
+ kVMX, //!< CPU has VMX (virtualization) [INTEL].
+ kVPCLMULQDQ, //!< CPU has VPCLMULQDQ (vector PCLMULQDQ 256|512-bit support).
+ kWAITPKG, //!< CPU has WAITPKG (UMONITOR, UMWAIT, TPAUSE).
+ kWBNOINVD, //!< CPU has WBNOINVD.
+ kXOP, //!< CPU has XOP (XOP instructions) [AMD].
+ kXSAVE, //!< CPU has XSAVE.
+ kXSAVEC, //!< CPU has XSAVEC.
+ kXSAVEOPT, //!< CPU has XSAVEOPT.
+ kXSAVES, //!< CPU has XSAVES.
+ // @EnumValuesEnd@
+
+ kMaxValue = kXSAVES
+ };
+
+ #define ASMJIT_X86_FEATURE(FEATURE) \
+ inline bool has##FEATURE() const noexcept { return has(X86::k##FEATURE); }
+
+ ASMJIT_X86_FEATURE(MT)
+ ASMJIT_X86_FEATURE(NX)
+ ASMJIT_X86_FEATURE(3DNOW)
+ ASMJIT_X86_FEATURE(3DNOW2)
+ ASMJIT_X86_FEATURE(ADX)
+ ASMJIT_X86_FEATURE(AESNI)
+ ASMJIT_X86_FEATURE(ALTMOVCR8)
+ ASMJIT_X86_FEATURE(AMX_BF16)
+ ASMJIT_X86_FEATURE(AMX_INT8)
+ ASMJIT_X86_FEATURE(AMX_TILE)
+ ASMJIT_X86_FEATURE(AVX)
+ ASMJIT_X86_FEATURE(AVX2)
+ ASMJIT_X86_FEATURE(AVX512_4FMAPS)
+ ASMJIT_X86_FEATURE(AVX512_4VNNIW)
+ ASMJIT_X86_FEATURE(AVX512_BF16)
+ ASMJIT_X86_FEATURE(AVX512_BITALG)
+ ASMJIT_X86_FEATURE(AVX512_BW)
+ ASMJIT_X86_FEATURE(AVX512_CDI)
+ ASMJIT_X86_FEATURE(AVX512_DQ)
+ ASMJIT_X86_FEATURE(AVX512_ERI)
+ ASMJIT_X86_FEATURE(AVX512_F)
+ ASMJIT_X86_FEATURE(AVX512_FP16)
+ ASMJIT_X86_FEATURE(AVX512_IFMA)
+ ASMJIT_X86_FEATURE(AVX512_PFI)
+ ASMJIT_X86_FEATURE(AVX512_VBMI)
+ ASMJIT_X86_FEATURE(AVX512_VBMI2)
+ ASMJIT_X86_FEATURE(AVX512_VL)
+ ASMJIT_X86_FEATURE(AVX512_VNNI)
+ ASMJIT_X86_FEATURE(AVX512_VP2INTERSECT)
+ ASMJIT_X86_FEATURE(AVX512_VPOPCNTDQ)
+ ASMJIT_X86_FEATURE(AVX_VNNI)
+ ASMJIT_X86_FEATURE(BMI)
+ ASMJIT_X86_FEATURE(BMI2)
+ ASMJIT_X86_FEATURE(CET_IBT)
+ ASMJIT_X86_FEATURE(CET_SS)
+ ASMJIT_X86_FEATURE(CLDEMOTE)
+ ASMJIT_X86_FEATURE(CLFLUSH)
+ ASMJIT_X86_FEATURE(CLFLUSHOPT)
+ ASMJIT_X86_FEATURE(CLWB)
+ ASMJIT_X86_FEATURE(CLZERO)
+ ASMJIT_X86_FEATURE(CMOV)
+ ASMJIT_X86_FEATURE(CMPXCHG16B)
+ ASMJIT_X86_FEATURE(CMPXCHG8B)
+ ASMJIT_X86_FEATURE(ENCLV)
+ ASMJIT_X86_FEATURE(ENQCMD)
+ ASMJIT_X86_FEATURE(ERMS)
+ ASMJIT_X86_FEATURE(F16C)
+ ASMJIT_X86_FEATURE(FMA)
+ ASMJIT_X86_FEATURE(FMA4)
+ ASMJIT_X86_FEATURE(FPU)
+ ASMJIT_X86_FEATURE(FSGSBASE)
+ ASMJIT_X86_FEATURE(FXSR)
+ ASMJIT_X86_FEATURE(FXSROPT)
+ ASMJIT_X86_FEATURE(GEODE)
+ ASMJIT_X86_FEATURE(GFNI)
+ ASMJIT_X86_FEATURE(HLE)
+ ASMJIT_X86_FEATURE(HRESET)
+ ASMJIT_X86_FEATURE(I486)
+ ASMJIT_X86_FEATURE(LAHFSAHF)
+ ASMJIT_X86_FEATURE(LWP)
+ ASMJIT_X86_FEATURE(LZCNT)
+ ASMJIT_X86_FEATURE(MCOMMIT)
+ ASMJIT_X86_FEATURE(MMX)
+ ASMJIT_X86_FEATURE(MMX2)
+ ASMJIT_X86_FEATURE(MONITOR)
+ ASMJIT_X86_FEATURE(MONITORX)
+ ASMJIT_X86_FEATURE(MOVBE)
+ ASMJIT_X86_FEATURE(MOVDIR64B)
+ ASMJIT_X86_FEATURE(MOVDIRI)
+ ASMJIT_X86_FEATURE(MPX)
+ ASMJIT_X86_FEATURE(MSR)
+ ASMJIT_X86_FEATURE(MSSE)
+ ASMJIT_X86_FEATURE(OSXSAVE)
+ ASMJIT_X86_FEATURE(OSPKE)
+ ASMJIT_X86_FEATURE(PCLMULQDQ)
+ ASMJIT_X86_FEATURE(PCONFIG)
+ ASMJIT_X86_FEATURE(POPCNT)
+ ASMJIT_X86_FEATURE(PREFETCHW)
+ ASMJIT_X86_FEATURE(PREFETCHWT1)
+ ASMJIT_X86_FEATURE(PTWRITE)
+ ASMJIT_X86_FEATURE(RDPID)
+ ASMJIT_X86_FEATURE(RDPRU)
+ ASMJIT_X86_FEATURE(RDRAND)
+ ASMJIT_X86_FEATURE(RDSEED)
+ ASMJIT_X86_FEATURE(RDTSC)
+ ASMJIT_X86_FEATURE(RDTSCP)
+ ASMJIT_X86_FEATURE(RTM)
+ ASMJIT_X86_FEATURE(SERIALIZE)
+ ASMJIT_X86_FEATURE(SHA)
+ ASMJIT_X86_FEATURE(SKINIT)
+ ASMJIT_X86_FEATURE(SMAP)
+ ASMJIT_X86_FEATURE(SMEP)
+ ASMJIT_X86_FEATURE(SMX)
+ ASMJIT_X86_FEATURE(SNP)
+ ASMJIT_X86_FEATURE(SSE)
+ ASMJIT_X86_FEATURE(SSE2)
+ ASMJIT_X86_FEATURE(SSE3)
+ ASMJIT_X86_FEATURE(SSE4_1)
+ ASMJIT_X86_FEATURE(SSE4_2)
+ ASMJIT_X86_FEATURE(SSE4A)
+ ASMJIT_X86_FEATURE(SSSE3)
+ ASMJIT_X86_FEATURE(SVM)
+ ASMJIT_X86_FEATURE(TBM)
+ ASMJIT_X86_FEATURE(TSX)
+ ASMJIT_X86_FEATURE(TSXLDTRK)
+ ASMJIT_X86_FEATURE(UINTR)
+ ASMJIT_X86_FEATURE(VAES)
+ ASMJIT_X86_FEATURE(VMX)
+ ASMJIT_X86_FEATURE(VPCLMULQDQ)
+ ASMJIT_X86_FEATURE(WAITPKG)
+ ASMJIT_X86_FEATURE(WBNOINVD)
+ ASMJIT_X86_FEATURE(XOP)
+ ASMJIT_X86_FEATURE(XSAVE)
+ ASMJIT_X86_FEATURE(XSAVEC)
+ ASMJIT_X86_FEATURE(XSAVEOPT)
+ ASMJIT_X86_FEATURE(XSAVES)
+
+ #undef ASMJIT_X86_FEATURE
+ };
+
+ //! ARM specific features data.
+ struct ARM : public Data {
+ //! ARM CPU feature identifiers.
+ enum Id : uint8_t {
+ // @EnumValuesBegin{"enum": "CpuFeatures::ARM"}@
+ kNone = 0, //!< No feature (never set, used internally).
+ kTHUMB, //!< THUMB v1 ISA.
+ kTHUMBv2, //!< THUMB v2 ISA.
+
+ kARMv6, //!< ARMv6 ISA.
+ kARMv7, //!< ARMv7 ISA.
+ kARMv8a, //!< ARMv8-A ISA.
+ kARMv8_1a, //!< ARMv8.1-A ISA.
+ kARMv8_2a, //!< ARMv8.2-A ISA.
+ kARMv8_3a, //!< ARMv8.3-A ISA.
+ kARMv8_4a, //!< ARMv8.4-A ISA.
+ kARMv8_5a, //!< ARMv8.5-A ISA.
+ kARMv8_6a, //!< ARMv8.6-A ISA.
+ kARMv8_7a, //!< ARMv8.6-A ISA.
+
+ kVFPv2, //!< CPU has VFPv2 instruction set.
+ kVFPv3, //!< CPU has VFPv3 instruction set.
+ kVFPv4, //!< CPU has VFPv4 instruction set.
+ kVFP_D32, //!< CPU has 32 VFP-D (64-bit) registers.
+
+ kAES, //!< CPU has AES (AArch64 only).
+ kALTNZCV, //!< CPU has ALTNZCV (AArch64 only).
+ kASIMD, //!< CPU has Advanced SIMD (NEON on ARM/THUMB).
+ kBF16, //!< CPU has BF16 (AArch64 only).
+ kBTI, //!< CPU has BTI (branch target identification).
+ kCPUID, //!< CPU has accessible CPUID register (ID_AA64ZFR0_EL1).
+ kCRC32, //!< CPU has CRC32 .
+ kDGH, //!< CPU has DGH (AArch64 only).
+ kDIT, //!< CPU has data independent timing instructions (DIT).
+ kDOTPROD, //!< CPU has DOTPROD (SDOT/UDOT).
+ kEDSP, //!< CPU has EDSP (ARM/THUMB only).
+ kFCMA, //!< CPU has FCMA (FCADD/FCMLA).
+ kFJCVTZS, //!< CPU has FJCVTZS (AArch64 only).
+ kFLAGM, //!< CPU has FLAGM (AArch64 only).
+ kFP16CONV, //!< CPU has FP16 (half-float) conversion.
+ kFP16FML, //!< CPU has FMLAL{2}/FMLSL{2}
+ kFP16FULL, //!< CPU has full support for FP16.
+ kFRINT, //!< CPU has FRINT[32|64][X|Z] (AArch64 only).
+ kI8MM, //!< CPU has I8MM (AArch64 only).
+ kIDIVA, //!< CPU has hardware SDIV and UDIV (ARM mode).
+ kIDIVT, //!< CPU has hardware SDIV and UDIV (THUMB mode).
+ kLSE, //!< CPU has large system extensions (LSE) (AArch64 only).
+ kMTE, //!< CPU has MTE (AArch64 only).
+ kRCPC_IMMO, //!< CPU has RCPC_IMMO (AArch64 only).
+ kRDM, //!< CPU has RDM (AArch64 only).
+ kPMU, //!< CPU has PMU (AArch64 only).
+ kPMULL, //!< CPU has PMULL (AArch64 only).
+ kRNG, //!< CPU has random number generation (RNG).
+ kSB, //!< CPU has speculative barrier SB (AArch64 only).
+ kSHA1, //!< CPU has SHA1.
+ kSHA2, //!< CPU has SHA2.
+ kSHA3, //!< CPU has SHA3.
+ kSHA512, //!< CPU has SHA512.
+ kSM3, //!< CPU has SM3.
+ kSM4, //!< CPU has SM4.
+ kSSBS, //!< CPU has SSBS.
+ kSVE, //!< CPU has SVE (AArch64 only).
+ kSVE_BF16, //!< CPU has SVE-BF16 (AArch64 only).
+ kSVE_F32MM, //!< CPU has SVE-F32MM (AArch64 only).
+ kSVE_F64MM, //!< CPU has SVE-F64MM (AArch64 only).
+ kSVE_I8MM, //!< CPU has SVE-I8MM (AArch64 only).
+ kSVE_PMULL, //!< CPU has SVE-PMULL (AArch64 only).
+ kSVE2, //!< CPU has SVE2 (AArch64 only).
+ kSVE2_AES, //!< CPU has SVE2-AES (AArch64 only).
+ kSVE2_BITPERM, //!< CPU has SVE2-BITPERM (AArch64 only).
+ kSVE2_SHA3, //!< CPU has SVE2-SHA3 (AArch64 only).
+ kSVE2_SM4, //!< CPU has SVE2-SM4 (AArch64 only).
+ kTME, //!< CPU has transactional memory extensions (TME).
+ // @EnumValuesEnd@
+
+ kMaxValue = kTME
+ };
+
+ #define ASMJIT_ARM_FEATURE(FEATURE) \
+ inline bool has##FEATURE() const noexcept { return has(ARM::k##FEATURE); }
+
+ ASMJIT_ARM_FEATURE(THUMB)
+ ASMJIT_ARM_FEATURE(THUMBv2)
+
+ ASMJIT_ARM_FEATURE(ARMv6)
+ ASMJIT_ARM_FEATURE(ARMv7)
+ ASMJIT_ARM_FEATURE(ARMv8a)
+ ASMJIT_ARM_FEATURE(ARMv8_1a)
+ ASMJIT_ARM_FEATURE(ARMv8_2a)
+ ASMJIT_ARM_FEATURE(ARMv8_3a)
+ ASMJIT_ARM_FEATURE(ARMv8_4a)
+ ASMJIT_ARM_FEATURE(ARMv8_5a)
+ ASMJIT_ARM_FEATURE(ARMv8_6a)
+ ASMJIT_ARM_FEATURE(ARMv8_7a)
+
+ ASMJIT_ARM_FEATURE(VFPv2)
+ ASMJIT_ARM_FEATURE(VFPv3)
+ ASMJIT_ARM_FEATURE(VFPv4)
+ ASMJIT_ARM_FEATURE(VFP_D32)
+
+ ASMJIT_ARM_FEATURE(AES)
+ ASMJIT_ARM_FEATURE(ALTNZCV)
+ ASMJIT_ARM_FEATURE(ASIMD)
+ ASMJIT_ARM_FEATURE(BF16)
+ ASMJIT_ARM_FEATURE(BTI)
+ ASMJIT_ARM_FEATURE(CPUID)
+ ASMJIT_ARM_FEATURE(CRC32)
+ ASMJIT_ARM_FEATURE(DGH)
+ ASMJIT_ARM_FEATURE(DIT)
+ ASMJIT_ARM_FEATURE(DOTPROD)
+ ASMJIT_ARM_FEATURE(EDSP)
+ ASMJIT_ARM_FEATURE(FCMA)
+ ASMJIT_ARM_FEATURE(FLAGM)
+ ASMJIT_ARM_FEATURE(FP16CONV)
+ ASMJIT_ARM_FEATURE(FP16FML)
+ ASMJIT_ARM_FEATURE(FP16FULL)
+ ASMJIT_ARM_FEATURE(FRINT)
+ ASMJIT_ARM_FEATURE(IDIVA)
+ ASMJIT_ARM_FEATURE(IDIVT)
+ ASMJIT_ARM_FEATURE(LSE)
+ ASMJIT_ARM_FEATURE(MTE)
+ ASMJIT_ARM_FEATURE(FJCVTZS)
+ ASMJIT_ARM_FEATURE(I8MM)
+ ASMJIT_ARM_FEATURE(RCPC_IMMO)
+ ASMJIT_ARM_FEATURE(RDM)
+ ASMJIT_ARM_FEATURE(PMU)
+ ASMJIT_ARM_FEATURE(PMULL)
+ ASMJIT_ARM_FEATURE(RNG)
+ ASMJIT_ARM_FEATURE(SB)
+ ASMJIT_ARM_FEATURE(SHA1)
+ ASMJIT_ARM_FEATURE(SHA2)
+ ASMJIT_ARM_FEATURE(SHA3)
+ ASMJIT_ARM_FEATURE(SHA512)
+ ASMJIT_ARM_FEATURE(SM3)
+ ASMJIT_ARM_FEATURE(SM4)
+ ASMJIT_ARM_FEATURE(SSBS)
+ ASMJIT_ARM_FEATURE(SVE)
+ ASMJIT_ARM_FEATURE(SVE_BF16)
+ ASMJIT_ARM_FEATURE(SVE_F32MM)
+ ASMJIT_ARM_FEATURE(SVE_F64MM)
+ ASMJIT_ARM_FEATURE(SVE_I8MM)
+ ASMJIT_ARM_FEATURE(SVE_PMULL)
+ ASMJIT_ARM_FEATURE(SVE2)
+ ASMJIT_ARM_FEATURE(SVE2_AES)
+ ASMJIT_ARM_FEATURE(SVE2_BITPERM)
+ ASMJIT_ARM_FEATURE(SVE2_SHA3)
+ ASMJIT_ARM_FEATURE(SVE2_SM4)
+ ASMJIT_ARM_FEATURE(TME)
+
+ #undef ASMJIT_ARM_FEATURE
+ };
+
+ static_assert(uint32_t(X86::kMaxValue) < kMaxFeatures, "The number of X86 CPU features cannot exceed CpuFeatures::kMaxFeatures");
+ static_assert(uint32_t(ARM::kMaxValue) < kMaxFeatures, "The number of ARM CPU features cannot exceed CpuFeatures::kMaxFeatures");
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ Data _data {};
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ inline CpuFeatures() noexcept {}
+ inline CpuFeatures(const CpuFeatures& other) noexcept = default;
+ inline explicit CpuFeatures(Globals::NoInit_) noexcept {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
+
+ inline CpuFeatures& operator=(const CpuFeatures& other) noexcept = default;
+
+ inline bool operator==(const CpuFeatures& other) noexcept { return eq(other); }
+ inline bool operator!=(const CpuFeatures& other) noexcept { return !eq(other); }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns true if there are no features set.
+ inline bool empty() const noexcept { return _data.empty(); }
+
+ //! Casts this base class into a derived type `T`.
+ template<typename T = Data>
+ inline T& data() noexcept { return static_cast<T&>(_data); }
+
+ //! Casts this base class into a derived type `T` (const).
+ template<typename T = Data>
+ inline const T& data() const noexcept { return static_cast<const T&>(_data); }
+
+ //! Returns CpuFeatures::Data as \ref CpuFeatures::X86.
+ inline X86& x86() noexcept { return data<X86>(); }
+ //! Returns CpuFeatures::Data as \ref CpuFeatures::X86 (const).
+ inline const X86& x86() const noexcept { return data<X86>(); }
+
+ //! Returns CpuFeatures::Data as \ref CpuFeatures::ARM.
+ inline ARM& arm() noexcept { return data<ARM>(); }
+ //! Returns CpuFeatures::Data as \ref CpuFeatures::ARM (const).
+ inline const ARM& arm() const noexcept { return data<ARM>(); }
+
+ //! Returns all features as array of bitwords (see \ref Support::BitWord).
+ inline BitWord* bits() noexcept { return _data.bits(); }
+ //! Returns all features as array of bitwords (const).
+ inline const BitWord* bits() const noexcept { return _data.bits(); }
+ //! Returns the number of BitWords returned by \ref bits().
+ inline size_t bitWordCount() const noexcept { return _data.bitWordCount(); }
+
+ //! Returns \ref Support::BitVectorIterator, that can be used to iterate over all features efficiently.
+ inline Iterator iterator() const noexcept { return _data.iterator(); }
+
+ //! Tests whether the feature `featureId` is present.
+ template<typename FeatureId>
+ inline bool has(const FeatureId& featureId) const noexcept { return _data.has(featureId); }
+
+ //! Tests whether all features as defined by `other` are present.
+ inline bool hasAll(const CpuFeatures& other) const noexcept { return _data.hasAll(other._data); }
+
+ //! \}
+
+ //! \name Manipulation
+ //! \{
+
+ inline void reset() noexcept { _data.reset(); }
+
+ //! Adds the given CPU `featureId` to the list of features.
+ template<typename... Args>
+ inline void add(Args&&... args) noexcept { return _data.add(std::forward<Args>(args)...); }
+
+ //! Adds the given CPU `featureId` to the list of features if `condition` is true.
+ template<typename... Args>
+ inline void addIf(bool condition, Args&&... args) noexcept { return _data.addIf(condition, std::forward<Args>(args)...); }
+
+ //! Removes the given CPU `featureId` from the list of features.
+ template<typename... Args>
+ inline void remove(Args&&... args) noexcept { return _data.remove(std::forward<Args>(args)...); }
+
+ //! Tests whether this CPU features matches `other`.
+ inline bool eq(const CpuFeatures& other) const noexcept { return _data.eq(other._data); }
+
+ //! \}
+};
//! CPU information.
class CpuInfo {
public:
+ //! \name Members
+ //! \{
+
//! Architecture.
- uint8_t _arch;
+ Arch _arch;
//! Sub-architecture.
- uint8_t _subArch;
+ SubArch _subArch;
+ //! True if the CPU was detected, false if the detection failed or it's not available.
+ bool _wasDetected;
//! Reserved for future use.
- uint16_t _reserved;
+ uint8_t _reserved;
//! CPU family ID.
uint32_t _familyId;
//! CPU model ID.
@@ -69,7 +696,9 @@ public:
//! CPU brand string.
FixedString<64> _brand;
//! CPU features.
- BaseFeatures _features;
+ CpuFeatures _features;
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -83,10 +712,10 @@ public:
//! Returns the host CPU information.
ASMJIT_API static const CpuInfo& host() noexcept;
- //! Initializes CpuInfo to the given architecture, see \ref Environment.
- inline void initArch(uint32_t arch, uint32_t subArch = 0u) noexcept {
- _arch = uint8_t(arch);
- _subArch = uint8_t(subArch);
+ //! Initializes CpuInfo architecture and sub-architecture members to `arch` and `subArch`, respectively.
+ inline void initArch(Arch arch, SubArch subArch = SubArch::kUnknown) noexcept {
+ _arch = arch;
+ _subArch = subArch;
}
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
@@ -103,46 +732,76 @@ public:
//! \name Accessors
//! \{
- //! Returns the CPU architecture id, see \ref Environment::Arch.
- inline uint32_t arch() const noexcept { return _arch; }
- //! Returns the CPU architecture sub-id, see \ref Environment::SubArch.
- inline uint32_t subArch() const noexcept { return _subArch; }
+ //! Returns the CPU architecture this information relates to.
+ inline Arch arch() const noexcept { return _arch; }
+
+ //! Returns the CPU sub-architecture this information relates to.
+ inline SubArch subArch() const noexcept { return _subArch; }
+
+ //! Returns whether the CPU was detected successfully.
+ //!
+ //! If the returned value is false it means that AsmJit either failed to detect the CPU or it doesn't have
+ //! implementation targeting the host architecture and operating system.
+ inline bool wasDetected() const noexcept { return _wasDetected; }
//! Returns the CPU family ID.
+ //!
+ //! Family identifier matches the FamilyId read by using CPUID on X86 architecture.
inline uint32_t familyId() const noexcept { return _familyId; }
+
//! Returns the CPU model ID.
+ //!
+ //! Family identifier matches the ModelId read by using CPUID on X86 architecture.
+
inline uint32_t modelId() const noexcept { return _modelId; }
//! Returns the CPU brand id.
+ //!
+ //! Family identifier matches the BrandId read by using CPUID on X86 architecture.
inline uint32_t brandId() const noexcept { return _brandId; }
+
//! Returns the CPU stepping.
+ //!
+ //! Family identifier matches the Stepping information read by using CPUID on X86 architecture.
inline uint32_t stepping() const noexcept { return _stepping; }
+
//! Returns the processor type.
+ //!
+ //! Family identifier matches the ProcessorType read by using CPUID on X86 architecture.
inline uint32_t processorType() const noexcept { return _processorType; }
- //! Returns the number of maximum logical processors.
+
+ //! Returns the maximum number of logical processors.
inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; }
//! Returns the size of a cache line flush.
inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; }
+
//! Returns number of hardware threads available.
inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; }
- //! Returns the CPU vendor.
+ //! Returns a CPU vendor string.
inline const char* vendor() const noexcept { return _vendor.str; }
- //! Tests whether the CPU vendor is equal to `s`.
+ //! Tests whether the CPU vendor string is equal to `s`.
inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); }
- //! Returns the CPU brand string.
+ //! Returns a CPU brand string.
inline const char* brand() const noexcept { return _brand.str; }
- //! Returns all CPU features as `BaseFeatures`, cast to your arch-specific class
- //! if needed.
- template<typename T = BaseFeatures>
- inline const T& features() const noexcept { return _features.as<T>(); }
+ //! Returns CPU features.
+ inline CpuFeatures& features() noexcept { return _features; }
+ //! Returns CPU features (const).
+ inline const CpuFeatures& features() const noexcept { return _features; }
//! Tests whether the CPU has the given `feature`.
- inline bool hasFeature(uint32_t featureId) const noexcept { return _features.has(featureId); }
- //! Adds the given CPU `feature` to the list of this CpuInfo features.
- inline CpuInfo& addFeature(uint32_t featureId) noexcept { _features.add(featureId); return *this; }
+ template<typename FeatureId>
+ inline bool hasFeature(const FeatureId& featureId) const noexcept { return _features.has(featureId); }
+
+ //! Adds the given CPU `featureId` to the list of features.
+ template<typename... Args>
+ inline void addFeature(Args&&... args) noexcept { return _features.add(std::forward<Args>(args)...); }
+
+ //! Removes the given CPU `featureId` from the list of features.
+ template<typename... Args>
+ inline void removeFeature(Args&&... args) noexcept { return _features.remove(std::forward<Args>(args)...); }
//! \}
};
diff --git a/src/asmjit/core/datatypes.h b/src/asmjit/core/datatypes.h
deleted file mode 100644
index 2f6cc1e..0000000
--- a/src/asmjit/core/datatypes.h
+++ /dev/null
@@ -1,1071 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#ifndef ASMJIT_CORE_DATATYPES_H_INCLUDED
-#define ASMJIT_CORE_DATATYPES_H_INCLUDED
-
-#include "../core/globals.h"
-
-#ifndef ASMJIT_NO_DEPRECATED
-
-ASMJIT_BEGIN_NAMESPACE
-
-// ============================================================================
-// [asmjit::Data64]
-// ============================================================================
-
-//! 64-bit data useful for creating SIMD constants.
-union ASMJIT_DEPRECATED_STRUCT("Data64 is deprecated and will be removed in the future") Data64 {
- //! Array of eight 8-bit signed integers.
- int8_t sb[8];
- //! Array of eight 8-bit unsigned integers.
- uint8_t ub[8];
- //! Array of four 16-bit signed integers.
- int16_t sw[4];
- //! Array of four 16-bit unsigned integers.
- uint16_t uw[4];
- //! Array of two 32-bit signed integers.
- int32_t sd[2];
- //! Array of two 32-bit unsigned integers.
- uint32_t ud[2];
- //! Array of one 64-bit signed integer.
- int64_t sq[1];
- //! Array of one 64-bit unsigned integer.
- uint64_t uq[1];
-
- //! Array of two SP-FP values.
- float sf[2];
- //! Array of one DP-FP value.
- double df[1];
-
- //! \name Construction & Destruction
- //! \{
-
- //! Sets all eight 8-bit signed integers.
- static inline Data64 fromI8(int8_t x0) noexcept {
- Data64 self;
- self.setI8(x0);
- return self;
- }
-
- //! Sets all eight 8-bit unsigned integers.
- static inline Data64 fromU8(uint8_t x0) noexcept {
- Data64 self;
- self.setU8(x0);
- return self;
- }
-
- //! Sets all eight 8-bit signed integers.
- static inline Data64 fromI8(
- int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) noexcept {
-
- Data64 self;
- self.setI8(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all eight 8-bit unsigned integers.
- static inline Data64 fromU8(
- uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) noexcept {
-
- Data64 self;
- self.setU8(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all four 16-bit signed integers.
- static inline Data64 fromI16(int16_t x0) noexcept {
- Data64 self;
- self.setI16(x0);
- return self;
- }
-
- //! Sets all four 16-bit unsigned integers.
- static inline Data64 fromU16(uint16_t x0) noexcept {
- Data64 self;
- self.setU16(x0);
- return self;
- }
-
- //! Sets all four 16-bit signed integers.
- static inline Data64 fromI16(int16_t x0, int16_t x1, int16_t x2, int16_t x3) noexcept {
- Data64 self;
- self.setI16(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all four 16-bit unsigned integers.
- static inline Data64 fromU16(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) noexcept {
- Data64 self;
- self.setU16(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all two 32-bit signed integers.
- static inline Data64 fromI32(int32_t x0) noexcept {
- Data64 self;
- self.setI32(x0);
- return self;
- }
-
- //! Sets all two 32-bit unsigned integers.
- static inline Data64 fromU32(uint32_t x0) noexcept {
- Data64 self;
- self.setU32(x0);
- return self;
- }
-
- //! Sets all two 32-bit signed integers.
- static inline Data64 fromI32(int32_t x0, int32_t x1) noexcept {
- Data64 self;
- self.setI32(x0, x1);
- return self;
- }
-
- //! Sets all two 32-bit unsigned integers.
- static inline Data64 fromU32(uint32_t x0, uint32_t x1) noexcept {
- Data64 self;
- self.setU32(x0, x1);
- return self;
- }
-
- //! Sets 64-bit signed integer.
- static inline Data64 fromI64(int64_t x0) noexcept {
- Data64 self;
- self.setI64(x0);
- return self;
- }
-
- //! Sets 64-bit unsigned integer.
- static inline Data64 fromU64(uint64_t x0) noexcept {
- Data64 self;
- self.setU64(x0);
- return self;
- }
-
- //! Sets all two SP-FP values.
- static inline Data64 fromF32(float x0) noexcept {
- Data64 self;
- self.setF32(x0);
- return self;
- }
-
- //! Sets all two SP-FP values.
- static inline Data64 fromF32(float x0, float x1) noexcept {
- Data64 self;
- self.setF32(x0, x1);
- return self;
- }
-
- //! Sets all two SP-FP values.
- static inline Data64 fromF64(double x0) noexcept {
- Data64 self;
- self.setF64(x0);
- return self;
- }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Sets all eight 8-bit signed integers.
- inline void setI8(int8_t x0) noexcept {
- setU8(uint8_t(x0));
- }
-
- //! Sets all eight 8-bit unsigned integers.
- inline void setU8(uint8_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0101010101010101u;
- uq[0] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x01010101u;
- ud[0] = xd;
- ud[1] = xd;
- }
- }
-
- //! Sets all eight 8-bit signed integers.
- inline void setI8(
- int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) noexcept {
-
- sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3;
- sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7;
- }
-
- //! Sets all eight 8-bit unsigned integers.
- inline void setU8(
- uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) noexcept {
-
- ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3;
- ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7;
- }
-
- //! Sets all four 16-bit signed integers.
- inline void setI16(int16_t x0) noexcept {
- setU16(uint16_t(x0));
- }
-
- //! Sets all four 16-bit unsigned integers.
- inline void setU16(uint16_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0001000100010001u;
- uq[0] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x00010001u;
- ud[0] = xd;
- ud[1] = xd;
- }
- }
-
- //! Sets all four 16-bit signed integers.
- inline void setI16(int16_t x0, int16_t x1, int16_t x2, int16_t x3) noexcept {
- sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
- }
-
- //! Sets all four 16-bit unsigned integers.
- inline void setU16(uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) noexcept {
- uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
- }
-
- //! Sets all two 32-bit signed integers.
- inline void setI32(int32_t x0) noexcept {
- sd[0] = x0; sd[1] = x0;
- }
-
- //! Sets all two 32-bit unsigned integers.
- inline void setU32(uint32_t x0) noexcept {
- ud[0] = x0; ud[1] = x0;
- }
-
- //! Sets all two 32-bit signed integers.
- inline void setI32(int32_t x0, int32_t x1) noexcept {
- sd[0] = x0; sd[1] = x1;
- }
-
- //! Sets all two 32-bit unsigned integers.
- inline void setU32(uint32_t x0, uint32_t x1) noexcept {
- ud[0] = x0; ud[1] = x1;
- }
-
- //! Sets 64-bit signed integer.
- inline void setI64(int64_t x0) noexcept {
- sq[0] = x0;
- }
-
- //! Sets 64-bit unsigned integer.
- inline void setU64(uint64_t x0) noexcept {
- uq[0] = x0;
- }
-
- //! Sets all two SP-FP values.
- inline void setF32(float x0) noexcept {
- sf[0] = x0; sf[1] = x0;
- }
-
- //! Sets all two SP-FP values.
- inline void setF32(float x0, float x1) noexcept {
- sf[0] = x0; sf[1] = x1;
- }
-
- //! Sets all two SP-FP values.
- inline void setF64(double x0) noexcept {
- df[0] = x0;
- }
-};
-
-// ============================================================================
-// [asmjit::Data128]
-// ============================================================================
-
-//! 128-bit data useful for creating SIMD constants.
-union ASMJIT_DEPRECATED_STRUCT("Data128 is deprecated and will be removed in the future") Data128 {
- //! Array of sixteen 8-bit signed integers.
- int8_t sb[16];
- //! Array of sixteen 8-bit unsigned integers.
- uint8_t ub[16];
- //! Array of eight 16-bit signed integers.
- int16_t sw[8];
- //! Array of eight 16-bit unsigned integers.
- uint16_t uw[8];
- //! Array of four 32-bit signed integers.
- int32_t sd[4];
- //! Array of four 32-bit unsigned integers.
- uint32_t ud[4];
- //! Array of two 64-bit signed integers.
- int64_t sq[2];
- //! Array of two 64-bit unsigned integers.
- uint64_t uq[2];
-
- //! Array of four 32-bit single precision floating points.
- float sf[4];
- //! Array of two 64-bit double precision floating points.
- double df[2];
-
- //! \name Construction & Destruction
- //! \{
-
- //! Sets all sixteen 8-bit signed integers.
- static inline Data128 fromI8(int8_t x0) noexcept {
- Data128 self;
- self.setI8(x0);
- return self;
- }
-
- //! Sets all sixteen 8-bit unsigned integers.
- static inline Data128 fromU8(uint8_t x0) noexcept {
- Data128 self;
- self.setU8(x0);
- return self;
- }
-
- //! Sets all sixteen 8-bit signed integers.
- static inline Data128 fromI8(
- 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) noexcept {
-
- Data128 self;
- self.setI8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
- return self;
- }
-
- //! Sets all sixteen 8-bit unsigned integers.
- static inline Data128 fromU8(
- 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) noexcept {
-
- Data128 self;
- self.setU8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
- return self;
- }
-
- //! Sets all eight 16-bit signed integers.
- static inline Data128 fromI16(int16_t x0) noexcept {
- Data128 self;
- self.setI16(x0);
- return self;
- }
-
- //! Sets all eight 16-bit unsigned integers.
- static inline Data128 fromU16(uint16_t x0) noexcept {
- Data128 self;
- self.setU16(x0);
- return self;
- }
-
- //! Sets all eight 16-bit signed integers.
- static inline Data128 fromI16(
- int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) noexcept {
-
- Data128 self;
- self.setI16(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all eight 16-bit unsigned integers.
- static inline Data128 fromU16(
- uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) noexcept {
-
- Data128 self;
- self.setU16(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all four 32-bit signed integers.
- static inline Data128 fromI32(int32_t x0) noexcept {
- Data128 self;
- self.setI32(x0);
- return self;
- }
-
- //! Sets all four 32-bit unsigned integers.
- static inline Data128 fromU32(uint32_t x0) noexcept {
- Data128 self;
- self.setU32(x0);
- return self;
- }
-
- //! Sets all four 32-bit signed integers.
- static inline Data128 fromI32(int32_t x0, int32_t x1, int32_t x2, int32_t x3) noexcept {
- Data128 self;
- self.setI32(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all four 32-bit unsigned integers.
- static inline Data128 fromU32(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept {
- Data128 self;
- self.setU32(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all two 64-bit signed integers.
- static inline Data128 fromI64(int64_t x0) noexcept {
- Data128 self;
- self.setI64(x0);
- return self;
- }
-
- //! Sets all two 64-bit unsigned integers.
- static inline Data128 fromU64(uint64_t x0) noexcept {
- Data128 self;
- self.setU64(x0);
- return self;
- }
-
- //! Sets all two 64-bit signed integers.
- static inline Data128 fromI64(int64_t x0, int64_t x1) noexcept {
- Data128 self;
- self.setI64(x0, x1);
- return self;
- }
-
- //! Sets all two 64-bit unsigned integers.
- static inline Data128 fromU64(uint64_t x0, uint64_t x1) noexcept {
- Data128 self;
- self.setU64(x0, x1);
- return self;
- }
-
- //! Sets all four SP-FP floats.
- static inline Data128 fromF32(float x0) noexcept {
- Data128 self;
- self.setF32(x0);
- return self;
- }
-
- //! Sets all four SP-FP floats.
- static inline Data128 fromF32(float x0, float x1, float x2, float x3) noexcept {
- Data128 self;
- self.setF32(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all two DP-FP floats.
- static inline Data128 fromF64(double x0) noexcept {
- Data128 self;
- self.setF64(x0);
- return self;
- }
-
- //! Sets all two DP-FP floats.
- static inline Data128 fromF64(double x0, double x1) noexcept {
- Data128 self;
- self.setF64(x0, x1);
- return self;
- }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Sets all sixteen 8-bit signed integers.
- inline void setI8(int8_t x0) noexcept {
- setU8(uint8_t(x0));
- }
-
- //! Sets all sixteen 8-bit unsigned integers.
- inline void setU8(uint8_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0101010101010101u;
- uq[0] = xq;
- uq[1] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x01010101u;
- ud[0] = xd;
- ud[1] = xd;
- ud[2] = xd;
- ud[3] = xd;
- }
- }
-
- //! Sets all sixteen 8-bit signed integers.
- inline void setI8(
- 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) noexcept {
-
- sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ;
- sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
- sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11;
- sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
- }
-
- //! Sets all sixteen 8-bit unsigned integers.
- inline void setU8(
- 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) noexcept {
-
- ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ;
- ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
- ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11;
- ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
- }
-
- //! Sets all eight 16-bit signed integers.
- inline void setI16(int16_t x0) noexcept {
- setU16(uint16_t(x0));
- }
-
- //! Sets all eight 16-bit unsigned integers.
- inline void setU16(uint16_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0001000100010001u;
- uq[0] = xq;
- uq[1] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x00010001u;
- ud[0] = xd;
- ud[1] = xd;
- ud[2] = xd;
- ud[3] = xd;
- }
- }
-
- //! Sets all eight 16-bit signed integers.
- inline void setI16(
- int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) noexcept {
-
- sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3;
- sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7;
- }
-
- //! Sets all eight 16-bit unsigned integers.
- inline void setU16(
- uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) noexcept {
-
- uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3;
- uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7;
- }
-
- //! Sets all four 32-bit signed integers.
- inline void setI32(int32_t x0) noexcept {
- setU32(uint32_t(x0));
- }
-
- //! Sets all four 32-bit unsigned integers.
- inline void setU32(uint32_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t t = (uint64_t(x0) << 32) + x0;
- uq[0] = t;
- uq[1] = t;
- }
- else {
- ud[0] = x0;
- ud[1] = x0;
- ud[2] = x0;
- ud[3] = x0;
- }
- }
-
- //! Sets all four 32-bit signed integers.
- inline void setI32(int32_t x0, int32_t x1, int32_t x2, int32_t x3) noexcept {
- sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
- }
-
- //! Sets all four 32-bit unsigned integers.
- inline void setU32(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept {
- ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
- }
-
- //! Sets all two 64-bit signed integers.
- inline void setI64(int64_t x0) noexcept {
- sq[0] = x0; sq[1] = x0;
- }
-
- //! Sets all two 64-bit unsigned integers.
- inline void setU64(uint64_t x0) noexcept {
- uq[0] = x0; uq[1] = x0;
- }
-
- //! Sets all two 64-bit signed integers.
- inline void setI64(int64_t x0, int64_t x1) noexcept {
- sq[0] = x0; sq[1] = x1;
- }
-
- //! Sets all two 64-bit unsigned integers.
- inline void setU64(uint64_t x0, uint64_t x1) noexcept {
- uq[0] = x0; uq[1] = x1;
- }
-
- //! Sets all four SP-FP floats.
- inline void setF32(float x0) noexcept {
- sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
- }
-
- //! Sets all four SP-FP floats.
- inline void setF32(float x0, float x1, float x2, float x3) noexcept {
- sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
- }
-
- //! Sets all two DP-FP floats.
- inline void setF64(double x0) noexcept {
- df[0] = x0; df[1] = x0;
- }
-
- //! Sets all two DP-FP floats.
- inline void setF64(double x0, double x1) noexcept {
- df[0] = x0; df[1] = x1;
- }
-};
-
-// ============================================================================
-// [asmjit::Data256]
-// ============================================================================
-
-//! 256-bit data useful for creating SIMD constants.
-union ASMJIT_DEPRECATED_STRUCT("Data256 is deprecated and will be removed in the future") Data256 {
- //! Array of thirty two 8-bit signed integers.
- int8_t sb[32];
- //! Array of thirty two 8-bit unsigned integers.
- uint8_t ub[32];
- //! Array of sixteen 16-bit signed integers.
- int16_t sw[16];
- //! Array of sixteen 16-bit unsigned integers.
- uint16_t uw[16];
- //! Array of eight 32-bit signed integers.
- int32_t sd[8];
- //! Array of eight 32-bit unsigned integers.
- uint32_t ud[8];
- //! Array of four 64-bit signed integers.
- int64_t sq[4];
- //! Array of four 64-bit unsigned integers.
- uint64_t uq[4];
-
- //! Array of eight 32-bit single precision floating points.
- float sf[8];
- //! Array of four 64-bit double precision floating points.
- double df[4];
-
- //! \name Construction & Destruction
- //! \{
-
- //! Sets all thirty two 8-bit signed integers.
- static inline Data256 fromI8(int8_t x0) noexcept {
- Data256 self;
- self.setI8(x0);
- return self;
- }
-
- //! Sets all thirty two 8-bit unsigned integers.
- static inline Data256 fromU8(uint8_t x0) noexcept {
- Data256 self;
- self.setU8(x0);
- return self;
- }
-
- //! Sets all thirty two 8-bit signed integers.
- static inline Data256 fromI8(
- 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,
- int8_t x16, int8_t x17, int8_t x18, int8_t x19,
- int8_t x20, int8_t x21, int8_t x22, int8_t x23,
- int8_t x24, int8_t x25, int8_t x26, int8_t x27,
- int8_t x28, int8_t x29, int8_t x30, int8_t x31) noexcept {
-
- Data256 self;
- self.setI8(
- 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);
- return self;
- }
-
- //! Sets all thirty two 8-bit unsigned integers.
- static inline Data256 fromU8(
- 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,
- uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
- uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
- uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
- uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) noexcept {
-
- Data256 self;
- self.setU8(
- 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);
- return self;
- }
-
- //! Sets all sixteen 16-bit signed integers.
- static inline Data256 fromI16(int16_t x0) noexcept {
- Data256 self;
- self.setI16(x0);
- return self;
- }
-
- //! Sets all sixteen 16-bit unsigned integers.
- static inline Data256 fromU16(uint16_t x0) noexcept {
- Data256 self;
- self.setU16(x0);
- return self;
- }
-
- //! Sets all sixteen 16-bit signed integers.
- static inline Data256 fromI16(
- 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) noexcept {
-
- Data256 self;
- self.setI16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
- return self;
- }
-
- //! Sets all sixteen 16-bit unsigned integers.
- static inline Data256 fromU16(
- 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) noexcept {
-
- Data256 self;
- self.setU16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
- return self;
- }
-
- //! Sets all eight 32-bit signed integers.
- static inline Data256 fromI32(int32_t x0) noexcept {
- Data256 self;
- self.setI32(x0);
- return self;
- }
-
- //! Sets all eight 32-bit unsigned integers.
- static inline Data256 fromU32(uint32_t x0) noexcept {
- Data256 self;
- self.setU32(x0);
- return self;
- }
-
- //! Sets all eight 32-bit signed integers.
- static inline Data256 fromI32(
- int32_t x0, int32_t x1, int32_t x2, int32_t x3,
- int32_t x4, int32_t x5, int32_t x6, int32_t x7) noexcept {
-
- Data256 self;
- self.setI32(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all eight 32-bit unsigned integers.
- static inline Data256 fromU32(
- uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
- uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept {
-
- Data256 self;
- self.setU32(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all four 64-bit signed integers.
- static inline Data256 fromI64(int64_t x0) noexcept {
- Data256 self;
- self.setI64(x0);
- return self;
- }
-
- //! Sets all four 64-bit unsigned integers.
- static inline Data256 fromU64(uint64_t x0) noexcept {
- Data256 self;
- self.setU64(x0);
- return self;
- }
-
- //! Sets all four 64-bit signed integers.
- static inline Data256 fromI64(int64_t x0, int64_t x1, int64_t x2, int64_t x3) noexcept {
- Data256 self;
- self.setI64(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all four 64-bit unsigned integers.
- static inline Data256 fromU64(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) noexcept {
- Data256 self;
- self.setU64(x0, x1, x2, x3);
- return self;
- }
-
- //! Sets all eight SP-FP floats.
- static inline Data256 fromF32(float x0) noexcept {
- Data256 self;
- self.setF32(x0);
- return self;
- }
-
- //! Sets all eight SP-FP floats.
- static inline Data256 fromF32(
- float x0, float x1, float x2, float x3,
- float x4, float x5, float x6, float x7) noexcept {
-
- Data256 self;
- self.setF32(x0, x1, x2, x3, x4, x5, x6, x7);
- return self;
- }
-
- //! Sets all four DP-FP floats.
- static inline Data256 fromF64(double x0) noexcept {
- Data256 self;
- self.setF64(x0);
- return self;
- }
-
- //! Sets all four DP-FP floats.
- static inline Data256 fromF64(double x0, double x1, double x2, double x3) noexcept {
- Data256 self;
- self.setF64(x0, x1, x2, x3);
- return self;
- }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Sets all thirty two 8-bit signed integers.
- inline void setI8(int8_t x0) noexcept {
- setU8(uint8_t(x0));
- }
-
- //! Sets all thirty two 8-bit unsigned integers.
- inline void setU8(uint8_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0101010101010101u;
- uq[0] = xq;
- uq[1] = xq;
- uq[2] = xq;
- uq[3] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x01010101u;
- ud[0] = xd;
- ud[1] = xd;
- ud[2] = xd;
- ud[3] = xd;
- ud[4] = xd;
- ud[5] = xd;
- ud[6] = xd;
- ud[7] = xd;
- }
- }
-
- //! Sets all thirty two 8-bit signed integers.
- inline void setI8(
- 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,
- int8_t x16, int8_t x17, int8_t x18, int8_t x19,
- int8_t x20, int8_t x21, int8_t x22, int8_t x23,
- int8_t x24, int8_t x25, int8_t x26, int8_t x27,
- int8_t x28, int8_t x29, int8_t x30, int8_t x31) noexcept {
-
- sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ;
- sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ;
- sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11;
- sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15;
- sb[16] = x16; sb[17] = x17; sb[18] = x18; sb[19] = x19;
- sb[20] = x20; sb[21] = x21; sb[22] = x22; sb[23] = x23;
- sb[24] = x24; sb[25] = x25; sb[26] = x26; sb[27] = x27;
- sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31;
- }
-
- //! Sets all thirty two 8-bit unsigned integers.
- inline void setU8(
- 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,
- uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19,
- uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23,
- uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27,
- uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) noexcept {
-
- ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ;
- ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ;
- ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11;
- ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15;
- ub[16] = x16; ub[17] = x17; ub[18] = x18; ub[19] = x19;
- ub[20] = x20; ub[21] = x21; ub[22] = x22; ub[23] = x23;
- ub[24] = x24; ub[25] = x25; ub[26] = x26; ub[27] = x27;
- ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31;
- }
-
- //! Sets all sixteen 16-bit signed integers.
- inline void setI16(int16_t x0) noexcept {
- setU16(uint16_t(x0));
- }
-
- //! Sets all eight 16-bit unsigned integers.
- inline void setU16(uint16_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = uint64_t(x0) * 0x0001000100010001u;
- uq[0] = xq;
- uq[1] = xq;
- uq[2] = xq;
- uq[3] = xq;
- }
- else {
- uint32_t xd = uint32_t(x0) * 0x00010001u;
- ud[0] = xd;
- ud[1] = xd;
- ud[2] = xd;
- ud[3] = xd;
- ud[4] = xd;
- ud[5] = xd;
- ud[6] = xd;
- ud[7] = xd;
- }
- }
-
- //! Sets all sixteen 16-bit signed integers.
- inline void setI16(
- 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) noexcept {
-
- sw[0 ] = x0 ; sw[1 ] = x1 ; sw[2 ] = x2 ; sw[3 ] = x3 ;
- sw[4 ] = x4 ; sw[5 ] = x5 ; sw[6 ] = x6 ; sw[7 ] = x7 ;
- sw[8 ] = x8 ; sw[9 ] = x9 ; sw[10] = x10; sw[11] = x11;
- sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15;
- }
-
- //! Sets all sixteen 16-bit unsigned integers.
- inline void setU16(
- 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) noexcept {
-
- uw[0 ] = x0 ; uw[1 ] = x1 ; uw[2 ] = x2 ; uw[3 ] = x3 ;
- uw[4 ] = x4 ; uw[5 ] = x5 ; uw[6 ] = x6 ; uw[7 ] = x7 ;
- uw[8 ] = x8 ; uw[9 ] = x9 ; uw[10] = x10; uw[11] = x11;
- uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15;
- }
-
- //! Sets all eight 32-bit signed integers.
- inline void setI32(int32_t x0) noexcept {
- setU32(uint32_t(x0));
- }
-
- //! Sets all eight 32-bit unsigned integers.
- inline void setU32(uint32_t x0) noexcept {
- if (ASMJIT_ARCH_BITS >= 64) {
- uint64_t xq = (uint64_t(x0) << 32) + x0;
- uq[0] = xq;
- uq[1] = xq;
- uq[2] = xq;
- uq[3] = xq;
- }
- else {
- ud[0] = x0;
- ud[1] = x0;
- ud[2] = x0;
- ud[3] = x0;
- ud[4] = x0;
- ud[5] = x0;
- ud[6] = x0;
- ud[7] = x0;
- }
- }
-
- //! Sets all eight 32-bit signed integers.
- inline void setI32(
- int32_t x0, int32_t x1, int32_t x2, int32_t x3,
- int32_t x4, int32_t x5, int32_t x6, int32_t x7) noexcept {
-
- sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3;
- sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7;
- }
-
- //! Sets all eight 32-bit unsigned integers.
- inline void setU32(
- uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3,
- uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept {
-
- ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3;
- ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7;
- }
-
- //! Sets all four 64-bit signed integers.
- inline void setI64(int64_t x0) noexcept {
- sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0;
- }
-
- //! Sets all four 64-bit unsigned integers.
- inline void setU64(uint64_t x0) noexcept {
- uq[0] = x0; uq[1] = x0; uq[2] = x0; uq[3] = x0;
- }
-
- //! Sets all four 64-bit signed integers.
- inline void setI64(int64_t x0, int64_t x1, int64_t x2, int64_t x3) noexcept {
- sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3;
- }
-
- //! Sets all four 64-bit unsigned integers.
- inline void setU64(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) noexcept {
- uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3;
- }
-
- //! Sets all eight SP-FP floats.
- inline void setF32(float x0) noexcept {
- sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0;
- sf[4] = x0; sf[5] = x0; sf[6] = x0; sf[7] = x0;
- }
-
- //! Sets all eight SP-FP floats.
- inline void setF32(
- float x0, float x1, float x2, float x3,
- float x4, float x5, float x6, float x7) noexcept {
-
- sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3;
- sf[4] = x4; sf[5] = x5; sf[6] = x6; sf[7] = x7;
- }
-
- //! Sets all four DP-FP floats.
- inline void setF64(double x0) noexcept {
- df[0] = x0; df[1] = x0; df[2] = x0; df[3] = x0;
- }
-
- //! Sets all four DP-FP floats.
- inline void setF64(double x0, double x1, double x2, double x3) noexcept {
- df[0] = x0; df[1] = x1; df[2] = x2; df[3] = x3;
- }
-
- //! \}
-};
-
-ASMJIT_END_NAMESPACE
-
-#endif // !ASMJIT_NO_DEPRECATED
-#endif // ASMJIT_CORE_DATATYPES_H_INCLUDED
diff --git a/src/asmjit/core/emithelper.cpp b/src/asmjit/core/emithelper.cpp
index a77211e..bcdf098 100644
--- a/src/asmjit/core/emithelper.cpp
+++ b/src/asmjit/core/emithelper.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/archtraits.h"
@@ -33,12 +15,11 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::BaseEmitHelper - Formatting]
-// ============================================================================
+// BaseEmitHelper - Formatting
+// ===========================
#ifdef ASMJIT_DUMP_ARGS_ASSIGNMENT
-static void dumpFuncValue(String& sb, uint32_t arch, const FuncValue& value) noexcept {
+static void dumpFuncValue(String& sb, Arch arch, const FuncValue& value) noexcept {
Formatter::formatTypeId(sb, value.typeId());
sb.append('@');
@@ -59,7 +40,7 @@ static void dumpFuncValue(String& sb, uint32_t arch, const FuncValue& value) noe
static void dumpAssignment(String& sb, const FuncArgsContext& ctx) noexcept {
typedef FuncArgsContext::Var Var;
- uint32_t arch = ctx.arch();
+ Arch arch = ctx.arch();
uint32_t varCount = ctx.varCount();
for (uint32_t i = 0; i < varCount; i++) {
@@ -80,9 +61,8 @@ static void dumpAssignment(String& sb, const FuncArgsContext& ctx) noexcept {
}
#endif
-// ============================================================================
-// [asmjit::BaseEmitHelper - EmitArgsAssignment]
-// ============================================================================
+// BaseEmitHelper - EmitArgsAssignment
+// ===================================
ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args) {
typedef FuncArgsContext::Var Var;
@@ -95,7 +75,7 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
kWorkPostponed = 0x04
};
- uint32_t arch = frame.arch();
+ Arch arch = frame.arch();
const ArchTraits& archTraits = ArchTraits::byArch(arch);
RAConstraints constraints;
@@ -112,11 +92,11 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
}
#endif
+ auto& workData = ctx._workData;
uint32_t varCount = ctx._varCount;
- WorkData* workData = ctx._workData;
-
uint32_t saVarId = ctx._saVarId;
- BaseReg sp = BaseReg::fromSignatureAndId(_emitter->_gpRegInfo.signature(), archTraits.spRegId());
+
+ BaseReg sp = BaseReg(_emitter->_gpSignature, archTraits.spRegId());
BaseReg sa = sp;
if (frame.hasDynamicAlignment()) {
@@ -126,10 +106,8 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
sa.setId(saVarId < varCount ? ctx._vars[saVarId].cur.regId() : frame.saRegId());
}
- // --------------------------------------------------------------------------
// Register to stack and stack to stack moves must be first as now we have
// the biggest chance of having as many as possible unassigned registers.
- // --------------------------------------------------------------------------
if (ctx._stackDstMask) {
// Base address of all arguments passed by stack.
@@ -163,33 +141,32 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
if (cur.isReg() && !cur.isIndirect()) {
WorkData& wd = workData[archTraits.regTypeToGroup(cur.regType())];
- uint32_t rId = cur.regId();
+ uint32_t regId = cur.regId();
- reg.setSignatureAndId(archTraits.regTypeToSignature(cur.regType()), rId);
- wd.unassign(varId, rId);
+ reg.setSignatureAndId(archTraits.regTypeToSignature(cur.regType()), regId);
+ wd.unassign(varId, regId);
}
else {
- // Stack to reg move - tricky since we move stack to stack we can decide which
- // register to use. In general we follow the rule that IntToInt moves will use
- // GP regs with possibility to signature or zero extend, and all other moves will
- // either use GP or VEC regs depending on the size of the move.
- RegInfo rInfo = getSuitableRegForMemToMemMove(arch, out.typeId(), cur.typeId());
- if (ASMJIT_UNLIKELY(!rInfo.isValid()))
+ // Stack to reg move - tricky since we move stack to stack we can decide which register to use. In general
+ // we follow the rule that IntToInt moves will use GP regs with possibility to signature or zero extend,
+ // and all other moves will either use GP or VEC regs depending on the size of the move.
+ OperandSignature signature = getSuitableRegForMemToMemMove(arch, out.typeId(), cur.typeId());
+ if (ASMJIT_UNLIKELY(!signature.isValid()))
return DebugUtils::errored(kErrorInvalidState);
- WorkData& wd = workData[rInfo.group()];
- uint32_t availableRegs = wd.availableRegs();
+ WorkData& wd = workData[signature.regGroup()];
+ RegMask availableRegs = wd.availableRegs();
if (ASMJIT_UNLIKELY(!availableRegs))
return DebugUtils::errored(kErrorInvalidState);
- uint32_t rId = Support::ctz(availableRegs);
- reg.setSignatureAndId(rInfo.signature(), rId);
+ uint32_t availableId = Support::ctz(availableRegs);
+ reg.setSignatureAndId(signature, availableId);
ASMJIT_PROPAGATE(emitArgMove(reg, out.typeId(), srcStackPtr, cur.typeId()));
}
if (cur.isIndirect() && cur.isReg())
- workData[BaseReg::kGroupGp].unassign(varId, cur.regId());
+ workData[RegGroup::kGp].unassign(varId, cur.regId());
// Register to stack move.
ASMJIT_PROPAGATE(emitRegMove(dstStackPtr, reg, cur.typeId()));
@@ -197,10 +174,7 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
}
}
- // --------------------------------------------------------------------------
- // Shuffle all registers that are currently assigned accordingly to target
- // assignment.
- // --------------------------------------------------------------------------
+ // Shuffle all registers that are currently assigned accordingly to target assignment.
uint32_t workFlags = kWorkNone;
for (;;) {
@@ -212,8 +186,8 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
FuncValue& cur = var.cur;
FuncValue& out = var.out;
- uint32_t curGroup = archTraits.regTypeToGroup(cur.regType());
- uint32_t outGroup = archTraits.regTypeToGroup(out.regType());
+ RegGroup curGroup = archTraits.regTypeToGroup(cur.regType());
+ RegGroup outGroup = archTraits.regTypeToGroup(out.regType());
uint32_t curId = cur.regId();
uint32_t outId = out.regId();
@@ -228,8 +202,8 @@ ASMJIT_FAVOR_SIZE Error BaseEmitHelper::emitArgsAssignment(const FuncFrame& fram
EmitMove:
ASMJIT_PROPAGATE(
emitArgMove(
- BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(out.regType()), outId), out.typeId(),
- BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(cur.regType()), curId), cur.typeId()));
+ BaseReg(archTraits.regTypeToSignature(out.regType()), outId), out.typeId(),
+ BaseReg(archTraits.regTypeToSignature(cur.regType()), curId), cur.typeId()));
wd.reassign(varId, outId, curId);
cur.initReg(out.regType(), outId, out.typeId());
@@ -244,15 +218,15 @@ EmitMove:
if (!altVar.out.isInitialized() || (altVar.out.isReg() && altVar.out.regId() == curId)) {
// Only few architectures provide swap operations, and only for few register groups.
- if (archTraits.hasSwap(curGroup)) {
- uint32_t highestType = Support::max(cur.regType(), altVar.cur.regType());
- if (Support::isBetween<uint32_t>(highestType, BaseReg::kTypeGp8Lo, BaseReg::kTypeGp16))
- highestType = BaseReg::kTypeGp32;
+ if (archTraits.hasInstRegSwap(curGroup)) {
+ RegType highestType = Support::max(cur.regType(), altVar.cur.regType());
+ if (Support::isBetween(highestType, RegType::kGp8Lo, RegType::kGp16))
+ highestType = RegType::kGp32;
- uint32_t signature = archTraits.regTypeToSignature(highestType);
+ OperandSignature signature = archTraits.regTypeToSignature(highestType);
ASMJIT_PROPAGATE(
- emitRegSwap(BaseReg::fromSignatureAndId(signature, outId),
- BaseReg::fromSignatureAndId(signature, curId)));
+ emitRegSwap(BaseReg(signature, outId), BaseReg(signature, curId)));
+
wd.swap(varId, curId, altId, outId);
cur.setRegId(outId);
var.markDone();
@@ -264,9 +238,9 @@ EmitMove:
}
else {
// If there is a scratch register it can be used to perform the swap.
- uint32_t availableRegs = wd.availableRegs();
+ RegMask availableRegs = wd.availableRegs();
if (availableRegs) {
- uint32_t inOutRegs = wd.dstRegs();
+ RegMask inOutRegs = wd.dstRegs();
if (availableRegs & ~inOutRegs)
availableRegs &= ~inOutRegs;
outId = Support::ctz(availableRegs);
@@ -294,10 +268,8 @@ EmitMove:
workFlags = (workFlags & kWorkDidSome) ? kWorkNone : kWorkPostponed;
}
- // --------------------------------------------------------------------------
// Load arguments passed by stack into registers. This is pretty simple and
// it never requires multiple iterations like the previous phase.
- // --------------------------------------------------------------------------
if (ctx._hasStackSrc) {
uint32_t iterCount = 1;
@@ -317,12 +289,12 @@ EmitMove:
ASMJIT_ASSERT(var.out.isReg());
uint32_t outId = var.out.regId();
- uint32_t outType = var.out.regType();
+ RegType outType = var.out.regType();
- uint32_t group = archTraits.regTypeToGroup(outType);
- WorkData& wd = ctx._workData[group];
+ RegGroup group = archTraits.regTypeToGroup(outType);
+ WorkData& wd = workData[group];
- if (outId == sa.id() && group == BaseReg::kGroupGp) {
+ if (outId == sa.id() && group == RegGroup::kGp) {
// This register will be processed last as we still need `saRegId`.
if (iterCount == 1) {
iterCount++;
@@ -331,7 +303,7 @@ EmitMove:
wd.unassign(wd._physToVarId[outId], outId);
}
- BaseReg dstReg = BaseReg::fromSignatureAndId(archTraits.regTypeToSignature(outType), outId);
+ BaseReg dstReg = BaseReg(archTraits.regTypeToSignature(outType), outId);
BaseMem srcMem = baseArgPtr.cloneAdjusted(var.cur.stackOffset());
ASMJIT_PROPAGATE(emitArgMove(
diff --git a/src/asmjit/core/emithelper_p.h b/src/asmjit/core/emithelper_p.h
index cb8ddf0..0333959 100644
--- a/src/asmjit/core/emithelper_p.h
+++ b/src/asmjit/core/emithelper_p.h
@@ -1,26 +1,7 @@
-
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
+// This file is part of AsmJit project <https://asmjit.com>
//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_EMITHELPER_P_H_INCLUDED
#define ASMJIT_CORE_EMITHELPER_P_H_INCLUDED
@@ -35,10 +16,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::BaseEmitHelper]
-// ============================================================================
-
//! Helper class that provides utilities for each supported architecture.
class BaseEmitHelper {
public:
@@ -50,12 +27,11 @@ public:
inline BaseEmitter* emitter() const noexcept { return _emitter; }
inline void setEmitter(BaseEmitter* emitter) noexcept { _emitter = emitter; }
- //! Emits a pure move operation between two registers or the same type or
- //! between a register and its home slot. This function does not handle
- //! register conversion.
+ //! Emits a pure move operation between two registers or the same type or between a register and its home
+ //! slot. This function does not handle register conversion.
virtual Error emitRegMove(
const Operand_& dst_,
- const Operand_& src_, uint32_t typeId, const char* comment = nullptr) = 0;
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr) = 0;
//! Emits swap between two registers.
virtual Error emitRegSwap(
@@ -64,13 +40,12 @@ public:
//! Emits move from a function argument (either register or stack) to a register.
//!
- //! This function can handle the necessary conversion from one argument to
- //! another, and from one register type to another, if it's possible. Any
- //! attempt of conversion that requires third register of a different group
+ //! This function can handle the necessary conversion from one argument to another, and from one register type
+ //! to another, if it's possible. Any attempt of conversion that requires third register of a different group
//! (for example conversion from K to MMX on X86/X64) will fail.
virtual Error emitArgMove(
- const BaseReg& dst_, uint32_t dstTypeId,
- const Operand_& src_, uint32_t srcTypeId, const char* comment = nullptr) = 0;
+ const BaseReg& dst_, TypeId dstTypeId,
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) = 0;
Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args);
};
diff --git a/src/asmjit/core/emitter.cpp b/src/asmjit/core/emitter.cpp
index 2877dc8..38061b5 100644
--- a/src/asmjit/core/emitter.cpp
+++ b/src/asmjit/core/emitter.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/emitterutils_p.h"
@@ -39,91 +21,85 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::BaseEmitter - Construction / Destruction]
-// ============================================================================
+// BaseEmitter - Construction & Destruction
+// ========================================
-BaseEmitter::BaseEmitter(uint32_t emitterType) noexcept
- : _emitterType(uint8_t(emitterType)) {}
+BaseEmitter::BaseEmitter(EmitterType emitterType) noexcept
+ : _emitterType(emitterType) {}
BaseEmitter::~BaseEmitter() noexcept {
if (_code) {
- _addEmitterFlags(kFlagDestroyed);
+ _addEmitterFlags(EmitterFlags::kDestroyed);
_code->detach(this);
}
}
-// ============================================================================
-// [asmjit::BaseEmitter - Finalize]
-// ============================================================================
+// BaseEmitter - Finalize
+// ======================
Error BaseEmitter::finalize() {
// Does nothing by default, overridden by `BaseBuilder` and `BaseCompiler`.
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Internals]
-// ============================================================================
+// BaseEmitter - Internals
+// =======================
-static constexpr uint32_t kEmitterPreservedFlags = BaseEmitter::kFlagOwnLogger | BaseEmitter::kFlagOwnErrorHandler;
+static constexpr EmitterFlags kEmitterPreservedFlags = EmitterFlags::kOwnLogger | EmitterFlags::kOwnErrorHandler;
static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept {
bool emitComments = false;
- bool hasValidationOptions = false;
+ bool hasDiagnosticOptions = false;
- if (self->emitterType() == BaseEmitter::kTypeAssembler) {
+ if (self->emitterType() == EmitterType::kAssembler) {
// Assembler: Don't emit comments if logger is not attached.
emitComments = self->_code != nullptr && self->_logger != nullptr;
- hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionAssembler);
+ hasDiagnosticOptions = self->hasDiagnosticOption(DiagnosticOptions::kValidateAssembler);
}
else {
// Builder/Compiler: Always emit comments, we cannot assume they won't be used.
emitComments = self->_code != nullptr;
- hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate);
+ hasDiagnosticOptions = self->hasDiagnosticOption(DiagnosticOptions::kValidateIntermediate);
}
if (emitComments)
- self->_addEmitterFlags(BaseEmitter::kFlagLogComments);
+ self->_addEmitterFlags(EmitterFlags::kLogComments);
else
- self->_clearEmitterFlags(BaseEmitter::kFlagLogComments);
+ self->_clearEmitterFlags(EmitterFlags::kLogComments);
- // The reserved option tells emitter (Assembler/Builder/Compiler) that there
- // may be either a border case (CodeHolder not attached, for example) or that
- // logging or validation is required.
- if (self->_code == nullptr || self->_logger || hasValidationOptions)
- self->_forcedInstOptions |= BaseInst::kOptionReserved;
+ // The reserved option tells emitter (Assembler/Builder/Compiler) that there may be either a border
+ // case (CodeHolder not attached, for example) or that logging or validation is required.
+ if (self->_code == nullptr || self->_logger || hasDiagnosticOptions)
+ self->_forcedInstOptions |= InstOptions::kReserved;
else
- self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
+ self->_forcedInstOptions &= ~InstOptions::kReserved;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Validation Options]
-// ============================================================================
+// BaseEmitter - Diagnostic Options
+// ================================
-void BaseEmitter::addValidationOptions(uint32_t options) noexcept {
- _validationOptions = uint8_t(_validationOptions | options);
+void BaseEmitter::addDiagnosticOptions(DiagnosticOptions options) noexcept {
+ _diagnosticOptions |= options;
BaseEmitter_updateForcedOptions(this);
}
-void BaseEmitter::clearValidationOptions(uint32_t options) noexcept {
- _validationOptions = uint8_t(_validationOptions | options);
+void BaseEmitter::clearDiagnosticOptions(DiagnosticOptions options) noexcept {
+ _diagnosticOptions &= ~options;
BaseEmitter_updateForcedOptions(this);
}
-// ============================================================================
-// [asmjit::BaseEmitter - Logging]
-// ============================================================================
+// BaseEmitter - Logging
+// =====================
void BaseEmitter::setLogger(Logger* logger) noexcept {
#ifndef ASMJIT_NO_LOGGING
if (logger) {
_logger = logger;
- _addEmitterFlags(kFlagOwnLogger);
+ _addEmitterFlags(EmitterFlags::kOwnLogger);
}
else {
_logger = nullptr;
- _clearEmitterFlags(kFlagOwnLogger);
+ _clearEmitterFlags(EmitterFlags::kOwnLogger);
if (_code)
_logger = _code->logger();
}
@@ -133,18 +109,17 @@ void BaseEmitter::setLogger(Logger* logger) noexcept {
#endif
}
-// ============================================================================
-// [asmjit::BaseEmitter - Error Handling]
-// ============================================================================
+// BaseEmitter - Error Handling
+// ============================
void BaseEmitter::setErrorHandler(ErrorHandler* errorHandler) noexcept {
if (errorHandler) {
_errorHandler = errorHandler;
- _addEmitterFlags(kFlagOwnErrorHandler);
+ _addEmitterFlags(EmitterFlags::kOwnErrorHandler);
}
else {
_errorHandler = nullptr;
- _clearEmitterFlags(kFlagOwnErrorHandler);
+ _clearEmitterFlags(EmitterFlags::kOwnErrorHandler);
if (_code)
_errorHandler = _code->errorHandler();
}
@@ -160,58 +135,55 @@ Error BaseEmitter::reportError(Error err, const char* message) {
return err;
}
-// ============================================================================
-// [asmjit::BaseEmitter - Labels]
-// ============================================================================
+// BaseEmitter - Labels
+// ====================
Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
- return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : uint32_t(Globals::kInvalidId));
+ return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : Globals::kInvalidId);
}
bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept {
return _code && labelId < _code->labelCount();
}
-// ============================================================================
-// [asmjit::BaseEmitter - Emit (Low-Level)]
-// ============================================================================
+// BaseEmitter - Emit (Low-Level)
+// ==============================
using EmitterUtils::noExt;
-Error BaseEmitter::_emitI(uint32_t instId) {
+Error BaseEmitter::_emitI(InstId instId) {
return _emit(instId, noExt[0], noExt[1], noExt[2], noExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0) {
return _emit(instId, o0, noExt[1], noExt[2], noExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1) {
return _emit(instId, o0, o1, noExt[2], noExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2) {
return _emit(instId, o0, o1, o2, noExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
Operand_ opExt[3] = { o3 };
return _emit(instId, o0, o1, o2, opExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4) {
Operand_ opExt[3] = { o3, o4 };
return _emit(instId, o0, o1, o2, opExt);
}
-Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
+Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
Operand_ opExt[3] = { o3, o4, o5 };
return _emit(instId, o0, o1, o2, opExt);
}
-Error BaseEmitter::_emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) {
+Error BaseEmitter::_emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
const Operand_* op = operands;
-
Operand_ opExt[3];
switch (opCount) {
@@ -247,9 +219,8 @@ Error BaseEmitter::_emitOpArray(uint32_t instId, const Operand_* operands, size_
}
}
-// ============================================================================
-// [asmjit::BaseEmitter - Emit (High-Level)]
-// ============================================================================
+// BaseEmitter - Emit (High-Level)
+// ===============================
ASMJIT_FAVOR_SIZE Error BaseEmitter::emitProlog(const FuncFrame& frame) {
if (ASMJIT_UNLIKELY(!_code))
@@ -314,13 +285,12 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame,
return DebugUtils::errored(kErrorInvalidArch);
}
-// ============================================================================
-// [asmjit::BaseEmitter - Comment]
-// ============================================================================
+// BaseEmitter - Comment
+// =====================
Error BaseEmitter::commentf(const char* fmt, ...) {
- if (!hasEmitterFlag(kFlagLogComments)) {
- if (!hasEmitterFlag(kFlagAttached))
+ if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
+ if (!hasEmitterFlag(EmitterFlags::kAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
return kErrorOk;
}
@@ -342,8 +312,8 @@ Error BaseEmitter::commentf(const char* fmt, ...) {
}
Error BaseEmitter::commentv(const char* fmt, va_list ap) {
- if (!hasEmitterFlag(kFlagLogComments)) {
- if (!hasEmitterFlag(kFlagAttached))
+ if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
+ if (!hasEmitterFlag(EmitterFlags::kAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
return kErrorOk;
}
@@ -360,18 +330,17 @@ Error BaseEmitter::commentv(const char* fmt, va_list ap) {
#endif
}
-// ============================================================================
-// [asmjit::BaseEmitter - Events]
-// ============================================================================
+// BaseEmitter - Events
+// ====================
Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
_code = code;
_environment = code->environment();
- _addEmitterFlags(kFlagAttached);
+ _addEmitterFlags(EmitterFlags::kAttached);
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
- uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
- _gpRegInfo.setSignature(archTraits._regInfo[nativeRegType].signature());
+ RegType nativeRegType = Environment::is32Bit(code->arch()) ? RegType::kGp32 : RegType::kGp64;
+ _gpSignature = archTraits.regTypeToSignature(nativeRegType);
onSettingsUpdated();
return kErrorOk;
@@ -387,13 +356,13 @@ Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
_errorHandler = nullptr;
_clearEmitterFlags(~kEmitterPreservedFlags);
- _forcedInstOptions = BaseInst::kOptionReserved;
+ _forcedInstOptions = InstOptions::kReserved;
_privateData = 0;
_environment.reset();
- _gpRegInfo.reset();
+ _gpSignature.reset();
- _instOptions = 0;
+ _instOptions = InstOptions::kNone;
_extraReg.reset();
_inlineComment = nullptr;
diff --git a/src/asmjit/core/emitter.h b/src/asmjit/core/emitter.h
index 44cda70..17a98ba 100644
--- a/src/asmjit/core/emitter.h
+++ b/src/asmjit/core/emitter.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_EMITTER_H_INCLUDED
#define ASMJIT_CORE_EMITTER_H_INCLUDED
@@ -35,41 +17,203 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class ConstPool;
class FuncFrame;
class FuncArgsAssignment;
-// ============================================================================
-// [asmjit::BaseEmitter]
-// ============================================================================
+//! Align mode, used by \ref BaseEmitter::align().
+enum class AlignMode : uint8_t {
+ //! Align executable code.
+ kCode = 0,
+ //! Align non-executable code.
+ kData = 1,
+ //! Align by a sequence of zeros.
+ kZero = 2,
+
+ //! Maximum value of `AlignMode`.
+ kMaxValue = kZero
+};
+
+//! Emitter type used by \ref BaseEmitter.
+enum class EmitterType : uint8_t {
+ //! Unknown or uninitialized.
+ kNone = 0,
+ //! Emitter inherits from \ref BaseAssembler.
+ kAssembler = 1,
+ //! Emitter inherits from \ref BaseBuilder.
+ kBuilder = 2,
+ //! Emitter inherits from \ref BaseCompiler.
+ kCompiler = 3,
+
+ //! Maximum value of `EmitterType`.
+ kMaxValue = kCompiler
+};
+
+//! Emitter flags, used by \ref BaseEmitter.
+enum class EmitterFlags : uint8_t {
+ //! No flags.
+ kNone = 0u,
+ //! Emitter is attached to CodeHolder.
+ kAttached = 0x01u,
+ //! The emitter must emit comments.
+ kLogComments = 0x08u,
+ //! The emitter has its own \ref Logger (not propagated from \ref CodeHolder).
+ kOwnLogger = 0x10u,
+ //! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).
+ kOwnErrorHandler = 0x20u,
+ //! The emitter was finalized.
+ kFinalized = 0x40u,
+ //! The emitter was destroyed.
+ //!
+ //! This flag is used for a very short time when an emitter is being destroyed by
+ //! CodeHolder.
+ kDestroyed = 0x80u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(EmitterFlags)
+
+//! Encoding options.
+enum class EncodingOptions : uint32_t {
+ //! No encoding options.
+ kNone = 0,
+
+ //! Emit instructions that are optimized for size, if possible.
+ //!
+ //! Default: false.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! When this option is set it the assembler will try to fix instructions if possible into operation equivalent
+ //! instructions that take less bytes by taking advantage of implicit zero extension. For example instruction
+ //! like `mov r64, imm` and `and r64, imm` can be translated to `mov r32, imm` and `and r32, imm` when the
+ //! immediate constant is lesser than `2^31`.
+ kOptimizeForSize = 0x00000001u,
+
+ //! Emit optimized code-alignment sequences.
+ //!
+ //! Default: false.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! Default align sequence used by X86 architecture is one-byte (0x90) opcode that is often shown by disassemblers
+ //! as NOP. However there are more optimized align sequences for 2-11 bytes that may execute faster on certain CPUs.
+ //! If this feature is enabled AsmJit will generate specialized sequences for alignment between 2 to 11 bytes.
+ kOptimizedAlign = 0x00000002u,
+
+ //! Emit jump-prediction hints.
+ //!
+ //! Default: false.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! Jump prediction is usually based on the direction of the jump. If the jump is backward it is usually predicted as
+ //! taken; and if the jump is forward it is usually predicted as not-taken. The reason is that loops generally use
+ //! backward jumps and conditions usually use forward jumps. However this behavior can be overridden by using
+ //! instruction prefixes. 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. Newer processors implement heuristics for branch prediction and ignore static hints. This means
+ //! that this feature can be only used for annotation purposes.
+ kPredictedJumps = 0x00000010u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(EncodingOptions)
+
+//! Diagnostic options are used to tell emitters and their passes to perform diagnostics when emitting or processing
+//! user code. These options control validation and extra diagnostics that can be performed by higher level emitters.
+//!
+//! Instruction Validation
+//! ----------------------
+//!
+//! \ref BaseAssembler implementation perform by default only basic checks that are necessary to identify all
+//! variations of an instruction so the correct encoding can be selected. This is fine for production-ready code
+//! as the assembler doesn't have to perform checks that would slow it down. However, sometimes these checks are
+//! beneficial especially when the project that uses AsmJit is in a development phase, in which mistakes happen
+//! often. To make the experience of using AsmJit seamless it offers validation features that can be controlled
+//! by \ref DiagnosticOptions.
+//!
+//! Compiler Diagnostics
+//! --------------------
+//!
+//! Diagnostic options work with \ref BaseCompiler passes (precisely with its register allocation pass). These options
+//! can be used to enable logging of all operations that the Compiler does.
+enum class DiagnosticOptions : uint32_t {
+ //! No validation options.
+ kNone = 0,
+
+ //! Perform strict validation in \ref BaseAssembler::emit() implementations.
+ //!
+ //! This flag ensures that each instruction is checked before it's encoded into a binary representation. This flag
+ //! is only relevant for \ref BaseAssembler implementations, but can be set in any other emitter type, in that case
+ //! if that emitter needs to create an assembler on its own, for the purpose of \ref BaseEmitter::finalize() it
+ //! would propagate this flag to such assembler so all instructions passed to it are explicitly validated.
+ //!
+ //! Default: false.
+ kValidateAssembler = 0x00000001u,
+
+ //! Perform strict validation in \ref BaseBuilder::emit() and \ref BaseCompiler::emit() implementations.
+ //!
+ //! This flag ensures that each instruction is checked before an \ref InstNode representing the instruction is
+ //! created by \ref BaseBuilder or \ref BaseCompiler. This option could be more useful than \ref kValidateAssembler
+ //! in cases in which there is an invalid instruction passed to an assembler, which was invalid much earlier, most
+ //! likely when such instruction was passed to Builder/Compiler.
+ //!
+ //! This is a separate option that was introduced, because it's possible to manipulate the instruction stream
+ //! emitted by \ref BaseBuilder and \ref BaseCompiler - this means that it's allowed to emit invalid instructions
+ //! (for example with missing operands) that will be fixed later before finalizing it.
+ //!
+ //! Default: false.
+ kValidateIntermediate = 0x00000002u,
+
+ //! Annotate all nodes processed by register allocator (Compiler/RA).
+ //!
+ //! \note Annotations don't need debug options, however, some debug options like `kRADebugLiveness` may influence
+ //! their output (for example the mentioned option would add liveness information to per-instruction annotation).
+ kRAAnnotate = 0x00000080u,
+
+ //! Debug CFG generation and other related algorithms / operations (Compiler/RA).
+ kRADebugCFG = 0x00000100u,
+
+ //! Debug liveness analysis (Compiler/RA).
+ kRADebugLiveness = 0x00000200u,
+
+ //! Debug register allocation assignment (Compiler/RA).
+ kRADebugAssignment = 0x00000400u,
+
+ //! Debug the removal of code part of unreachable blocks.
+ kRADebugUnreachable = 0x00000800u,
-//! Provides a base foundation to emit code - specialized by `Assembler` and
-//! `BaseBuilder`.
+ //! Enable all debug options (Compiler/RA).
+ kRADebugAll = 0x0000FF00u,
+};
+ASMJIT_DEFINE_ENUM_FLAGS(DiagnosticOptions)
+
+//! Provides a base foundation to emitting code - specialized by \ref BaseAssembler and \ref BaseBuilder.
class ASMJIT_VIRTAPI BaseEmitter {
public:
ASMJIT_BASE_CLASS(BaseEmitter)
+ //! \name Members
+ //! \{
+
//! See \ref EmitterType.
- uint8_t _emitterType = 0;
- //! See \ref BaseEmitter::EmitterFlags.
- uint8_t _emitterFlags = 0;
- //! Validation flags in case validation is used, see \ref InstAPI::ValidationFlags.
+ EmitterType _emitterType = EmitterType::kNone;
+ //! See \ref EmitterFlags.
+ EmitterFlags _emitterFlags = EmitterFlags::kNone;
+ //! Validation flags in case validation is used.
//!
- //! \note Validation flags are specific to the emitter and they are setup at
- //! construction time and then never changed.
- uint8_t _validationFlags = 0;
- //! Validation options, see \ref ValidationOptions.
- uint8_t _validationOptions = 0;
+ //! \note Validation flags are specific to the emitter and they are setup at construction time and then never
+ //! changed.
+ ValidationFlags _validationFlags = ValidationFlags::kNone;
+ //! Validation options.
+ DiagnosticOptions _diagnosticOptions = DiagnosticOptions::kNone;
- //! Encoding options, see \ref EncodingOptions.
- uint32_t _encodingOptions = 0;
+ //! Encoding options.
+ EncodingOptions _encodingOptions = EncodingOptions::kNone;
//! Forced instruction options, combined with \ref _instOptions by \ref emit().
- uint32_t _forcedInstOptions = BaseInst::kOptionReserved;
+ InstOptions _forcedInstOptions = InstOptions::kReserved;
//! Internal private data used freely by any emitter.
uint32_t _privateData = 0;
@@ -83,143 +227,21 @@ public:
//! Describes the target environment, matches \ref CodeHolder::environment().
Environment _environment {};
//! Native GP register signature and signature related information.
- RegInfo _gpRegInfo {};
+ OperandSignature _gpSignature {};
//! Next instruction options (affects the next instruction).
- uint32_t _instOptions = 0;
+ InstOptions _instOptions = InstOptions::kNone;
//! Extra register (op-mask {k} on AVX-512) (affects the next instruction).
RegOnly _extraReg {};
//! Inline comment of the next instruction (affects the next instruction).
const char* _inlineComment = nullptr;
- //! Emitter type.
- enum EmitterType : uint32_t {
- //! Unknown or uninitialized.
- kTypeNone = 0,
- //! Emitter inherits from \ref BaseAssembler.
- kTypeAssembler = 1,
- //! Emitter inherits from \ref BaseBuilder.
- kTypeBuilder = 2,
- //! Emitter inherits from \ref BaseCompiler.
- kTypeCompiler = 3,
-
- //! Count of emitter types.
- kTypeCount = 4
- };
-
- //! Emitter flags.
- enum EmitterFlags : uint32_t {
- //! Emitter is attached to CodeHolder.
- kFlagAttached = 0x01u,
- //! The emitter must emit comments.
- kFlagLogComments = 0x08u,
- //! The emitter has its own \ref Logger (not propagated from \ref CodeHolder).
- kFlagOwnLogger = 0x10u,
- //! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).
- kFlagOwnErrorHandler = 0x20u,
- //! The emitter was finalized.
- kFlagFinalized = 0x40u,
- //! The emitter was destroyed.
- kFlagDestroyed = 0x80u
- };
-
- //! Encoding options.
- enum EncodingOptions : uint32_t {
- //! Emit instructions that are optimized for size, if possible.
- //!
- //! Default: false.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! When this option is set it the assembler will try to fix instructions
- //! if possible into operation equivalent instructions that take less bytes
- //! by taking advantage of implicit zero extension. For example instruction
- //! like `mov r64, imm` and `and r64, imm` can be translated to `mov r32, imm`
- //! and `and r32, imm` when the immediate constant is lesser than `2^31`.
- kEncodingOptionOptimizeForSize = 0x00000001u,
-
- //! Emit optimized code-alignment sequences.
- //!
- //! Default: false.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! Default align sequence used by X86 architecture is one-byte (0x90)
- //! opcode that is often shown by disassemblers as NOP. However there are
- //! more optimized align sequences for 2-11 bytes that may execute faster
- //! on certain CPUs. If this feature is enabled AsmJit will generate
- //! specialized sequences for alignment between 2 to 11 bytes.
- kEncodingOptionOptimizedAlign = 0x00000002u,
-
- //! Emit jump-prediction hints.
- //!
- //! Default: false.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! Jump prediction is usually based on the direction of the jump. If the
- //! jump is backward it is usually predicted as taken; and if the jump is
- //! forward it is usually predicted as not-taken. The reason is that loops
- //! generally use backward jumps and conditions usually use forward jumps.
- //! However this behavior can be overridden by using instruction prefixes.
- //! 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. Newer processors
- //! implement heuristics for branch prediction and ignore static hints. This
- //! means that this feature can be only used for annotation purposes.
- kEncodingOptionPredictedJumps = 0x00000010u
- };
-
-#ifndef ASMJIT_NO_DEPRECATED
- enum EmitterOptions : uint32_t {
- kOptionOptimizedForSize = kEncodingOptionOptimizeForSize,
- kOptionOptimizedAlign = kEncodingOptionOptimizedAlign,
- kOptionPredictedJumps = kEncodingOptionPredictedJumps
- };
-#endif
-
- //! Validation options are used to tell emitters to perform strict validation
- //! of instructions passed to \ref emit().
- //!
- //! \ref BaseAssembler implementation perform by default only basic checks
- //! that are necessary to identify all variations of an instruction so the
- //! correct encoding can be selected. This is fine for production-ready code
- //! as the assembler doesn't have to perform checks that would slow it down.
- //! However, sometimes these checks are beneficial especially when the project
- //! that uses AsmJit is in a development phase, in which mistakes happen often.
- //! To make the experience of using AsmJit seamless it offers validation
- //! features that can be controlled by `ValidationOptions`.
- enum ValidationOptions : uint32_t {
- //! Perform strict validation in \ref BaseAssembler::emit() implementations.
- //!
- //! This flag ensures that each instruction is checked before it's encoded
- //! into a binary representation. This flag is only relevant for \ref
- //! BaseAssembler implementations, but can be set in any other emitter type,
- //! in that case if that emitter needs to create an assembler on its own,
- //! for the purpose of \ref finalize() it would propagate this flag to such
- //! assembler so all instructions passed to it are explicitly validated.
- //!
- //! Default: false.
- kValidationOptionAssembler = 0x00000001u,
-
- //! Perform strict validation in \ref BaseBuilder::emit() and \ref
- //! BaseCompiler::emit() implementations.
- //!
- //! This flag ensures that each instruction is checked before an \ref
- //! InstNode representing the instruction is created by Builder or Compiler.
- //!
- //! Default: false.
- kValidationOptionIntermediate = 0x00000002u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
- ASMJIT_API explicit BaseEmitter(uint32_t emitterType) noexcept;
+ ASMJIT_API explicit BaseEmitter(EmitterType emitterType) noexcept;
ASMJIT_API virtual ~BaseEmitter() noexcept;
//! \}
@@ -239,28 +261,28 @@ public:
//! \{
//! Returns the type of this emitter, see `EmitterType`.
- inline uint32_t emitterType() const noexcept { return _emitterType; }
+ inline EmitterType emitterType() const noexcept { return _emitterType; }
//! Returns emitter flags , see `Flags`.
- inline uint32_t emitterFlags() const noexcept { return _emitterFlags; }
+ inline EmitterFlags emitterFlags() const noexcept { return _emitterFlags; }
//! Tests whether the emitter inherits from `BaseAssembler`.
- inline bool isAssembler() const noexcept { return _emitterType == kTypeAssembler; }
+ inline bool isAssembler() const noexcept { return _emitterType == EmitterType::kAssembler; }
//! Tests whether the emitter inherits from `BaseBuilder`.
//!
//! \note Both Builder and Compiler emitters would return `true`.
- inline bool isBuilder() const noexcept { return _emitterType >= kTypeBuilder; }
+ inline bool isBuilder() const noexcept { return uint32_t(_emitterType) >= uint32_t(EmitterType::kBuilder); }
//! Tests whether the emitter inherits from `BaseCompiler`.
- inline bool isCompiler() const noexcept { return _emitterType == kTypeCompiler; }
+ inline bool isCompiler() const noexcept { return _emitterType == EmitterType::kCompiler; }
//! Tests whether the emitter has the given `flag` enabled.
- inline bool hasEmitterFlag(uint32_t flag) const noexcept { return (_emitterFlags & flag) != 0; }
+ inline bool hasEmitterFlag(EmitterFlags flag) const noexcept { return Support::test(_emitterFlags, flag); }
//! Tests whether the emitter is finalized.
- inline bool isFinalized() const noexcept { return hasEmitterFlag(kFlagFinalized); }
+ inline bool isFinalized() const noexcept { return hasEmitterFlag(EmitterFlags::kFinalized); }
//! Tests whether the emitter is destroyed (only used during destruction).
- inline bool isDestroyed() const noexcept { return hasEmitterFlag(kFlagDestroyed); }
+ inline bool isDestroyed() const noexcept { return hasEmitterFlag(EmitterFlags::kDestroyed); }
- inline void _addEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags | flags); }
- inline void _clearEmitterFlags(uint32_t flags) noexcept { _emitterFlags = uint8_t(_emitterFlags & ~flags); }
+ inline void _addEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags |= flags; }
+ inline void _clearEmitterFlags(EmitterFlags flags) noexcept { _emitterFlags &= _emitterFlags & ~flags; }
//! \}
@@ -270,7 +292,7 @@ public:
//! Returns the CodeHolder this emitter is attached to.
inline CodeHolder* code() const noexcept { return _code; }
- //! Returns the target environment, see \ref Environment.
+ //! Returns the target environment.
//!
//! The returned \ref Environment reference matches \ref CodeHolder::environment().
inline const Environment& environment() const noexcept { return _environment; }
@@ -281,9 +303,9 @@ public:
inline bool is64Bit() const noexcept { return environment().is64Bit(); }
//! Returns the target architecture type.
- inline uint32_t arch() const noexcept { return environment().arch(); }
+ inline Arch arch() const noexcept { return environment().arch(); }
//! Returns the target architecture sub-type.
- inline uint32_t subArch() const noexcept { return environment().subArch(); }
+ inline SubArch subArch() const noexcept { return environment().subArch(); }
//! Returns the target architecture's GP register size (4 or 8 bytes).
inline uint32_t registerSize() const noexcept { return environment().registerSize(); }
@@ -298,12 +320,10 @@ public:
//! Finalizes this emitter.
//!
- //! Materializes the content of the emitter by serializing it to the attached
- //! \ref CodeHolder through an architecture specific \ref BaseAssembler. This
- //! function won't do anything if the emitter inherits from \ref BaseAssembler
- //! as assemblers emit directly to a \ref CodeBuffer held by \ref CodeHolder.
- //! However, if this is an emitter that inherits from \ref BaseBuilder or \ref
- //! BaseCompiler then these emitters need the materialization phase as they
+ //! Materializes the content of the emitter by serializing it to the attached \ref CodeHolder through an architecture
+ //! specific \ref BaseAssembler. This function won't do anything if the emitter inherits from \ref BaseAssembler as
+ //! assemblers emit directly to a \ref CodeBuffer held by \ref CodeHolder. However, if this is an emitter that
+ //! inherits from \ref BaseBuilder or \ref BaseCompiler then these emitters need the materialization phase as they
//! store their content in a representation not visible to \ref CodeHolder.
ASMJIT_API virtual Error finalize();
@@ -317,29 +337,27 @@ public:
//! Tests whether the emitter has its own logger.
//!
- //! Own logger means that it overrides the possible logger that may be used
- //! by \ref CodeHolder this emitter is attached to.
- inline bool hasOwnLogger() const noexcept { return hasEmitterFlag(kFlagOwnLogger); }
+ //! Own logger means that it overrides the possible logger that may be used by \ref CodeHolder this emitter is
+ //! attached to.
+ inline bool hasOwnLogger() const noexcept { return hasEmitterFlag(EmitterFlags::kOwnLogger); }
//! Returns the logger this emitter uses.
//!
- //! The returned logger is either the emitter's own logger or it's logger
- //! used by \ref CodeHolder this emitter is attached to.
+ //! The returned logger is either the emitter's own logger or it's logger used by \ref CodeHolder this emitter
+ //! is attached to.
inline Logger* logger() const noexcept { return _logger; }
//! Sets or resets the logger of the emitter.
//!
- //! If the `logger` argument is non-null then the logger will be considered
- //! emitter's own logger, see \ref hasOwnLogger() for more details. If the
- //! given `logger` is null then the emitter will automatically use logger
+ //! If the `logger` argument is non-null then the logger will be considered emitter's own logger, see \ref
+ //! hasOwnLogger() for more details. If the given `logger` is null then the emitter will automatically use logger
//! that is attached to the \ref CodeHolder this emitter is attached to.
ASMJIT_API void setLogger(Logger* logger) noexcept;
//! Resets the logger of this emitter.
//!
- //! The emitter will bail to using a logger attached to \ref CodeHolder this
- //! emitter is attached to, or no logger at all if \ref CodeHolder doesn't
- //! have one.
+ //! The emitter will bail to using a logger attached to \ref CodeHolder this emitter is attached to, or no logger
+ //! at all if \ref CodeHolder doesn't have one.
inline void resetLogger() noexcept { return setLogger(nullptr); }
//! \}
@@ -352,14 +370,14 @@ public:
//! Tests whether the emitter has its own error handler.
//!
- //! Own error handler means that it overrides the possible error handler that
- //! may be used by \ref CodeHolder this emitter is attached to.
- inline bool hasOwnErrorHandler() const noexcept { return hasEmitterFlag(kFlagOwnErrorHandler); }
+ //! Own error handler means that it overrides the possible error handler that may be used by \ref CodeHolder this
+ //! emitter is attached to.
+ inline bool hasOwnErrorHandler() const noexcept { return hasEmitterFlag(EmitterFlags::kOwnErrorHandler); }
//! Returns the error handler this emitter uses.
//!
- //! The returned error handler is either the emitter's own error handler or
- //! it's error handler used by \ref CodeHolder this emitter is attached to.
+ //! The returned error handler is either the emitter's own error handler or it's error handler used by
+ //! \ref CodeHolder this emitter is attached to.
inline ErrorHandler* errorHandler() const noexcept { return _errorHandler; }
//! Sets or resets the error handler of the emitter.
@@ -369,11 +387,9 @@ public:
inline void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
//! Handles the given error in the following way:
- //! 1. If the emitter has \ref ErrorHandler attached, it calls its
- //! \ref ErrorHandler::handleError() member function first, and
- //! then returns the error. The `handleError()` function may throw.
- //! 2. if the emitter doesn't have \ref ErrorHandler, the error is
- //! simply returned.
+ //! 1. If the emitter has \ref ErrorHandler attached, it calls its \ref ErrorHandler::handleError() member function
+ //! first, and then returns the error. The `handleError()` function may throw.
+ //! 2. if the emitter doesn't have \ref ErrorHandler, the error is simply returned.
ASMJIT_API Error reportError(Error err, const char* message = nullptr);
//! \}
@@ -381,61 +397,51 @@ public:
//! \name Encoding Options
//! \{
- //! Returns encoding options, see \ref EncodingOptions.
- inline uint32_t encodingOptions() const noexcept { return _encodingOptions; }
+ //! Returns encoding options.
+ inline EncodingOptions encodingOptions() const noexcept { return _encodingOptions; }
//! Tests whether the encoding `option` is set.
- inline bool hasEncodingOption(uint32_t option) const noexcept { return (_encodingOptions & option) != 0; }
+ inline bool hasEncodingOption(EncodingOptions option) const noexcept { return Support::test(_encodingOptions, option); }
- //! Enables the given encoding `options`, see \ref EncodingOptions.
- inline void addEncodingOptions(uint32_t options) noexcept { _encodingOptions |= options; }
- //! Disables the given encoding `options`, see \ref EncodingOptions.
- inline void clearEncodingOptions(uint32_t options) noexcept { _encodingOptions &= ~options; }
+ //! Enables the given encoding `options`.
+ inline void addEncodingOptions(EncodingOptions options) noexcept { _encodingOptions |= options; }
+ //! Disables the given encoding `options`.
+ inline void clearEncodingOptions(EncodingOptions options) noexcept { _encodingOptions &= ~options; }
//! \}
- //! \name Validation Options
+ //! \name Diagnostic Options
//! \{
- //! Returns the emitter's validation options, see \ref ValidationOptions.
- inline uint32_t validationOptions() const noexcept {
- return _validationOptions;
- }
+ //! Returns the emitter's diagnostic options.
+ inline DiagnosticOptions diagnosticOptions() const noexcept { return _diagnosticOptions; }
- //! Tests whether the given `option` is present in validation options.
- inline bool hasValidationOption(uint32_t option) const noexcept {
- return (_validationOptions & option) != 0;
- }
+ //! Tests whether the given `option` is present in the emitter's diagnostic options.
+ inline bool hasDiagnosticOption(DiagnosticOptions option) const noexcept { return Support::test(_diagnosticOptions, option); }
- //! Activates the given validation `options`, see \ref ValidationOptions.
+ //! Activates the given diagnostic `options`.
//!
- //! This function is used to activate explicit validation options that will
- //! be then used by all emitter implementations. There are in general two
- //! possibilities:
+ //! This function is used to activate explicit validation options that will be then used by all emitter
+ //! implementations. There are in general two possibilities:
//!
- //! - Architecture specific assembler is used. In this case a
- //! \ref kValidationOptionAssembler can be used to turn on explicit
- //! validation that will be used before an instruction is emitted.
- //! This means that internally an extra step will be performed to
- //! make sure that the instruction is correct. This is needed, because
- //! by default assemblers prefer speed over strictness.
+ //! - Architecture specific assembler is used. In this case a \ref DiagnosticOptions::kValidateAssembler can be
+ //! used to turn on explicit validation that will be used before an instruction is emitted. This means that
+ //! internally an extra step will be performed to make sure that the instruction is correct. This is needed,
+ //! because by default assemblers prefer speed over strictness.
//!
//! This option should be used in debug builds as it's pretty expensive.
//!
- //! - Architecture specific builder or compiler is used. In this case
- //! the user can turn on \ref kValidationOptionIntermediate option
- //! that adds explicit validation step before the Builder or Compiler
- //! creates an \ref InstNode to represent an emitted instruction. Error
- //! will be returned if the instruction is ill-formed. In addition,
- //! also \ref kValidationOptionAssembler can be used, which would not be
- //! consumed by Builder / Compiler directly, but it would be propagated
- //! to an architecture specific \ref BaseAssembler implementation it
- //! creates during \ref BaseEmitter::finalize().
- ASMJIT_API void addValidationOptions(uint32_t options) noexcept;
+ //! - Architecture specific builder or compiler is used. In this case the user can turn on
+ //! \ref DiagnosticOptions::kValidateIntermediate option that adds explicit validation step before the Builder
+ //! or Compiler creates an \ref InstNode to represent an emitted instruction. Error will be returned if the
+ //! instruction is ill-formed. In addition, also \ref DiagnosticOptions::kValidateAssembler can be used, which
+ //! would not be consumed by Builder / Compiler directly, but it would be propagated to an architecture specific
+ //! \ref BaseAssembler implementation it creates during \ref BaseEmitter::finalize().
+ ASMJIT_API void addDiagnosticOptions(DiagnosticOptions options) noexcept;
//! Deactivates the given validation `options`.
//!
- //! See \ref addValidationOptions() and \ref ValidationOptions for more details.
- ASMJIT_API void clearValidationOptions(uint32_t options) noexcept;
+ //! See \ref addDiagnosticOptions() and \ref DiagnosticOptions for more details.
+ ASMJIT_API void clearDiagnosticOptions(DiagnosticOptions options) noexcept;
//! \}
@@ -444,20 +450,19 @@ public:
//! Returns forced instruction options.
//!
- //! Forced instruction options are merged with next instruction options before
- //! the instruction is encoded. These options have some bits reserved that are
- //! used by error handling, logging, and instruction validation purposes. Other
- //! options are globals that affect each instruction.
- inline uint32_t forcedInstOptions() const noexcept { return _forcedInstOptions; }
+ //! Forced instruction options are merged with next instruction options before the instruction is encoded. These
+ //! options have some bits reserved that are used by error handling, logging, and instruction validation purposes.
+ //! Other options are globals that affect each instruction.
+ inline InstOptions forcedInstOptions() const noexcept { return _forcedInstOptions; }
//! Returns options of the next instruction.
- inline uint32_t instOptions() const noexcept { return _instOptions; }
+ inline InstOptions instOptions() const noexcept { return _instOptions; }
//! Returns options of the next instruction.
- inline void setInstOptions(uint32_t options) noexcept { _instOptions = options; }
+ inline void setInstOptions(InstOptions options) noexcept { _instOptions = options; }
//! Adds options of the next instruction.
- inline void addInstOptions(uint32_t options) noexcept { _instOptions |= options; }
+ inline void addInstOptions(InstOptions options) noexcept { _instOptions |= options; }
//! Resets options of the next instruction.
- inline void resetInstOptions() noexcept { _instOptions = 0; }
+ inline void resetInstOptions() noexcept { _instOptions = InstOptions::kNone; }
//! Tests whether the extra register operand is valid.
inline bool hasExtraReg() const noexcept { return _extraReg.isReg(); }
@@ -474,9 +479,8 @@ public:
inline const char* inlineComment() const noexcept { return _inlineComment; }
//! Sets comment/annotation of the next instruction.
//!
- //! \note This string is set back to null by `_emit()`, but until that it has
- //! to remain valid as the Emitter is not required to make a copy of it (and
- //! it would be slow to do that for each instruction).
+ //! \note This string is set back to null by `_emit()`, but until that it has to remain valid as the Emitter is not
+ //! required to make a copy of it (and it would be slow to do that for each instruction).
inline void setInlineComment(const char* s) noexcept { _inlineComment = s; }
//! Resets the comment/annotation to nullptr.
inline void resetInlineComment() noexcept { _inlineComment = nullptr; }
@@ -496,19 +500,19 @@ public:
//! Creates a new label.
virtual Label newLabel() = 0;
//! Creates a new named label.
- virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) = 0;
+ virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) = 0;
+ //! Creates a new anonymous label with a name, which can only be used for debugging purposes.
+ inline Label newAnonymousLabel(const char* name, size_t nameSize = SIZE_MAX) { return newNamedLabel(name, nameSize, LabelType::kAnonymous); }
//! Creates a new external label.
- inline Label newExternalLabel(const char* name, size_t nameSize = SIZE_MAX) {
- return newNamedLabel(name, nameSize, Label::kTypeExternal);
- }
+ inline Label newExternalLabel(const char* name, size_t nameSize = SIZE_MAX) { return newNamedLabel(name, nameSize, LabelType::kExternal); }
//! Returns `Label` by `name`.
//!
//! Returns invalid Label in case that the name is invalid or label was not found.
//!
- //! \note This function doesn't trigger ErrorHandler in case the name is invalid
- //! or no such label exist. You must always check the validity of the `Label` returned.
+ //! \note This function doesn't trigger ErrorHandler in case the name is invalid or no such label exist. You must
+ //! always check the validity of the `Label` returned.
ASMJIT_API Label labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId) noexcept;
//! Binds the `label` to the current position of the current section.
@@ -526,41 +530,39 @@ public:
//! \name Emit
//! \{
- // NOTE: These `emit()` helpers are designed to address a code-bloat generated
- // by C++ compilers to call a function having many arguments. Each parameter to
- // `_emit()` requires some code to pass it, which means that if we default to
- // 5 arguments in `_emit()` and instId the C++ compiler would have to generate
- // a virtual function call having 5 parameters and additional `this` argument,
- // which is quite a lot. Since by default most instructions have 2 to 3 operands
- // it's better to introduce helpers that pass from 0 to 6 operands that help to
- // reduce the size of emit(...) function call.
+ // NOTE: These `emit()` helpers are designed to address a code-bloat generated by C++ compilers to call a function
+ // having many arguments. Each parameter to `_emit()` requires some code to pass it, which means that if we default
+ // to 5 arguments in `_emit()` and instId the C++ compiler would have to generate a virtual function call having 5
+ // parameters and additional `this` argument, which is quite a lot. Since by default most instructions have 2 to 3
+ // operands it's better to introduce helpers that pass from 0 to 6 operands that help to reduce the size of emit(...)
+ // function call.
//! Emits an instruction (internal).
- ASMJIT_API Error _emitI(uint32_t instId);
+ ASMJIT_API Error _emitI(InstId instId);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0, const Operand_& o1);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4);
//! \overload
- ASMJIT_API Error _emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5);
+ ASMJIT_API Error _emitI(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5);
//! Emits an instruction `instId` with the given `operands`.
template<typename... Args>
- ASMJIT_INLINE Error emit(uint32_t instId, Args&&... operands) {
+ ASMJIT_FORCE_INLINE Error emit(InstId instId, Args&&... operands) {
return _emitI(instId, Support::ForwardOp<Args>::forward(operands)...);
}
- inline Error emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount) {
+ ASMJIT_FORCE_INLINE Error emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
return _emitOpArray(instId, operands, opCount);
}
- inline Error emitInst(const BaseInst& inst, const Operand_* operands, size_t opCount) {
+ ASMJIT_FORCE_INLINE Error emitInst(const BaseInst& inst, const Operand_* operands, size_t opCount) {
setInstOptions(inst.options());
setExtraReg(inst.extraReg());
return _emitOpArray(inst.id(), operands, opCount);
@@ -568,9 +570,9 @@ public:
//! \cond INTERNAL
//! Emits an instruction - all 6 operands must be defined.
- virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
+ virtual Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
//! Emits instruction having operands stored in array.
- ASMJIT_API virtual Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t opCount);
+ ASMJIT_API virtual Error _emitOpArray(InstId instId, const Operand_* operands, size_t opCount);
//! \endcond
//! \}
@@ -589,9 +591,10 @@ public:
//! Aligns the current CodeBuffer position to the `alignment` specified.
//!
- //! The sequence that is used to fill the gap between the aligned location
- //! and the current location depends on the align `mode`, see \ref AlignMode.
- virtual Error align(uint32_t alignMode, uint32_t alignment) = 0;
+ //! The sequence that is used to fill the gap between the aligned location and the current location depends on the
+ //! align `mode`, see \ref AlignMode. The `alignment` argument specifies alignment in bytes, so for example when
+ //! it's `32` it means that the code buffer will be aligned to `32` bytes.
+ virtual Error align(AlignMode alignMode, uint32_t alignment) = 0;
//! \}
@@ -604,49 +607,49 @@ public:
//! Embeds a typed data array.
//!
//! This is the most flexible function for embedding data as it allows to:
- //! - Assign a `typeId` to the data, so the emitter knows the type of
- //! items stored in `data`. Binary data should use \ref Type::kIdU8.
- //! - Repeat the given data `repeatCount` times, so the data can be used
- //! as a fill pattern for example, or as a pattern used by SIMD instructions.
- virtual Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0;
+ //!
+ //! - Assign a `typeId` to the data, so the emitter knows the type of items stored in `data`. Binary data should
+ //! use \ref TypeId::kUInt8.
+ //!
+ //! - Repeat the given data `repeatCount` times, so the data can be used as a fill pattern for example, or as a
+ //! pattern used by SIMD instructions.
+ virtual Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0;
//! Embeds int8_t `value` repeated by `repeatCount`.
- inline Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI8, &value, 1, repeatCount); }
+ inline Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt8, &value, 1, repeatCount); }
//! Embeds uint8_t `value` repeated by `repeatCount`.
- inline Error embedUInt8(uint8_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU8, &value, 1, repeatCount); }
+ inline Error embedUInt8(uint8_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kUInt8, &value, 1, repeatCount); }
//! Embeds int16_t `value` repeated by `repeatCount`.
- inline Error embedInt16(int16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI16, &value, 1, repeatCount); }
+ inline Error embedInt16(int16_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt16, &value, 1, repeatCount); }
//! Embeds uint16_t `value` repeated by `repeatCount`.
- inline Error embedUInt16(uint16_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU16, &value, 1, repeatCount); }
+ inline Error embedUInt16(uint16_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kUInt16, &value, 1, repeatCount); }
//! Embeds int32_t `value` repeated by `repeatCount`.
- inline Error embedInt32(int32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI32, &value, 1, repeatCount); }
+ inline Error embedInt32(int32_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt32, &value, 1, repeatCount); }
//! Embeds uint32_t `value` repeated by `repeatCount`.
- inline Error embedUInt32(uint32_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU32, &value, 1, repeatCount); }
+ inline Error embedUInt32(uint32_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kUInt32, &value, 1, repeatCount); }
//! Embeds int64_t `value` repeated by `repeatCount`.
- inline Error embedInt64(int64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdI64, &value, 1, repeatCount); }
+ inline Error embedInt64(int64_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt64, &value, 1, repeatCount); }
//! Embeds uint64_t `value` repeated by `repeatCount`.
- inline Error embedUInt64(uint64_t value, size_t repeatCount = 1) { return embedDataArray(Type::kIdU64, &value, 1, repeatCount); }
+ inline Error embedUInt64(uint64_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kUInt64, &value, 1, repeatCount); }
//! Embeds a floating point `value` repeated by `repeatCount`.
- inline Error embedFloat(float value, size_t repeatCount = 1) { return embedDataArray(Type::kIdF32, &value, 1, repeatCount); }
+ inline Error embedFloat(float value, size_t repeatCount = 1) { return embedDataArray(TypeId(TypeUtils::TypeIdOfT<float>::kTypeId), &value, 1, repeatCount); }
//! Embeds a floating point `value` repeated by `repeatCount`.
- inline Error embedDouble(double value, size_t repeatCount = 1) { return embedDataArray(Type::IdOfT<double>::kTypeId, &value, 1, repeatCount); }
+ inline Error embedDouble(double value, size_t repeatCount = 1) { return embedDataArray(TypeId(TypeUtils::TypeIdOfT<double>::kTypeId), &value, 1, repeatCount); }
//! Embeds a constant pool at the current offset by performing the following:
- //! 1. Aligns by using kAlignData to the minimum `pool` alignment.
+ //! 1. Aligns by using AlignMode::kData to the minimum `pool` alignment.
//! 2. Binds the ConstPool label so it's bound to an aligned location.
//! 3. Emits ConstPool content.
virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
//! Embeds an absolute `label` address as data.
//!
- //! The `dataSize` is an optional argument that can be used to specify the
- //! size of the address data. If it's zero (default) the address size is
- //! deduced from the target architecture (either 4 or 8 bytes).
+ //! The `dataSize` is an optional argument that can be used to specify the size of the address data. If it's zero
+ //! (default) the address size is deduced from the target architecture (either 4 or 8 bytes).
virtual Error embedLabel(const Label& label, size_t dataSize = 0) = 0;
- //! Embeds a delta (distance) between the `label` and `base` calculating it
- //! as `label - base`. This function was designed to make it easier to embed
- //! lookup tables where each index is a relative distance of two labels.
+ //! Embeds a delta (distance) between the `label` and `base` calculating it as `label - base`. This function was
+ //! designed to make it easier to embed lookup tables where each index is a relative distance of two labels.
virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) = 0;
//! \}
@@ -672,48 +675,20 @@ public:
//! Called after the emitter was detached from `CodeHolder`.
virtual Error onDetach(CodeHolder* code) noexcept = 0;
- //! Called when \ref CodeHolder has updated an important setting, which
- //! involves the following:
+ //! Called when \ref CodeHolder has updated an important setting, which involves the following:
//!
- //! - \ref Logger has been changed (\ref CodeHolder::setLogger() has been
- //! called).
- //! - \ref ErrorHandler has been changed (\ref CodeHolder::setErrorHandler()
- //! has been called).
+ //! - \ref Logger has been changed (\ref CodeHolder::setLogger() has been called).
//!
- //! This function ensures that the settings are properly propagated from
- //! \ref CodeHolder to the emitter.
+ //! - \ref ErrorHandler has been changed (\ref CodeHolder::setErrorHandler() has been called).
//!
- //! \note This function is virtual and can be overridden, however, if you
- //! do so, always call \ref BaseEmitter::onSettingsUpdated() within your
- //! own implementation to ensure that the emitter is in a consistent state.
+ //! This function ensures that the settings are properly propagated from \ref CodeHolder to the emitter.
+ //!
+ //! \note This function is virtual and can be overridden, however, if you do so, always call \ref
+ //! BaseEmitter::onSettingsUpdated() within your own implementation to ensure that the emitter is
+ //! in a consistent state.
ASMJIT_API virtual void onSettingsUpdated() noexcept;
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use environment() instead")
- inline CodeInfo codeInfo() const noexcept {
- return CodeInfo(_environment, _code ? _code->baseAddress() : Globals::kNoBaseAddress);
- }
-
- ASMJIT_DEPRECATED("Use arch() instead")
- inline uint32_t archId() const noexcept { return arch(); }
-
- ASMJIT_DEPRECATED("Use registerSize() instead")
- inline uint32_t gpSize() const noexcept { return registerSize(); }
-
- ASMJIT_DEPRECATED("Use encodingOptions() instead")
- inline uint32_t emitterOptions() const noexcept { return encodingOptions(); }
-
- ASMJIT_DEPRECATED("Use addEncodingOptions() instead")
- inline void addEmitterOptions(uint32_t options) noexcept { addEncodingOptions(options); }
-
- ASMJIT_DEPRECATED("Use clearEncodingOptions() instead")
- inline void clearEmitterOptions(uint32_t options) noexcept { clearEncodingOptions(options); }
-
- ASMJIT_DEPRECATED("Use forcedInstOptions() instead")
- inline uint32_t globalInstOptions() const noexcept { return forcedInstOptions(); }
-#endif // !ASMJIT_NO_DEPRECATED
};
//! \}
diff --git a/src/asmjit/core/emitterutils.cpp b/src/asmjit/core/emitterutils.cpp
index 1115934..ba79787 100644
--- a/src/asmjit/core/emitterutils.cpp
+++ b/src/asmjit/core/emitterutils.cpp
@@ -1,57 +1,33 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/assembler.h"
#include "../core/emitterutils_p.h"
-#include "../core/formatter.h"
+#include "../core/formatter_p.h"
#include "../core/logger.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::EmitterUtils]
-// ============================================================================
-
namespace EmitterUtils {
#ifndef ASMJIT_NO_LOGGING
-Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept {
- size_t currentSize = sb.size();
- size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0;
-
- ASMJIT_ASSERT(binSize >= dispSize);
+Error finishFormattedLine(String& sb, const FormatOptions& formatOptions, const uint8_t* binData, size_t binSize, size_t offsetSize, size_t immSize, const char* comment) noexcept {
+ ASMJIT_ASSERT(binSize >= offsetSize);
const size_t kNoBinSize = SIZE_MAX;
+ size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0;
+
if ((binSize != 0 && binSize != kNoBinSize) || commentSize) {
- size_t align = kMaxInstLineSize;
char sep = ';';
+ size_t padding = Formatter::paddingFromOptions(formatOptions, FormatPaddingGroup::kRegularLine);
for (size_t i = (binSize == kNoBinSize); i < 2; i++) {
- size_t begin = sb.size();
- ASMJIT_PROPAGATE(sb.padEnd(align));
+ ASMJIT_PROPAGATE(sb.padEnd(padding));
if (sep) {
ASMJIT_PROPAGATE(sb.append(sep));
@@ -60,8 +36,8 @@ Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t disp
// Append binary data or comment.
if (i == 0) {
- ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - dispSize - immSize));
- ASMJIT_PROPAGATE(sb.appendChars('.', dispSize * 2));
+ ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - offsetSize - immSize));
+ ASMJIT_PROPAGATE(sb.appendChars('.', offsetSize * 2));
ASMJIT_PROPAGATE(sb.appendHex(binData + binSize - immSize, immSize));
if (commentSize == 0) break;
}
@@ -69,9 +45,8 @@ Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t disp
ASMJIT_PROPAGATE(sb.append(comment, commentSize));
}
- currentSize += sb.size() - begin;
- align += kMaxBinarySize;
sep = '|';
+ padding += Formatter::paddingFromOptions(formatOptions, FormatPaddingGroup::kMachineCode);
}
}
@@ -82,55 +57,59 @@ void logLabelBound(BaseAssembler* self, const Label& label) noexcept {
Logger* logger = self->logger();
StringTmp<512> sb;
- size_t binSize = logger->hasFlag(FormatOptions::kFlagMachineCode) ? size_t(0) : SIZE_MAX;
+ size_t binSize = logger->hasFlag(FormatFlags::kMachineCode) ? size_t(0) : SIZE_MAX;
- sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationLabel));
+ sb.appendChars(' ', logger->indentation(FormatIndentationGroup::kLabel));
Formatter::formatLabel(sb, logger->flags(), self, label.id());
sb.append(':');
- EmitterUtils::formatLine(sb, nullptr, binSize, 0, 0, self->_inlineComment);
+ finishFormattedLine(sb, logger->options(), nullptr, binSize, 0, 0, self->_inlineComment);
logger->log(sb.data(), sb.size());
}
void logInstructionEmitted(
BaseAssembler* self,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
+ InstId instId,
+ InstOptions options,
+ const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
uint32_t relSize, uint32_t immSize, uint8_t* afterCursor) {
Logger* logger = self->logger();
ASMJIT_ASSERT(logger != nullptr);
StringTmp<256> sb;
- uint32_t flags = logger->flags();
+ FormatFlags formatFlags = logger->flags();
uint8_t* beforeCursor = self->bufferPtr();
intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor);
Operand_ opArray[Globals::kMaxOpCount];
- EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+ opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode));
- Formatter::formatInstruction(sb, flags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+ sb.appendChars(' ', logger->indentation(FormatIndentationGroup::kCode));
+ Formatter::formatInstruction(sb, formatFlags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
- if ((flags & FormatOptions::kFlagMachineCode) != 0)
- EmitterUtils::formatLine(sb, self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment());
+ if (Support::test(formatFlags, FormatFlags::kMachineCode))
+ finishFormattedLine(sb, logger->options(), self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment());
else
- EmitterUtils::formatLine(sb, nullptr, SIZE_MAX, 0, 0, self->inlineComment());
+ finishFormattedLine(sb, logger->options(), nullptr, SIZE_MAX, 0, 0, self->inlineComment());
logger->log(sb);
}
Error logInstructionFailed(
BaseAssembler* self,
Error err,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+ InstId instId,
+ InstOptions options,
+ const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
StringTmp<256> sb;
sb.append(DebugUtils::errorAsString(err));
sb.append(": ");
Operand_ opArray[Globals::kMaxOpCount];
- EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
+ opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
- Formatter::formatInstruction(sb, 0, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
+ Formatter::formatInstruction(sb, FormatFlags::kNone, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount);
if (self->inlineComment()) {
sb.append(" ; ");
diff --git a/src/asmjit/core/emitterutils_p.h b/src/asmjit/core/emitterutils_p.h
index 7e222d3..b7610e7 100644
--- a/src/asmjit/core/emitterutils_p.h
+++ b/src/asmjit/core/emitterutils_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
#define ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED
@@ -30,26 +12,26 @@
ASMJIT_BEGIN_NAMESPACE
class BaseAssembler;
+class FormatOptions;
//! \cond INTERNAL
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::EmitterUtils]
-// ============================================================================
-
+//! Utilities used by various emitters, mostly Assembler implementations.
namespace EmitterUtils {
-static const Operand_ noExt[3] {};
+//! Default paddings used by Emitter utils and Formatter.
+
+static constexpr Operand noExt[3];
-enum kOpIndex {
+enum kOpIndex : uint32_t {
kOp3 = 0,
kOp4 = 1,
kOp5 = 2
};
-static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
uint32_t opCount = 0;
if (opExt[kOp3].isNone()) {
@@ -67,7 +49,7 @@ static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Oper
return opCount;
}
-static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
+static ASMJIT_FORCE_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept {
dst[0].copyFrom(o0);
dst[1].copyFrom(o1);
dst[2].copyFrom(o2);
@@ -77,25 +59,23 @@ static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount]
}
#ifndef ASMJIT_NO_LOGGING
-enum : uint32_t {
- // Has to be big to be able to hold all metadata compiler can assign to a
- // single instruction.
- kMaxInstLineSize = 44,
- kMaxBinarySize = 26
-};
-
-Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept;
+Error finishFormattedLine(String& sb, const FormatOptions& formatOptions, const uint8_t* binData, size_t binSize, size_t offsetSize, size_t immSize, const char* comment) noexcept;
void logLabelBound(BaseAssembler* self, const Label& label) noexcept;
void logInstructionEmitted(
BaseAssembler* self,
- uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
+ InstId instId,
+ InstOptions options,
+ const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt,
uint32_t relSize, uint32_t immSize, uint8_t* afterCursor);
Error logInstructionFailed(
BaseAssembler* self,
- Error err, uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt);
+ Error err,
+ InstId instId,
+ InstOptions options,
+ const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt);
#endif
}
diff --git a/src/asmjit/core/environment.cpp b/src/asmjit/core/environment.cpp
index 3be2b15..9a694af 100644
--- a/src/asmjit/core/environment.cpp
+++ b/src/asmjit/core/environment.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/environment.h"
diff --git a/src/asmjit/core/environment.h b/src/asmjit/core/environment.h
index 58e8734..8225ef2 100644
--- a/src/asmjit/core/environment.h
+++ b/src/asmjit/core/environment.h
@@ -1,30 +1,12 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
#define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
-#include "../core/globals.h"
+#include "../core/archtraits.h"
#if defined(__APPLE__)
#include <TargetConditionals.h>
@@ -35,301 +17,222 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::Environment]
-// ============================================================================
-
-//! Represents an environment, which is usually related to a \ref Target.
-//!
-//! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is
-//! sometimes called "Triple" (historically it used to be 3 only parts) or
-//! "Tuple", which is a convention used by Debian Linux.
+//! Vendor.
//!
-//! AsmJit doesn't support all possible combinations or architectures and ABIs,
-//! however, it models the environment similarly to other compilers for future
-//! extensibility.
-class Environment {
-public:
- //! Architecture type, see \ref Arch.
- uint8_t _arch;
- //! Sub-architecture type, see \ref SubArch.
- uint8_t _subArch;
- //! Vendor type, see \ref Vendor.
- uint8_t _vendor;
- //! Platform type, see \ref Platform.
- uint8_t _platform;
- //! ABI type, see \ref Abi.
- uint8_t _abi;
- //! Object format, see \ref Format.
- uint8_t _format;
- //! Reserved for future use, must be zero.
- uint16_t _reserved;
-
- //! Architecture.
- enum Arch : uint32_t {
- //! Unknown or uninitialized architecture.
- kArchUnknown = 0,
-
- //! Mask used by 32-bit architectures (odd are 32-bit, even are 64-bit).
- kArch32BitMask = 0x01,
- //! Mask used by big-endian architectures.
- kArchBigEndianMask = 0x80u,
-
- //! 32-bit X86 architecture.
- kArchX86 = 1,
- //! 64-bit X86 architecture also known as X86_64 and AMD64.
- kArchX64 = 2,
-
- //! 32-bit RISC-V architecture.
- kArchRISCV32 = 3,
- //! 64-bit RISC-V architecture.
- kArchRISCV64 = 4,
-
- //! 32-bit ARM architecture (little endian).
- kArchARM = 5,
- //! 32-bit ARM architecture (big endian).
- kArchARM_BE = kArchARM | kArchBigEndianMask,
- //! 64-bit ARM architecture in (little endian).
- kArchAArch64 = 6,
- //! 64-bit ARM architecture in (big endian).
- kArchAArch64_BE = kArchAArch64 | kArchBigEndianMask,
- //! 32-bit ARM in Thumb mode (little endian).
- kArchThumb = 7,
- //! 32-bit ARM in Thumb mode (big endian).
- kArchThumb_BE = kArchThumb | kArchBigEndianMask,
-
- // 8 is not used, even numbers are 64-bit architectures.
-
- //! 32-bit MIPS architecture in (little endian).
- kArchMIPS32_LE = 9,
- //! 32-bit MIPS architecture in (big endian).
- kArchMIPS32_BE = kArchMIPS32_LE | kArchBigEndianMask,
- //! 64-bit MIPS architecture in (little endian).
- kArchMIPS64_LE = 10,
- //! 64-bit MIPS architecture in (big endian).
- kArchMIPS64_BE = kArchMIPS64_LE | kArchBigEndianMask,
-
- //! Count of architectures.
- kArchCount = 11
- };
-
- //! Sub-architecture.
- enum SubArch : uint32_t {
- //! Unknown or uninitialized architecture sub-type.
- kSubArchUnknown = 0,
-
- //! Count of sub-architectures.
- kSubArchCount
- };
-
- //! Vendor.
- //!
- //! \note AsmJit doesn't use vendor information at the moment. It's provided
- //! for future use, if required.
- enum Vendor : uint32_t {
- //! Unknown or uninitialized vendor.
- kVendorUnknown = 0,
-
- //! Count of vendor identifiers.
- kVendorCount
- };
-
- //! Platform / OS.
- enum Platform : uint32_t {
- //! Unknown or uninitialized platform.
- kPlatformUnknown = 0,
-
- //! Windows OS.
- kPlatformWindows,
-
- //! Other platform, most likely POSIX based.
- kPlatformOther,
-
- //! Linux OS.
- kPlatformLinux,
- //! GNU/Hurd OS.
- kPlatformHurd,
-
- //! FreeBSD OS.
- kPlatformFreeBSD,
- //! OpenBSD OS.
- kPlatformOpenBSD,
- //! NetBSD OS.
- kPlatformNetBSD,
- //! DragonFly BSD OS.
- kPlatformDragonFlyBSD,
-
- //! Haiku OS.
- kPlatformHaiku,
-
- //! Apple OSX.
- kPlatformOSX,
- //! Apple iOS.
- kPlatformIOS,
- //! Apple TVOS.
- kPlatformTVOS,
- //! Apple WatchOS.
- kPlatformWatchOS,
-
- //! Emscripten platform.
- kPlatformEmscripten,
-
- //! Count of platform identifiers.
- kPlatformCount
- };
-
- //! ABI.
- enum Abi : uint32_t {
- //! Unknown or uninitialied environment.
- kAbiUnknown = 0,
- //! Microsoft ABI.
- kAbiMSVC,
- //! GNU ABI.
- kAbiGNU,
- //! Android Environment / ABI.
- kAbiAndroid,
- //! Cygwin ABI.
- kAbiCygwin,
-
- //! Count of known ABI types.
- kAbiCount
- };
-
- //! Object format.
- //!
- //! \note AsmJit doesn't really use anything except \ref kFormatUnknown and
- //! \ref kFormatJIT at the moment. Object file formats are provided for
- //! future extensibility and a possibility to generate object files at some
- //! point.
- enum Format : uint32_t {
- //! Unknown or uninitialized object format.
- kFormatUnknown = 0,
-
- //! JIT code generation object, most likely \ref JitRuntime or a custom
- //! \ref Target implementation.
- kFormatJIT,
-
- //! Executable and linkable format (ELF).
- kFormatELF,
- //! Common object file format.
- kFormatCOFF,
- //! Extended COFF object format.
- kFormatXCOFF,
- //! Mach object file format.
- kFormatMachO,
-
- //! Count of object format types.
- kFormatCount
- };
-
- //! \name Environment Detection
- //! \{
-
-#ifdef _DOXYGEN
- //! Architecture detected at compile-time (architecture of the host).
- static constexpr Arch kArchHost = DETECTED_AT_COMPILE_TIME;
- //! Sub-architecture detected at compile-time (sub-architecture of the host).
- static constexpr SubArch kSubArchHost = DETECTED_AT_COMPILE_TIME;
- //! Vendor detected at compile-time (vendor of the host).
- static constexpr Vendor kVendorHost = DETECTED_AT_COMPILE_TIME;
- //! Platform detected at compile-time (platform of the host).
- static constexpr Platform kPlatformHost = DETECTED_AT_COMPILE_TIME;
- //! ABI detected at compile-time (ABI of the host).
- static constexpr Abi kAbiHost = DETECTED_AT_COMPILE_TIME;
+//! \note AsmJit doesn't use vendor information at the moment. It's provided for future use, if required.
+enum class Vendor : uint8_t {
+ //! Unknown or uninitialized platform vendor.
+ kUnknown = 0,
+
+ //! Maximum value of `PlatformVendor`.
+ kMaxValue = kUnknown,
+
+ //! Platform vendor detected at compile-time.
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
#else
- static constexpr Arch kArchHost =
- ASMJIT_ARCH_X86 == 32 ? kArchX86 :
- ASMJIT_ARCH_X86 == 64 ? kArchX64 :
-
- ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kArchARM :
- ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kArchARM_BE :
- ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kArchAArch64 :
- ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kArchAArch64_BE :
-
- ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kArchMIPS32_LE :
- ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kArchMIPS32_BE :
- ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kArchMIPS64_LE :
- ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kArchMIPS64_BE :
-
- kArchUnknown;
-
- static constexpr SubArch kSubArchHost =
- kSubArchUnknown;
+ kUnknown
+#endif
+};
- static constexpr Vendor kVendorHost =
- kVendorUnknown;
+//! Platform - runtime environment or operating system.
+enum class Platform : uint8_t {
+ //! Unknown or uninitialized platform.
+ kUnknown = 0,
+
+ //! Windows OS.
+ kWindows,
+
+ //! Other platform that is not Windows, most likely POSIX based.
+ kOther,
+
+ //! Linux OS.
+ kLinux,
+ //! GNU/Hurd OS.
+ kHurd,
+
+ //! FreeBSD OS.
+ kFreeBSD,
+ //! OpenBSD OS.
+ kOpenBSD,
+ //! NetBSD OS.
+ kNetBSD,
+ //! DragonFly BSD OS.
+ kDragonFlyBSD,
+
+ //! Haiku OS.
+ kHaiku,
+
+ //! Apple OSX.
+ kOSX,
+ //! Apple iOS.
+ kIOS,
+ //! Apple TVOS.
+ kTVOS,
+ //! Apple WatchOS.
+ kWatchOS,
+
+ //! Emscripten platform.
+ kEmscripten,
+
+ //! Maximum value of `Platform`.
+ kMaxValue = kEmscripten,
- static constexpr Platform kPlatformHost =
-#if defined(__EMSCRIPTEN__)
- kPlatformEmscripten
+ //! Platform detected at compile-time (platform of the host).
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#elif defined(__EMSCRIPTEN__)
+ kEmscripten
#elif defined(_WIN32)
- kPlatformWindows
+ kWindows
#elif defined(__linux__)
- kPlatformLinux
+ kLinux
#elif defined(__gnu_hurd__)
- kPlatformHurd
+ kHurd
#elif defined(__FreeBSD__)
- kPlatformFreeBSD
+ kFreeBSD
#elif defined(__OpenBSD__)
- kPlatformOpenBSD
+ kOpenBSD
#elif defined(__NetBSD__)
- kPlatformNetBSD
+ kNetBSD
#elif defined(__DragonFly__)
- kPlatformDragonFlyBSD
+ kDragonFlyBSD
#elif defined(__HAIKU__)
- kPlatformHaiku
+ kHaiku
#elif defined(__APPLE__) && TARGET_OS_OSX
- kPlatformOSX
+ kOSX
#elif defined(__APPLE__) && TARGET_OS_TV
- kPlatformTVOS
+ kTVOS
#elif defined(__APPLE__) && TARGET_OS_WATCH
- kPlatformWatchOS
+ kWatchOS
#elif defined(__APPLE__) && TARGET_OS_IPHONE
- kPlatformIOS
+ kIOS
#else
- kPlatformOther
+ kOther
#endif
- ;
+};
- static constexpr Abi kAbiHost =
-#if defined(_MSC_VER)
- kAbiMSVC
+//! Platform ABI (application binary interface).
+enum class PlatformABI : uint8_t {
+ //! Unknown or uninitialied environment.
+ kUnknown = 0,
+ //! Microsoft ABI.
+ kMSVC,
+ //! GNU ABI.
+ kGNU,
+ //! Android Environment / ABI.
+ kAndroid,
+ //! Cygwin ABI.
+ kCygwin,
+
+ //! Maximum value of `PlatformABI`.
+ kMaxValue,
+
+ //! Host ABI detected at compile-time.
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#elif defined(_MSC_VER)
+ kMSVC
#elif defined(__CYGWIN__)
- kAbiCygwin
+ kCygwin
#elif defined(__MINGW32__) || defined(__GLIBC__)
- kAbiGNU
+ kGNU
#elif defined(__ANDROID__)
- kAbiAndroid
+ kAndroid
#else
- kAbiUnknown
+ kUnknown
#endif
- ;
+};
-#endif
+//! Object format.
+//!
+//! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at
+//! the moment. Object file formats are provided for future extensibility and a possibility to generate object
+//! files at some point.
+enum class ObjectFormat : uint8_t {
+ //! Unknown or uninitialized object format.
+ kUnknown = 0,
+
+ //! JIT code generation object, most likely \ref JitRuntime or a custom
+ //! \ref Target implementation.
+ kJIT,
+
+ //! Executable and linkable format (ELF).
+ kELF,
+ //! Common object file format.
+ kCOFF,
+ //! Extended COFF object format.
+ kXCOFF,
+ //! Mach object file format.
+ kMachO,
+
+ //! Maximum value of `ObjectFormat`.
+ kMaxValue
+};
+
+//! Represents an environment, which is usually related to a \ref Target.
+//!
+//! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is sometimes called "Triple" (historically
+//! it used to be 3 only parts) or "Tuple", which is a convention used by Debian Linux.
+//!
+//! AsmJit doesn't support all possible combinations or architectures and ABIs, however, it models the environment
+//! similarly to other compilers for future extensibility.
+class Environment {
+public:
+ //! \name Members
+ //! \{
+
+ //! Architecture.
+ Arch _arch;
+ //! Sub-architecture type.
+ SubArch _subArch;
+ //! Vendor type.
+ Vendor _vendor;
+ //! Platform.
+ Platform _platform;
+ //! Platform ABI.
+ PlatformABI _platformABI;
+ //! Object format.
+ ObjectFormat _objectFormat;
+ //! Reserved for future use, must be zero.
+ uint8_t _reserved[2];
//! \}
- //! \name Construction / Destruction
+ //! \name Construction & Destruction
//! \{
inline Environment() noexcept :
- _arch(uint8_t(kArchUnknown)),
- _subArch(uint8_t(kSubArchUnknown)),
- _vendor(uint8_t(kVendorUnknown)),
- _platform(uint8_t(kPlatformUnknown)),
- _abi(uint8_t(kAbiUnknown)),
- _format(uint8_t(kFormatUnknown)),
- _reserved(0) {}
+ _arch(Arch::kUnknown),
+ _subArch(SubArch::kUnknown),
+ _vendor(Vendor::kUnknown),
+ _platform(Platform::kUnknown),
+ _platformABI(PlatformABI::kUnknown),
+ _objectFormat(ObjectFormat::kUnknown),
+ _reserved { 0, 0 } {}
+
+ inline explicit Environment(
+ Arch arch,
+ SubArch subArch = SubArch::kUnknown,
+ Vendor vendor = Vendor::kUnknown,
+ Platform platform = Platform::kUnknown,
+ PlatformABI abi = PlatformABI::kUnknown,
+ ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept {
+
+ init(arch, subArch, vendor, platform, abi, objectFormat);
+ }
inline Environment(const Environment& other) noexcept = default;
- inline explicit Environment(uint32_t arch,
- uint32_t subArch = kSubArchUnknown,
- uint32_t vendor = kVendorUnknown,
- uint32_t platform = kPlatformUnknown,
- uint32_t abi = kAbiUnknown,
- uint32_t format = kFormatUnknown) noexcept {
- init(arch, subArch, vendor, platform, abi, format);
+ //! Returns the host environment constructed from preprocessor macros defined by the compiler.
+ //!
+ //! The returned environment should precisely match the target host architecture, sub-architecture, platform,
+ //! and ABI.
+ static inline Environment host() noexcept {
+ return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown);
}
//! \}
@@ -358,7 +261,7 @@ public:
//! Tests whether the environment is initialized, which means it must have
//! a valid architecture.
inline bool isInitialized() const noexcept {
- return _arch != kArchUnknown;
+ return _arch != Arch::kUnknown;
}
inline uint64_t _packed() const noexcept {
@@ -369,56 +272,60 @@ public:
//! Resets all members of the environment to zero / unknown.
inline void reset() noexcept {
- _arch = uint8_t(kArchUnknown);
- _subArch = uint8_t(kSubArchUnknown);
- _vendor = uint8_t(kVendorUnknown);
- _platform = uint8_t(kPlatformUnknown);
- _abi = uint8_t(kAbiUnknown);
- _format = uint8_t(kFormatUnknown);
- _reserved = 0;
+ _arch = Arch::kUnknown;
+ _subArch = SubArch::kUnknown;
+ _vendor = Vendor::kUnknown;
+ _platform = Platform::kUnknown;
+ _platformABI = PlatformABI::kUnknown;
+ _objectFormat = ObjectFormat::kUnknown;
+ _reserved[0] = 0;
+ _reserved[1] = 0;
}
inline bool equals(const Environment& other) const noexcept {
return _packed() == other._packed();
}
- //! Returns the architecture, see \ref Arch.
- inline uint32_t arch() const noexcept { return _arch; }
- //! Returns the sub-architecture, see \ref SubArch.
- inline uint32_t subArch() const noexcept { return _subArch; }
- //! Returns vendor, see \ref Vendor.
- inline uint32_t vendor() const noexcept { return _vendor; }
- //! Returns target's platform or operating system, see \ref Platform.
- inline uint32_t platform() const noexcept { return _platform; }
- //! Returns target's ABI, see \ref Abi.
- inline uint32_t abi() const noexcept { return _abi; }
- //! Returns target's object format, see \ref Format.
- inline uint32_t format() const noexcept { return _format; }
-
- inline void init(uint32_t arch,
- uint32_t subArch = kSubArchUnknown,
- uint32_t vendor = kVendorUnknown,
- uint32_t platform = kPlatformUnknown,
- uint32_t abi = kAbiUnknown,
- uint32_t format = kFormatUnknown) noexcept {
- _arch = uint8_t(arch);
- _subArch = uint8_t(subArch);
- _vendor = uint8_t(vendor);
- _platform = uint8_t(platform);
- _abi = uint8_t(abi);
- _format = uint8_t(format);
- _reserved = 0;
+ //! Returns the architecture.
+ inline Arch arch() const noexcept { return _arch; }
+ //! Returns the sub-architecture.
+ inline SubArch subArch() const noexcept { return _subArch; }
+ //! Returns vendor.
+ inline Vendor vendor() const noexcept { return _vendor; }
+ //! Returns target's platform or operating system.
+ inline Platform platform() const noexcept { return _platform; }
+ //! Returns target's ABI.
+ inline PlatformABI platformABI() const noexcept { return _platformABI; }
+ //! Returns target's object format.
+ inline ObjectFormat objectFormat() const noexcept { return _objectFormat; }
+
+ inline void init(
+ Arch arch,
+ SubArch subArch = SubArch::kUnknown,
+ Vendor vendor = Vendor::kUnknown,
+ Platform platform = Platform::kUnknown,
+ PlatformABI platformABI = PlatformABI::kUnknown,
+ ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept {
+
+ _arch = arch;
+ _subArch = subArch;
+ _vendor = vendor;
+ _platform = platform;
+ _platformABI = platformABI;
+ _objectFormat = objectFormat;
+ _reserved[0] = 0;
+ _reserved[1] = 0;
}
- inline bool isArchX86() const noexcept { return _arch == kArchX86; }
- inline bool isArchX64() const noexcept { return _arch == kArchX64; }
- inline bool isArchRISCV32() const noexcept { return _arch == kArchRISCV32; }
- inline bool isArchRISCV64() const noexcept { return _arch == kArchRISCV64; }
- inline bool isArchARM() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchARM; }
- inline bool isArchThumb() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchThumb; }
- inline bool isArchAArch64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchAArch64; }
- inline bool isArchMIPS32() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS32_LE; }
- inline bool isArchMIPS64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS64_LE; }
+ inline bool isArchX86() const noexcept { return _arch == Arch::kX86; }
+ inline bool isArchX64() const noexcept { return _arch == Arch::kX64; }
+ inline bool isArchARM() const noexcept { return isArchARM(_arch); }
+ inline bool isArchThumb() const noexcept { return isArchThumb(_arch); }
+ inline bool isArchAArch64() const noexcept { return isArchAArch64(_arch); }
+ inline bool isArchMIPS32() const noexcept { return isArchMIPS32(_arch); }
+ inline bool isArchMIPS64() const noexcept { return isArchMIPS64(_arch); }
+ inline bool isArchRISCV32() const noexcept { return _arch == Arch::kRISCV32; }
+ inline bool isArchRISCV64() const noexcept { return _arch == Arch::kRISCV64; }
//! Tests whether the architecture is 32-bit.
inline bool is32Bit() const noexcept { return is32Bit(_arch); }
@@ -432,45 +339,45 @@ public:
//! Tests whether this architecture is of X86 family.
inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
- //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
- inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
//! Tests whether this architecture family is ARM, Thumb, or AArch64.
inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
//! Tests whether this architecture family is MISP or MIPS64.
inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
+ //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
+ inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
//! Tests whether the environment platform is Windows.
- inline bool isPlatformWindows() const noexcept { return _platform == kPlatformWindows; }
+ inline bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; }
//! Tests whether the environment platform is Linux.
- inline bool isPlatformLinux() const noexcept { return _platform == kPlatformLinux; }
+ inline bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; }
//! Tests whether the environment platform is Hurd.
- inline bool isPlatformHurd() const noexcept { return _platform == kPlatformHurd; }
+ inline bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; }
//! Tests whether the environment platform is Haiku.
- inline bool isPlatformHaiku() const noexcept { return _platform == kPlatformHaiku; }
+ inline bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; }
//! Tests whether the environment platform is any BSD.
inline bool isPlatformBSD() const noexcept {
- return _platform == kPlatformFreeBSD ||
- _platform == kPlatformOpenBSD ||
- _platform == kPlatformNetBSD ||
- _platform == kPlatformDragonFlyBSD;
+ return _platform == Platform::kFreeBSD ||
+ _platform == Platform::kOpenBSD ||
+ _platform == Platform::kNetBSD ||
+ _platform == Platform::kDragonFlyBSD;
}
//! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
inline bool isPlatformApple() const noexcept {
- return _platform == kPlatformOSX ||
- _platform == kPlatformIOS ||
- _platform == kPlatformTVOS ||
- _platform == kPlatformWatchOS;
+ return _platform == Platform::kOSX ||
+ _platform == Platform::kIOS ||
+ _platform == Platform::kTVOS ||
+ _platform == Platform::kWatchOS;
}
//! Tests whether the ABI is MSVC.
- inline bool isAbiMSVC() const noexcept { return _abi == kAbiMSVC; }
+ inline bool isMSVC() const noexcept { return _platformABI == PlatformABI::kMSVC; }
//! Tests whether the ABI is GNU.
- inline bool isAbiGNU() const noexcept { return _abi == kAbiGNU; }
+ inline bool isGNU() const noexcept { return _platformABI == PlatformABI::kGNU; }
//! Returns a calculated stack alignment for this environment.
ASMJIT_API uint32_t stackAlignment() const noexcept;
@@ -479,134 +386,109 @@ public:
uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
//! Sets the architecture to `arch`.
- inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); }
+ inline void setArch(Arch arch) noexcept { _arch = arch; }
//! Sets the sub-architecture to `subArch`.
- inline void setSubArch(uint32_t subArch) noexcept { _subArch = uint8_t(subArch); }
+ inline void setSubArch(SubArch subArch) noexcept { _subArch = subArch; }
//! Sets the vendor to `vendor`.
- inline void setVendor(uint32_t vendor) noexcept { _vendor = uint8_t(vendor); }
+ inline void setVendor(Vendor vendor) noexcept { _vendor = vendor; }
//! Sets the platform to `platform`.
- inline void setPlatform(uint32_t platform) noexcept { _platform = uint8_t(platform); }
- //! Sets the ABI to `abi`.
- inline void setAbi(uint32_t abi) noexcept { _abi = uint8_t(abi); }
- //! Sets the object format to `format`.
- inline void setFormat(uint32_t format) noexcept { _format = uint8_t(format); }
+ inline void setPlatform(Platform platform) noexcept { _platform = platform; }
+ //! Sets the ABI to `platformABI`.
+ inline void setPlatformABI(PlatformABI platformABI) noexcept { _platformABI = platformABI; }
+ //! Sets the object format to `objectFormat`.
+ inline void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; }
//! \}
//! \name Static Utilities
//! \{
- static inline bool isValidArch(uint32_t arch) noexcept {
- return (arch & ~kArchBigEndianMask) != 0 &&
- (arch & ~kArchBigEndianMask) < kArchCount;
+ static inline bool isDefinedArch(Arch arch) noexcept {
+ return uint32_t(arch) <= uint32_t(Arch::kMaxValue);
+ }
+
+ static inline bool isValidArch(Arch arch) noexcept {
+ return arch != Arch::kUnknown && uint32_t(arch) <= uint32_t(Arch::kMaxValue);
}
//! Tests whether the given architecture `arch` is 32-bit.
- static inline bool is32Bit(uint32_t arch) noexcept {
- return (arch & kArch32BitMask) == kArch32BitMask;
+ static inline bool is32Bit(Arch arch) noexcept {
+ return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == uint32_t(Arch::k32BitMask);
}
//! Tests whether the given architecture `arch` is 64-bit.
- static inline bool is64Bit(uint32_t arch) noexcept {
- return (arch & kArch32BitMask) == 0;
+ static inline bool is64Bit(Arch arch) noexcept {
+ return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == 0;
}
//! Tests whether the given architecture `arch` is little endian.
- static inline bool isLittleEndian(uint32_t arch) noexcept {
- return (arch & kArchBigEndianMask) == 0;
+ static inline bool isLittleEndian(Arch arch) noexcept {
+ return uint32_t(arch) < uint32_t(Arch::kBigEndian);
}
//! Tests whether the given architecture `arch` is big endian.
- static inline bool isBigEndian(uint32_t arch) noexcept {
- return (arch & kArchBigEndianMask) == kArchBigEndianMask;
+ static inline bool isBigEndian(Arch arch) noexcept {
+ return uint32_t(arch) >= uint32_t(Arch::kBigEndian);
}
- //! Tests whether the given architecture is AArch64.
- static inline bool isArchAArch64(uint32_t arch) noexcept {
- arch &= ~kArchBigEndianMask;
- return arch == kArchAArch64;
+ //! Tests whether the given architecture is ARM or ARM_BE.
+ static inline bool isArchARM(Arch arch) noexcept {
+ return arch == Arch::kARM || arch == Arch::kARM_BE;
}
- //! Tests whether the given architecture family is X86 or X64.
- static inline bool isFamilyX86(uint32_t arch) noexcept {
- return arch == kArchX86 ||
- arch == kArchX64;
+ //! Tests whether the given architecture is Thumb or Thumb_BE.
+ static inline bool isArchThumb(Arch arch) noexcept {
+ return arch == Arch::kThumb || arch == Arch::kThumb_BE;
}
- //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
- static inline bool isFamilyRISCV(uint32_t arch) noexcept {
- return arch == kArchRISCV32 ||
- arch == kArchRISCV64;
+ //! Tests whether the given architecture is AArch64 or AArch64_BE.
+ static inline bool isArchAArch64(Arch arch) noexcept {
+ return arch == Arch::kAArch64 || arch == Arch::kAArch64_BE;
+ }
+
+ //! Tests whether the given architecture is MIPS32_LE or MIPS32_BE.
+ static inline bool isArchMIPS32(Arch arch) noexcept {
+ return arch == Arch::kMIPS32_LE || arch == Arch::kMIPS32_BE;
+ }
+
+ //! Tests whether the given architecture is MIPS64_LE or MIPS64_BE.
+ static inline bool isArchMIPS64(Arch arch) noexcept {
+ return arch == Arch::kMIPS64_LE || arch == Arch::kMIPS64_BE;
+ }
+
+ //! Tests whether the given architecture family is X86 or X64.
+ static inline bool isFamilyX86(Arch arch) noexcept {
+ return arch == Arch::kX86 || arch == Arch::kX64;
}
//! Tests whether the given architecture family is ARM, Thumb, or AArch64.
- static inline bool isFamilyARM(uint32_t arch) noexcept {
- arch &= ~kArchBigEndianMask;
- return arch == kArchARM ||
- arch == kArchAArch64 ||
- arch == kArchThumb;
+ static inline bool isFamilyARM(Arch arch) noexcept {
+ return isArchARM(arch) || isArchAArch64(arch) || isArchThumb(arch);
}
//! Tests whether the given architecture family is MISP or MIPS64.
- static inline bool isFamilyMIPS(uint32_t arch) noexcept {
- arch &= ~kArchBigEndianMask;
- return arch == kArchMIPS32_LE ||
- arch == kArchMIPS64_LE;
+ static inline bool isFamilyMIPS(Arch arch) noexcept {
+ return isArchMIPS32(arch) || isArchMIPS64(arch);
+ }
+
+ //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
+ static inline bool isFamilyRISCV(Arch arch) noexcept {
+ return arch == Arch::kRISCV32 || arch == Arch::kRISCV64;
}
//! Returns a native general purpose register size from the given architecture.
- static uint32_t registerSizeFromArch(uint32_t arch) noexcept {
+ static inline uint32_t registerSizeFromArch(Arch arch) noexcept {
return is32Bit(arch) ? 4u : 8u;
}
//! \}
};
-//! Returns the host environment constructed from preprocessor macros defined
-//! by the compiler.
-//!
-//! The returned environment should precisely match the target host architecture,
-//! sub-architecture, platform, and ABI.
-static ASMJIT_INLINE Environment hostEnvironment() noexcept {
- return Environment(Environment::kArchHost,
- Environment::kSubArchHost,
- Environment::kVendorHost,
- Environment::kPlatformHost,
- Environment::kAbiHost,
- Environment::kFormatUnknown);
-}
-
static_assert(sizeof(Environment) == 8,
"Environment must occupy exactly 8 bytes.");
//! \}
-#ifndef ASMJIT_NO_DEPRECATED
-class ASMJIT_DEPRECATED_STRUCT("Use Environment instead") ArchInfo : public Environment {
-public:
- inline ArchInfo() noexcept : Environment() {}
-
- inline ArchInfo(const Environment& other) noexcept : Environment(other) {}
- inline explicit ArchInfo(uint32_t arch, uint32_t subArch = kSubArchUnknown) noexcept
- : Environment(arch, subArch) {}
-
- enum Id : uint32_t {
- kIdNone = Environment::kArchUnknown,
- kIdX86 = Environment::kArchX86,
- kIdX64 = Environment::kArchX64,
- kIdA32 = Environment::kArchARM,
- kIdA64 = Environment::kArchAArch64,
- kIdHost = Environment::kArchHost
- };
-
- enum SubType : uint32_t {
- kSubIdNone = Environment::kSubArchUnknown
- };
-
- static inline ArchInfo host() noexcept { return ArchInfo(hostEnvironment()); }
-};
-#endif // !ASMJIT_NO_DEPRECATED
-
ASMJIT_END_NAMESPACE
#endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
diff --git a/src/asmjit/core/errorhandler.cpp b/src/asmjit/core/errorhandler.cpp
index 8372d75..5a7dac5 100644
--- a/src/asmjit/core/errorhandler.cpp
+++ b/src/asmjit/core/errorhandler.cpp
@@ -1,36 +1,13 @@
-
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
+// This file is part of AsmJit project <https://asmjit.com>
//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/errorhandler.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ErrorHandler]
-// ============================================================================
-
ErrorHandler::ErrorHandler() noexcept {}
ErrorHandler::~ErrorHandler() noexcept {}
diff --git a/src/asmjit/core/errorhandler.h b/src/asmjit/core/errorhandler.h
index b26a654..5151d43 100644
--- a/src/asmjit/core/errorhandler.h
+++ b/src/asmjit/core/errorhandler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ERRORHANDLER_H_INCLUDED
#define ASMJIT_CORE_ERRORHANDLER_H_INCLUDED
@@ -31,41 +13,28 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_error_handling
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class BaseEmitter;
-// ============================================================================
-// [asmjit::ErrorHandler]
-// ============================================================================
-
//! Error handler can be used to override the default behavior of error handling.
//!
-//! It's available to all classes that inherit `BaseEmitter`. Override
-//! \ref ErrorHandler::handleError() to implement your own error handler.
+//! It's available to all classes that inherit `BaseEmitter`. Override \ref ErrorHandler::handleError() to implement
+//! your own error handler.
//!
//! The following use-cases are supported:
//!
-//! - Record the error and continue code generation. This is the simplest
-//! approach that can be used to at least log possible errors.
-//! - Throw an exception. AsmJit doesn't use exceptions and is completely
-//! exception-safe, but it's perfectly legal to throw an exception from
-//! the error handler.
-//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler,
-//! Builder and Compiler to a consistent state before calling \ref handleError(),
-//! so `longjmp()` can be used without issues to cancel the code-generation if
-//! an error occurred. This method can be used if exception handling in your
-//! project is turned off and you still want some comfort. In most cases it
-//! should be safe as AsmJit uses \ref Zone memory and the ownership of memory
-//! it allocates always ends with the instance that allocated it. If using this
-//! approach please never jump outside the life-time of \ref CodeHolder and
-//! \ref BaseEmitter.
-//!
-//! \ref ErrorHandler can be attached to \ref CodeHolder or \ref BaseEmitter,
-//! which has a priority. The example below uses error handler that just prints
-//! the error, but lets AsmJit continue:
+//! - Record the error and continue code generation. This is the simplest approach that can be used to at least log
+//! possible errors.
+//! - Throw an exception. AsmJit doesn't use exceptions and is completely exception-safe, but it's perfectly legal
+//! to throw an exception from the error handler.
+//! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, Builder and Compiler to
+//! a consistent state before calling \ref handleError(), so `longjmp()` can be used without issues to cancel the
+//! code generation if an error occurred. This method can be used if exception handling in your project is turned
+//! off and you still want some comfort. In most cases it should be safe as AsmJit uses \ref Zone memory and the
+//! ownership of memory it allocates always ends with the instance that allocated it. If using this approach please
+//! never jump outside the life-time of \ref CodeHolder and \ref BaseEmitter.
+//!
+//! \ref ErrorHandler can be attached to \ref CodeHolder or \ref BaseEmitter, which has a priority. The example below
+//! uses error handler that just prints the error, but lets AsmJit continue:
//!
//! ```
//! // Error Handling #1 - Logging and returning Error.
@@ -108,12 +77,10 @@ class BaseEmitter;
//! }
//! ```
//!
-//! If error happens during instruction emitting / encoding the assembler behaves
-//! transactionally - the output buffer won't advance if encoding failed, thus
-//! either a fully encoded instruction or nothing is emitted. The error handling
-//! shown above is useful, but it's still not the best way of dealing with errors
-//! in AsmJit. The following example shows how to use exception handling to handle
-//! errors in a more C++ way:
+//! If error happens during instruction emitting / encoding the assembler behaves transactionally - the output buffer
+//! won't advance if encoding failed, thus either a fully encoded instruction or nothing is emitted. The error handling
+//! shown above is useful, but it's still not the best way of dealing with errors in AsmJit. The following example
+//! shows how to use exception handling to handle errors in a more C++ way:
//!
//! ```
//! // Error Handling #2 - Throwing an exception.
@@ -168,13 +135,10 @@ class BaseEmitter;
//! }
//! ```
//!
-//! If C++ exceptions are not what you like or your project turns off them
-//! completely there is still a way of reducing the error handling to a minimum
-//! by using a standard setjmp/longjmp approach. AsmJit is exception-safe and
-//! cleans up everything before calling the ErrorHandler, so any approach is
-//! safe. You can simply jump from the error handler without causing any
-//! side-effects or memory leaks. The following example demonstrates how it
-//! could be done:
+//! If C++ exceptions are not what you like or your project turns off them completely there is still a way of reducing
+//! the error handling to a minimum by using a standard setjmp/longjmp approach. AsmJit is exception-safe and cleans
+//! up everything before calling the ErrorHandler, so any approach is safe. You can simply jump from the error handler
+//! without causing any side-effects or memory leaks. The following example demonstrates how it could be done:
//!
//! ```
//! // Error Handling #3 - Using setjmp/longjmp if exceptions are not allowed.
@@ -223,40 +187,37 @@ class ASMJIT_VIRTAPI ErrorHandler {
public:
ASMJIT_BASE_CLASS(ErrorHandler)
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
+ //! \name Construction & Destruction
+ //! \{
//! Creates a new `ErrorHandler` instance.
ASMJIT_API ErrorHandler() noexcept;
//! Destroys the `ErrorHandler` instance.
ASMJIT_API virtual ~ErrorHandler() noexcept;
- // --------------------------------------------------------------------------
- // [Handle Error]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Interface
+ //! \{
//! Error handler (must be reimplemented).
//!
- //! Error handler is called after an error happened and before it's propagated
- //! to the caller. There are multiple ways how the error handler can be used:
+ //! Error handler is called after an error happened and before it's propagated to the caller. There are multiple
+ //! ways how the error handler can be used:
//!
- //! 1. User-based error handling without throwing exception or using C's
- //! `longjmp()`. This is for users that don't use exceptions and want
- //! customized error handling.
+ //! 1. User-based error handling without throwing exception or using C's`longjmp()`. This is for users that don't
+ //! use exceptions and want customized error handling.
//!
- //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely
- //! exception-safe, but you can throw exception from your error handler if
- //! this way is the preferred way of handling errors in your project.
+ //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely exception-safe, but you can throw
+ //! exception from your error handler if this way is the preferred way of handling errors in your project.
//!
- //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts
- //! `BaseEmitter` to a consistent state before calling `handleError()`
- //! so `longjmp()` can be used without any issues to cancel the code
- //! generation if an error occurred. There is no difference between
- //! exceptions and `longjmp()` from AsmJit's perspective, however,
- //! never jump outside of `CodeHolder` and `BaseEmitter` scope as you
- //! would leak memory.
+ //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts `BaseEmitter` to a consistent state before
+ //! calling `handleError()` so `longjmp()` can be used without any issues to cancel the code generation if an
+ //! error occurred. There is no difference between exceptions and `longjmp()` from AsmJit's perspective, however,
+ //! never jump outside of `CodeHolder` and `BaseEmitter` scope as you would leak memory.
virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0;
+
+ //! \}
};
//! \}
diff --git a/src/asmjit/core/features.h b/src/asmjit/core/features.h
deleted file mode 100644
index 0f2cfe2..0000000
--- a/src/asmjit/core/features.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#ifndef ASMJIT_CORE_FEATURES_H_INCLUDED
-#define ASMJIT_CORE_FEATURES_H_INCLUDED
-
-#include "../core/globals.h"
-#include "../core/support.h"
-
-ASMJIT_BEGIN_NAMESPACE
-
-//! \addtogroup asmjit_core
-//! \{
-
-// ============================================================================
-// [asmjit::BaseFeatures]
-// ============================================================================
-
-//! Base class that provides information about CPU features.
-//!
-//! Internally each feature is represented by a single bit in an embedded
-//! bit-array, however, feature bits are defined by an architecture specific
-//! implementations, like \ref x86::Features.
-class BaseFeatures {
-public:
- typedef Support::BitWord BitWord;
- typedef Support::BitVectorIterator<BitWord> Iterator;
-
- enum : uint32_t {
- kMaxFeatures = 256,
- kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits
- };
-
- BitWord _bits[kNumBitWords];
-
- //! \name Construction & Destruction
- //! \{
-
- inline BaseFeatures() noexcept { reset(); }
- inline BaseFeatures(const BaseFeatures& other) noexcept = default;
- inline explicit BaseFeatures(Globals::NoInit_) noexcept {}
-
- inline void reset() noexcept {
- for (size_t i = 0; i < kNumBitWords; i++)
- _bits[i] = 0;
- }
-
- //! \}
-
- //! \name Overloaded Operators
- //! \{
-
- inline BaseFeatures& operator=(const BaseFeatures& other) noexcept = default;
-
- inline bool operator==(const BaseFeatures& other) noexcept { return eq(other); }
- inline bool operator!=(const BaseFeatures& other) noexcept { return !eq(other); }
-
- //! \}
-
- //! \name Cast
- //! \{
-
- //! Casts this base class into a derived type `T`.
- template<typename T>
- inline T& as() noexcept { return static_cast<T&>(*this); }
-
- //! Casts this base class into a derived type `T` (const).
- template<typename T>
- inline const T& as() const noexcept { return static_cast<const T&>(*this); }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- inline bool empty() const noexcept {
- for (uint32_t i = 0; i < kNumBitWords; i++)
- if (_bits[i])
- return false;
- return true;
- }
-
- //! Returns all features as array of bitwords (see \ref Support::BitWord).
- inline BitWord* bits() noexcept { return _bits; }
- //! Returns all features as array of bitwords (const).
- inline const BitWord* bits() const noexcept { return _bits; }
-
- //! Returns the number of BitWords returned by \ref bits().
- inline size_t bitWordCount() const noexcept { return kNumBitWords; }
-
- //! Returns \ref Support::BitVectorIterator, that can be used to iterate
- //! all features efficiently
- inline Iterator iterator() const noexcept {
- return Iterator(_bits, kNumBitWords);
- }
-
- //! Tests whether the feature `featureId` is present.
- inline bool has(uint32_t featureId) const noexcept {
- ASMJIT_ASSERT(featureId < kMaxFeatures);
-
- uint32_t idx = featureId / Support::kBitWordSizeInBits;
- uint32_t bit = featureId % Support::kBitWordSizeInBits;
-
- return bool((_bits[idx] >> bit) & 0x1);
- }
-
- //! Tests whether all features as defined by `other` are present.
- inline bool hasAll(const BaseFeatures& other) const noexcept {
- for (uint32_t i = 0; i < kNumBitWords; i++)
- if ((_bits[i] & other._bits[i]) != other._bits[i])
- return false;
- return true;
- }
-
- //! \}
-
- //! \name Utilities
- //! \{
-
- //! Adds the given CPU `featureId` to the list of features.
- inline void add(uint32_t featureId) noexcept {
- ASMJIT_ASSERT(featureId < kMaxFeatures);
-
- uint32_t idx = featureId / Support::kBitWordSizeInBits;
- uint32_t bit = featureId % Support::kBitWordSizeInBits;
-
- _bits[idx] |= BitWord(1) << bit;
- }
-
- template<typename... Args>
- inline void add(uint32_t featureId, Args... otherIds) noexcept {
- add(featureId);
- add(otherIds...);
- }
-
- //! Removes the given CPU `featureId` from the list of features.
- inline void remove(uint32_t featureId) noexcept {
- ASMJIT_ASSERT(featureId < kMaxFeatures);
-
- uint32_t idx = featureId / Support::kBitWordSizeInBits;
- uint32_t bit = featureId % Support::kBitWordSizeInBits;
-
- _bits[idx] &= ~(BitWord(1) << bit);
- }
-
- template<typename... Args>
- inline void remove(uint32_t featureId, Args... otherIds) noexcept {
- remove(featureId);
- remove(otherIds...);
- }
-
- inline bool eq(const BaseFeatures& other) const noexcept {
- for (size_t i = 0; i < kNumBitWords; i++)
- if (_bits[i] != other._bits[i])
- return false;
- return true;
- }
-
- //! \}
-};
-
-//! \}
-
-ASMJIT_END_NAMESPACE
-
-#endif // ASMJIT_CORE_FEATURES_H_INCLUDED
diff --git a/src/asmjit/core/formatter.cpp b/src/asmjit/core/formatter.cpp
index 124eebf..efa0c47 100644
--- a/src/asmjit/core/formatter.cpp
+++ b/src/asmjit/core/formatter.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_LOGGING
@@ -29,7 +11,7 @@
#include "../core/codeholder.h"
#include "../core/compiler.h"
#include "../core/emitter.h"
-#include "../core/formatter.h"
+#include "../core/formatter_p.h"
#include "../core/string.h"
#include "../core/support.h"
#include "../core/type.h"
@@ -48,10 +30,6 @@ ASMJIT_BEGIN_NAMESPACE
class VirtReg;
#endif
-// ============================================================================
-// [asmjit::Formatter]
-// ============================================================================
-
namespace Formatter {
static const char wordNameTable[][8] = {
@@ -72,40 +50,44 @@ static const char wordNameTable[][8] = {
};
-Error formatTypeId(String& sb, uint32_t typeId) noexcept {
- if (typeId == Type::kIdVoid)
+Error formatTypeId(String& sb, TypeId typeId) noexcept {
+ if (typeId == TypeId::kVoid)
return sb.append("void");
- if (!Type::isValid(typeId))
+ if (!TypeUtils::isValid(typeId))
return sb.append("unknown");
const char* typeName = "unknown";
- uint32_t typeSize = Type::sizeOf(typeId);
-
- uint32_t baseId = Type::baseOf(typeId);
- switch (baseId) {
- case Type::kIdIntPtr : typeName = "iptr" ; break;
- case Type::kIdUIntPtr: typeName = "uptr" ; break;
- case Type::kIdI8 : typeName = "i8" ; break;
- case Type::kIdU8 : typeName = "u8" ; break;
- case Type::kIdI16 : typeName = "i16" ; break;
- case Type::kIdU16 : typeName = "u16" ; break;
- case Type::kIdI32 : typeName = "i32" ; break;
- case Type::kIdU32 : typeName = "u32" ; break;
- case Type::kIdI64 : typeName = "i64" ; break;
- case Type::kIdU64 : typeName = "u64" ; break;
- case Type::kIdF32 : typeName = "f32" ; break;
- case Type::kIdF64 : typeName = "f64" ; break;
- case Type::kIdF80 : typeName = "f80" ; break;
- case Type::kIdMask8 : typeName = "mask8" ; break;
- case Type::kIdMask16 : typeName = "mask16"; break;
- case Type::kIdMask32 : typeName = "mask32"; break;
- case Type::kIdMask64 : typeName = "mask64"; break;
- case Type::kIdMmx32 : typeName = "mmx32" ; break;
- case Type::kIdMmx64 : typeName = "mmx64" ; break;
+ uint32_t typeSize = TypeUtils::sizeOf(typeId);
+ TypeId scalarType = TypeUtils::scalarOf(typeId);
+
+ switch (scalarType) {
+ case TypeId::kIntPtr : typeName = "intptr" ; break;
+ case TypeId::kUIntPtr: typeName = "uintptr"; break;
+ case TypeId::kInt8 : typeName = "int8" ; break;
+ case TypeId::kUInt8 : typeName = "uint8" ; break;
+ case TypeId::kInt16 : typeName = "int16" ; break;
+ case TypeId::kUInt16 : typeName = "uint16" ; break;
+ case TypeId::kInt32 : typeName = "int32" ; break;
+ case TypeId::kUInt32 : typeName = "uint32" ; break;
+ case TypeId::kInt64 : typeName = "int64" ; break;
+ case TypeId::kUInt64 : typeName = "uint64" ; break;
+ case TypeId::kFloat32: typeName = "float32"; break;
+ case TypeId::kFloat64: typeName = "float64"; break;
+ case TypeId::kFloat80: typeName = "float80"; break;
+ case TypeId::kMask8 : typeName = "mask8" ; break;
+ case TypeId::kMask16 : typeName = "mask16" ; break;
+ case TypeId::kMask32 : typeName = "mask32" ; break;
+ case TypeId::kMask64 : typeName = "mask64" ; break;
+ case TypeId::kMmx32 : typeName = "mmx32" ; break;
+ case TypeId::kMmx64 : typeName = "mmx64" ; break;
+
+ default:
+ typeName = "unknown";
+ break;
}
- uint32_t baseSize = Type::sizeOf(baseId);
+ uint32_t baseSize = TypeUtils::sizeOf(scalarType);
if (typeSize > baseSize) {
uint32_t count = typeSize / baseSize;
return sb.appendFormat("%sx%u", typeName, unsigned(count));
@@ -117,7 +99,7 @@ Error formatTypeId(String& sb, uint32_t typeId) noexcept {
Error formatFeature(
String& sb,
- uint32_t arch,
+ Arch arch,
uint32_t featureId) noexcept {
#if !defined(ASMJIT_NO_X86)
@@ -135,7 +117,7 @@ Error formatFeature(
Error formatLabel(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
uint32_t labelId) noexcept {
@@ -159,6 +141,9 @@ Error formatLabel(
ASMJIT_PROPAGATE(sb.append('.'));
}
+
+ if (le->type() == LabelType::kAnonymous)
+ ASMJIT_PROPAGATE(sb.append("L%u@", labelId));
return sb.append(le->name());
}
else {
@@ -168,10 +153,10 @@ Error formatLabel(
Error formatRegister(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
- uint32_t regType,
+ Arch arch,
+ RegType regType,
uint32_t regId) noexcept {
#if !defined(ASMJIT_NO_X86)
@@ -189,9 +174,9 @@ Error formatRegister(
Error formatOperand(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const Operand_& op) noexcept {
#if !defined(ASMJIT_NO_X86)
@@ -209,21 +194,21 @@ Error formatOperand(
ASMJIT_API Error formatDataType(
String& sb,
- uint32_t formatFlags,
- uint32_t arch,
- uint32_t typeId) noexcept
+ FormatFlags formatFlags,
+ Arch arch,
+ TypeId typeId) noexcept
{
DebugUtils::unused(formatFlags);
- if (ASMJIT_UNLIKELY(arch >= Environment::kArchCount))
+ if (ASMJIT_UNLIKELY(uint32_t(arch) > uint32_t(Arch::kMaxValue)))
return DebugUtils::errored(kErrorInvalidArch);
- uint32_t typeSize = Type::sizeOf(typeId);
+ uint32_t typeSize = TypeUtils::sizeOf(typeId);
if (typeSize == 0 || typeSize > 8)
return DebugUtils::errored(kErrorInvalidState);
uint32_t typeSizeLog2 = Support::ctz(typeSize);
- return sb.append(wordNameTable[size_t(_archTraits[arch].isaWordNameId(typeSizeLog2))]);
+ return sb.append(wordNameTable[size_t(ArchTraits::byArch(arch).typeNameIdByIndex(typeSizeLog2))]);
}
static Error formatDataHelper(String& sb, const char* typeName, uint32_t typeSize, const uint8_t* data, size_t itemCount) noexcept {
@@ -232,7 +217,7 @@ static Error formatDataHelper(String& sb, const char* typeName, uint32_t typeSiz
sb.append(' ');
for (size_t i = 0; i < itemCount; i++) {
- uint64_t v;
+ uint64_t v = 0;
if (i != 0)
ASMJIT_PROPAGATE(sb.append(", ", 2));
@@ -244,7 +229,7 @@ static Error formatDataHelper(String& sb, const char* typeName, uint32_t typeSiz
case 8: v = Support::readU64u(data); break;
}
- ASMJIT_PROPAGATE(sb.appendUInt(v, 16, typeSize * 2, String::kFormatAlternate));
+ ASMJIT_PROPAGATE(sb.appendUInt(v, 16, typeSize * 2, StringFormatFlags::kAlternate));
data += typeSize;
}
@@ -253,16 +238,16 @@ static Error formatDataHelper(String& sb, const char* typeName, uint32_t typeSiz
Error formatData(
String& sb,
- uint32_t formatFlags,
- uint32_t arch,
- uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) noexcept
+ FormatFlags formatFlags,
+ Arch arch,
+ TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) noexcept
{
DebugUtils::unused(formatFlags);
- if (ASMJIT_UNLIKELY(arch >= Environment::kArchCount))
+ if (ASMJIT_UNLIKELY(!Environment::isDefinedArch(arch)))
return DebugUtils::errored(kErrorInvalidArch);
- uint32_t typeSize = Type::sizeOf(typeId);
+ uint32_t typeSize = TypeUtils::sizeOf(typeId);
if (typeSize == 0)
return DebugUtils::errored(kErrorInvalidState);
@@ -277,7 +262,7 @@ Error formatData(
}
uint32_t typeSizeLog2 = Support::ctz(typeSize);
- const char* wordName = wordNameTable[size_t(_archTraits[arch].isaWordNameId(typeSizeLog2))];
+ const char* wordName = wordNameTable[size_t(ArchTraits::byArch(arch).typeNameIdByIndex(typeSizeLog2))];
if (repeatCount > 1)
ASMJIT_PROPAGATE(sb.appendFormat(".repeat %zu ", repeatCount));
@@ -287,9 +272,9 @@ Error formatData(
Error formatInstruction(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
#if !defined(ASMJIT_NO_X86)
@@ -308,8 +293,8 @@ Error formatInstruction(
#ifndef ASMJIT_NO_BUILDER
#ifndef ASMJIT_NO_COMPILER
-static Error formatFuncValue(String& sb, uint32_t formatFlags, const BaseEmitter* emitter, FuncValue value) noexcept {
- uint32_t typeId = value.typeId();
+static Error formatFuncValue(String& sb, FormatFlags formatFlags, const BaseEmitter* emitter, FuncValue value) noexcept {
+ TypeId typeId = value.typeId();
ASMJIT_PROPAGATE(formatTypeId(sb, typeId));
if (value.isAssigned()) {
@@ -338,10 +323,10 @@ static Error formatFuncValue(String& sb, uint32_t formatFlags, const BaseEmitter
static Error formatFuncValuePack(
String& sb,
- uint32_t formatFlags,
- const BaseEmitter* emitter,
+ FormatFlags formatFlags,
+ const BaseCompiler* cc,
const FuncValuePack& pack,
- VirtReg* const* vRegs) noexcept {
+ const RegOnly* vRegs) noexcept {
size_t count = pack.count();
if (!count)
@@ -358,11 +343,16 @@ static Error formatFuncValuePack(
if (valueIndex)
ASMJIT_PROPAGATE(sb.append(", "));
- ASMJIT_PROPAGATE(formatFuncValue(sb, formatFlags, emitter, value));
+ ASMJIT_PROPAGATE(formatFuncValue(sb, formatFlags, cc, value));
if (vRegs) {
- static const char nullRet[] = "<none>";
- ASMJIT_PROPAGATE(sb.appendFormat(" %s", vRegs[valueIndex] ? vRegs[valueIndex]->name() : nullRet));
+ const VirtReg* virtReg = nullptr;
+ static const char nullReg[] = "<none>";
+
+ if (vRegs[valueIndex].isReg() && cc->isVirtIdValid(vRegs[valueIndex].id()))
+ virtReg = cc->virtRegById(vRegs[valueIndex].id());
+
+ ASMJIT_PROPAGATE(sb.appendFormat(" %s", virtReg ? virtReg->name() : nullReg));
}
}
@@ -374,17 +364,17 @@ static Error formatFuncValuePack(
static Error formatFuncRets(
String& sb,
- uint32_t formatFlags,
- const BaseEmitter* emitter,
+ FormatFlags formatFlags,
+ const BaseCompiler* cc,
const FuncDetail& fd) noexcept {
- return formatFuncValuePack(sb, formatFlags, emitter, fd.retPack(), nullptr);
+ return formatFuncValuePack(sb, formatFlags, cc, fd.retPack(), nullptr);
}
static Error formatFuncArgs(
String& sb,
- uint32_t formatFlags,
- const BaseEmitter* emitter,
+ FormatFlags formatFlags,
+ const BaseCompiler* cc,
const FuncDetail& fd,
const FuncNode::ArgPack* argPacks) noexcept {
@@ -396,7 +386,7 @@ static Error formatFuncArgs(
if (argIndex)
ASMJIT_PROPAGATE(sb.append(", "));
- ASMJIT_PROPAGATE(formatFuncValuePack(sb, formatFlags, emitter, fd.argPack(argIndex), argPacks[argIndex]._data));
+ ASMJIT_PROPAGATE(formatFuncValuePack(sb, formatFlags, cc, fd.argPack(argIndex), argPacks[argIndex]._data));
}
return kErrorOk;
@@ -405,25 +395,26 @@ static Error formatFuncArgs(
Error formatNode(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder,
const BaseNode* node) noexcept {
- if (node->hasPosition() && (formatFlags & FormatOptions::kFlagPositions) != 0)
+ if (node->hasPosition() && formatOptions.hasFlag(FormatFlags::kPositions))
ASMJIT_PROPAGATE(sb.appendFormat("<%05u> ", node->position()));
+ size_t startLineIndex = sb.size();
+
switch (node->type()) {
- case BaseNode::kNodeInst:
- case BaseNode::kNodeJump: {
+ case NodeType::kInst:
+ case NodeType::kJump: {
const InstNode* instNode = node->as<InstNode>();
- ASMJIT_PROPAGATE(
- formatInstruction(sb, formatFlags, builder,
- builder->arch(),
- instNode->baseInst(), instNode->operands(), instNode->opCount()));
+ ASMJIT_PROPAGATE(formatInstruction(sb, formatOptions.flags(), builder,
+ builder->arch(),
+ instNode->baseInst(), instNode->operands(), instNode->opCount()));
break;
}
- case BaseNode::kNodeSection: {
+ case NodeType::kSection: {
const SectionNode* sectionNode = node->as<SectionNode>();
if (builder->_code->isSectionValid(sectionNode->id())) {
const Section* section = builder->_code->sectionById(sectionNode->id());
@@ -432,65 +423,64 @@ Error formatNode(
break;
}
- case BaseNode::kNodeLabel: {
+ case NodeType::kLabel: {
const LabelNode* labelNode = node->as<LabelNode>();
- ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, labelNode->labelId()));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatOptions.flags(), builder, labelNode->labelId()));
ASMJIT_PROPAGATE(sb.append(":"));
break;
}
- case BaseNode::kNodeAlign: {
+ case NodeType::kAlign: {
const AlignNode* alignNode = node->as<AlignNode>();
- ASMJIT_PROPAGATE(
- sb.appendFormat(".align %u (%s)",
- alignNode->alignment(),
- alignNode->alignMode() == kAlignCode ? "code" : "data"));
+ ASMJIT_PROPAGATE(sb.appendFormat(".align %u (%s)",
+ alignNode->alignment(),
+ alignNode->alignMode() == AlignMode::kCode ? "code" : "data"));
break;
}
- case BaseNode::kNodeEmbedData: {
+ case NodeType::kEmbedData: {
const EmbedDataNode* embedNode = node->as<EmbedDataNode>();
ASMJIT_PROPAGATE(sb.append('.'));
- ASMJIT_PROPAGATE(formatDataType(sb, formatFlags, builder->arch(), embedNode->typeId()));
+ ASMJIT_PROPAGATE(formatDataType(sb, formatOptions.flags(), builder->arch(), embedNode->typeId()));
ASMJIT_PROPAGATE(sb.appendFormat(" {Count=%zu Repeat=%zu TotalSize=%zu}", embedNode->itemCount(), embedNode->repeatCount(), embedNode->dataSize()));
break;
}
- case BaseNode::kNodeEmbedLabel: {
+ case NodeType::kEmbedLabel: {
const EmbedLabelNode* embedNode = node->as<EmbedLabelNode>();
ASMJIT_PROPAGATE(sb.append(".label "));
- ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId()));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatOptions.flags(), builder, embedNode->labelId()));
break;
}
- case BaseNode::kNodeEmbedLabelDelta: {
+ case NodeType::kEmbedLabelDelta: {
const EmbedLabelDeltaNode* embedNode = node->as<EmbedLabelDeltaNode>();
ASMJIT_PROPAGATE(sb.append(".label ("));
- ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->labelId()));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatOptions.flags(), builder, embedNode->labelId()));
ASMJIT_PROPAGATE(sb.append(" - "));
- ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, embedNode->baseLabelId()));
+ ASMJIT_PROPAGATE(formatLabel(sb, formatOptions.flags(), builder, embedNode->baseLabelId()));
ASMJIT_PROPAGATE(sb.append(")"));
break;
}
- case BaseNode::kNodeConstPool: {
+ case NodeType::kConstPool: {
const ConstPoolNode* constPoolNode = node->as<ConstPoolNode>();
ASMJIT_PROPAGATE(sb.appendFormat("[ConstPool Size=%zu Alignment=%zu]", constPoolNode->size(), constPoolNode->alignment()));
break;
};
- case BaseNode::kNodeComment: {
+ case NodeType::kComment: {
const CommentNode* commentNode = node->as<CommentNode>();
ASMJIT_PROPAGATE(sb.appendFormat("; %s", commentNode->inlineComment()));
break;
}
- case BaseNode::kNodeSentinel: {
+ case NodeType::kSentinel: {
const SentinelNode* sentinelNode = node->as<SentinelNode>();
const char* sentinelName = nullptr;
switch (sentinelNode->sentinelType()) {
- case SentinelNode::kSentinelFuncEnd:
+ case SentinelType::kFuncEnd:
sentinelName = "[FuncEnd]";
break;
@@ -504,20 +494,22 @@ Error formatNode(
}
#ifndef ASMJIT_NO_COMPILER
- case BaseNode::kNodeFunc: {
+ case NodeType::kFunc: {
const FuncNode* funcNode = node->as<FuncNode>();
- ASMJIT_PROPAGATE(formatLabel(sb, formatFlags, builder, funcNode->labelId()));
- ASMJIT_PROPAGATE(sb.append(": "));
+ if (builder->isCompiler()) {
+ ASMJIT_PROPAGATE(formatLabel(sb, formatOptions.flags(), builder, funcNode->labelId()));
+ ASMJIT_PROPAGATE(sb.append(": "));
- ASMJIT_PROPAGATE(formatFuncRets(sb, formatFlags, builder, funcNode->detail()));
- ASMJIT_PROPAGATE(sb.append(" Func("));
- ASMJIT_PROPAGATE(formatFuncArgs(sb, formatFlags, builder, funcNode->detail(), funcNode->argPacks()));
- ASMJIT_PROPAGATE(sb.append(")"));
+ ASMJIT_PROPAGATE(formatFuncRets(sb, formatOptions.flags(), static_cast<const BaseCompiler*>(builder), funcNode->detail()));
+ ASMJIT_PROPAGATE(sb.append(" Func("));
+ ASMJIT_PROPAGATE(formatFuncArgs(sb, formatOptions.flags(), static_cast<const BaseCompiler*>(builder), funcNode->detail(), funcNode->argPacks()));
+ ASMJIT_PROPAGATE(sb.append(")"));
+ }
break;
}
- case BaseNode::kNodeFuncRet: {
+ case NodeType::kFuncRet: {
const FuncRetNode* retNode = node->as<FuncRetNode>();
ASMJIT_PROPAGATE(sb.append("[FuncRet]"));
@@ -525,18 +517,17 @@ Error formatNode(
const Operand_& op = retNode->_opArray[i];
if (!op.isNone()) {
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
- ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, builder, builder->arch(), op));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatOptions.flags(), builder, builder->arch(), op));
}
}
break;
}
- case BaseNode::kNodeInvoke: {
+ case NodeType::kInvoke: {
const InvokeNode* invokeNode = node->as<InvokeNode>();
- ASMJIT_PROPAGATE(
- formatInstruction(sb, formatFlags, builder,
- builder->arch(),
- invokeNode->baseInst(), invokeNode->operands(), invokeNode->opCount()));
+ ASMJIT_PROPAGATE(formatInstruction(sb, formatOptions.flags(), builder,
+ builder->arch(),
+ invokeNode->baseInst(), invokeNode->operands(), invokeNode->opCount()));
break;
}
#endif
@@ -547,28 +538,38 @@ Error formatNode(
}
}
+ if (node->hasInlineComment()) {
+ size_t requiredPadding = paddingFromOptions(formatOptions, FormatPaddingGroup::kRegularLine);
+ size_t currentPadding = sb.size() - startLineIndex;
+
+ if (currentPadding < requiredPadding)
+ ASMJIT_PROPAGATE(sb.appendChars(' ', requiredPadding - currentPadding));
+
+ ASMJIT_PROPAGATE(sb.append("; "));
+ ASMJIT_PROPAGATE(sb.append(node->inlineComment()));
+ }
+
return kErrorOk;
}
-
Error formatNodeList(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder) noexcept {
- return formatNodeList(sb, formatFlags, builder, builder->firstNode(), nullptr);
+ return formatNodeList(sb, formatOptions, builder, builder->firstNode(), nullptr);
}
Error formatNodeList(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder,
const BaseNode* begin,
const BaseNode* end) noexcept {
const BaseNode* node = begin;
while (node != end) {
- ASMJIT_PROPAGATE(formatNode(sb, formatFlags, builder, node));
+ ASMJIT_PROPAGATE(formatNode(sb, formatOptions, builder, node));
ASMJIT_PROPAGATE(sb.append('\n'));
node = node->next();
}
diff --git a/src/asmjit/core/formatter.h b/src/asmjit/core/formatter.h
index 513d764..d7a4b93 100644
--- a/src/asmjit/core/formatter.h
+++ b/src/asmjit/core/formatter.h
@@ -1,126 +1,98 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_FORMATTER_H_INCLUDED
#define ASMJIT_CORE_FORMATTER_H_INCLUDED
+#include "../core/globals.h"
#include "../core/inst.h"
#include "../core/string.h"
-
-#ifndef ASMJIT_NO_LOGGING
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_logging
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
+class BaseBuilder;
class BaseEmitter;
+class BaseNode;
struct Operand_;
-#ifndef ASMJIT_NO_BUILDER
-class BaseBuilder;
-class BaseNode;
-#endif
+//! Format flags used by \ref Logger and \ref FormatOptions.
+enum class FormatFlags : uint32_t {
+ //! No formatting flags.
+ kNone = 0u,
+
+ //! Show also binary form of each logged instruction (Assembler).
+ kMachineCode = 0x00000001u,
+ //! Show a text explanation of some immediate values.
+ kExplainImms = 0x00000002u,
+ //! Use hexadecimal notation of immediate values.
+ kHexImms = 0x00000004u,
+ //! Use hexadecimal notation of addresses and offsets in addresses.
+ kHexOffsets = 0x00000008u,
+ //! Show casts between virtual register types (Compiler output).
+ kRegCasts = 0x00000010u,
+ //! Show positions associated with nodes (Compiler output).
+ kPositions = 0x00000020u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(FormatFlags)
+
+//! Format indentation group, used by \ref FormatOptions.
+enum class FormatIndentationGroup : uint32_t {
+ //! Indentation used for instructions and directives.
+ kCode = 0u,
+ //! Indentation used for labels and function nodes.
+ kLabel = 1u,
+ //! Indentation used for comments (not inline comments).
+ kComment = 2u,
+
+ //! \cond INTERNAL
+ //! Reserved for future use.
+ kReserved = 3u,
+ //! \endcond
+
+ //! Maximum value of `FormatIndentationGroup`.
+ kMaxValue = kReserved
+};
-#ifndef ASMJIT_NO_COMPILER
-class BaseCompiler;
-#endif
+//! Format padding group, used by \ref FormatOptions.
+enum class FormatPaddingGroup : uint32_t {
+ //! Describes padding of a regular line, which can represent instruction, data, or assembler directives.
+ kRegularLine = 0,
+ //! Describes padding of machine code dump that is visible next to the instruction, if enabled.
+ kMachineCode = 1,
-// ============================================================================
-// [asmjit::FormatOptions]
-// ============================================================================
+ //! Maximum value of `FormatPaddingGroup`.
+ kMaxValue = kMachineCode
+};
//! Formatting options used by \ref Logger and \ref Formatter.
class FormatOptions {
public:
- //! Format flags, see \ref Flags.
- uint32_t _flags;
- //! Indentation by type, see \ref IndentationType.
- uint8_t _indentation[4];
-
- //! Flags can enable a logging feature.
- enum Flags : uint32_t {
- //! No flags.
- kNoFlags = 0u,
-
- //! Show also binary form of each logged instruction (Assembler).
- kFlagMachineCode = 0x00000001u,
- //! Show a text explanation of some immediate values.
- kFlagExplainImms = 0x00000002u,
- //! Use hexadecimal notation of immediate values.
- kFlagHexImms = 0x00000004u,
- //! Use hexadecimal notation of address offsets.
- kFlagHexOffsets = 0x00000008u,
- //! Show casts between virtual register types (Compiler).
- kFlagRegCasts = 0x00000010u,
- //! Show positions associated with nodes (Compiler).
- kFlagPositions = 0x00000020u,
- //! Annotate nodes that are lowered by passes.
- kFlagAnnotations = 0x00000040u,
-
- // TODO: These must go, keep this only for formatting.
- //! Show an additional output from passes.
- kFlagDebugPasses = 0x00000080u,
- //! Show an additional output from RA.
- kFlagDebugRA = 0x00000100u
- };
-
- //! Describes indentation type of code, label, or comment in logger output.
- enum IndentationType : uint32_t {
- //! Indentation used for instructions and directives.
- kIndentationCode = 0u,
- //! Indentation used for labels and function nodes.
- kIndentationLabel = 1u,
- //! Indentation used for comments (not inline comments).
- kIndentationComment = 2u,
- //! \cond INTERNAL
- //! Reserved for future use.
- kIndentationReserved = 3u
- //! \endcond
- };
-
- //! \name Construction & Destruction
+ //! \name Members
//! \{
- //! Creates a default-initialized FormatOptions.
- constexpr FormatOptions() noexcept
- : _flags(0),
- _indentation { 0, 0, 0, 0 } {}
+ //! Format flags.
+ FormatFlags _flags = FormatFlags::kNone;
+ //! Indentations for each indentation group.
+ Support::Array<uint8_t, uint32_t(FormatIndentationGroup::kMaxValue) + 1> _indentation {};
+ //! Paddings for each padding group.
+ Support::Array<uint16_t, uint32_t(FormatPaddingGroup::kMaxValue) + 1> _padding {};
- constexpr FormatOptions(const FormatOptions& other) noexcept = default;
- inline FormatOptions& operator=(const FormatOptions& other) noexcept = default;
+ //! \}
+
+ //! \name Reset
+ //! \{
//! Resets FormatOptions to its default initialized state.
inline void reset() noexcept {
- _flags = 0;
- _indentation[0] = 0;
- _indentation[1] = 0;
- _indentation[2] = 0;
- _indentation[3] = 0;
+ _flags = FormatFlags::kNone;
+ _indentation.fill(uint8_t(0));
+ _padding.fill(uint16_t(0));
}
//! \}
@@ -129,104 +101,109 @@ public:
//! \{
//! Returns format flags.
- constexpr uint32_t flags() const noexcept { return _flags; }
+ inline FormatFlags flags() const noexcept { return _flags; }
//! Tests whether the given `flag` is set in format flags.
- constexpr bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasFlag(FormatFlags flag) const noexcept { return Support::test(_flags, flag); }
+
//! Resets all format flags to `flags`.
- inline void setFlags(uint32_t flags) noexcept { _flags = flags; }
+ inline void setFlags(FormatFlags flags) noexcept { _flags = flags; }
//! Adds `flags` to format flags.
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ inline void addFlags(FormatFlags flags) noexcept { _flags |= flags; }
//! Removes `flags` from format flags.
- inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
-
- //! Returns indentation for the given `type`, see \ref IndentationType.
- constexpr uint8_t indentation(uint32_t type) const noexcept { return _indentation[type]; }
- //! Sets indentation for the given `type`, see \ref IndentationType.
- inline void setIndentation(uint32_t type, uint32_t n) noexcept { _indentation[type] = uint8_t(n); }
- //! Resets indentation for the given `type` to zero.
- inline void resetIndentation(uint32_t type) noexcept { _indentation[type] = uint8_t(0); }
+ inline void clearFlags(FormatFlags flags) noexcept { _flags &= ~flags; }
+
+ //! Returns indentation for the given indentation `group`.
+ inline uint8_t indentation(FormatIndentationGroup group) const noexcept { return _indentation[group]; }
+ //! Sets indentation for the given indentation `group`.
+ inline void setIndentation(FormatIndentationGroup group, uint32_t n) noexcept { _indentation[group] = uint8_t(n); }
+ //! Resets indentation for the given indentation `group` to zero.
+ inline void resetIndentation(FormatIndentationGroup group) noexcept { _indentation[group] = uint8_t(0); }
+
+ //! Returns pading for the given padding `group`.
+ inline size_t padding(FormatPaddingGroup group) const noexcept { return _padding[group]; }
+ //! Sets pading for the given padding `group`.
+ inline void setPadding(FormatPaddingGroup group, size_t n) noexcept { _padding[group] = uint16_t(n); }
+ //! Resets pading for the given padding `group` to zero, which means that a default padding will be used
+ //! based on the target architecture properties.
+ inline void resetPadding(FormatPaddingGroup group) noexcept { _padding[group] = uint16_t(0); }
//! \}
};
-// ============================================================================
-// [asmjit::Formatter]
-// ============================================================================
-
//! Provides formatting functionality to format operands, instructions, and nodes.
namespace Formatter {
+#ifndef ASMJIT_NO_LOGGING
+
//! Appends a formatted `typeId` to the output string `sb`.
ASMJIT_API Error formatTypeId(
String& sb,
- uint32_t typeId) noexcept;
+ TypeId typeId) noexcept;
//! Appends a formatted `featureId` to the output string `sb`.
//!
-//! See \ref BaseFeatures.
+//! See \ref CpuFeatures.
ASMJIT_API Error formatFeature(
String& sb,
- uint32_t arch,
+ Arch arch,
uint32_t featureId) noexcept;
//! Appends a formatted register to the output string `sb`.
//!
-//! \note Emitter is optional, but it's required to format virtual registers,
-//! which won't be formatted properly if the `emitter` is not provided.
+//! \note Emitter is optional, but it's required to format virtual registers, which won't be formatted properly
+//! if the `emitter` is not provided.
ASMJIT_API Error formatRegister(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
- uint32_t regType,
+ Arch arch,
+ RegType regType,
uint32_t regId) noexcept;
//! Appends a formatted label to the output string `sb`.
//!
-//! \note Emitter is optional, but it's required to format named labels
-//! properly, otherwise the formatted as it is an anonymous label.
+//! \note Emitter is optional, but it's required to format named labels properly, otherwise the formatted as
+//! it is an anonymous label.
ASMJIT_API Error formatLabel(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
uint32_t labelId) noexcept;
//! Appends a formatted operand to the output string `sb`.
//!
-//! \note Emitter is optional, but it's required to format named labels and
-//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
-//! more details.
+//! \note Emitter is optional, but it's required to format named labels and virtual registers. See
+//! \ref formatRegister() and \ref formatLabel() for more details.
ASMJIT_API Error formatOperand(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const Operand_& op) noexcept;
//! Appends a formatted data-type to the output string `sb`.
ASMJIT_API Error formatDataType(
String& sb,
- uint32_t formatFlags,
- uint32_t arch,
- uint32_t typeId) noexcept;
+ FormatFlags formatFlags,
+ Arch arch,
+ TypeId typeId) noexcept;
//! Appends a formatted data to the output string `sb`.
ASMJIT_API Error formatData(
String& sb,
- uint32_t formatFlags,
- uint32_t arch,
- uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;
+ FormatFlags formatFlags,
+ Arch arch,
+ TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;
//! Appends a formatted instruction to the output string `sb`.
//!
-//! \note Emitter is optional, but it's required to format named labels and
-//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
-//! more details.
+//! \note Emitter is optional, but it's required to format named labels and virtual registers. See
+//! \ref formatRegister() and \ref formatLabel() for more details.
ASMJIT_API Error formatInstruction(
String& sb,
- uint32_t formatFlags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
#ifndef ASMJIT_NO_BUILDER
@@ -235,7 +212,7 @@ ASMJIT_API Error formatInstruction(
//! The `node` must belong to the provided `builder`.
ASMJIT_API Error formatNode(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder,
const BaseNode* node) noexcept;
@@ -244,27 +221,27 @@ ASMJIT_API Error formatNode(
//! All nodes that are part of the given `builder` will be appended.
ASMJIT_API Error formatNodeList(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder) noexcept;
//! Appends formatted nodes to the output string `sb`.
//!
-//! This function works the same as \ref formatNode(), but appends more nodes
-//! to the output string, separating each node with a newline '\n' character.
+//! This function works the same as \ref formatNode(), but appends more nodes to the output string,
+//! separating each node with a newline '\n' character.
ASMJIT_API Error formatNodeList(
String& sb,
- uint32_t formatFlags,
+ const FormatOptions& formatOptions,
const BaseBuilder* builder,
const BaseNode* begin,
const BaseNode* end) noexcept;
#endif
+#endif
+
} // {Formatter}
//! \}
ASMJIT_END_NAMESPACE
-#endif
-
#endif // ASMJIT_CORE_FORMATTER_H_INCLUDED
diff --git a/src/asmjit/core/formatter_p.h b/src/asmjit/core/formatter_p.h
new file mode 100644
index 0000000..6070fd7
--- /dev/null
+++ b/src/asmjit/core/formatter_p.h
@@ -0,0 +1,34 @@
+// This file is part of AsmJit project <https://asmjit.com>
+//
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+
+#ifndef ASMJIT_CORE_FORMATTER_P_H_INCLUDED
+#define ASMJIT_CORE_FORMATTER_P_H_INCLUDED
+
+#include "../core/formatter.h"
+
+ASMJIT_BEGIN_NAMESPACE
+
+//! \cond INTERNAL
+//! \addtogroup asmjit_logging
+//! \{
+
+namespace Formatter {
+
+static ASMJIT_FORCE_INLINE size_t paddingFromOptions(const FormatOptions& formatOptions, FormatPaddingGroup group) noexcept {
+ static constexpr uint16_t _defaultPaddingTable[uint32_t(FormatPaddingGroup::kMaxValue) + 1] = { 44, 26 };
+ static_assert(uint32_t(FormatPaddingGroup::kMaxValue) + 1 == 2, "If a new group is defined it must be added here");
+
+ size_t padding = formatOptions.padding(group);
+ return padding ? padding : size_t(_defaultPaddingTable[uint32_t(group)]);
+}
+
+} // {Formatter}
+
+//! \}
+//! \endcond
+
+ASMJIT_END_NAMESPACE
+
+#endif // ASMJIT_CORE_FORMATTER_H_P_INCLUDED
diff --git a/src/asmjit/core/func.cpp b/src/asmjit/core/func.cpp
index cf017fe..fcc962c 100644
--- a/src/asmjit/core/func.cpp
+++ b/src/asmjit/core/func.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/archtraits.h"
@@ -38,11 +20,10 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::CallConv - Init / Reset]
-// ============================================================================
+// CallConv - Init & Reset
+// =======================
-ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId, const Environment& environment) noexcept {
+ASMJIT_FAVOR_SIZE Error CallConv::init(CallConvId ccId, const Environment& environment) noexcept {
reset();
#if !defined(ASMJIT_NO_X86)
@@ -58,12 +39,11 @@ ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId, const Environment& environ
return DebugUtils::errored(kErrorInvalidArgument);
}
-// ============================================================================
-// [asmjit::FuncDetail - Init / Reset]
-// ============================================================================
+// FuncDetail - Init / Reset
+// =========================
ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const Environment& environment) noexcept {
- uint32_t ccId = signature.callConv();
+ CallConvId ccId = signature.callConvId();
uint32_t argCount = signature.argCount();
if (ASMJIT_UNLIKELY(argCount > Globals::kMaxFuncArgs))
@@ -73,19 +53,20 @@ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const E
ASMJIT_PROPAGATE(cc.init(ccId, environment));
uint32_t registerSize = Environment::registerSizeFromArch(cc.arch());
- uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize);
+ uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize);
- const uint8_t* signatureArgs = signature.args();
+ const TypeId* signatureArgs = signature.args();
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
FuncValuePack& argPack = _args[argIndex];
- argPack[0].initTypeId(Type::deabstract(signatureArgs[argIndex], deabstractDelta));
+ argPack[0].initTypeId(TypeUtils::deabstract(signatureArgs[argIndex], deabstractDelta));
}
+
_argCount = uint8_t(argCount);
_vaIndex = uint8_t(signature.vaIndex());
- uint32_t ret = signature.ret();
- if (ret != Type::kIdVoid)
- _rets[0].initTypeId(Type::deabstract(ret, deabstractDelta));
+ TypeId ret = signature.ret();
+ if (ret != TypeId::kVoid)
+ _rets[0].initTypeId(TypeUtils::deabstract(ret, deabstractDelta));
#if !defined(ASMJIT_NO_X86)
if (environment.isFamilyX86())
@@ -97,28 +78,26 @@ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const E
return arm::FuncInternal::initFuncDetail(*this, signature, registerSize);
#endif
- // We should never bubble here as if `cc.init()` succeeded then there has to
- // be an implementation for the current architecture. However, stay safe.
+ // We should never bubble here as if `cc.init()` succeeded then there has to be an implementation for the current
+ // architecture. However, stay safe.
return DebugUtils::errored(kErrorInvalidArgument);
}
-// ============================================================================
-// [asmjit::FuncFrame - Init / Finalize]
-// ============================================================================
+// FuncFrame - Init
+// ================
ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept {
- uint32_t arch = func.callConv().arch();
+ Arch arch = func.callConv().arch();
if (!Environment::isValidArch(arch))
return DebugUtils::errored(kErrorInvalidArch);
const ArchTraits& archTraits = ArchTraits::byArch(arch);
- // Initializing FuncFrame means making a copy of some properties of `func`.
- // Properties like `_localStackSize` will be set by the user before the frame
- // is finalized.
+ // Initializing FuncFrame means making a copy of some properties of `func`. Properties like `_localStackSize` will
+ // be set by the user before the frame is finalized.
reset();
- _arch = uint8_t(arch);
+ _arch = arch;
_spRegId = uint8_t(archTraits.spRegId());
_saRegId = uint8_t(BaseReg::kIdBad);
@@ -134,34 +113,37 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept {
_spillZoneSize = uint8_t(func.spillZoneSize());
_finalStackAlignment = uint8_t(_naturalStackAlignment);
- if (func.hasFlag(CallConv::kFlagCalleePopsStack)) {
+ if (func.hasFlag(CallConvFlags::kCalleePopsStack)) {
_calleeStackCleanup = uint16_t(func.argStackSize());
}
// Initial masks of dirty and preserved registers.
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
_dirtyRegs[group] = func.usedRegs(group);
_preservedRegs[group] = func.preservedRegs(group);
}
// Exclude stack pointer - this register is never included in saved GP regs.
- _preservedRegs[BaseReg::kGroupGp] &= ~Support::bitMask(archTraits.spRegId());
+ _preservedRegs[RegGroup::kGp] &= ~Support::bitMask(archTraits.spRegId());
- // The size and alignment of save/restore area of registers for each significant register group.
- memcpy(_saveRestoreRegSize, func.callConv()._saveRestoreRegSize, sizeof(_saveRestoreRegSize));
- memcpy(_saveRestoreAlignment, func.callConv()._saveRestoreAlignment, sizeof(_saveRestoreAlignment));
+ // The size and alignment of save/restore area of registers for each virtual register group
+ _saveRestoreRegSize = func.callConv()._saveRestoreRegSize;
+ _saveRestoreAlignment = func.callConv()._saveRestoreAlignment;
return kErrorOk;
}
+// FuncFrame - Finalize
+// ====================
+
ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
if (!Environment::isValidArch(arch()))
return DebugUtils::errored(kErrorInvalidArch);
const ArchTraits& archTraits = ArchTraits::byArch(arch());
- uint32_t registerSize = _saveRestoreRegSize[BaseReg::kGroupGp];
- uint32_t vectorSize = _saveRestoreRegSize[BaseReg::kGroupVec];
+ uint32_t registerSize = _saveRestoreRegSize[RegGroup::kGp];
+ uint32_t vectorSize = _saveRestoreRegSize[RegGroup::kVec];
uint32_t returnAddressSize = archTraits.hasLinkReg() ? 0u : registerSize;
// The final stack alignment must be updated accordingly to call and local stack alignments.
@@ -179,12 +161,12 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
// Make frame pointer dirty if the function uses it.
if (hasFP) {
- _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(kFp);
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(kFp);
- // Currently required by ARM, if this works differently across architectures
- // we would have to generalize most likely in CallConv.
+ // Currently required by ARM, if this works differently across architectures we would have to generalize most
+ // likely in CallConv.
if (kLr != BaseReg::kIdBad)
- _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(kLr);
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(kLr);
}
// These two are identical if the function doesn't align its stack dynamically.
@@ -192,22 +174,22 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
if (saRegId == BaseReg::kIdBad)
saRegId = kSp;
- // Fix stack arguments base-register from SP to FP in case it was not picked
- // before and the function performs dynamic stack alignment.
+ // Fix stack arguments base-register from SP to FP in case it was not picked before and the function performs
+ // dynamic stack alignment.
if (hasDA && saRegId == kSp)
saRegId = kFp;
// Mark as dirty any register but SP if used as SA pointer.
if (saRegId != kSp)
- _dirtyRegs[BaseReg::kGroupGp] |= Support::bitMask(saRegId);
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(saRegId);
_spRegId = uint8_t(kSp);
_saRegId = uint8_t(saRegId);
// Setup stack size used to save preserved registers.
uint32_t saveRestoreSizes[2] {};
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- saveRestoreSizes[size_t(!archTraits.hasPushPop(group))]
+ for (RegGroup group : RegGroupVirtValues{})
+ saveRestoreSizes[size_t(!archTraits.hasInstPushPop(group))]
+= Support::alignUp(Support::popcnt(savedRegs(group)) * saveRestoreRegSize(group), saveRestoreAlignment(group));
_pushPopSaveSize = uint16_t(saveRestoreSizes[0]);
@@ -220,11 +202,10 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
_localStackOffset = v; // Store 'localStackOffset' <- Function's local stack starts here.
v += localStackSize(); // Count 'localStackSize' <- Function's local stack ends here.
- // If the function's stack must be aligned, calculate the alignment necessary
- // to store vector registers, and set `FuncFrame::kAttrAlignedVecSR` to inform
- // PEI that it can use instructions that perform aligned stores/loads.
+ // If the function's stack must be aligned, calculate the alignment necessary to store vector registers, and set
+ // `FuncAttributes::kAlignedVecSR` to inform PEI that it can use instructions that perform aligned stores/loads.
if (stackAlignment >= vectorSize && _extraRegSaveSize) {
- addAttributes(FuncFrame::kAttrAlignedVecSR);
+ addAttributes(FuncAttributes::kAlignedVecSR);
v = Support::alignUp(v, vectorSize); // Align 'extraRegSaveOffset'.
}
@@ -243,23 +224,19 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
// Link Register
// -------------
//
- // The stack is aligned after the function call as the return address is
- // stored in a link register. Some architectures may require to always
- // have aligned stack after PUSH/POP operation, which is represented by
- // ArchTraits::stackAlignmentConstraint().
+ // The stack is aligned after the function call as the return address is stored in a link register. Some
+ // architectures may require to always have aligned stack after PUSH/POP operation, which is represented
+ // by ArchTraits::stackAlignmentConstraint().
//
// No Link Register (X86/X64)
// --------------------------
//
- // The return address should be stored after GP save/restore regs. It has
- // the same size as `registerSize` (basically the native register/pointer
- // size). We don't adjust it now as `v` now contains the exact size that the
- // function requires to adjust (call frame + stack frame, vec stack size).
- // The stack (if we consider this size) is misaligned now, as it's always
- // aligned before the function call - when `call()` is executed it pushes
- // the current EIP|RIP onto the stack, and misaligns it by 12 or 8 bytes
- // (depending on the architecture). So count number of bytes needed to align
- // it up to the function's CallFrame (the beginning).
+ // The return address should be stored after GP save/restore regs. It has the same size as `registerSize`
+ // (basically the native register/pointer size). We don't adjust it now as `v` now contains the exact size
+ // that the function requires to adjust (call frame + stack frame, vec stack size). The stack (if we consider
+ // this size) is misaligned now, as it's always aligned before the function call - when `call()` is executed
+ // it pushes the current EIP|RIP onto the stack, and misaligns it by 12 or 8 bytes (depending on the
+ // architecture). So count number of bytes needed to align it up to the function's CallFrame (the beginning).
if (v || hasFuncCalls() || !returnAddressSize)
v += Support::alignUpDiff(v + pushPopSaveSize() + returnAddressSize, stackAlignment);
@@ -285,12 +262,11 @@ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::FuncArgsAssignment]
-// ============================================================================
+// FuncArgsAssignment - UpdateFuncFrame
+// ====================================
ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) const noexcept {
- uint32_t arch = frame.arch();
+ Arch arch = frame.arch();
const FuncDetail* func = funcDetail();
if (!func)
diff --git a/src/asmjit/core/func.h b/src/asmjit/core/func.h
index 9f63096..8ecf148 100644
--- a/src/asmjit/core/func.h
+++ b/src/asmjit/core/func.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_FUNC_H_INCLUDED
#define ASMJIT_CORE_FUNC_H_INCLUDED
@@ -35,23 +17,172 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_function
//! \{
-// ============================================================================
-// [asmjit::CallConv]
-// ============================================================================
+//! Calling convention id.
+//!
+//! Calling conventions can be divided into the following groups:
+//!
+//! - Universal - calling conventions are applicable to any target. They will be converted to a target dependent
+//! calling convention at runtime by \ref CallConv::init() with some help from \ref Environment. The purpose of
+//! these calling conventions is to make using functions less target dependent and closer to C and C++.
+//!
+//! - Target specific - calling conventions that are used by a particular architecture and ABI. For example
+//! Windows 64-bit calling convention and AMD64 SystemV calling convention.
+enum class CallConvId : uint8_t {
+ //! None or invalid (can't be used).
+ kNone = 0,
+
+ // Universal Calling Conventions
+ // -----------------------------
+
+ //! Standard function call or explicit `__cdecl` where it can be specified.
+ //!
+ //! This is a universal calling convention, which is used to initialize specific calling connventions based on
+ //! architecture, platform, and its ABI.
+ kCDecl = 1,
+
+ //! `__stdcall` on targets that support this calling convention (X86).
+ //!
+ //! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support
+ //! this calling convention it will be replaced by \ref CallConvId::kCDecl.
+ kStdCall = 2,
+
+ //! `__fastcall` on targets that support this calling convention (X86).
+ //!
+ //! \note This calling convention is only supported on 32-bit X86. If used on environment that doesn't support
+ //! this calling convention it will be replaced by \ref CallConvId::kCDecl.
+ kFastCall = 3,
+
+ //! `__vectorcall` on targets that support this calling convention (X86/X64).
+ //!
+ //! \note This calling convention is only supported on 32-bit and 64-bit X86 architecture on Windows platform.
+ //! If used on environment that doesn't support this calling it will be replaced by \ref CallConvId::kCDecl.
+ kVectorCall = 4,
+
+ //! `__thiscall` on targets that support this calling convention (X86).
+ //!
+ //! \note This calling convention is only supported on 32-bit X86 Windows platform. If used on environment that
+ //! doesn't support this calling convention it will be replaced by \ref CallConvId::kCDecl.
+ kThisCall = 5,
+
+ //! `__attribute__((regparm(1)))` convention (GCC and Clang).
+ kRegParm1 = 6,
+ //! `__attribute__((regparm(2)))` convention (GCC and Clang).
+ kRegParm2 = 7,
+ //! `__attribute__((regparm(3)))` convention (GCC and Clang).
+ kRegParm3 = 8,
+
+ //! Soft-float calling convention (ARM).
+ //!
+ //! Floating point arguments are passed via general purpose registers.
+ kSoftFloat = 9,
+
+ //! Hard-float calling convention (ARM).
+ //!
+ //! Floating point arguments are passed via SIMD registers.
+ kHardFloat = 10,
+
+ //! AsmJit specific calling convention designed for calling functions inside a multimedia code that don't use many
+ //! registers internally, but are long enough to be called and not inlined. These functions are usually used to
+ //! calculate trigonometric functions, logarithms, etc...
+ kLightCall2 = 16,
+ kLightCall3 = 17,
+ kLightCall4 = 18,
+
+ // ABI-Specific Calling Conventions
+ // --------------------------------
+
+ //! X64 System-V calling convention.
+ kX64SystemV = 32,
+ //! X64 Windows calling convention.
+ kX64Windows = 33,
+
+ //! Maximum value of `CallConvId`.
+ kMaxValue = kX64Windows,
+
+ // Host Calling Conventions
+ // ------------------------
+
+ //! Host calling convention detected at compile-time.
+ kHost =
+#if defined(_DOXYGEN)
+ DETECTED_AT_COMPILE_TIME
+#elif ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
+ kSoftFloat
+#elif ASMJIT_ARCH_ARM == 32 && !defined(__SOFTFP__)
+ kHardFloat
+#else
+ kCDecl
+#endif
+};
+
+//! Strategy used by calling conventions to assign registers to function arguments.
+//!
+//! Calling convention strategy describes how AsmJit should convert function arguments used by \ref FuncSignature
+//! into register identifiers and stack offsets. The \ref CallConvStrategy::kDefault strategy assigns registers
+//! and then stack whereas \ref CallConvStrategy::kX64Windows strategy does register shadowing as defined by WIN64
+//! calling convention, which is only used by 64-bit Windows.
+enum class CallConvStrategy : uint8_t {
+ //! Default register assignment strategy.
+ kDefault = 0,
+ //! Windows 64-bit ABI register assignment strategy.
+ kX64Windows = 1,
+ //! Windows 64-bit __vectorcall register assignment strategy.
+ kX64VectorCall = 2,
+
+ //! Maximum value of `CallConvStrategy`.
+ kMaxValue = kX64VectorCall
+};
+
+//! Calling convention flags.
+enum class CallConvFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+ //! Callee is responsible for cleaning up the stack.
+ kCalleePopsStack = 0x0001u,
+ //! Pass vector arguments indirectly (as a pointer).
+ kIndirectVecArgs = 0x0002u,
+ //! Pass F32 and F64 arguments via VEC128 register.
+ kPassFloatsByVec = 0x0004u,
+ //! Pass MMX and vector arguments via stack if the function has variable arguments.
+ kPassVecByStackIfVA = 0x0008u,
+ //! MMX registers are passed and returned via GP registers.
+ kPassMmxByGp = 0x0010u,
+ //! MMX registers are passed and returned via XMM registers.
+ kPassMmxByXmm = 0x0020u,
+ //! Calling convention can be used with variable arguments.
+ kVarArgCompatible = 0x0080u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(CallConvFlags)
//! Function calling convention.
//!
-//! Function calling convention is a scheme that defines how function parameters
-//! are passed and how function returns its result. AsmJit defines a variety of
-//! architecture and OS specific calling conventions and also provides a compile
-//! time detection to make the code-generation easier.
+//! Function calling convention is a scheme that defines how function parameters are passed and how function
+//! returns its result. AsmJit defines a variety of architecture and OS specific calling conventions and also
+//! provides a compile time detection to make the code-generation easier.
struct CallConv {
- //! Calling convention id, see \ref Id.
- uint8_t _id;
- //! Architecture identifier, see \ref Environment::Arch.
- uint8_t _arch;
- //! Register assignment strategy, see \ref Strategy.
- uint8_t _strategy;
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ //! Maximum number of register arguments per register group.
+ //!
+ //! \note This is not really AsmJit's limitatation, it's just the number that makes sense considering all common
+ //! calling conventions. Usually even conventions that use registers to pass function arguments are limited to 8
+ //! and less arguments passed via registers per group.
+ kMaxRegArgsPerGroup = 16
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ //! Target architecture.
+ Arch _arch;
+ //! Calling convention id.
+ CallConvId _id;
+ //! Register assignment strategy.
+ CallConvStrategy _strategy;
//! Red zone size (AMD64 == 128 bytes).
uint8_t _redZoneSize;
@@ -60,29 +191,18 @@ struct CallConv {
//! Natural stack alignment as defined by OS/ABI.
uint8_t _naturalStackAlignment;
- //! Flags.
- uint16_t _flags;
+ //! Calling convention flags.
+ CallConvFlags _flags;
//! Size to save/restore per register group.
- uint8_t _saveRestoreRegSize[BaseReg::kGroupVirt];
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreRegSize;
//! Alignment of save/restore groups.
- uint8_t _saveRestoreAlignment[BaseReg::kGroupVirt];
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreAlignment;
//! Mask of all passed registers, per group.
- uint32_t _passedRegs[BaseReg::kGroupVirt];
+ Support::Array<RegMask, Globals::kNumVirtGroups> _passedRegs;
//! Mask of all preserved registers, per group.
- uint32_t _preservedRegs[BaseReg::kGroupVirt];
-
- //! Internal limits of AsmJit's CallConv.
- enum Limits : uint32_t {
- //! Maximum number of register arguments per register group.
- //!
- //! \note This is not really AsmJit's limitatation, it's just the number
- //! that makes sense considering all common calling conventions. Usually
- //! even conventions that use registers to pass function arguments are
- //! limited to 8 and less arguments passed via registers per group.
- kMaxRegArgsPerGroup = 16
- };
+ Support::Array<RegMask, Globals::kNumVirtGroups> _preservedRegs;
//! Passed registers' order.
union RegOrder {
@@ -93,177 +213,26 @@ struct CallConv {
};
//! Passed registers' order, per register group.
- RegOrder _passedOrder[BaseReg::kGroupVirt];
-
- //! Calling convention id.
- //!
- //! Calling conventions can be divided into the following groups:
- //!
- //! - Universal - calling conventions are applicable to any target. They
- //! will be converted to a target dependent calling convention at runtime
- //! by \ref init(). The purpose of these conventions is to make using
- //! functions less target dependent and closer to how they are declared
- //! in C and C++.
- //!
- //! - Target specific - calling conventions that are used by a particular
- //! architecture and ABI. For example Windows 64-bit calling convention
- //! and AMD64 SystemV calling convention.
- enum Id : uint32_t {
- //! None or invalid (can't be used).
- kIdNone = 0,
-
- // ------------------------------------------------------------------------
- // [Universal Calling Conventions]
- // ------------------------------------------------------------------------
-
- //! Standard function call or explicit `__cdecl` where it can be specified.
- //!
- //! This is a universal calling convention, which is used to initialize
- //! specific calling connventions based on architecture, platform, and its ABI.
- kIdCDecl = 1,
-
- //! `__stdcall` on targets that support this calling convention (X86).
- //!
- //! \note This calling convention is only supported on 32-bit X86. If used
- //! on environment that doesn't support this calling convention it will be
- //! replaced by \ref kIdCDecl.
- kIdStdCall = 2,
-
- //! `__fastcall` on targets that support this calling convention (X86).
- //!
- //! \note This calling convention is only supported on 32-bit X86. If used
- //! on environment that doesn't support this calling convention it will be
- //! replaced by \ref kIdCDecl.
- kIdFastCall = 3,
-
- //! `__vectorcall` on targets that support this calling convention (X86/X64).
- //!
- //! \note This calling convention is only supported on 32-bit and 64-bit
- //! X86 architecture on Windows platform. If used on environment that doesn't
- //! support this calling it will be replaced by \ref kIdCDecl.
- kIdVectorCall = 4,
-
- //! `__thiscall` on targets that support this calling convention (X86).
- //!
- //! \note This calling convention is only supported on 32-bit X86 Windows
- //! platform. If used on environment that doesn't support this calling
- //! convention it will be replaced by \ref kIdCDecl.
- kIdThisCall = 5,
-
- //! `__attribute__((regparm(1)))` convention (GCC and Clang).
- kIdRegParm1 = 6,
- //! `__attribute__((regparm(2)))` convention (GCC and Clang).
- kIdRegParm2 = 7,
- //! `__attribute__((regparm(3)))` convention (GCC and Clang).
- kIdRegParm3 = 8,
-
- //! Soft-float calling convention (ARM).
- //!
- //! Floating point arguments are passed via general purpose registers.
- kIdSoftFloat = 9,
-
- //! Hard-float calling convention (ARM).
- //!
- //! Floating point arguments are passed via SIMD registers.
- kIdHardFloat = 10,
-
- //! AsmJit specific calling convention designed for calling functions
- //! inside a multimedia code that don't use many registers internally,
- //! but are long enough to be called and not inlined. These functions are
- //! usually used to calculate trigonometric functions, logarithms, etc...
- kIdLightCall2 = 16,
- kIdLightCall3 = 17,
- kIdLightCall4 = 18,
-
- // ------------------------------------------------------------------------
- // [ABI-Specific Calling Conventions]
- // ------------------------------------------------------------------------
-
- //! X64 System-V calling convention.
- kIdX64SystemV = 32,
- //! X64 Windows calling convention.
- kIdX64Windows = 33,
-
- // ------------------------------------------------------------------------
- // [Host]
- // ------------------------------------------------------------------------
-
- //! Host calling convention detected at compile-time.
- kIdHost =
-#if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
- kIdSoftFloat
-#elif ASMJIT_ARCH_ARM == 32 && !defined(__SOFTFP__)
- kIdHardFloat
-#else
- kIdCDecl
-#endif
-
-#ifndef ASMJIT_NO_DEPRECATE
- , kIdHostCDecl = kIdCDecl
- , kIdHostStdCall = kIdStdCall
- , kIdHostFastCall = kIdFastCall
- , kIdHostLightCall2 = kIdLightCall2
- , kIdHostLightCall3 = kIdLightCall3
- , kIdHostLightCall4 = kIdLightCall4
-#endif // !ASMJIT_NO_DEPRECATE
- };
-
- //! Strategy used to assign registers to function arguments.
- //!
- //! This is AsmJit specific. It basically describes how AsmJit should convert
- //! the function arguments defined by `FuncSignature` into register IDs and
- //! stack offsets. The default strategy `kStrategyDefault` assigns registers
- //! and then stack whereas `kStrategyWin64` strategy does register shadowing
- //! as defined by WIN64 calling convention - it applies to 64-bit calling
- //! conventions only.
- enum Strategy : uint32_t {
- //! Default register assignment strategy.
- kStrategyDefault = 0,
- //! Windows 64-bit ABI register assignment strategy.
- kStrategyX64Windows = 1,
- //! Windows 64-bit __vectorcall register assignment strategy.
- kStrategyX64VectorCall = 2,
-
- //! Number of assignment strategies.
- kStrategyCount = 3
- };
+ Support::Array<RegOrder, Globals::kNumVirtGroups> _passedOrder;
- //! Calling convention flags.
- enum Flags : uint32_t {
- //! Callee is responsible for cleaning up the stack.
- kFlagCalleePopsStack = 0x0001u,
- //! Pass vector arguments indirectly (as a pointer).
- kFlagIndirectVecArgs = 0x0002u,
- //! Pass F32 and F64 arguments via VEC128 register.
- kFlagPassFloatsByVec = 0x0004u,
- //! Pass MMX and vector arguments via stack if the function has variable arguments.
- kFlagPassVecByStackIfVA = 0x0008u,
- //! MMX registers are passed and returned via GP registers.
- kFlagPassMmxByGp = 0x0010u,
- //! MMX registers are passed and returned via XMM registers.
- kFlagPassMmxByXmm = 0x0020u,
- //! Calling convention can be used with variable arguments.
- kFlagVarArgCompatible = 0x0080u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
- //! Initializes this calling convention to the given `ccId` based on the
- //! `environment`.
+ //! Initializes this calling convention to the given `ccId` based on the `environment`.
//!
- //! See \ref Id and \ref Environment for more details.
- ASMJIT_API Error init(uint32_t ccId, const Environment& environment) noexcept;
+ //! See \ref CallConvId and \ref Environment for more details.
+ ASMJIT_API Error init(CallConvId ccId, const Environment& environment) noexcept;
//! Resets this CallConv struct into a defined state.
//!
- //! It's recommended to reset the \ref CallConv struct in case you would
- //! like create a custom calling convention as it prevents from using an
- //! uninitialized data (CallConv doesn't have a constructor that would
- //! initialize it, it's just a struct).
+ //! It's recommended to reset the \ref CallConv struct in case you would like create a custom calling convention
+ //! as it prevents from using an uninitialized data (CallConv doesn't have a constructor that would initialize it,
+ //! it's just a struct).
inline void reset() noexcept {
memset(this, 0, sizeof(*this));
- memset(_passedOrder, 0xFF, sizeof(_passedOrder));
+ memset(_passedOrder.data(), 0xFF, sizeof(_passedOrder));
}
//! \}
@@ -271,29 +240,29 @@ struct CallConv {
//! \name Accessors
//! \{
- //! Returns the calling convention id, see `Id`.
- inline uint32_t id() const noexcept { return _id; }
- //! Sets the calling convention id, see `Id`.
- inline void setId(uint32_t id) noexcept { _id = uint8_t(id); }
+ //! Returns the target architecture of this calling convention.
+ inline Arch arch() const noexcept { return _arch; }
+ //! Sets the target architecture of this calling convention.
+ inline void setArch(Arch arch) noexcept { _arch = arch; }
- //! Returns the calling function architecture id.
- inline uint32_t arch() const noexcept { return _arch; }
- //! Sets the calling function architecture id.
- inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); }
+ //! Returns the calling convention id.
+ inline CallConvId id() const noexcept { return _id; }
+ //! Sets the calling convention id.
+ inline void setId(CallConvId ccId) noexcept { _id = ccId; }
- //! Returns the strategy used to assign registers to arguments, see `Strategy`.
- inline uint32_t strategy() const noexcept { return _strategy; }
- //! Sets the strategy used to assign registers to arguments, see `Strategy`.
- inline void setStrategy(uint32_t strategy) noexcept { _strategy = uint8_t(strategy); }
+ //! Returns the strategy used to assign registers to arguments.
+ inline CallConvStrategy strategy() const noexcept { return _strategy; }
+ //! Sets the strategy used to assign registers to arguments.
+ inline void setStrategy(CallConvStrategy ccStrategy) noexcept { _strategy = ccStrategy; }
//! Tests whether the calling convention has the given `flag` set.
- inline bool hasFlag(uint32_t flag) const noexcept { return (uint32_t(_flags) & flag) != 0; }
+ inline bool hasFlag(CallConvFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Returns the calling convention flags, see `Flags`.
- inline uint32_t flags() const noexcept { return _flags; }
+ inline CallConvFlags flags() const noexcept { return _flags; }
//! Adds the calling convention flags, see `Flags`.
- inline void setFlags(uint32_t flag) noexcept { _flags = uint16_t(flag); };
+ inline void setFlags(CallConvFlags flag) noexcept { _flags = flag; };
//! Adds the calling convention flags, see `Flags`.
- inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); };
+ inline void addFlags(CallConvFlags flags) noexcept { _flags |= flags; };
//! Tests whether this calling convention specifies 'RedZone'.
inline bool hasRedZone() const noexcept { return _redZoneSize != 0; }
@@ -314,35 +283,34 @@ struct CallConv {
inline uint32_t naturalStackAlignment() const noexcept { return _naturalStackAlignment; }
//! Sets a natural stack alignment.
//!
- //! This function can be used to override the default stack alignment in case
- //! that you know that it's alignment is different. For example it allows to
- //! implement custom calling conventions that guarantee higher stack alignment.
+ //! This function can be used to override the default stack alignment in case that you know that it's alignment is
+ //! different. For example it allows to implement custom calling conventions that guarantee higher stack alignment.
inline void setNaturalStackAlignment(uint32_t value) noexcept { _naturalStackAlignment = uint8_t(value); }
//! Returns the size of a register (or its part) to be saved and restored of the given `group`.
- inline uint32_t saveRestoreRegSize(uint32_t group) const noexcept { return _saveRestoreRegSize[group]; }
+ inline uint32_t saveRestoreRegSize(RegGroup group) const noexcept { return _saveRestoreRegSize[group]; }
//! Sets the size of a vector register (or its part) to be saved and restored.
- inline void setSaveRestoreRegSize(uint32_t group, uint32_t size) noexcept { _saveRestoreRegSize[group] = uint8_t(size); }
+ inline void setSaveRestoreRegSize(RegGroup group, uint32_t size) noexcept { _saveRestoreRegSize[group] = uint8_t(size); }
//! Returns the alignment of a save-restore area of the given `group`.
- inline uint32_t saveRestoreAlignment(uint32_t group) const noexcept { return _saveRestoreAlignment[group]; }
+ inline uint32_t saveRestoreAlignment(RegGroup group) const noexcept { return _saveRestoreAlignment[group]; }
//! Sets the alignment of a save-restore area of the given `group`.
- inline void setSaveRestoreAlignment(uint32_t group, uint32_t alignment) noexcept { _saveRestoreAlignment[group] = uint8_t(alignment); }
+ inline void setSaveRestoreAlignment(RegGroup group, uint32_t alignment) noexcept { _saveRestoreAlignment[group] = uint8_t(alignment); }
- //! Returns the order of passed registers of the given `group`, see \ref BaseReg::RegGroup.
- inline const uint8_t* passedOrder(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
- return _passedOrder[group].id;
+ //! Returns the order of passed registers of the given `group`.
+ inline const uint8_t* passedOrder(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ return _passedOrder[size_t(group)].id;
}
- //! Returns the mask of passed registers of the given `group`, see \ref BaseReg::RegGroup.
- inline uint32_t passedRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
- return _passedRegs[group];
+ //! Returns the mask of passed registers of the given `group`.
+ inline RegMask passedRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ return _passedRegs[size_t(group)];
}
- inline void _setPassedPacked(uint32_t group, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void _setPassedPacked(RegGroup group, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_passedOrder[group].packed[0] = p0;
_passedOrder[group].packed[1] = p1;
@@ -351,19 +319,19 @@ struct CallConv {
}
//! Resets the order and mask of passed registers.
- inline void setPassedToNone(uint32_t group) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void setPassedToNone(RegGroup group) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_setPassedPacked(group, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu);
- _passedRegs[group] = 0u;
+ _passedRegs[size_t(group)] = 0u;
}
//! Sets the order and mask of passed registers.
- inline void setPassedOrder(uint32_t group, uint32_t a0, uint32_t a1 = 0xFF, uint32_t a2 = 0xFF, uint32_t a3 = 0xFF, uint32_t a4 = 0xFF, uint32_t a5 = 0xFF, uint32_t a6 = 0xFF, uint32_t a7 = 0xFF) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void setPassedOrder(RegGroup group, uint32_t a0, uint32_t a1 = 0xFF, uint32_t a2 = 0xFF, uint32_t a3 = 0xFF, uint32_t a4 = 0xFF, uint32_t a5 = 0xFF, uint32_t a6 = 0xFF, uint32_t a7 = 0xFF) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
- // NOTE: This should always be called with all arguments known at compile time,
- // so even if it looks scary it should be translated into few instructions.
+ // NOTE: This should always be called with all arguments known at compile time, so even if it looks scary it
+ // should be translated into few instructions.
_setPassedPacked(group, Support::bytepack32_4x8(a0, a1, a2, a3),
Support::bytepack32_4x8(a4, a5, a6, a7),
0xFFFFFFFFu,
@@ -379,59 +347,63 @@ struct CallConv {
(a7 != 0xFF ? 1u << a7 : 0u) ;
}
- //! Returns preserved register mask of the given `group`, see \ref BaseReg::RegGroup.
- inline uint32_t preservedRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ //! Returns preserved register mask of the given `group`.
+ inline RegMask preservedRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _preservedRegs[group];
}
- //! Sets preserved register mask of the given `group`, see \ref BaseReg::RegGroup.
- inline void setPreservedRegs(uint32_t group, uint32_t regs) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ //! Sets preserved register mask of the given `group`.
+ inline void setPreservedRegs(RegGroup group, RegMask regs) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_preservedRegs[group] = regs;
}
//! \}
};
-// ============================================================================
-// [asmjit::FuncSignature]
-// ============================================================================
-
//! Function signature.
//!
-//! Contains information about function return type, count of arguments and
-//! their TypeIds. Function signature is a low level structure which doesn't
-//! contain platform specific or calling convention specific information.
+//! Contains information about function return type, count of arguments and their TypeIds. Function signature is
+//! a low level structure which doesn't contain platform specific or calling convention specific information.
struct FuncSignature {
+ //! \name Constants
+ //! \{
+
+ enum : uint8_t {
+ //! Doesn't have variable number of arguments (`...`).
+ kNoVarArgs = 0xFFu
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! Calling convention id.
- uint8_t _callConv;
+ CallConvId _ccId;
//! Count of arguments.
uint8_t _argCount;
//! Index of a first VA or `kNoVarArgs`.
uint8_t _vaIndex;
//! Return value TypeId.
- uint8_t _ret;
+ TypeId _ret;
//! Function arguments TypeIds.
- const uint8_t* _args;
+ const TypeId* _args;
- enum : uint8_t {
- //! Doesn't have variable number of arguments (`...`).
- kNoVarArgs = 0xFF
- };
+ //! \}
//! \name Initializtion & Reset
//! \{
//! Initializes the function signature.
- inline void init(uint32_t ccId, uint32_t vaIndex, uint32_t ret, const uint8_t* args, uint32_t argCount) noexcept {
- ASMJIT_ASSERT(ccId <= 0xFF);
+ inline void init(CallConvId ccId, uint32_t vaIndex, TypeId ret, const TypeId* args, uint32_t argCount) noexcept {
ASMJIT_ASSERT(argCount <= 0xFF);
- _callConv = uint8_t(ccId);
+ _ccId = ccId;
_argCount = uint8_t(argCount);
_vaIndex = uint8_t(vaIndex);
- _ret = uint8_t(ret);
+ _ret = ret;
_args = args;
}
@@ -443,9 +415,9 @@ struct FuncSignature {
//! \{
//! Returns the calling convention.
- inline uint32_t callConv() const noexcept { return _callConv; }
+ inline CallConvId callConvId() const noexcept { return _ccId; }
//! Sets the calling convention to `ccId`;
- inline void setCallConv(uint32_t ccId) noexcept { _callConv = uint8_t(ccId); }
+ inline void setCallConvId(CallConvId ccId) noexcept { _ccId = ccId; }
//! Tests whether the function has variable number of arguments (...).
inline bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
@@ -459,48 +431,40 @@ struct FuncSignature {
//! Returns the number of function arguments.
inline uint32_t argCount() const noexcept { return _argCount; }
- inline bool hasRet() const noexcept { return _ret != Type::kIdVoid; }
+ inline bool hasRet() const noexcept { return _ret != TypeId::kVoid; }
//! Returns the return value type.
- inline uint32_t ret() const noexcept { return _ret; }
+ inline TypeId ret() const noexcept { return _ret; }
//! Returns the type of the argument at index `i`.
- inline uint32_t arg(uint32_t i) const noexcept {
+ inline TypeId arg(uint32_t i) const noexcept {
ASMJIT_ASSERT(i < _argCount);
return _args[i];
}
//! Returns the array of function arguments' types.
- inline const uint8_t* args() const noexcept { return _args; }
+ inline const TypeId* args() const noexcept { return _args; }
//! \}
};
-// ============================================================================
-// [asmjit::FuncSignatureT]
-// ============================================================================
-
template<typename... RET_ARGS>
class FuncSignatureT : public FuncSignature {
public:
- inline FuncSignatureT(uint32_t ccId = CallConv::kIdHost, uint32_t vaIndex = kNoVarArgs) noexcept {
- static const uint8_t ret_args[] = { (uint8_t(Type::IdOfT<RET_ARGS>::kTypeId))... };
+ inline FuncSignatureT(CallConvId ccId = CallConvId::kHost, uint32_t vaIndex = kNoVarArgs) noexcept {
+ static constexpr TypeId ret_args[] = { (TypeId(TypeUtils::TypeIdOfT<RET_ARGS>::kTypeId))... };
init(ccId, vaIndex, ret_args[0], ret_args + 1, uint32_t(ASMJIT_ARRAY_SIZE(ret_args) - 1));
}
};
-// ============================================================================
-// [asmjit::FuncSignatureBuilder]
-// ============================================================================
-
//! Function signature builder.
class FuncSignatureBuilder : public FuncSignature {
public:
- uint8_t _builderArgList[Globals::kMaxFuncArgs];
+ TypeId _builderArgList[Globals::kMaxFuncArgs];
//! \name Initializtion & Reset
//! \{
- inline FuncSignatureBuilder(uint32_t ccId = CallConv::kIdHost, uint32_t vaIndex = kNoVarArgs) noexcept {
- init(ccId, vaIndex, Type::kIdVoid, _builderArgList, 0);
+ inline FuncSignatureBuilder(CallConvId ccId = CallConvId::kHost, uint32_t vaIndex = kNoVarArgs) noexcept {
+ init(ccId, vaIndex, TypeId::kVoid, _builderArgList, 0);
}
//! \}
@@ -509,42 +473,39 @@ public:
//! \{
//! Sets the return type to `retType`.
- inline void setRet(uint32_t retType) noexcept { _ret = uint8_t(retType); }
+ inline void setRet(TypeId retType) noexcept { _ret = retType; }
//! Sets the return type based on `T`.
template<typename T>
- inline void setRetT() noexcept { setRet(Type::IdOfT<T>::kTypeId); }
+ inline void setRetT() noexcept { setRet(TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
//! Sets the argument at index `index` to `argType`.
- inline void setArg(uint32_t index, uint32_t argType) noexcept {
+ inline void setArg(uint32_t index, TypeId argType) noexcept {
ASMJIT_ASSERT(index < _argCount);
- _builderArgList[index] = uint8_t(argType);
+ _builderArgList[index] = argType;
}
//! Sets the argument at index `i` to the type based on `T`.
template<typename T>
- inline void setArgT(uint32_t index) noexcept { setArg(index, Type::IdOfT<T>::kTypeId); }
+ inline void setArgT(uint32_t index) noexcept { setArg(index, TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
//! Appends an argument of `type` to the function prototype.
- inline void addArg(uint32_t type) noexcept {
+ inline void addArg(TypeId type) noexcept {
ASMJIT_ASSERT(_argCount < Globals::kMaxFuncArgs);
- _builderArgList[_argCount++] = uint8_t(type);
+ _builderArgList[_argCount++] = type;
}
//! Appends an argument of type based on `T` to the function prototype.
template<typename T>
- inline void addArgT() noexcept { addArg(Type::IdOfT<T>::kTypeId); }
+ inline void addArgT() noexcept { addArg(TypeId(TypeUtils::TypeIdOfT<T>::kTypeId)); }
//! \}
};
-// ============================================================================
-// [asmjit::FuncValue]
-// ============================================================================
-
-//! Argument or return value (or its part) as defined by `FuncSignature`, but
-//! with register or stack address (and other metadata) assigned.
+//! Argument or return value (or its part) as defined by `FuncSignature`, but with register or stack address
+//! (and other metadata) assigned.
struct FuncValue {
- uint32_t _data;
+ //! \name Constants
+ //! \{
- enum Parts : uint32_t {
+ enum Bits : uint32_t {
kTypeIdShift = 0, //!< TypeId shift.
kTypeIdMask = 0x000000FFu, //!< TypeId mask.
@@ -563,23 +524,33 @@ struct FuncValue {
kRegTypeMask = 0xFF000000u //!< RegType mask.
};
- //! \name Initializtion & Reset
+ //! \}
+
+ //! \name Members
//! \{
- // These initialize the whole `FuncValue` to either register or stack. Useful
- // when you know all of these properties and wanna just set it up.
+ uint32_t _data;
+
+ //! \}
+
+ //! \name Initializtion & Reset
+ //!
+ //! These initialize the whole `FuncValue` to either register or stack. Useful when you know all of these
+ //! properties and wanna just set it up.
+ //!
+ //! \{
//! Initializes the `typeId` of this `FuncValue`.
- inline void initTypeId(uint32_t typeId) noexcept {
- _data = typeId << kTypeIdShift;
+ inline void initTypeId(TypeId typeId) noexcept {
+ _data = uint32_t(typeId) << kTypeIdShift;
}
- inline void initReg(uint32_t regType, uint32_t regId, uint32_t typeId, uint32_t flags = 0) noexcept {
- _data = (regType << kRegTypeShift) | (regId << kRegIdShift) | (typeId << kTypeIdShift) | kFlagIsReg | flags;
+ inline void initReg(RegType regType, uint32_t regId, TypeId typeId, uint32_t flags = 0) noexcept {
+ _data = (uint32_t(regType) << kRegTypeShift) | (regId << kRegIdShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsReg | flags;
}
- inline void initStack(int32_t offset, uint32_t typeId) noexcept {
- _data = (uint32_t(offset) << kStackOffsetShift) | (typeId << kTypeIdShift) | kFlagIsStack;
+ inline void initStack(int32_t offset, TypeId typeId) noexcept {
+ _data = (uint32_t(offset) << kStackOffsetShift) | (uint32_t(typeId) << kTypeIdShift) | kFlagIsStack;
}
//! Resets the value to its unassigned state.
@@ -588,15 +559,15 @@ struct FuncValue {
//! \}
//! \name Assign
+ //!
+ //! These initialize only part of `FuncValue`, useful when building `FuncValue` incrementally. The caller
+ //! should first init the type-id by caliing `initTypeId` and then continue building either register or stack.
+ //!
//! \{
- // These initialize only part of `FuncValue`, useful when building `FuncValue`
- // incrementally. The caller should first init the type-id by caliing `initTypeId`
- // and then continue building either register or stack.
-
- inline void assignRegData(uint32_t regType, uint32_t regId) noexcept {
+ inline void assignRegData(RegType regType, uint32_t regId) noexcept {
ASMJIT_ASSERT((_data & (kRegTypeMask | kRegIdMask)) == 0);
- _data |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kFlagIsReg;
+ _data |= (uint32_t(regType) << kRegTypeShift) | (regId << kRegIdShift) | kFlagIsReg;
}
inline void assignStackOffset(int32_t offset) noexcept {
@@ -609,12 +580,13 @@ struct FuncValue {
//! \name Accessors
//! \{
+ //! Returns true if the value is initialized (explicit bool cast).
inline explicit operator bool() const noexcept { return _data != 0; }
inline void _replaceValue(uint32_t mask, uint32_t value) noexcept { _data = (_data & ~mask) | value; }
//! Tests whether the `FuncValue` has a flag `flag` set.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_data & flag) != 0; }
+ inline bool hasFlag(uint32_t flag) const noexcept { return Support::test(_data, flag); }
//! Adds `flags` to `FuncValue`.
inline void addFlags(uint32_t flags) noexcept { _data |= flags; }
//! Clears `flags` of `FuncValue`.
@@ -635,9 +607,9 @@ struct FuncValue {
inline bool isDone() const noexcept { return hasFlag(kFlagIsDone); }
//! Returns a register type of the register used to pass function argument or return value.
- inline uint32_t regType() const noexcept { return (_data & kRegTypeMask) >> kRegTypeShift; }
+ inline RegType regType() const noexcept { return RegType((_data & kRegTypeMask) >> kRegTypeShift); }
//! Sets a register type of the register used to pass function argument or return value.
- inline void setRegType(uint32_t regType) noexcept { _replaceValue(kRegTypeMask, regType << kRegTypeShift); }
+ inline void setRegType(RegType regType) noexcept { _replaceValue(kRegTypeMask, uint32_t(regType) << kRegTypeShift); }
//! Returns a physical id of the register used to pass function argument or return value.
inline uint32_t regId() const noexcept { return (_data & kRegIdMask) >> kRegIdShift; }
@@ -649,35 +621,43 @@ struct FuncValue {
//! Sets a stack offset of this argument.
inline void setStackOffset(int32_t offset) noexcept { _replaceValue(kStackOffsetMask, uint32_t(offset) << kStackOffsetShift); }
- //! Tests whether the argument or return value has associated `Type::Id`.
- inline bool hasTypeId() const noexcept { return (_data & kTypeIdMask) != 0; }
+ //! Tests whether the argument or return value has associated `TypeId`.
+ inline bool hasTypeId() const noexcept { return Support::test(_data, kTypeIdMask); }
//! Returns a TypeId of this argument or return value.
- inline uint32_t typeId() const noexcept { return (_data & kTypeIdMask) >> kTypeIdShift; }
+ inline TypeId typeId() const noexcept { return TypeId((_data & kTypeIdMask) >> kTypeIdShift); }
//! Sets a TypeId of this argument or return value.
- inline void setTypeId(uint32_t typeId) noexcept { _replaceValue(kTypeIdMask, typeId << kTypeIdShift); }
+ inline void setTypeId(TypeId typeId) noexcept { _replaceValue(kTypeIdMask, uint32_t(typeId) << kTypeIdShift); }
//! \}
};
-// ============================================================================
-// [asmjit::FuncValuePack]
-// ============================================================================
-
-//! Contains multiple `FuncValue` instances in an array so functions that use
-//! multiple registers for arguments or return values can represent all inputs
-//! and outputs.
+//! Contains multiple `FuncValue` instances in an array so functions that use multiple registers for arguments or
+//! return values can represent all inputs and outputs.
struct FuncValuePack {
public:
- //! Values data.
+ //! \name Members
+ //! \{
+
+ //! Values of the pack.
FuncValue _values[Globals::kMaxValuePack];
+ //! \}
+
+ //! \name Initialization & Reset
+ //! \{
+
+ //! Resets all values in the pack.
inline void reset() noexcept {
for (size_t i = 0; i < Globals::kMaxValuePack; i++)
_values[i].reset();
}
- //! Calculates how many values are in the pack, checking for non-values
- //! from the end.
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Calculates how many values are in the pack, checking for non-values from the end.
inline uint32_t count() const noexcept {
uint32_t n = Globals::kMaxValuePack;
while (n && !_values[n - 1])
@@ -698,18 +678,18 @@ public:
return _values[index].isInitialized();
}
- inline void assignReg(size_t index, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignReg(size_t index, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
ASMJIT_ASSERT(reg.isPhysReg());
_values[index].initReg(reg.type(), reg.id(), typeId);
}
- inline void assignReg(size_t index, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignReg(size_t index, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
_values[index].initReg(regType, regId, typeId);
}
- inline void assignStack(size_t index, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignStack(size_t index, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
_values[index].initStack(offset, typeId);
}
@@ -723,19 +703,70 @@ public:
ASMJIT_ASSERT(index < Globals::kMaxValuePack);
return _values[index];
}
+
+ //! \}
};
-// ============================================================================
-// [asmjit::FuncDetail]
-// ============================================================================
+//! Attributes are designed in a way that all are initially false, and user or \ref FuncFrame finalizer adds
+//! them when necessary.
+enum class FuncAttributes : uint32_t {
+ //! No attributes.
+ kNoAttributes = 0,
+
+ //! Function has variable number of arguments.
+ kHasVarArgs = 0x00000001u,
+ //! Preserve frame pointer (don't omit FP).
+ kHasPreservedFP = 0x00000010u,
+ //! Function calls other functions (is not leaf).
+ kHasFuncCalls = 0x00000020u,
+ //! Function has aligned save/restore of vector registers.
+ kAlignedVecSR = 0x00000040u,
+ //! FuncFrame is finalized and can be used by prolog/epilog inserter (PEI).
+ kIsFinalized = 0x00000800u,
+
+ // X86 Specific Attributes
+ // -----------------------
+
+ //! Enables the use of AVX within the function's body, prolog, and epilog (X86).
+ //!
+ //! This flag instructs prolog and epilog emitter to use AVX instead of SSE for manipulating XMM registers.
+ kX86_AVXEnabled = 0x00010000u,
+
+ //! Enables the use of AVX-512 within the function's body, prolog, and epilog (X86).
+ //!
+ //! This flag instructs Compiler register allocator to use additional 16 registers introduced by AVX-512.
+ //! Additionally, if the functions saves full width of ZMM registers (custom calling conventions only) then
+ //! the prolog/epilog inserter would use AVX-512 move instructions to emit the save and restore sequence.
+ kX86_AVX512Enabled = 0x00020000u,
+
+ //! This flag instructs the epilog writer to emit EMMS instruction before RET (X86).
+ kX86_MMXCleanup = 0x00040000u,
+
+ //! This flag instructs the epilog writer to emit VZEROUPPER instruction before RET (X86).
+ kX86_AVXCleanup = 0x00080000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(FuncAttributes)
-//! Function detail - CallConv and expanded FuncSignature.
+//! Function detail - \ref CallConv and expanded \ref FuncSignature.
//!
-//! Function detail is architecture and OS dependent representation of a function.
-//! It contains calling convention and expanded function signature so all
-//! arguments have assigned either register type & id or stack address.
+//! Function detail is architecture and OS dependent representation of a function. It contains a materialized
+//! calling convention and expanded function signature so all arguments have assigned either register type/id
+//! or stack address.
class FuncDetail {
public:
+ //! \name Constants
+ //! \{
+
+ enum : uint8_t {
+ //! Doesn't have variable number of arguments (`...`).
+ kNoVarArgs = 0xFFu
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! Calling convention.
CallConv _callConv;
//! Number of function arguments.
@@ -744,8 +775,8 @@ public:
uint8_t _vaIndex;
//! Reserved for future use.
uint16_t _reserved;
- //! Registers that contains arguments.
- uint32_t _usedRegs[BaseReg::kGroupVirt];
+ //! Registers that contain arguments.
+ Support::Array<RegMask, Globals::kNumVirtGroups> _usedRegs;
//! Size of arguments passed by stack.
uint32_t _argStackSize;
//! Function return value(s).
@@ -753,10 +784,7 @@ public:
//! Function arguments.
FuncValuePack _args[Globals::kMaxFuncArgs];
- enum : uint8_t {
- //! Doesn't have variable number of arguments (`...`).
- kNoVarArgs = 0xFF
- };
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -777,9 +805,9 @@ public:
inline const CallConv& callConv() const noexcept { return _callConv; }
//! Returns the associated calling convention flags, see `CallConv::Flags`.
- inline uint32_t flags() const noexcept { return _callConv.flags(); }
+ inline CallConvFlags flags() const noexcept { return _callConv.flags(); }
//! Checks whether a CallConv `flag` is set, see `CallConv::Flags`.
- inline bool hasFlag(uint32_t ccFlag) const noexcept { return _callConv.hasFlag(ccFlag); }
+ inline bool hasFlag(CallConvFlags ccFlag) const noexcept { return _callConv.hasFlag(ccFlag); }
//! Tests whether the function has a return value.
inline bool hasRet() const noexcept { return bool(_rets[0]); }
@@ -851,50 +879,47 @@ public:
inline uint32_t naturalStackAlignment() const noexcept { return _callConv.naturalStackAlignment(); }
//! Returns a mask of all passed registers of the given register `group`.
- inline uint32_t passedRegs(uint32_t group) const noexcept { return _callConv.passedRegs(group); }
+ inline RegMask passedRegs(RegGroup group) const noexcept { return _callConv.passedRegs(group); }
//! Returns a mask of all preserved registers of the given register `group`.
- inline uint32_t preservedRegs(uint32_t group) const noexcept { return _callConv.preservedRegs(group); }
+ inline RegMask preservedRegs(RegGroup group) const noexcept { return _callConv.preservedRegs(group); }
//! Returns a mask of all used registers of the given register `group`.
- inline uint32_t usedRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
- return _usedRegs[group];
+ inline RegMask usedRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ return _usedRegs[size_t(group)];
}
//! Adds `regs` to the mask of used registers of the given register `group`.
- inline void addUsedRegs(uint32_t group, uint32_t regs) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
- _usedRegs[group] |= regs;
+ inline void addUsedRegs(RegGroup group, RegMask regs) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ _usedRegs[size_t(group)] |= regs;
}
//! \}
};
-// ============================================================================
-// [asmjit::FuncFrame]
-// ============================================================================
-
//! Function frame.
//!
-//! Function frame is used directly by prolog and epilog insertion (PEI) utils.
-//! It provides information necessary to insert a proper and ABI comforming
-//! prolog and epilog. Function frame calculation is based on `CallConv` and
+//! Function frame is used directly by prolog and epilog insertion (PEI) utils. It provides information necessary to
+//! insert a proper and ABI comforming prolog and epilog. Function frame calculation is based on `CallConv` and
//! other function attributes.
//!
//! SSE vs AVX vs AVX-512
//! ---------------------
//!
-//! Function frame provides a way to tell prolog/epilog inserter to use AVX
-//! instructions instead of SSE. Use `setAvxEnabled()` and `setAvx512Enabled()`
-//! to enable AVX and/or AVX-512, respectively. Enabling AVX-512 is mostly for
-//! Compiler as it would use 32 SIMD registers instead of 16 when enabled.
+//! Function frame provides a way to tell prolog/epilog inserter to use AVX instructions instead of SSE. Use
+//! `setAvxEnabled()` and `setAvx512Enabled()` to enable AVX and/or AVX-512, respectively. Enabling AVX-512
+//! is mostly for Compiler as it would use 32 SIMD registers instead of 16 when enabled.
+//!
+//! \note If your code uses AVX instructions and AVX is not enabled there would be a performance hit in case that
+//! some registers had to be saved/restored in function's prolog/epilog, respectively. Thus, it's recommended to
+//! always let the function frame know about the use of AVX.
//!
//! Function Frame Structure
//! ------------------------
//!
-//! Various properties can contribute to the size and structure of the function
-//! frame. The function frame in most cases won't use all of the properties
-//! illustrated (for example Spill Zone and Red Zone are never used together).
+//! Various properties can contribute to the size and structure of the function frame. The function frame in most
+//! cases won't use all of the properties illustrated (for example Spill Zone and Red Zone are never used together).
//!
//! ```
//! +-----------------------------+
@@ -915,49 +940,24 @@ public:
//! ```
class FuncFrame {
public:
- enum Tag : uint32_t {
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
//! Tag used to inform that some offset is invalid.
kTagInvalidOffset = 0xFFFFFFFFu
};
- //! Attributes are designed in a way that all are initially false, and user
- //! or FuncFrame finalizer adds them when necessary.
- enum Attributes : uint32_t {
- //! Function has variable number of arguments.
- kAttrHasVarArgs = 0x00000001u,
- //! Preserve frame pointer (don't omit FP).
- kAttrHasPreservedFP = 0x00000010u,
- //! Function calls other functions (is not leaf).
- kAttrHasFuncCalls = 0x00000020u,
-
- //! Function uses AVX (X86).
- //!
- //! This flag instructs prolog and epilog emitter to use AVX instead of SSE for manipulating
- //! XMM registers.
- kAttrX86AvxEnabled = 0x00010000u,
- //! Function uses AVX-512 (X86).
- //!
- //! This flag instructs Compiler register allocator to use additional 16 registers introduced
- //! by AVX-512.
- kAttrX86Avx512Enabled = 0x00020000u,
-
- //! This flag instructs epilog writer to emit EMMS instruction before RET (X86).
- kAttrX86MmxCleanup = 0x00040000u,
-
- //! This flag instructs epilog writer to emit VZEROUPPER instruction before RET (X86).
- kAttrX86AvxCleanup = 0x00080000u,
+ //! \}
- //! Function has aligned save/restore of vector registers.
- kAttrAlignedVecSR = 0x40000000u,
- //! FuncFrame is finalized and can be used by PEI.
- kAttrIsFinalized = 0x80000000u
- };
+ //! \name Members
+ //! \{
//! Function attributes.
- uint32_t _attributes;
+ FuncAttributes _attributes;
- //! Architecture, see \ref Environment::Arch.
- uint8_t _arch;
+ //! Target architecture.
+ Arch _arch;
//! SP register ID (to access call stack and local stack).
uint8_t _spRegId;
//! SA register ID (to access stack arguments).
@@ -1002,13 +1002,13 @@ public:
uint32_t _stackAdjustment;
//! Registers that are dirty.
- uint32_t _dirtyRegs[BaseReg::kGroupVirt];
+ Support::Array<RegMask, Globals::kNumVirtGroups> _dirtyRegs;
//! Registers that must be preserved (copied from CallConv).
- uint32_t _preservedRegs[BaseReg::kGroupVirt];
+ Support::Array<RegMask, Globals::kNumVirtGroups> _preservedRegs;
//! Size to save/restore per register group.
- uint8_t _saveRestoreRegSize[BaseReg::kGroupVirt];
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreRegSize;
//! Alignment of save/restore area per register group.
- uint8_t _saveRestoreAlignment[BaseReg::kGroupVirt];
+ Support::Array<uint8_t, Globals::kNumVirtGroups> _saveRestoreAlignment;
//! Stack size required to save registers with push/pop.
uint16_t _pushPopSaveSize;
@@ -1019,6 +1019,8 @@ public:
//! Offset where extra ragisters that cannot use push/pop are stored.
uint32_t _extraRegSaveOffset;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -1040,72 +1042,72 @@ public:
//! \{
//! Returns the target architecture of the function frame.
- inline uint32_t arch() const noexcept { return _arch; }
+ inline Arch arch() const noexcept { return _arch; }
//! Returns function frame attributes, see `Attributes`.
- inline uint32_t attributes() const noexcept { return _attributes; }
+ inline FuncAttributes attributes() const noexcept { return _attributes; }
//! Checks whether the FuncFame contains an attribute `attr`.
- inline bool hasAttribute(uint32_t attr) const noexcept { return (_attributes & attr) != 0; }
+ inline bool hasAttribute(FuncAttributes attr) const noexcept { return Support::test(_attributes, attr); }
//! Adds attributes `attrs` to the FuncFrame.
- inline void addAttributes(uint32_t attrs) noexcept { _attributes |= attrs; }
+ inline void addAttributes(FuncAttributes attrs) noexcept { _attributes |= attrs; }
//! Clears attributes `attrs` from the FrameFrame.
- inline void clearAttributes(uint32_t attrs) noexcept { _attributes &= ~attrs; }
+ inline void clearAttributes(FuncAttributes attrs) noexcept { _attributes &= ~attrs; }
//! Tests whether the function has variable number of arguments.
- inline bool hasVarArgs() const noexcept { return hasAttribute(kAttrHasVarArgs); }
+ inline bool hasVarArgs() const noexcept { return hasAttribute(FuncAttributes::kHasVarArgs); }
//! Sets the variable arguments flag.
- inline void setVarArgs() noexcept { addAttributes(kAttrHasVarArgs); }
+ inline void setVarArgs() noexcept { addAttributes(FuncAttributes::kHasVarArgs); }
//! Resets variable arguments flag.
- inline void resetVarArgs() noexcept { clearAttributes(kAttrHasVarArgs); }
+ inline void resetVarArgs() noexcept { clearAttributes(FuncAttributes::kHasVarArgs); }
//! Tests whether the function preserves frame pointer (EBP|ESP on X86).
- inline bool hasPreservedFP() const noexcept { return hasAttribute(kAttrHasPreservedFP); }
+ inline bool hasPreservedFP() const noexcept { return hasAttribute(FuncAttributes::kHasPreservedFP); }
//! Enables preserved frame pointer.
- inline void setPreservedFP() noexcept { addAttributes(kAttrHasPreservedFP); }
+ inline void setPreservedFP() noexcept { addAttributes(FuncAttributes::kHasPreservedFP); }
//! Disables preserved frame pointer.
- inline void resetPreservedFP() noexcept { clearAttributes(kAttrHasPreservedFP); }
+ inline void resetPreservedFP() noexcept { clearAttributes(FuncAttributes::kHasPreservedFP); }
//! Tests whether the function calls other functions.
- inline bool hasFuncCalls() const noexcept { return hasAttribute(kAttrHasFuncCalls); }
+ inline bool hasFuncCalls() const noexcept { return hasAttribute(FuncAttributes::kHasFuncCalls); }
//! Sets `kFlagHasCalls` to true.
- inline void setFuncCalls() noexcept { addAttributes(kAttrHasFuncCalls); }
+ inline void setFuncCalls() noexcept { addAttributes(FuncAttributes::kHasFuncCalls); }
//! Sets `kFlagHasCalls` to false.
- inline void resetFuncCalls() noexcept { clearAttributes(kAttrHasFuncCalls); }
+ inline void resetFuncCalls() noexcept { clearAttributes(FuncAttributes::kHasFuncCalls); }
//! Tests whether the function has AVX enabled.
- inline bool isAvxEnabled() const noexcept { return hasAttribute(kAttrX86AvxEnabled); }
+ inline bool isAvxEnabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVXEnabled); }
//! Enables AVX use.
- inline void setAvxEnabled() noexcept { addAttributes(kAttrX86AvxEnabled); }
+ inline void setAvxEnabled() noexcept { addAttributes(FuncAttributes::kX86_AVXEnabled); }
//! Disables AVX use.
- inline void resetAvxEnabled() noexcept { clearAttributes(kAttrX86AvxEnabled); }
+ inline void resetAvxEnabled() noexcept { clearAttributes(FuncAttributes::kX86_AVXEnabled); }
//! Tests whether the function has AVX-512 enabled.
- inline bool isAvx512Enabled() const noexcept { return hasAttribute(kAttrX86Avx512Enabled); }
+ inline bool isAvx512Enabled() const noexcept { return hasAttribute(FuncAttributes::kX86_AVX512Enabled); }
//! Enables AVX-512 use.
- inline void setAvx512Enabled() noexcept { addAttributes(kAttrX86Avx512Enabled); }
+ inline void setAvx512Enabled() noexcept { addAttributes(FuncAttributes::kX86_AVX512Enabled); }
//! Disables AVX-512 use.
- inline void resetAvx512Enabled() noexcept { clearAttributes(kAttrX86Avx512Enabled); }
+ inline void resetAvx512Enabled() noexcept { clearAttributes(FuncAttributes::kX86_AVX512Enabled); }
//! Tests whether the function has MMX cleanup - 'emms' instruction in epilog.
- inline bool hasMmxCleanup() const noexcept { return hasAttribute(kAttrX86MmxCleanup); }
+ inline bool hasMmxCleanup() const noexcept { return hasAttribute(FuncAttributes::kX86_MMXCleanup); }
//! Enables MMX cleanup.
- inline void setMmxCleanup() noexcept { addAttributes(kAttrX86MmxCleanup); }
+ inline void setMmxCleanup() noexcept { addAttributes(FuncAttributes::kX86_MMXCleanup); }
//! Disables MMX cleanup.
- inline void resetMmxCleanup() noexcept { clearAttributes(kAttrX86MmxCleanup); }
+ inline void resetMmxCleanup() noexcept { clearAttributes(FuncAttributes::kX86_MMXCleanup); }
//! Tests whether the function has AVX cleanup - 'vzeroupper' instruction in epilog.
- inline bool hasAvxCleanup() const noexcept { return hasAttribute(kAttrX86AvxCleanup); }
+ inline bool hasAvxCleanup() const noexcept { return hasAttribute(FuncAttributes::kX86_AVXCleanup); }
//! Enables AVX cleanup.
- inline void setAvxCleanup() noexcept { addAttributes(kAttrX86AvxCleanup); }
+ inline void setAvxCleanup() noexcept { addAttributes(FuncAttributes::kX86_AVXCleanup); }
//! Disables AVX cleanup.
- inline void resetAvxCleanup() noexcept { clearAttributes(kAttrX86AvxCleanup); }
+ inline void resetAvxCleanup() noexcept { clearAttributes(FuncAttributes::kX86_AVXCleanup); }
//! Tests whether the function uses call stack.
inline bool hasCallStack() const noexcept { return _callStackSize != 0; }
//! Tests whether the function uses local stack.
inline bool hasLocalStack() const noexcept { return _localStackSize != 0; }
//! Tests whether vector registers can be saved and restored by using aligned reads and writes.
- inline bool hasAlignedVecSR() const noexcept { return hasAttribute(kAttrAlignedVecSR); }
+ inline bool hasAlignedVecSR() const noexcept { return hasAttribute(FuncAttributes::kAlignedVecSR); }
//! Tests whether the function has to align stack dynamically.
inline bool hasDynamicAlignment() const noexcept { return _finalStackAlignment >= _minDynamicAlignment; }
@@ -1201,28 +1203,26 @@ public:
inline uint32_t saOffsetFromSP() const noexcept { return _saOffsetFromSP; }
inline uint32_t saOffsetFromSA() const noexcept { return _saOffsetFromSA; }
- //! Returns mask of registers of the given register `group` that are modified
- //! by the function. The engine would then calculate which registers must be
- //! saved & restored by the function by using the data provided by the calling
- //! convention.
- inline uint32_t dirtyRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ //! Returns mask of registers of the given register `group` that are modified by the function. The engine would
+ //! then calculate which registers must be saved & restored by the function by using the data provided by the
+ //! calling convention.
+ inline RegMask dirtyRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _dirtyRegs[group];
}
//! Sets which registers (as a mask) are modified by the function.
//!
- //! \remarks Please note that this will completely overwrite the existing
- //! register mask, use `addDirtyRegs()` to modify the existing register
- //! mask.
- inline void setDirtyRegs(uint32_t group, uint32_t regs) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ //! \remarks Please note that this will completely overwrite the existing register mask, use `addDirtyRegs()`
+ //! to modify the existing register mask.
+ inline void setDirtyRegs(RegGroup group, RegMask regs) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_dirtyRegs[group] = regs;
}
//! Adds which registers (as a mask) are modified by the function.
- inline void addDirtyRegs(uint32_t group, uint32_t regs) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void addDirtyRegs(RegGroup group, RegMask regs) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_dirtyRegs[group] |= regs;
}
@@ -1234,7 +1234,7 @@ public:
//! \overload
template<typename... Args>
- ASMJIT_INLINE void addDirtyRegs(const BaseReg& reg, Args&&... args) noexcept {
+ inline void addDirtyRegs(const BaseReg& reg, Args&&... args) noexcept {
addDirtyRegs(reg);
addDirtyRegs(std::forward<Args>(args)...);
}
@@ -1244,37 +1244,35 @@ public:
_dirtyRegs[i] = 0xFFFFFFFFu;
}
- inline void setAllDirty(uint32_t group) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void setAllDirty(RegGroup group) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
_dirtyRegs[group] = 0xFFFFFFFFu;
}
- //! Returns a calculated mask of registers of the given `group` that will be
- //! saved and restored in the function's prolog and epilog, respectively. The
- //! register mask is calculated from both `dirtyRegs` (provided by user) and
+ //! Returns a calculated mask of registers of the given `group` that will be saved and restored in the function's
+ //! prolog and epilog, respectively. The register mask is calculated from both `dirtyRegs` (provided by user) and
//! `preservedMask` (provided by the calling convention).
- inline uint32_t savedRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline RegMask savedRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _dirtyRegs[group] & _preservedRegs[group];
}
//! Returns the mask of preserved registers of the given register `group`.
//!
- //! Preserved registers are those that must survive the function call
- //! unmodified. The function can only modify preserved registers it they
- //! are saved and restored in funciton's prolog and epilog, respectively.
- inline uint32_t preservedRegs(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ //! Preserved registers are those that must survive the function call unmodified. The function can only modify
+ //! preserved registers it they are saved and restored in funciton's prolog and epilog, respectively.
+ inline RegMask preservedRegs(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _preservedRegs[group];
}
- inline uint32_t saveRestoreRegSize(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline uint32_t saveRestoreRegSize(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _saveRestoreRegSize[group];
}
- inline uint32_t saveRestoreAlignment(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline uint32_t saveRestoreAlignment(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
return _saveRestoreAlignment[group];
}
@@ -1288,12 +1286,10 @@ public:
//! Returns an offset to the stack where registers are saved via push/pop.
inline uint32_t pushPopSaveOffset() const noexcept { return _pushPopSaveOffset; }
- //! Returns stack size required to save/restore extra registers that don't
- //! use push/pop/
+ //! Returns stack size required to save/restore extra registers that don't use push/pop/
//!
- //! \note On X86 this covers all registers except GP registers, on other
- //! architectures it can be always zero (for example AArch64 saves all
- //! registers via push/pop like instructions, so this would be zero).
+ //! \note On X86 this covers all registers except GP registers, on other architectures it can be always
+ //! zero (for example AArch64 saves all registers via push/pop like instructions, so this would be zero).
inline uint32_t extraRegSaveSize() const noexcept { return _extraRegSaveSize; }
//! Returns an offset to the stack where extra registers are saved.
inline uint32_t extraRegSaveOffset() const noexcept { return _extraRegSaveOffset; }
@@ -1302,9 +1298,8 @@ public:
inline bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
//! Returns function's stack adjustment used in function's prolog and epilog.
//!
- //! If the returned value is zero it means that the stack is not adjusted.
- //! This can mean both that the stack is not used and/or the stack is only
- //! adjusted by instructions that pust/pop registers into/from stack.
+ //! If the returned value is zero it means that the stack is not adjusted. This can mean both that the stack
+ //! is not used and/or the stack is only adjusted by instructions that pust/pop registers into/from stack.
inline uint32_t stackAdjustment() const noexcept { return _stackAdjustment; }
//! \}
@@ -1317,14 +1312,13 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::FuncArgsAssignment]
-// ============================================================================
-
-//! A helper class that can be used to assign a physical register for each
-//! function argument. Use with `BaseEmitter::emitArgsAssignment()`.
+//! A helper class that can be used to assign a physical register for each function argument. Use with
+//! `BaseEmitter::emitArgsAssignment()`.
class FuncArgsAssignment {
public:
+ //! \name Members
+ //! \{
+
//! Function detail.
const FuncDetail* _funcDetail;
//! Register that can be used to access arguments passed by stack.
@@ -1334,6 +1328,8 @@ public:
//! Mapping of each function argument.
FuncValuePack _argPacks[Globals::kMaxFuncArgs];
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -1377,41 +1373,40 @@ public:
return _argPacks[argIndex][valueIndex].isAssigned();
}
- inline void assignReg(size_t argIndex, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignReg(size_t argIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
ASMJIT_ASSERT(reg.isPhysReg());
_argPacks[argIndex][0].initReg(reg.type(), reg.id(), typeId);
}
- inline void assignReg(size_t argIndex, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignReg(size_t argIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][0].initReg(regType, regId, typeId);
}
- inline void assignStack(size_t argIndex, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignStack(size_t argIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][0].initStack(offset, typeId);
}
- inline void assignRegInPack(size_t argIndex, size_t valueIndex, const BaseReg& reg, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignRegInPack(size_t argIndex, size_t valueIndex, const BaseReg& reg, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
ASMJIT_ASSERT(reg.isPhysReg());
_argPacks[argIndex][valueIndex].initReg(reg.type(), reg.id(), typeId);
}
- inline void assignRegInPack(size_t argIndex, size_t valueIndex, uint32_t regType, uint32_t regId, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignRegInPack(size_t argIndex, size_t valueIndex, RegType regType, uint32_t regId, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][valueIndex].initReg(regType, regId, typeId);
}
- inline void assignStackInPack(size_t argIndex, size_t valueIndex, int32_t offset, uint32_t typeId = Type::kIdVoid) noexcept {
+ inline void assignStackInPack(size_t argIndex, size_t valueIndex, int32_t offset, TypeId typeId = TypeId::kVoid) noexcept {
ASMJIT_ASSERT(argIndex < ASMJIT_ARRAY_SIZE(_argPacks));
_argPacks[argIndex][valueIndex].initStack(offset, typeId);
}
- // NOTE: All `assignAll()` methods are shortcuts to assign all arguments at
- // once, however, since registers are passed all at once these initializers
- // don't provide any way to pass TypeId and/or to keep any argument between
+ // NOTE: All `assignAll()` methods are shortcuts to assign all arguments at once, however, since registers are
+ // passed all at once these initializers don't provide any way to pass TypeId and/or to keep any argument between
// the arguments passed unassigned.
inline void _assignAllInternal(size_t argIndex, const BaseReg& reg) noexcept {
assignReg(argIndex, reg);
@@ -1435,9 +1430,8 @@ public:
//! Update `FuncFrame` based on function's arguments assignment.
//!
- //! \note You MUST call this in orher to use `BaseEmitter::emitArgsAssignment()`,
- //! otherwise the FuncFrame would not contain the information necessary to
- //! assign all arguments into the registers and/or stack specified.
+ //! \note You MUST call this in orher to use `BaseEmitter::emitArgsAssignment()`, otherwise the FuncFrame would
+ //! not contain the information necessary to assign all arguments into the registers and/or stack specified.
ASMJIT_API Error updateFuncFrame(FuncFrame& frame) const noexcept;
//! \}
diff --git a/src/asmjit/core/funcargscontext.cpp b/src/asmjit/core/funcargscontext.cpp
index 331e205..8ce806f 100644
--- a/src/asmjit/core/funcargscontext.cpp
+++ b/src/asmjit/core/funcargscontext.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/funcargscontext_p.h"
@@ -31,29 +13,24 @@ ASMJIT_BEGIN_NAMESPACE
//! \{
FuncArgsContext::FuncArgsContext() noexcept {
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- _workData[group].reset();
+ for (RegGroup group : RegGroupVirtValues{})
+ _workData[size_t(group)].reset();
}
ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept {
- // The code has to be updated if this changes.
- ASMJIT_ASSERT(BaseReg::kGroupVirt == 4);
-
- uint32_t i;
-
- uint32_t arch = frame.arch();
+ Arch arch = frame.arch();
const FuncDetail& func = *args.funcDetail();
_archTraits = &ArchTraits::byArch(arch);
_constraints = constraints;
- _arch = uint8_t(arch);
+ _arch = arch;
// Initialize `_archRegs`.
- for (i = 0; i < BaseReg::kGroupVirt; i++)
- _workData[i]._archRegs = _constraints->availableRegs(i);
+ for (RegGroup group : RegGroupVirtValues{})
+ _workData[group]._archRegs = _constraints->availableRegs(group);
if (frame.hasPreservedFP())
- _workData[BaseReg::kGroupGp]._archRegs &= ~Support::bitMask(archTraits().fpRegId());
+ _workData[size_t(RegGroup::kGp)]._archRegs &= ~Support::bitMask(archTraits().fpRegId());
// Extract information from all function arguments/assignments and build Var[] array.
uint32_t varId = 0;
@@ -73,7 +50,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
FuncValue& src = var.cur;
FuncValue& dst = var.out;
- uint32_t dstGroup = 0xFFFFFFFFu;
+ RegGroup dstGroup = RegGroup::kMaxValue;
uint32_t dstId = BaseReg::kIdBad;
WorkData* dstWd = nullptr;
@@ -82,18 +59,17 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
return DebugUtils::errored(kErrorInvalidAssignment);
if (dst.isReg()) {
- uint32_t dstType = dst.regType();
+ RegType dstType = dst.regType();
if (ASMJIT_UNLIKELY(!archTraits().hasRegType(dstType)))
return DebugUtils::errored(kErrorInvalidRegType);
- // Copy TypeId from source if the destination doesn't have it. The RA
- // used by BaseCompiler would never leave TypeId undefined, but users
- // of FuncAPI can just assign phys regs without specifying the type.
+ // Copy TypeId from source if the destination doesn't have it. The RA used by BaseCompiler would never
+ // leave TypeId undefined, but users of FuncAPI can just assign phys regs without specifying the type.
if (!dst.hasTypeId())
dst.setTypeId(archTraits().regTypeToTypeId(dst.regType()));
dstGroup = archTraits().regTypeToGroup(dstType);
- if (ASMJIT_UNLIKELY(dstGroup >= BaseReg::kGroupVirt))
+ if (ASMJIT_UNLIKELY(dstGroup > RegGroup::kMaxVirt))
return DebugUtils::errored(kErrorInvalidRegGroup);
dstWd = &_workData[dstGroup];
@@ -112,15 +88,15 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
if (!dst.hasTypeId())
dst.setTypeId(src.typeId());
- RegInfo regInfo = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId());
- if (ASMJIT_UNLIKELY(!regInfo.isValid()))
+ OperandSignature signature = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId());
+ if (ASMJIT_UNLIKELY(!signature.isValid()))
return DebugUtils::errored(kErrorInvalidState);
- _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(regInfo.group()));
+ _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(signature.regGroup()));
}
if (src.isReg()) {
uint32_t srcId = src.regId();
- uint32_t srcGroup = archTraits().regTypeToGroup(src.regType());
+ RegGroup srcGroup = archTraits().regTypeToGroup(src.regType());
if (dstGroup == srcGroup) {
dstWd->assign(varId, srcId);
@@ -130,10 +106,10 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
var.markDone();
}
else {
- if (ASMJIT_UNLIKELY(srcGroup >= BaseReg::kGroupVirt))
+ if (ASMJIT_UNLIKELY(srcGroup > RegGroup::kMaxVirt))
return DebugUtils::errored(kErrorInvalidState);
- WorkData& srcData = _workData[srcGroup];
+ WorkData& srcData = _workData[size_t(srcGroup)];
srcData.assign(varId, srcId);
}
}
@@ -148,14 +124,15 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
}
// Initialize WorkData::workRegs.
- for (i = 0; i < BaseReg::kGroupVirt; i++) {
- _workData[i]._workRegs = (_workData[i].archRegs() & (frame.dirtyRegs(i) | ~frame.preservedRegs(i))) | _workData[i].dstRegs() | _workData[i].assignedRegs();
+ for (RegGroup group : RegGroupVirtValues{}) {
+ _workData[group]._workRegs =
+ (_workData[group].archRegs() & (frame.dirtyRegs(group) | ~frame.preservedRegs(group))) | _workData[group].dstRegs() | _workData[group].assignedRegs();
}
// Create a variable that represents `SARegId` if necessary.
bool saRegRequired = _hasStackSrc && frame.hasDynamicAlignment() && !frame.hasPreservedFP();
- WorkData& gpRegs = _workData[BaseReg::kGroupGp];
+ WorkData& gpRegs = _workData[RegGroup::kGp];
uint32_t saCurRegId = frame.saRegId();
uint32_t saOutRegId = args.saRegId();
@@ -173,8 +150,8 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
}
if (saRegRequired) {
- uint32_t ptrTypeId = Environment::is32Bit(arch) ? Type::kIdU32 : Type::kIdU64;
- uint32_t ptrRegType = Environment::is32Bit(arch) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
+ TypeId ptrTypeId = Environment::is32Bit(arch) ? TypeId::kUInt32 : TypeId::kUInt64;
+ RegType ptrRegType = Environment::is32Bit(arch) ? RegType::kGp32 : RegType::kGp64;
_saVarId = uint8_t(varId);
_hasPreservedFP = frame.hasPreservedFP();
@@ -187,7 +164,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
saCurRegId = saOutRegId;
}
else {
- uint32_t availableRegs = gpRegs.availableRegs();
+ RegMask availableRegs = gpRegs.availableRegs();
if (!availableRegs)
availableRegs = gpRegs.archRegs() & ~gpRegs.workRegs();
@@ -223,7 +200,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
uint32_t srcId = var.cur.regId();
uint32_t dstId = var.out.regId();
- uint32_t group = archTraits().regTypeToGroup(var.cur.regType());
+ RegGroup group = archTraits().regTypeToGroup(var.cur.regType());
if (group != archTraits().regTypeToGroup(var.out.regType()))
continue;
@@ -242,12 +219,12 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, co
}
ASMJIT_FAVOR_SIZE Error FuncArgsContext::markDstRegsDirty(FuncFrame& frame) noexcept {
- for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++) {
- WorkData& wd = _workData[i];
+ for (RegGroup group : RegGroupVirtValues{}) {
+ WorkData& wd = _workData[group];
uint32_t regs = wd.usedRegs() | wd._dstShuf;
wd._workRegs |= regs;
- frame.addDirtyRegs(i, regs);
+ frame.addDirtyRegs(group, regs);
}
return kErrorOk;
@@ -260,19 +237,19 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexc
groupMask |= _stackDstMask;
// Handle register swaps.
- groupMask |= _regSwapsMask & ~Support::bitMask(BaseReg::kGroupGp);
+ groupMask |= _regSwapsMask & ~Support::bitMask(RegGroup::kGp);
if (!groupMask)
return kErrorOk;
// Selects one dirty register per affected group that can be used as a scratch register.
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
if (Support::bitTest(groupMask, group)) {
WorkData& wd = _workData[group];
// Initially, pick some clobbered or dirty register.
- uint32_t workRegs = wd.workRegs();
- uint32_t regs = workRegs & ~(wd.usedRegs() | wd._dstShuf);
+ RegMask workRegs = wd.workRegs();
+ RegMask regs = workRegs & ~(wd.usedRegs() | wd._dstShuf);
// If that didn't work out pick some register which is not in 'used'.
if (!regs)
@@ -288,7 +265,7 @@ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexc
if (!regs)
continue;
- uint32_t regMask = Support::blsi(regs);
+ RegMask regMask = Support::blsi(regs);
wd._workRegs |= regMask;
frame.addDirtyRegs(group, regMask);
}
diff --git a/src/asmjit/core/funcargscontext_p.h b/src/asmjit/core/funcargscontext_p.h
index 6c4ea6a..1c928eb 100644
--- a/src/asmjit/core/funcargscontext_p.h
+++ b/src/asmjit/core/funcargscontext_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
#define ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
@@ -37,38 +19,30 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [TODO: Place somewhere else]
-// ============================================================================
-
-static inline RegInfo getSuitableRegForMemToMemMove(uint32_t arch, uint32_t dstTypeId, uint32_t srcTypeId) noexcept {
+static inline OperandSignature getSuitableRegForMemToMemMove(Arch arch, TypeId dstTypeId, TypeId srcTypeId) noexcept {
const ArchTraits& archTraits = ArchTraits::byArch(arch);
- uint32_t dstSize = Type::sizeOf(dstTypeId);
- uint32_t srcSize = Type::sizeOf(srcTypeId);
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
uint32_t maxSize = Support::max<uint32_t>(dstSize, srcSize);
uint32_t regSize = Environment::registerSizeFromArch(arch);
- uint32_t signature = 0;
- if (maxSize <= regSize || (Type::isInt(dstTypeId) && Type::isInt(srcTypeId)))
- signature = maxSize <= 4 ? archTraits.regTypeToSignature(BaseReg::kTypeGp32)
- : archTraits.regTypeToSignature(BaseReg::kTypeGp64);
- else if (maxSize <= 8 && archTraits.hasRegType(BaseReg::kTypeVec64))
- signature = archTraits.regTypeToSignature(BaseReg::kTypeVec64);
- else if (maxSize <= 16 && archTraits.hasRegType(BaseReg::kTypeVec128))
- signature = archTraits.regTypeToSignature(BaseReg::kTypeVec128);
- else if (maxSize <= 32 && archTraits.hasRegType(BaseReg::kTypeVec256))
- signature = archTraits.regTypeToSignature(BaseReg::kTypeVec256);
- else if (maxSize <= 64 && archTraits.hasRegType(BaseReg::kTypeVec512))
- signature = archTraits.regTypeToSignature(BaseReg::kTypeVec512);
-
- return RegInfo { signature };
+ OperandSignature signature(0);
+ if (maxSize <= regSize || (TypeUtils::isInt(dstTypeId) && TypeUtils::isInt(srcTypeId)))
+ signature = maxSize <= 4 ? archTraits.regTypeToSignature(RegType::kGp32)
+ : archTraits.regTypeToSignature(RegType::kGp64);
+ else if (maxSize <= 8 && archTraits.hasRegType(RegType::kVec64))
+ signature = archTraits.regTypeToSignature(RegType::kVec64);
+ else if (maxSize <= 16 && archTraits.hasRegType(RegType::kVec128))
+ signature = archTraits.regTypeToSignature(RegType::kVec128);
+ else if (maxSize <= 32 && archTraits.hasRegType(RegType::kVec256))
+ signature = archTraits.regTypeToSignature(RegType::kVec256);
+ else if (maxSize <= 64 && archTraits.hasRegType(RegType::kVec512))
+ signature = archTraits.regTypeToSignature(RegType::kVec512);
+
+ return signature;
}
-// ============================================================================
-// [asmjit::FuncArgsContext]
-// ============================================================================
-
class FuncArgsContext {
public:
enum VarId : uint32_t {
@@ -97,17 +71,17 @@ public:
struct WorkData {
//! All allocable registers provided by the architecture.
- uint32_t _archRegs;
+ RegMask _archRegs;
//! All registers that can be used by the shuffler.
- uint32_t _workRegs;
+ RegMask _workRegs;
//! Registers used by the shuffler (all).
- uint32_t _usedRegs;
+ RegMask _usedRegs;
//! Assigned registers.
- uint32_t _assignedRegs;
+ RegMask _assignedRegs;
//! Destination registers assigned to arguments or SA.
- uint32_t _dstRegs;
+ RegMask _dstRegs;
//! Destination registers that require shuffling.
- uint32_t _dstShuf;
+ RegMask _dstShuf;
//! Number of register swaps.
uint8_t _numSwaps;
//! Number of stack loads.
@@ -173,19 +147,20 @@ public:
_assignedRegs ^= Support::bitMask(regId);
}
- inline uint32_t archRegs() const noexcept { return _archRegs; }
- inline uint32_t workRegs() const noexcept { return _workRegs; }
- inline uint32_t usedRegs() const noexcept { return _usedRegs; }
- inline uint32_t assignedRegs() const noexcept { return _assignedRegs; }
- inline uint32_t dstRegs() const noexcept { return _dstRegs; }
- inline uint32_t availableRegs() const noexcept { return _workRegs & ~_assignedRegs; }
+ inline RegMask archRegs() const noexcept { return _archRegs; }
+ inline RegMask workRegs() const noexcept { return _workRegs; }
+ inline RegMask usedRegs() const noexcept { return _usedRegs; }
+ inline RegMask assignedRegs() const noexcept { return _assignedRegs; }
+ inline RegMask dstRegs() const noexcept { return _dstRegs; }
+ inline RegMask availableRegs() const noexcept { return _workRegs & ~_assignedRegs; }
};
//! Architecture traits.
const ArchTraits* _archTraits = nullptr;
+ //! Architecture constraints.
const RAConstraints* _constraints = nullptr;
- //! Architecture identifier.
- uint8_t _arch = 0;
+ //! Target architecture.
+ Arch _arch = Arch::kUnknown;
//! Has arguments passed via stack (SRC).
bool _hasStackSrc = false;
//! Has preserved frame-pointer (FP).
@@ -196,13 +171,13 @@ public:
uint8_t _regSwapsMask = 0;
uint8_t _saVarId = kVarIdNone;
uint32_t _varCount = 0;
- WorkData _workData[BaseReg::kGroupVirt];
+ Support::Array<WorkData, Globals::kNumVirtGroups> _workData;
Var _vars[Globals::kMaxFuncArgs * Globals::kMaxValuePack + 1];
FuncArgsContext() noexcept;
inline const ArchTraits& archTraits() const noexcept { return *_archTraits; }
- inline uint32_t arch() const noexcept { return _arch; }
+ inline Arch arch() const noexcept { return _arch; }
inline uint32_t varCount() const noexcept { return _varCount; }
inline size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); }
diff --git a/src/asmjit/core/globals.cpp b/src/asmjit/core/globals.cpp
index dc5083b..2bbd0c0 100644
--- a/src/asmjit/core/globals.cpp
+++ b/src/asmjit/core/globals.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/globals.h"
@@ -27,9 +9,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::DebugUtils]
-// ============================================================================
+// DebugUtils - Error As String
+// ============================
ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
#ifndef ASMJIT_NO_TEXT
@@ -54,7 +35,6 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
"LabelNameTooLong\0"
"InvalidLabelName\0"
"InvalidParentLabel\0"
- "NonLocalLabelCannotHaveParent\0"
"InvalidSection\0"
"TooManySections\0"
"InvalidSectionName\0"
@@ -97,6 +77,7 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
"InvalidUseOfGpq\0"
"InvalidUseOfF80\0"
"NotConsecutiveRegs\0"
+ "ConsecutiveRegsAllocation\0"
"IllegalVirtReg\0"
"TooManyVirtRegs\0"
"NoMorePhysRegs\0"
@@ -109,10 +90,10 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
static const uint16_t sErrorIndex[] = {
0, 3, 15, 31, 44, 56, 71, 90, 108, 123, 132, 148, 165, 178, 192, 210, 230,
- 247, 264, 283, 313, 328, 344, 363, 382, 400, 422, 440, 459, 474, 490, 504,
- 518, 538, 563, 581, 603, 625, 642, 659, 675, 691, 707, 724, 739, 754, 774,
- 794, 814, 847, 867, 882, 899, 918, 939, 959, 973, 994, 1008, 1026, 1042,
- 1058, 1077, 1092, 1108, 1123, 1138, 1168, 1192, 1211, 1239
+ 247, 264, 283, 298, 314, 333, 352, 370, 392, 410, 429, 444, 460, 474, 488,
+ 508, 533, 551, 573, 595, 612, 629, 645, 661, 677, 694, 709, 724, 744, 764,
+ 784, 817, 837, 852, 869, 888, 909, 929, 943, 964, 978, 996, 1012, 1028, 1047,
+ 1073, 1088, 1104, 1119, 1134, 1164, 1188, 1207, 1235
};
// @EnumStringEnd@
@@ -124,6 +105,9 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
#endif
}
+// DebugUtils - Debug Output
+// =========================
+
ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept {
#if defined(_WIN32)
::OutputDebugStringA(str);
@@ -132,6 +116,9 @@ ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept {
#endif
}
+// DebugUtils - Fatal Errors
+// =========================
+
ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept {
char str[1024];
diff --git a/src/asmjit/core/globals.h b/src/asmjit/core/globals.h
index 3b7bfc9..f2d3c6e 100644
--- a/src/asmjit/core/globals.h
+++ b/src/asmjit/core/globals.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_GLOBALS_H_INCLUDED
#define ASMJIT_CORE_GLOBALS_H_INCLUDED
@@ -28,10 +10,6 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Support]
-// ============================================================================
-
//! \cond INTERNAL
//! \addtogroup asmjit_utilities
//! \{
@@ -43,21 +21,21 @@ namespace Support {
#if defined(ASMJIT_NO_STDCXX)
namespace Support {
- ASMJIT_INLINE void* operatorNew(size_t n) noexcept { return malloc(n); }
- ASMJIT_INLINE void operatorDelete(void* p) noexcept { if (p) free(p); }
+ ASMJIT_FORCE_INLINE void* operatorNew(size_t n) noexcept { return malloc(n); }
+ ASMJIT_FORCE_INLINE void operatorDelete(void* p) noexcept { if (p) free(p); }
} // {Support}
-#define ASMJIT_BASE_CLASS(TYPE) \
- ASMJIT_INLINE void* operator new(size_t n) noexcept { \
- return Support::operatorNew(n); \
- } \
- \
- ASMJIT_INLINE void operator delete(void* p) noexcept { \
- Support::operatorDelete(p); \
- } \
- \
- ASMJIT_INLINE void* operator new(size_t, void* p) noexcept { return p; } \
- ASMJIT_INLINE void operator delete(void*, void*) noexcept {}
+#define ASMJIT_BASE_CLASS(TYPE) \
+ ASMJIT_FORCE_INLINE void* operator new(size_t n) noexcept { \
+ return Support::operatorNew(n); \
+ } \
+ \
+ ASMJIT_FORCE_INLINE void operator delete(void* p) noexcept { \
+ Support::operatorDelete(p); \
+ } \
+ \
+ ASMJIT_FORCE_INLINE void* operator new(size_t, void* p) noexcept { return p; } \
+ ASMJIT_FORCE_INLINE void operator delete(void*, void*) noexcept {}
#else
#define ASMJIT_BASE_CLASS(TYPE)
#endif
@@ -65,20 +43,32 @@ namespace Support {
//! \}
//! \endcond
-// ============================================================================
-// [asmjit::Globals]
-// ============================================================================
-
//! \addtogroup asmjit_core
//! \{
+//! Byte order.
+enum class ByteOrder {
+ //! Little endian.
+ kLE = 0,
+ //! Big endian.
+ kBE = 1,
+ //! Native byte order of the target architecture.
+ kNative = ASMJIT_ARCH_LE ? kLE : kBE,
+ //! Swapped byte order of the target architecture.
+ kSwapped = ASMJIT_ARCH_LE ? kBE : kLE
+};
+
+//! A policy that can be used with some `reset()` member functions.
+enum class ResetPolicy : uint32_t {
+ //! Soft reset, doesn't deallocate memory (default).
+ kSoft = 0,
+ //! Hard reset, releases all memory used, if any.
+ kHard = 1
+};
+
//! Contains typedefs, constants, and variables used globally by AsmJit.
namespace Globals {
-// ============================================================================
-// [asmjit::Globals::<global>]
-// ============================================================================
-
//! Host memory allocator overhead.
static constexpr uint32_t kAllocOverhead = uint32_t(sizeof(intptr_t) * 4);
@@ -92,13 +82,11 @@ static constexpr uint32_t kGrowThreshold = 1024 * 1024 * 16;
//!
//! `2 * log2(n + 1)`
//!
-//! Size of RB node is at least two pointers (without data),
-//! so a theoretical architecture limit would be:
+//! Size of RB node is at least two pointers (without data), so a theoretical architecture limit would be:
//!
//! `2 * log2(addressableMemorySize / sizeof(Node) + 1)`
//!
-//! Which yields 30 on 32-bit arch and 61 on 64-bit arch.
-//! The final value was adjusted by +1 for safety reasons.
+//! Which yields 30 on 32-bit arch and 61 on 64-bit arch. The final value was adjusted by +1 for safety reasons.
static constexpr uint32_t kMaxTreeHeight = (ASMJIT_ARCH_BITS == 32 ? 30 : 61) + 1;
//! Maximum number of operands per a single instruction.
@@ -135,34 +123,8 @@ static constexpr uint32_t kNotFound = 0xFFFFFFFFu;
//! Invalid base address.
static constexpr uint64_t kNoBaseAddress = ~uint64_t(0);
-// ============================================================================
-// [asmjit::Globals::ResetPolicy]
-// ============================================================================
-
-//! Reset policy used by most `reset()` functions.
-enum ResetPolicy : uint32_t {
- //! Soft reset, doesn't deallocate memory (default).
- kResetSoft = 0,
- //! Hard reset, releases all memory used, if any.
- kResetHard = 1
-};
-
-// ============================================================================
-// [asmjit::Globals::Link]
-// ============================================================================
-
-enum Link : uint32_t {
- kLinkLeft = 0,
- kLinkRight = 1,
-
- kLinkPrev = 0,
- kLinkNext = 1,
-
- kLinkFirst = 0,
- kLinkLast = 1,
-
- kLinkCount = 2
-};
+//! Number of virtual register groups.
+static constexpr uint32_t kNumVirtGroups = 4;
struct Init_ {};
struct NoInit_ {};
@@ -172,24 +134,6 @@ static const constexpr NoInit_ NoInit {};
} // {Globals}
-// ============================================================================
-// [asmjit::ByteOrder]
-// ============================================================================
-
-//! Byte order.
-namespace ByteOrder {
- enum : uint32_t {
- kLE = 0,
- kBE = 1,
- kNative = ASMJIT_ARCH_LE ? kLE : kBE,
- kSwapped = ASMJIT_ARCH_LE ? kBE : kLE
- };
-}
-
-// ============================================================================
-// [asmjit::ptr_as_func / func_as_ptr]
-// ============================================================================
-
template<typename Func>
static inline Func ptr_as_func(void* func) noexcept { return Support::ptr_cast_impl<Func, void*>(func); }
@@ -198,10 +142,6 @@ static inline void* func_as_ptr(Func func) noexcept { return Support::ptr_cast_i
//! \}
-// ============================================================================
-// [asmjit::Error]
-// ============================================================================
-
//! \addtogroup asmjit_error_handling
//! \{
@@ -223,9 +163,8 @@ enum ErrorCode : uint32_t {
//! Invalid state.
//!
- //! If this error is returned it means that either you are doing something
- //! wrong or AsmJit caught itself by doing something wrong. This error should
- //! never be ignored.
+ //! If this error is returned it means that either you are doing something wrong or AsmJit caught itself by
+ //! doing something wrong. This error should never be ignored.
kErrorInvalidState,
//! Invalid or incompatible architecture.
@@ -253,9 +192,8 @@ enum ErrorCode : uint32_t {
kErrorInvalidDirective,
//! Attempt to use uninitialized label.
kErrorInvalidLabel,
- //! Label index overflow - a single \ref BaseAssembler instance can hold
- //! almost 2^32 (4 billion) labels. If there is an attempt to create more
- //! labels then this error is returned.
+ //! Label index overflow - a single \ref BaseAssembler instance can hold almost 2^32 (4 billion) labels. If
+ //! there is an attempt to create more labels then this error is returned.
kErrorTooManyLabels,
//! Label is already bound.
kErrorLabelAlreadyBound,
@@ -265,10 +203,9 @@ enum ErrorCode : uint32_t {
kErrorLabelNameTooLong,
//! Label must always be local if it's anonymous (without a name).
kErrorInvalidLabelName,
- //! Parent id passed to \ref CodeHolder::newNamedLabelEntry() was invalid.
+ //! Parent id passed to \ref CodeHolder::newNamedLabelEntry() was either invalid or parent is not supported
+ //! by the requested `LabelType`.
kErrorInvalidParentLabel,
- //! Parent id specified for a non-local (global) label.
- kErrorNonLocalLabelCannotHaveParent,
//! Invalid section.
kErrorInvalidSection,
@@ -356,11 +293,12 @@ enum ErrorCode : uint32_t {
kErrorInvalidUseOfGpbHi,
//! Invalid use of a 64-bit GPQ register in 32-bit mode.
kErrorInvalidUseOfGpq,
- //! Invalid use of an 80-bit float (\ref Type::kIdF80).
+ //! Invalid use of an 80-bit float (\ref TypeId::kFloat80).
kErrorInvalidUseOfF80,
- //! Some registers in the instruction muse be consecutive (some ARM and AVX512
- //! neural-net instructions).
+ //! Instruction requires the use of consecutive registers, but registers in operands weren't (AVX512, ASIMD load/store, etc...).
kErrorNotConsecutiveRegs,
+ //! Failed to allocate consecutive registers - allocable registers either too restricted or a bug in RW info.
+ kErrorConsecutiveRegsAllocation,
//! Illegal virtual register - reported by instruction validation.
kErrorIllegalVirtReg,
@@ -388,23 +326,19 @@ enum ErrorCode : uint32_t {
kErrorCount
};
-// ============================================================================
-// [asmjit::DebugUtils]
-// ============================================================================
-
//! Debugging utilities.
namespace DebugUtils {
//! \cond INTERNAL
//! Used to silence warnings about unused arguments or variables.
template<typename... Args>
-static ASMJIT_INLINE void unused(Args&&...) noexcept {}
+static inline void unused(Args&&...) noexcept {}
//! \endcond
//! Returns the error `err` passed.
//!
-//! Provided for debugging purposes. Putting a breakpoint inside `errored` can
-//! help with tracing the origin of any error reported / returned by AsmJit.
+//! Provided for debugging purposes. Putting a breakpoint inside `errored` can help with tracing the origin of any
+//! error reported / returned by AsmJit.
static constexpr Error errored(Error err) noexcept { return err; }
//! Returns a printable version of `asmjit::Error` code.
@@ -419,12 +353,10 @@ ASMJIT_API void debugOutput(const char* str) noexcept;
//! \param line Line in the source file.
//! \param msg Message to display.
//!
-//! If you have problems with assertion failures a breakpoint can be put
-//! at \ref assertionFailed() function (asmjit/core/globals.cpp). A call stack
-//! will be available when such assertion failure is triggered. AsmJit always
-//! returns errors on failures, assertions are a last resort and usually mean
-//! unrecoverable state due to out of range array access or totally invalid
-//! arguments like nullptr where a valid pointer should be provided, etc...
+//! If you have problems with assertion failures a breakpoint can be put at \ref assertionFailed() function
+//! (asmjit/core/globals.cpp). A call stack will be available when such assertion failure is triggered. AsmJit
+//! always returns errors on failures, assertions are a last resort and usually mean unrecoverable state due to out
+//! of range array access or totally invalid arguments like nullptr where a valid pointer should be provided, etc...
ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, const char* msg) noexcept;
} // {DebugUtils}
@@ -445,9 +377,8 @@ ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, cons
//! \def ASMJIT_PROPAGATE(...)
//!
-//! Propagates a possible `Error` produced by `...` to the caller by returning
-//! the error immediately. Used by AsmJit internally, but kept public for users
-//! that want to use the same technique to propagate errors to the caller.
+//! Propagates a possible `Error` produced by `...` to the caller by returning the error immediately. Used by AsmJit
+//! internally, but kept public for users that want to use the same technique to propagate errors to the caller.
#define ASMJIT_PROPAGATE(...) \
do { \
::asmjit::Error _err = __VA_ARGS__; \
diff --git a/src/asmjit/core/inst.cpp b/src/asmjit/core/inst.cpp
index b949a60..26f1df9 100644
--- a/src/asmjit/core/inst.cpp
+++ b/src/asmjit/core/inst.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/archtraits.h"
@@ -35,12 +17,11 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::InstAPI - Text]
-// ============================================================================
+// InstAPI - InstId <-> String
+// ===========================
#ifndef ASMJIT_NO_TEXT
-Error InstAPI::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept {
+Error InstAPI::instIdToString(Arch arch, InstId instId, String& output) noexcept {
#if !defined(ASMJIT_NO_X86)
if (Environment::isFamilyX86(arch))
return x86::InstInternal::instIdToString(arch, instId, output);
@@ -54,7 +35,7 @@ Error InstAPI::instIdToString(uint32_t arch, uint32_t instId, String& output) no
return DebugUtils::errored(kErrorInvalidArch);
}
-uint32_t InstAPI::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept {
+InstId InstAPI::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
#if !defined(ASMJIT_NO_X86)
if (Environment::isFamilyX86(arch))
return x86::InstInternal::stringToInstId(arch, s, len);
@@ -69,12 +50,11 @@ uint32_t InstAPI::stringToInstId(uint32_t arch, const char* s, size_t len) noexc
}
#endif // !ASMJIT_NO_TEXT
-// ============================================================================
-// [asmjit::InstAPI - Validate]
-// ============================================================================
+// InstAPI - Validate
+// ==================
#ifndef ASMJIT_NO_VALIDATION
-Error InstAPI::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept {
+Error InstAPI::validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
#if !defined(ASMJIT_NO_X86)
if (Environment::isFamilyX86(arch))
return x86::InstInternal::validate(arch, inst, operands, opCount, validationFlags);
@@ -89,12 +69,11 @@ Error InstAPI::validate(uint32_t arch, const BaseInst& inst, const Operand_* ope
}
#endif // !ASMJIT_NO_VALIDATION
-// ============================================================================
-// [asmjit::InstAPI - QueryRWInfo]
-// ============================================================================
+// InstAPI - QueryRWInfo
+// =====================
#ifndef ASMJIT_NO_INTROSPECTION
-Error InstAPI::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
+Error InstAPI::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
if (ASMJIT_UNLIKELY(opCount > Globals::kMaxOpCount))
return DebugUtils::errored(kErrorInvalidArgument);
@@ -112,12 +91,11 @@ Error InstAPI::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_*
}
#endif // !ASMJIT_NO_INTROSPECTION
-// ============================================================================
-// [asmjit::InstAPI - QueryFeatures]
-// ============================================================================
+// InstAPI - QueryFeatures
+// =======================
#ifndef ASMJIT_NO_INTROSPECTION
-Error InstAPI::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept {
+Error InstAPI::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
#if !defined(ASMJIT_NO_X86)
if (Environment::isFamilyX86(arch))
return x86::InstInternal::queryFeatures(arch, inst, operands, opCount, out);
diff --git a/src/asmjit/core/inst.h b/src/asmjit/core/inst.h
index e803647..0b890d8 100644
--- a/src/asmjit/core/inst.h
+++ b/src/asmjit/core/inst.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_INST_H_INCLUDED
#define ASMJIT_CORE_INST_H_INCLUDED
@@ -34,20 +16,179 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_instruction_db
//! \{
-// ============================================================================
-// [asmjit::BaseInst]
-// ============================================================================
+//! Describes an instruction.
+//!
+//! Each architecture has a set of valid instructions indexed from 0. Instruction with 0 id is, however, a special
+//! instruction that describes an invalid instruction. Different architectures can share the same instruction id,
+//! which would describe a different instruction per architecture.
+//!
+//! Instruction identifiers listed by architecture:
+//!
+//! - \ref x86::Inst (X86 and X86_64)
+typedef uint32_t InstId;
+
+//! Instruction options.
+//!
+//! Instruction options complement instruction identifier and attributes.
+enum class InstOptions : uint32_t {
+ //! No options.
+ kNone = 0,
+
+ //! Used internally by emitters for handling errors and rare cases.
+ kReserved = 0x00000001u,
+
+ //! Prevents following a jump during compilation (Compiler).
+ kUnfollow = 0x00000002u,
+
+ //! Overwrite the destination operand(s) (Compiler).
+ //!
+ //! Hint that is important for register liveness analysis. It tells the compiler that the destination operand will
+ //! be overwritten now or by adjacent instructions. Compiler knows when a register is completely overwritten by a
+ //! single instruction, for example you don't have to mark "movaps" or "pxor x, x", however, if a pair of
+ //! instructions is used and the first of them doesn't completely overwrite the content of the destination,
+ //! Compiler fails to mark that register as dead.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! - All instructions that always overwrite at least the size of the register the virtual-register uses, for
+ //! example "mov", "movq", "movaps" don't need the overwrite option to be used - conversion, shuffle, and
+ //! other miscellaneous instructions included.
+ //!
+ //! - All instructions that clear the destination register if all operands are the same, for example "xor x, x",
+ //! "pcmpeqb x x", etc...
+ //!
+ //! - Consecutive instructions that partially overwrite the variable until there is no old content require
+ //! `BaseCompiler::overwrite()` to be used. Some examples (not always the best use cases thought):
+ //!
+ //! - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
+ //! - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
+ //! - `mov al, ?` followed by `and ax, 0xFF`
+ //! - `mov al, ?` followed by `mov ah, al`
+ //! - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
+ //!
+ //! - If the allocated virtual register is used temporarily for scalar operations. For example if you allocate a
+ //! full vector like `x86::Compiler::newXmm()` and then use that vector for scalar operations you should use
+ //! `overwrite()` directive:
+ //!
+ //! - `sqrtss x, y` - only LO element of `x` is changed, if you don't
+ //! use HI elements, use `compiler.overwrite().sqrtss(x, y)`.
+ kOverwrite = 0x00000004u,
+
+ //! Emit short-form of the instruction.
+ kShortForm = 0x00000010u,
+ //! Emit long-form of the instruction.
+ kLongForm = 0x00000020u,
+
+ //! Conditional jump is likely to be taken.
+ kTaken = 0x00000040u,
+ //! Conditional jump is unlikely to be taken.
+ kNotTaken = 0x00000080u,
+
+ // X86 & X64 Options
+ // -----------------
+
+ //! Use ModMR instead of ModRM if applicable.
+ kX86_ModMR = 0x00000100u,
+ //! Use ModRM instead of ModMR if applicable.
+ kX86_ModRM = 0x00000200u,
+ //! Use 3-byte VEX prefix if possible (AVX) (must be 0x00000400).
+ kX86_Vex3 = 0x00000400u,
+ //! Use VEX prefix when both VEX|EVEX prefixes are available (HINT: AVX_VNNI).
+ kX86_Vex = 0x00000800u,
+ //! Use 4-byte EVEX prefix if possible (AVX-512) (must be 0x00001000).
+ kX86_Evex = 0x00001000u,
+
+ //! LOCK prefix (lock-enabled instructions only).
+ kX86_Lock = 0x00002000u,
+ //! REP prefix (string instructions only).
+ kX86_Rep = 0x00004000u,
+ //! REPNE prefix (string instructions only).
+ kX86_Repne = 0x00008000u,
+
+ //! XACQUIRE prefix (only allowed instructions).
+ kX86_XAcquire = 0x00010000u,
+ //! XRELEASE prefix (only allowed instructions).
+ kX86_XRelease = 0x00020000u,
+
+ //! AVX-512: embedded-rounding {er} and implicit {sae}.
+ kX86_ER = 0x00040000u,
+ //! AVX-512: suppress-all-exceptions {sae}.
+ kX86_SAE = 0x00080000u,
+ //! AVX-512: round-to-nearest (even) {rn-sae} (bits 00).
+ kX86_RN_SAE = 0x00000000u,
+ //! AVX-512: round-down (toward -inf) {rd-sae} (bits 01).
+ kX86_RD_SAE = 0x00200000u,
+ //! AVX-512: round-up (toward +inf) {ru-sae} (bits 10).
+ kX86_RU_SAE = 0x00400000u,
+ //! AVX-512: round-toward-zero (truncate) {rz-sae} (bits 11).
+ kX86_RZ_SAE = 0x00600000u,
+ //! AVX-512: Use zeroing {k}{z} instead of merging {k}.
+ kX86_ZMask = 0x00800000u,
+
+ //! AVX-512: Mask to get embedded rounding bits (2 bits).
+ kX86_ERMask = kX86_RZ_SAE,
+ //! AVX-512: Mask of all possible AVX-512 options except EVEX prefix flag.
+ kX86_AVX512Mask = 0x00FC0000u,
+
+ //! Force REX.B and/or VEX.B field (X64 only).
+ kX86_OpCodeB = 0x01000000u,
+ //! Force REX.X and/or VEX.X field (X64 only).
+ kX86_OpCodeX = 0x02000000u,
+ //! Force REX.R and/or VEX.R field (X64 only).
+ kX86_OpCodeR = 0x04000000u,
+ //! Force REX.W and/or VEX.W field (X64 only).
+ kX86_OpCodeW = 0x08000000u,
+ //! Force REX prefix (X64 only).
+ kX86_Rex = 0x40000000u,
+ //! Invalid REX prefix (set by X86 or when AH|BH|CH|DH regs are used on X64).
+ kX86_InvalidRex = 0x80000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(InstOptions)
+
+//! Instruction control flow.
+enum class InstControlFlow : uint32_t {
+ //! Regular instruction.
+ kRegular = 0u,
+ //! Unconditional jump.
+ kJump = 1u,
+ //! Conditional jump (branch).
+ kBranch = 2u,
+ //! Function call.
+ kCall = 3u,
+ //! Function return.
+ kReturn = 4u,
+
+ //! Maximum value of `InstType`.
+ kMaxValue = kReturn
+};
+
+//! Hint that is used when both input operands to the instruction are the same.
+//!
+//! Provides hints to the instrution RW query regarding special cases in which two or more operands are the same
+//! registers. This is required by instructions such as XOR, AND, OR, SUB, etc... These hints will influence the
+//! RW operations query.
+enum class InstSameRegHint : uint8_t {
+ //! No special handling.
+ kNone = 0,
+ //! Operands become read-only, the operation doesn't change the content - `X & X` and similar.
+ kRO = 1,
+ //! Operands become write-only, the content of the input(s) don't matter - `X ^ X`, `X - X`, and similar.
+ kWO = 2
+};
-//! Instruction id, options, and extraReg in a single structure. This structure
-//! exists mainly to simplify analysis and validation API that requires `BaseInst`
-//! and `Operand[]` array.
+//! Instruction id, options, and extraReg in a single structure. This structure exists mainly to simplify analysis
+//! and validation API that requires `BaseInst` and `Operand[]` array.
class BaseInst {
public:
- //! Instruction id, see \ref BaseInst::Id or {arch-specific}::Inst::Id.
- uint32_t _id;
- //! Instruction options, see \ref BaseInst::Options or {arch-specific}::Inst::Options.
- uint32_t _options;
- //! Extra register used by instruction (either REP register or AVX-512 selector).
+ //! \name Members
+ //! \{
+
+ //! Instruction id.
+ InstId _id;
+ //! Instruction options.
+ InstOptions _options;
+ //! Extra register used by the instruction (either REP register or AVX-512 selector).
RegOnly _extraReg;
enum Id : uint32_t {
@@ -57,110 +198,39 @@ public:
kIdAbstract = 0x80000000u
};
- enum Options : uint32_t {
- //! Used internally by emitters for handling errors and rare cases.
- kOptionReserved = 0x00000001u,
-
- //! Prevents following a jump during compilation (BaseCompiler).
- kOptionUnfollow = 0x00000002u,
-
- //! Overwrite the destination operand(s) (BaseCompiler).
- //!
- //! Hint that is important for register liveness analysis. It tells the
- //! compiler that the destination operand will be overwritten now or by
- //! adjacent instructions. BaseCompiler knows when a register is completely
- //! overwritten by a single instruction, for example you don't have to
- //! mark "movaps" or "pxor x, x", however, if a pair of instructions is
- //! used and the first of them doesn't completely overwrite the content
- //! of the destination, BaseCompiler fails to mark that register as dead.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! - All instructions that always overwrite at least the size of the
- //! register the virtual-register uses , for example "mov", "movq",
- //! "movaps" don't need the overwrite option to be used - conversion,
- //! shuffle, and other miscellaneous instructions included.
- //!
- //! - All instructions that clear the destination register if all operands
- //! are the same, for example "xor x, x", "pcmpeqb x x", etc...
- //!
- //! - Consecutive instructions that partially overwrite the variable until
- //! there is no old content require `BaseCompiler::overwrite()` to be used.
- //! Some examples (not always the best use cases thought):
- //!
- //! - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
- //! - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
- //! - `mov al, ?` followed by `and ax, 0xFF`
- //! - `mov al, ?` followed by `mov ah, al`
- //! - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
- //!
- //! - If allocated variable is used temporarily for scalar operations. For
- //! example if you allocate a full vector like `x86::Compiler::newXmm()`
- //! and then use that vector for scalar operations you should use
- //! `overwrite()` directive:
- //!
- //! - `sqrtss x, y` - only LO element of `x` is changed, if you don't
- //! use HI elements, use `compiler.overwrite().sqrtss(x, y)`.
- kOptionOverwrite = 0x00000004u,
-
- //! Emit short-form of the instruction.
- kOptionShortForm = 0x00000010u,
- //! Emit long-form of the instruction.
- kOptionLongForm = 0x00000020u,
-
- //! Conditional jump is likely to be taken.
- kOptionTaken = 0x00000040u,
- //! Conditional jump is unlikely to be taken.
- kOptionNotTaken = 0x00000080u
- };
-
- //! Control type.
- enum ControlType : uint32_t {
- //! No control type (doesn't jump).
- kControlNone = 0u,
- //! Unconditional jump.
- kControlJump = 1u,
- //! Conditional jump (branch).
- kControlBranch = 2u,
- //! Function call.
- kControlCall = 3u,
- //! Function return.
- kControlReturn = 4u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
//! Creates a new BaseInst instance with `id` and `options` set.
//!
- //! Default values of `id` and `options` are zero, which means none instruction.
- //! Such instruction is guaranteed to never exist for any architecture supported
- //! by AsmJit.
- inline explicit BaseInst(uint32_t id = 0, uint32_t options = 0) noexcept
- : _id(id),
+ //! Default values of `id` and `options` are zero, which means 'none' instruction. Such instruction is guaranteed
+ //! to never exist for any architecture supported by AsmJit.
+ inline explicit BaseInst(InstId instId = 0, InstOptions options = InstOptions::kNone) noexcept
+ : _id(instId),
_options(options),
_extraReg() {}
- inline BaseInst(uint32_t id, uint32_t options, const RegOnly& extraReg) noexcept
- : _id(id),
+ inline BaseInst(InstId instId, InstOptions options, const RegOnly& extraReg) noexcept
+ : _id(instId),
_options(options),
_extraReg(extraReg) {}
- inline BaseInst(uint32_t id, uint32_t options, const BaseReg& extraReg) noexcept
- : _id(id),
+ inline BaseInst(InstId instId, InstOptions options, const BaseReg& extraReg) noexcept
+ : _id(instId),
_options(options),
_extraReg { extraReg.signature(), extraReg.id() } {}
//! \}
- //! \name Instruction ID
+ //! \name Instruction Id
//! \{
//! Returns the instruction id.
- inline uint32_t id() const noexcept { return _id; }
+ inline InstId id() const noexcept { return _id; }
//! Sets the instruction id to the given `id`.
- inline void setId(uint32_t id) noexcept { _id = id; }
+ inline void setId(InstId id) noexcept { _id = id; }
//! Resets the instruction id to zero, see \ref kIdNone.
inline void resetId() noexcept { _id = 0; }
@@ -169,12 +239,12 @@ public:
//! \name Instruction Options
//! \{
- inline uint32_t options() const noexcept { return _options; }
- inline bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; }
- inline void setOptions(uint32_t options) noexcept { _options = options; }
- inline void addOptions(uint32_t options) noexcept { _options |= options; }
- inline void clearOptions(uint32_t options) noexcept { _options &= ~options; }
- inline void resetOptions() noexcept { _options = 0; }
+ inline InstOptions options() const noexcept { return _options; }
+ inline bool hasOption(InstOptions option) const noexcept { return Support::test(_options, option); }
+ inline void setOptions(InstOptions options) noexcept { _options = options; }
+ inline void addOptions(InstOptions options) noexcept { _options |= options; }
+ inline void clearOptions(InstOptions options) noexcept { _options &= ~options; }
+ inline void resetOptions() noexcept { _options = InstOptions::kNone; }
//! \}
@@ -191,20 +261,144 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::OpRWInfo]
-// ============================================================================
+//! CPU read/write flags used by \ref InstRWInfo.
+//!
+//! These flags can be used to get a basic overview about CPU specifics flags used by instructions.
+enum class CpuRWFlags : uint32_t {
+ //! No flags.
+ kNone = 0x00000000u,
+
+ // Common RW Flags (0x000000FF)
+ // ----------------------------
+
+ //! Carry flag.
+ kCF = 0x00000001u,
+ //! Signed overflow flag.
+ kOF = 0x00000002u,
+ //! Sign flag (negative/sign, if set).
+ kSF = 0x00000004u,
+ //! Zero and/or equality flag (1 if zero/equal).
+ kZF = 0x00000008u,
+
+ // X86 Specific RW Flags (0xFFFFFF00)
+ // ----------------------------------
+
+ //! Carry flag (X86, X86_64).
+ kX86_CF = kCF,
+ //! Overflow flag (X86, X86_64).
+ kX86_OF = kOF,
+ //! Sign flag (X86, X86_64).
+ kX86_SF = kSF,
+ //! Zero flag (X86, X86_64).
+ kX86_ZF = kZF,
+
+ //! Adjust flag (X86, X86_64).
+ kX86_AF = 0x00000100u,
+ //! Parity flag (X86, X86_64).
+ kX86_PF = 0x00000200u,
+ //! Direction flag (X86, X86_64).
+ kX86_DF = 0x00000400u,
+ //! Interrupt enable flag (X86, X86_64).
+ kX86_IF = 0x00000800u,
+
+ //! Alignment check flag (X86, X86_64).
+ kX86_AC = 0x00001000u,
+
+ //! FPU C0 status flag (X86, X86_64).
+ kX86_C0 = 0x00010000u,
+ //! FPU C1 status flag (X86, X86_64).
+ kX86_C1 = 0x00020000u,
+ //! FPU C2 status flag (X86, X86_64).
+ kX86_C2 = 0x00040000u,
+ //! FPU C3 status flag (X86, X86_64).
+ kX86_C3 = 0x00080000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(CpuRWFlags)
+
+//! Operand read/write flags describe how the operand is accessed and some additional features.
+enum class OpRWFlags {
+ //! No flags.
+ kNone = 0,
+
+ //! Operand is read.
+ kRead = 0x00000001u,
+
+ //! Operand is written.
+ kWrite = 0x00000002u,
+
+ //! Operand is both read and written.
+ kRW = 0x00000003u,
+
+ //! Register operand can be replaced by a memory operand.
+ kRegMem = 0x00000004u,
+
+ //! The register must be allocated to the index of the previous register + 1.
+ //!
+ //! This flag is used by all architectures to describe instructions that use consecutive registers, where only the
+ //! first one is encoded in the instruction, and the others are just a sequence that starts with the first one. On
+ //! X86/X86_64 architecture this is used by instructions such as V4FMADDPS, V4FMADDSS, V4FNMADDPS, V4FNMADDSS,
+ //! VP4DPWSSD, VP4DPWSSDS, VP2INTERSECTD, and VP2INTERSECTQ. On ARM/AArch64 this is used by vector load and store
+ //! instructions that can load or store multiple registers at once.
+ kConsecutive = 0x00000008u,
+
+ //! The `extendByteMask()` represents a zero extension.
+ kZExt = 0x00000010u,
+
+ //! Register operand must use \ref OpRWInfo::physId().
+ kRegPhysId = 0x00000100u,
+ //! Base register of a memory operand must use \ref OpRWInfo::physId().
+ kMemPhysId = 0x00000200u,
+
+ //! This memory operand is only used to encode registers and doesn't access memory.
+ //!
+ //! X86 Specific
+ //! ------------
+ //!
+ //! Instructions that use such feature include BNDLDX, BNDSTX, and LEA.
+ kMemFake = 0x000000400u,
+
+ //! Base register of the memory operand will be read.
+ kMemBaseRead = 0x00001000u,
+ //! Base register of the memory operand will be written.
+ kMemBaseWrite = 0x00002000u,
+ //! Base register of the memory operand will be read & written.
+ kMemBaseRW = 0x00003000u,
+
+ //! Index register of the memory operand will be read.
+ kMemIndexRead = 0x00004000u,
+ //! Index register of the memory operand will be written.
+ kMemIndexWrite = 0x00008000u,
+ //! Index register of the memory operand will be read & written.
+ kMemIndexRW = 0x0000C000u,
+
+ //! Base register of the memory operand will be modified before the operation.
+ kMemBasePreModify = 0x00010000u,
+ //! Base register of the memory operand will be modified after the operation.
+ kMemBasePostModify = 0x00020000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(OpRWFlags)
+
+// Don't remove these asserts. Read/Write flags are used extensively
+// by Compiler and they must always be compatible with constants below.
+static_assert(uint32_t(OpRWFlags::kRead) == 0x1, "OpRWFlags::kRead flag must be 0x1");
+static_assert(uint32_t(OpRWFlags::kWrite) == 0x2, "OpRWFlags::kWrite flag must be 0x2");
+static_assert(uint32_t(OpRWFlags::kRegMem) == 0x4, "OpRWFlags::kRegMem flag must be 0x4");
//! Read/Write information related to a single operand, used by \ref InstRWInfo.
struct OpRWInfo {
- //! Read/Write flags, see \ref OpRWInfo::Flags.
- uint32_t _opFlags;
+ //! \name Members
+ //! \{
+
+ //! Read/Write flags.
+ OpRWFlags _opFlags;
//! Physical register index, if required.
uint8_t _physId;
//! Size of a possible memory operand that can replace a register operand.
uint8_t _rmSize;
+ //! If non-zero, then this is a consecutive lead register, and the value describes how many registers follow.
+ uint8_t _consecutiveLeadCount;
//! Reserved for future use.
- uint8_t _reserved[2];
+ uint8_t _reserved[1];
//! Read bit-mask where each bit represents one byte read from Reg/Mem.
uint64_t _readByteMask;
//! Write bit-mask where each bit represents one byte written to Reg/Mem.
@@ -212,61 +406,7 @@ struct OpRWInfo {
//! Zero/Sign extend bit-mask where each bit represents one byte written to Reg/Mem.
uint64_t _extendByteMask;
- //! Flags describe how the operand is accessed and some additional information.
- enum Flags : uint32_t {
- //! Operand is read.
- kRead = 0x00000001u,
-
- //! Operand is written.
- kWrite = 0x00000002u,
-
- //! Operand is both read and written.
- kRW = 0x00000003u,
-
- //! Register operand can be replaced by a memory operand.
- kRegMem = 0x00000004u,
-
- //! The `extendByteMask()` represents a zero extension.
- kZExt = 0x00000010u,
-
- //! Register operand must use \ref physId().
- kRegPhysId = 0x00000100u,
- //! Base register of a memory operand must use \ref physId().
- kMemPhysId = 0x00000200u,
-
- //! This memory operand is only used to encode registers and doesn't access memory.
- //!
- //! X86 Specific
- //! ------------
- //!
- //! Instructions that use such feature include BNDLDX, BNDSTX, and LEA.
- kMemFake = 0x000000400u,
-
- //! Base register of the memory operand will be read.
- kMemBaseRead = 0x00001000u,
- //! Base register of the memory operand will be written.
- kMemBaseWrite = 0x00002000u,
- //! Base register of the memory operand will be read & written.
- kMemBaseRW = 0x00003000u,
-
- //! Index register of the memory operand will be read.
- kMemIndexRead = 0x00004000u,
- //! Index register of the memory operand will be written.
- kMemIndexWrite = 0x00008000u,
- //! Index register of the memory operand will be read & written.
- kMemIndexRW = 0x0000C000u,
-
- //! Base register of the memory operand will be modified before the operation.
- kMemBasePreModify = 0x00010000u,
- //! Base register of the memory operand will be modified after the operation.
- kMemBasePostModify = 0x00020000u
- };
-
- // Don't remove these asserts. Read/Write flags are used extensively
- // by Compiler and they must always be compatible with constants below.
- static_assert(kRead == 0x1, "OpRWInfo::kRead flag must be 0x1");
- static_assert(kWrite == 0x2, "OpRWInfo::kWrite flag must be 0x2");
- static_assert(kRegMem == 0x4, "OpRWInfo::kRegMem flag must be 0x4");
+ //! \}
//! \name Reset
//! \{
@@ -276,20 +416,21 @@ struct OpRWInfo {
//! Resets this operand info (resets all members) and set common information
//! to the given `opFlags`, `regSize`, and possibly `physId`.
- inline void reset(uint32_t opFlags, uint32_t regSize, uint32_t physId = BaseReg::kIdBad) noexcept {
+ inline void reset(OpRWFlags opFlags, uint32_t regSize, uint32_t physId = BaseReg::kIdBad) noexcept {
_opFlags = opFlags;
_physId = uint8_t(physId);
- _rmSize = uint8_t((opFlags & kRegMem) ? regSize : uint32_t(0));
+ _rmSize = Support::test(opFlags, OpRWFlags::kRegMem) ? uint8_t(regSize) : uint8_t(0);
+ _consecutiveLeadCount = 0;
_resetReserved();
uint64_t mask = Support::lsbMask<uint64_t>(regSize);
- _readByteMask = opFlags & kRead ? mask : uint64_t(0);
- _writeByteMask = opFlags & kWrite ? mask : uint64_t(0);
+ _readByteMask = Support::test(opFlags, OpRWFlags::kRead) ? mask : uint64_t(0);
+ _writeByteMask = Support::test(opFlags, OpRWFlags::kWrite) ? mask : uint64_t(0);
_extendByteMask = 0;
}
inline void _resetReserved() noexcept {
- memset(_reserved, 0, sizeof(_reserved));
+ _reserved[0] = 0;
}
//! \}
@@ -297,77 +438,77 @@ struct OpRWInfo {
//! \name Operand Flags
//! \{
- //! Returns operand flags, see \ref Flags.
- inline uint32_t opFlags() const noexcept { return _opFlags; }
+ //! Returns operand flags.
+ inline OpRWFlags opFlags() const noexcept { return _opFlags; }
//! Tests whether operand flags contain the given `flag`.
- inline bool hasOpFlag(uint32_t flag) const noexcept { return (_opFlags & flag) != 0; }
+ inline bool hasOpFlag(OpRWFlags flag) const noexcept { return Support::test(_opFlags, flag); }
//! Adds the given `flags` to operand flags.
- inline void addOpFlags(uint32_t flags) noexcept { _opFlags |= flags; }
+ inline void addOpFlags(OpRWFlags flags) noexcept { _opFlags |= flags; }
//! Removes the given `flags` from operand flags.
- inline void clearOpFlags(uint32_t flags) noexcept { _opFlags &= ~flags; }
+ inline void clearOpFlags(OpRWFlags flags) noexcept { _opFlags &= ~flags; }
//! Tests whether this operand is read from.
- inline bool isRead() const noexcept { return hasOpFlag(kRead); }
+ inline bool isRead() const noexcept { return hasOpFlag(OpRWFlags::kRead); }
//! Tests whether this operand is written to.
- inline bool isWrite() const noexcept { return hasOpFlag(kWrite); }
+ inline bool isWrite() const noexcept { return hasOpFlag(OpRWFlags::kWrite); }
//! Tests whether this operand is both read and write.
- inline bool isReadWrite() const noexcept { return (_opFlags & kRW) == kRW; }
+ inline bool isReadWrite() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRW; }
//! Tests whether this operand is read only.
- inline bool isReadOnly() const noexcept { return (_opFlags & kRW) == kRead; }
+ inline bool isReadOnly() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kRead; }
//! Tests whether this operand is write only.
- inline bool isWriteOnly() const noexcept { return (_opFlags & kRW) == kWrite; }
+ inline bool isWriteOnly() const noexcept { return (_opFlags & OpRWFlags::kRW) == OpRWFlags::kWrite; }
+
+ //! Returns the type of a lead register, which is followed by consecutive registers.
+ inline uint32_t consecutiveLeadCount() const noexcept { return _consecutiveLeadCount; }
//! Tests whether this operand is Reg/Mem
//!
//! Reg/Mem operands can use either register or memory.
- inline bool isRm() const noexcept { return hasOpFlag(kRegMem); }
+ inline bool isRm() const noexcept { return hasOpFlag(OpRWFlags::kRegMem); }
//! Tests whether the operand will be zero extended.
- inline bool isZExt() const noexcept { return hasOpFlag(kZExt); }
+ inline bool isZExt() const noexcept { return hasOpFlag(OpRWFlags::kZExt); }
//! \}
//! \name Memory Flags
//! \{
- //! Tests whether this is a fake memory operand, which is only used, because
- //! of encoding. Fake memory operands do not access any memory, they are only
- //! used to encode registers.
- inline bool isMemFake() const noexcept { return hasOpFlag(kMemFake); }
+ //! Tests whether this is a fake memory operand, which is only used, because of encoding. Fake memory operands do
+ //! not access any memory, they are only used to encode registers.
+ inline bool isMemFake() const noexcept { return hasOpFlag(OpRWFlags::kMemFake); }
//! Tests whether the instruction's memory BASE register is used.
- inline bool isMemBaseUsed() const noexcept { return (_opFlags & kMemBaseRW) != 0; }
+ inline bool isMemBaseUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRW); }
//! Tests whether the instruction reads from its BASE registers.
- inline bool isMemBaseRead() const noexcept { return hasOpFlag(kMemBaseRead); }
+ inline bool isMemBaseRead() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseRead); }
//! Tests whether the instruction writes to its BASE registers.
- inline bool isMemBaseWrite() const noexcept { return hasOpFlag(kMemBaseWrite); }
+ inline bool isMemBaseWrite() const noexcept { return hasOpFlag(OpRWFlags::kMemBaseWrite); }
//! Tests whether the instruction reads and writes from/to its BASE registers.
- inline bool isMemBaseReadWrite() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRW; }
+ inline bool isMemBaseReadWrite() const noexcept { return (_opFlags & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseRW; }
//! Tests whether the instruction only reads from its BASE registers.
- inline bool isMemBaseReadOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseRead; }
+ inline bool isMemBaseReadOnly() const noexcept { return (_opFlags & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseRead; }
//! Tests whether the instruction only writes to its BASE registers.
- inline bool isMemBaseWriteOnly() const noexcept { return (_opFlags & kMemBaseRW) == kMemBaseWrite; }
+ inline bool isMemBaseWriteOnly() const noexcept { return (_opFlags & OpRWFlags::kMemBaseRW) == OpRWFlags::kMemBaseWrite; }
- //! Tests whether the instruction modifies the BASE register before it uses
- //! it to calculate the target address.
- inline bool isMemBasePreModify() const noexcept { return hasOpFlag(kMemBasePreModify); }
- //! Tests whether the instruction modifies the BASE register after it uses
- //! it to calculate the target address.
- inline bool isMemBasePostModify() const noexcept { return hasOpFlag(kMemBasePostModify); }
+ //! Tests whether the instruction modifies the BASE register before it uses it to calculate the target address.
+ inline bool isMemBasePreModify() const noexcept { return hasOpFlag(OpRWFlags::kMemBasePreModify); }
+ //! Tests whether the instruction modifies the BASE register after it uses it to calculate the target address.
+ inline bool isMemBasePostModify() const noexcept { return hasOpFlag(OpRWFlags::kMemBasePostModify); }
//! Tests whether the instruction's memory INDEX register is used.
- inline bool isMemIndexUsed() const noexcept { return (_opFlags & kMemIndexRW) != 0; }
+ inline bool isMemIndexUsed() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRW); }
//! Tests whether the instruction reads the INDEX registers.
- inline bool isMemIndexRead() const noexcept { return hasOpFlag(kMemIndexRead); }
+ inline bool isMemIndexRead() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexRead); }
//! Tests whether the instruction writes to its INDEX registers.
- inline bool isMemIndexWrite() const noexcept { return hasOpFlag(kMemIndexWrite); }
+ inline bool isMemIndexWrite() const noexcept { return hasOpFlag(OpRWFlags::kMemIndexWrite); }
//! Tests whether the instruction reads and writes from/to its INDEX registers.
- inline bool isMemIndexReadWrite() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRW; }
+ inline bool isMemIndexReadWrite() const noexcept { return (_opFlags & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexRW; }
//! Tests whether the instruction only reads from its INDEX registers.
- inline bool isMemIndexReadOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexRead; }
+ inline bool isMemIndexReadOnly() const noexcept { return (_opFlags & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexRead; }
//! Tests whether the instruction only writes to its INDEX registers.
- inline bool isMemIndexWriteOnly() const noexcept { return (_opFlags & kMemIndexRW) == kMemIndexWrite; }
+ inline bool isMemIndexWriteOnly() const noexcept { return (_opFlags & OpRWFlags::kMemIndexRW) == OpRWFlags::kMemIndexWrite; }
//! \}
@@ -415,18 +556,17 @@ struct OpRWInfo {
//! \}
};
-// ============================================================================
-// [asmjit::InstRWInfo]
-// ============================================================================
-
//! Read/Write information of an instruction.
struct InstRWInfo {
+ //! \name Members
+ //! \{
+
//! Instruction flags (there are no flags at the moment, this field is reserved).
uint32_t _instFlags;
- //! Mask of CPU flags read.
- uint32_t _readFlags;
- //! Mask of CPU flags written.
- uint32_t _writeFlags;
+ //! CPU flags read.
+ CpuRWFlags _readFlags;
+ //! CPU flags written.
+ CpuRWFlags _writeFlags;
//! Count of operands.
uint8_t _opCount;
//! CPU feature required for replacing register operand with memory operand.
@@ -438,6 +578,8 @@ struct InstRWInfo {
//! Read/Write info of instruction operands.
OpRWInfo _operands[Globals::kMaxOpCount];
+ //! \}
+
//! \name Commons
//! \{
@@ -446,40 +588,29 @@ struct InstRWInfo {
//! \}
- //! \name Instruction Flags
- //!
- //! \{
-
- inline uint32_t instFlags() const noexcept { return _instFlags; }
- inline bool hasInstFlag(uint32_t flag) const noexcept { return (_instFlags & flag) != 0; }
-
- //! }
-
- //! \name CPU Flags Read/Write Information
+ //! \name CPU Flags Information
//! \{
- //! Returns read flags of the instruction.
- inline uint32_t readFlags() const noexcept { return _readFlags; }
- //! Returns write flags of the instruction.
- inline uint32_t writeFlags() const noexcept { return _writeFlags; }
+ //! Returns a mask of CPU flags read.
+ inline CpuRWFlags readFlags() const noexcept { return _readFlags; }
+ //! Returns a mask of CPU flags written.
+ inline CpuRWFlags writeFlags() const noexcept { return _writeFlags; }
//! \}
//! \name Reg/Mem Information
//! \{
- //! Returns the CPU feature required to replace a register operand with memory
- //! operand. If the returned feature is zero (none) then this instruction
- //! either doesn't provide memory operand combination or there is no extra
- //! CPU feature required.
+ //! Returns the CPU feature required to replace a register operand with memory operand. If the returned feature is
+ //! zero (none) then this instruction either doesn't provide memory operand combination or there is no extra CPU
+ //! feature required.
//!
//! X86 Specific
//! ------------
//!
- //! Some AVX+ instructions may require extra features for replacing registers
- //! with memory operands, for example VPSLLDQ instruction only supports
- //! 'reg/reg/imm' combination on AVX/AVX2 capable CPUs and requires AVX-512 for
- //! 'reg/mem/imm' combination.
+ //! Some AVX+ instructions may require extra features for replacing registers with memory operands, for example
+ //! VPSLLDQ instruction only supports `vpslldq reg, reg, imm` combination on AVX/AVX2 capable CPUs and requires
+ //! AVX-512 for `vpslldq reg, mem, imm` combination.
inline uint32_t rmFeature() const noexcept { return _rmFeature; }
//! \}
@@ -505,49 +636,43 @@ struct InstRWInfo {
//! \}
};
-// ============================================================================
-// [asmjit::InstAPI]
-// ============================================================================
-
-//! Instruction API.
-namespace InstAPI {
-
//! Validation flags that can be used with \ref InstAPI::validate().
-enum ValidationFlags : uint32_t {
+enum class ValidationFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
//! Allow virtual registers in the instruction.
- kValidationFlagVirtRegs = 0x01u
+ kEnableVirtRegs = 0x01u
};
+ASMJIT_DEFINE_ENUM_FLAGS(ValidationFlags)
+
+//! Instruction API.
+namespace InstAPI {
#ifndef ASMJIT_NO_TEXT
-//! Appends the name of the instruction specified by `instId` and `instOptions`
-//! into the `output` string.
+//! Appends the name of the instruction specified by `instId` and `instOptions` into the `output` string.
//!
-//! \note Instruction options would only affect instruction prefix & suffix,
-//! other options would be ignored. If `instOptions` is zero then only raw
-//! instruction name (without any additional text) will be appended.
-ASMJIT_API Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept;
-
-//! Parses an instruction name in the given string `s`. Length is specified
-//! by `len` argument, which can be `SIZE_MAX` if `s` is known to be null
-//! terminated.
+//! \note Instruction options would only affect instruction prefix & suffix, other options would be ignored.
+//! If `instOptions` is zero then only raw instruction name (without any additional text) will be appended.
+ASMJIT_API Error instIdToString(Arch arch, InstId instId, String& output) noexcept;
+
+//! Parses an instruction name in the given string `s`. Length is specified by `len` argument, which can be
+//! `SIZE_MAX` if `s` is known to be null terminated.
//!
-//! Returns the parsed instruction id or \ref BaseInst::kIdNone if no such
-//! instruction exists.
-ASMJIT_API uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept;
+//! Returns the parsed instruction id or \ref BaseInst::kIdNone if no such instruction exists.
+ASMJIT_API InstId stringToInstId(Arch arch, const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-//! Validates the given instruction considering the validation `flags`, see
-//! \ref ValidationFlags.
-ASMJIT_API Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags = 0) noexcept;
+//! Validates the given instruction considering the given `validationFlags`.
+ASMJIT_API Error validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags = ValidationFlags::kNone) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
//! Gets Read/Write information of the given instruction.
-ASMJIT_API Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
+ASMJIT_API Error queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
//! Gets CPU features required by the given instruction.
-ASMJIT_API Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept;
+ASMJIT_API Error queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstAPI}
diff --git a/src/asmjit/core/jitallocator.cpp b/src/asmjit/core/jitallocator.cpp
index b576e21..19fbe4b 100644
--- a/src/asmjit/core/jitallocator.cpp
+++ b/src/asmjit/core/jitallocator.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_JIT
@@ -35,24 +17,24 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::JitAllocator - Constants]
-// ============================================================================
+// JitAllocator - Constants
+// ========================
-enum JitAllocatorConstants : uint32_t {
- //! Number of pools to use when `JitAllocator::kOptionUseMultiplePools` is set.
- //!
- //! Each pool increases granularity twice to make memory management more
- //! efficient. Ideal number of pools appears to be 3 to 4 as it distributes
- //! small and large functions properly.
- kJitAllocatorMultiPoolCount = 3,
+//! Number of pools to use when `JitAllocatorOptions::kUseMultiplePools` is set.
+//!
+//! Each pool increases granularity twice to make memory management more
+//! efficient. Ideal number of pools appears to be 3 to 4 as it distributes
+//! small and large functions properly.
+static constexpr uint32_t kJitAllocatorMultiPoolCount = 3;
- //! Minimum granularity (and the default granularity for pool #0).
- kJitAllocatorBaseGranularity = 64,
+//! Minimum granularity (and the default granularity for pool #0).
+static constexpr uint32_t kJitAllocatorBaseGranularity = 64;
- //! Maximum block size (32MB).
- kJitAllocatorMaxBlockSize = 1024 * 1024 * 32
-};
+//! Maximum block size (32MB).
+static constexpr uint32_t kJitAllocatorMaxBlockSize = 1024 * 1024 * 32;
+
+// JitAllocator - Fill Pattern
+// ===========================
static inline uint32_t JitAllocator_defaultFillPattern() noexcept {
// X86 and X86_64 - 4x 'int3' instruction.
@@ -63,9 +45,8 @@ static inline uint32_t JitAllocator_defaultFillPattern() noexcept {
return 0u;
}
-// ============================================================================
-// [asmjit::BitVectorRangeIterator]
-// ============================================================================
+// JitAllocator - BitVectorRangeIterator
+// =====================================
template<typename T, uint32_t B>
class BitVectorRangeIterator {
@@ -78,19 +59,19 @@ public:
enum : uint32_t { kBitWordSize = Support::bitSizeOf<T>() };
enum : T { kXorMask = B == 0 ? Support::allOnes<T>() : T(0) };
- ASMJIT_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords) noexcept {
+ ASMJIT_FORCE_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords) noexcept {
init(data, numBitWords);
}
- ASMJIT_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords, size_t start, size_t end) noexcept {
+ ASMJIT_FORCE_INLINE BitVectorRangeIterator(const T* data, size_t numBitWords, size_t start, size_t end) noexcept {
init(data, numBitWords, start, end);
}
- ASMJIT_INLINE void init(const T* data, size_t numBitWords) noexcept {
+ ASMJIT_FORCE_INLINE void init(const T* data, size_t numBitWords) noexcept {
init(data, numBitWords, 0, numBitWords * kBitWordSize);
}
- ASMJIT_INLINE void init(const T* data, size_t numBitWords, size_t start, size_t end) noexcept {
+ ASMJIT_FORCE_INLINE void init(const T* data, size_t numBitWords, size_t start, size_t end) noexcept {
ASMJIT_ASSERT(numBitWords >= (end + kBitWordSize - 1) / kBitWordSize);
DebugUtils::unused(numBitWords);
@@ -107,7 +88,7 @@ public:
_bitWord = bitWord;
}
- ASMJIT_INLINE bool nextRange(size_t* rangeStart, size_t* rangeEnd, size_t rangeHint = std::numeric_limits<size_t>::max()) noexcept {
+ ASMJIT_FORCE_INLINE bool nextRange(size_t* rangeStart, size_t* rangeEnd, size_t rangeHint = std::numeric_limits<size_t>::max()) noexcept {
// Skip all empty BitWords.
while (_bitWord == 0) {
_idx += kBitWordSize;
@@ -153,9 +134,8 @@ public:
}
};
-// ============================================================================
-// [asmjit::JitAllocator - Pool]
-// ============================================================================
+// JitAllocator - Pool
+// ===================
class JitAllocatorBlock;
@@ -163,6 +143,27 @@ class JitAllocatorPool {
public:
ASMJIT_NONCOPYABLE(JitAllocatorPool)
+ //! Double linked list of blocks.
+ ZoneList<JitAllocatorBlock> blocks;
+ //! Where to start looking first.
+ JitAllocatorBlock* cursor;
+
+ //! Count of blocks.
+ uint32_t blockCount;
+ //! Allocation granularity.
+ uint16_t granularity;
+ //! Log2(granularity).
+ uint8_t granularityLog2;
+ //! Count of empty blocks (either 0 or 1 as we won't keep more blocks empty).
+ uint8_t emptyBlockCount;
+
+ //! Number of bits reserved across all blocks.
+ size_t totalAreaSize;
+ //! Number of bits used across all blocks.
+ size_t totalAreaUsed;
+ //! Overhead of all blocks (in bytes).
+ size_t totalOverheadBytes;
+
inline JitAllocatorPool(uint32_t granularity) noexcept
: blocks(),
cursor(nullptr),
@@ -190,32 +191,10 @@ public:
using namespace Support;
return alignUp<size_t>(areaSize, kBitWordSizeInBits) / kBitWordSizeInBits;
}
-
- //! Double linked list of blocks.
- ZoneList<JitAllocatorBlock> blocks;
- //! Where to start looking first.
- JitAllocatorBlock* cursor;
-
- //! Count of blocks.
- uint32_t blockCount;
- //! Allocation granularity.
- uint16_t granularity;
- //! Log2(granularity).
- uint8_t granularityLog2;
- //! Count of empty blocks (either 0 or 1 as we won't keep more blocks empty).
- uint8_t emptyBlockCount;
-
- //! Number of bits reserved across all blocks.
- size_t totalAreaSize;
- //! Number of bits used across all blocks.
- size_t totalAreaUsed;
- //! Overhead of all blocks (in bytes).
- size_t totalOverheadBytes;
};
-// ============================================================================
-// [asmjit::JitAllocator - Block]
-// ============================================================================
+// JitAllocator - Block
+// ====================
class JitAllocatorBlock : public ZoneTreeNodeT<JitAllocatorBlock>,
public ZoneListNode<JitAllocatorBlock> {
@@ -280,7 +259,7 @@ public:
inline JitAllocatorPool* pool() const noexcept { return _pool; }
- inline uint8_t* roPtr() const noexcept { return static_cast<uint8_t*>(_mapping.ro); }
+ inline uint8_t* rxPtr() const noexcept { return static_cast<uint8_t*>(_mapping.rx); }
inline uint8_t* rwPtr() const noexcept { return static_cast<uint8_t*>(_mapping.rw); }
inline bool hasFlag(uint32_t f) const noexcept { return (_flags & f) != 0; }
@@ -376,30 +355,25 @@ public:
}
// RBTree default CMP uses '<' and '>' operators.
- inline bool operator<(const JitAllocatorBlock& other) const noexcept { return roPtr() < other.roPtr(); }
- inline bool operator>(const JitAllocatorBlock& other) const noexcept { return roPtr() > other.roPtr(); }
+ inline bool operator<(const JitAllocatorBlock& other) const noexcept { return rxPtr() < other.rxPtr(); }
+ inline bool operator>(const JitAllocatorBlock& other) const noexcept { return rxPtr() > other.rxPtr(); }
// Special implementation for querying blocks by `key`, which must be in `[BlockPtr, BlockPtr + BlockSize)` range.
- inline bool operator<(const uint8_t* key) const noexcept { return roPtr() + _blockSize <= key; }
- inline bool operator>(const uint8_t* key) const noexcept { return roPtr() > key; }
+ inline bool operator<(const uint8_t* key) const noexcept { return rxPtr() + _blockSize <= key; }
+ inline bool operator>(const uint8_t* key) const noexcept { return rxPtr() > key; }
};
-// ============================================================================
-// [asmjit::JitAllocator - PrivateImpl]
-// ============================================================================
+// JitAllocator - PrivateImpl
+// ==========================
class JitAllocatorPrivateImpl : public JitAllocator::Impl {
public:
- inline JitAllocatorPrivateImpl(JitAllocatorPool* pools, size_t poolCount) noexcept
- : JitAllocator::Impl {},
- pools(pools),
- poolCount(poolCount) {}
- inline ~JitAllocatorPrivateImpl() noexcept {}
-
//! Lock for thread safety.
mutable Lock lock;
//! System page size (also a minimum block size).
uint32_t pageSize;
+ //! Number of active allocations.
+ size_t allocationCount;
//! Blocks from all pools in RBTree.
ZoneTree<JitAllocatorBlock> tree;
@@ -407,14 +381,21 @@ public:
JitAllocatorPool* pools;
//! Number of allocator pools.
size_t poolCount;
+
+ inline JitAllocatorPrivateImpl(JitAllocatorPool* pools, size_t poolCount) noexcept
+ : JitAllocator::Impl {},
+ pageSize(0),
+ allocationCount(0),
+ pools(pools),
+ poolCount(poolCount) {}
+ inline ~JitAllocatorPrivateImpl() noexcept {}
};
static const JitAllocator::Impl JitAllocatorImpl_none {};
static const JitAllocator::CreateParams JitAllocatorParams_none {};
-// ============================================================================
-// [asmjit::JitAllocator - Utilities]
-// ============================================================================
+// JitAllocator - Utilities
+// ========================
static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::CreateParams* params) noexcept {
VirtMem::Info vmInfo = VirtMem::info();
@@ -422,14 +403,14 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::
if (!params)
params = &JitAllocatorParams_none;
- uint32_t options = params->options;
+ JitAllocatorOptions options = params->options;
uint32_t blockSize = params->blockSize;
uint32_t granularity = params->granularity;
uint32_t fillPattern = params->fillPattern;
// Setup pool count to [1..3].
size_t poolCount = 1;
- if (options & JitAllocator::kOptionUseMultiplePools)
+ if (Support::test(options, JitAllocatorOptions::kUseMultiplePools))
poolCount = kJitAllocatorMultiPoolCount;;
// Setup block size [64kB..256MB].
@@ -441,7 +422,7 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator::
granularity = kJitAllocatorBaseGranularity;
// Setup fill-pattern.
- if (!(options & JitAllocator::kOptionCustomFillPattern))
+ if (uint32_t(options & JitAllocatorOptions::kCustomFillPattern) == 0)
fillPattern = JitAllocator_defaultFillPattern();
size_t size = sizeof(JitAllocatorPrivateImpl) + sizeof(JitAllocatorPool) * poolCount;
@@ -533,26 +514,32 @@ static JitAllocatorBlock* JitAllocatorImpl_newBlock(JitAllocatorPrivateImpl* imp
uint32_t blockFlags = 0;
if (bitWords != nullptr) {
- if (impl->options & JitAllocator::kOptionUseDualMapping) {
- err = VirtMem::allocDualMapping(&virtMem, blockSize, VirtMem::kAccessRWX);
+ if (Support::test(impl->options, JitAllocatorOptions::kUseDualMapping)) {
+ err = VirtMem::allocDualMapping(&virtMem, blockSize, VirtMem::MemoryFlags::kAccessRWX);
blockFlags |= JitAllocatorBlock::kFlagDualMapped;
}
else {
- err = VirtMem::alloc(&virtMem.ro, blockSize, VirtMem::kAccessRWX);
- virtMem.rw = virtMem.ro;
+ err = VirtMem::alloc(&virtMem.rx, blockSize, VirtMem::MemoryFlags::kAccessRWX);
+ virtMem.rw = virtMem.rx;
}
}
// Out of memory.
if (ASMJIT_UNLIKELY(!block || !bitWords || err != kErrorOk)) {
- if (bitWords) ::free(bitWords);
- if (block) ::free(block);
+ if (bitWords)
+ ::free(bitWords);
+
+ if (block)
+ ::free(block);
+
return nullptr;
}
// Fill the memory if the secure mode is enabled.
- if (impl->options & JitAllocator::kOptionFillUnusedMemory)
+ if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory)) {
+ VirtMem::ProtectJitReadWriteScope scope(virtMem.rw, blockSize);
JitAllocatorImpl_fillPattern(virtMem.rw, impl->fillPattern, blockSize);
+ }
memset(bitWords, 0, size_t(numBitWords) * 2 * sizeof(BitWord));
return new(block) JitAllocatorBlock(pool, virtMem, blockSize, blockFlags, bitWords, bitWords + numBitWords, areaSize);
@@ -564,7 +551,7 @@ static void JitAllocatorImpl_deleteBlock(JitAllocatorPrivateImpl* impl, JitAlloc
if (block->hasFlag(JitAllocatorBlock::kFlagDualMapped))
VirtMem::releaseDualMapping(&block->_mapping, block->blockSize());
else
- VirtMem::release(block->roPtr(), block->blockSize());
+ VirtMem::release(block->rxPtr(), block->blockSize());
::free(block->_usedBitVector);
::free(block);
@@ -603,26 +590,31 @@ static void JitAllocatorImpl_removeBlock(JitAllocatorPrivateImpl* impl, JitAlloc
}
static void JitAllocatorImpl_wipeOutBlock(JitAllocatorPrivateImpl* impl, JitAllocatorBlock* block) noexcept {
- JitAllocatorPool* pool = block->pool();
-
if (block->hasFlag(JitAllocatorBlock::kFlagEmpty))
return;
+ JitAllocatorPool* pool = block->pool();
uint32_t areaSize = block->areaSize();
uint32_t granularity = pool->granularity;
size_t numBitWords = pool->bitWordCountFromAreaSize(areaSize);
- if (impl->options & JitAllocator::kOptionFillUnusedMemory) {
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
+ if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory)) {
uint8_t* rwPtr = block->rwPtr();
- for (size_t i = 0; i < numBitWords; i++) {
- Support::BitWordIterator<Support::BitWord> it(block->_usedBitVector[i]);
- while (it.hasNext()) {
- size_t index = it.next();
- JitAllocatorImpl_fillPattern(rwPtr + index * granularity , impl->fillPattern, granularity);
- }
- rwPtr += Support::bitSizeOf<Support::BitWord>() * granularity;
+ BitVectorRangeIterator<Support::BitWord, 0> it(block->_usedBitVector, pool->bitWordCountFromAreaSize(block->areaSize()));
+
+ size_t rangeStart;
+ size_t rangeEnd;
+
+ while (it.nextRange(&rangeStart, &rangeEnd)) {
+ uint8_t* spanPtr = rwPtr + rangeStart * granularity;
+ size_t spanSize = (rangeEnd - rangeStart) * granularity;
+
+ JitAllocatorImpl_fillPattern(spanPtr, impl->fillPattern, spanSize);
+ VirtMem::flushInstructionCache(spanPtr, spanSize);
}
}
+ VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute);
memset(block->_usedBitVector, 0, size_t(numBitWords) * sizeof(Support::BitWord));
memset(block->_stopBitVector, 0, size_t(numBitWords) * sizeof(Support::BitWord));
@@ -635,9 +627,8 @@ static void JitAllocatorImpl_wipeOutBlock(JitAllocatorPrivateImpl* impl, JitAllo
block->clearFlags(JitAllocatorBlock::kFlagDirty);
}
-// ============================================================================
-// [asmjit::JitAllocator - Construction / Destruction]
-// ============================================================================
+// JitAllocator - Construction & Destruction
+// =========================================
JitAllocator::JitAllocator(const CreateParams* params) noexcept {
_impl = JitAllocatorImpl_new(params);
@@ -649,15 +640,14 @@ JitAllocator::~JitAllocator() noexcept {
if (_impl == &JitAllocatorImpl_none)
return;
- reset(Globals::kResetHard);
+ reset(ResetPolicy::kHard);
JitAllocatorImpl_destroy(static_cast<JitAllocatorPrivateImpl*>(_impl));
}
-// ============================================================================
-// [asmjit::JitAllocator - Reset]
-// ============================================================================
+// JitAllocator - Reset
+// ====================
-void JitAllocator::reset(uint32_t resetPolicy) noexcept {
+void JitAllocator::reset(ResetPolicy resetPolicy) noexcept {
if (_impl == &JitAllocatorImpl_none)
return;
@@ -670,7 +660,7 @@ void JitAllocator::reset(uint32_t resetPolicy) noexcept {
JitAllocatorBlock* block = pool.blocks.first();
JitAllocatorBlock* blockToKeep = nullptr;
- if (resetPolicy != Globals::kResetHard && !(impl->options & kOptionImmediateRelease)) {
+ if (resetPolicy != ResetPolicy::kHard && uint32_t(impl->options & JitAllocatorOptions::kImmediateRelease) == 0) {
blockToKeep = block;
block = block->next();
}
@@ -693,9 +683,8 @@ void JitAllocator::reset(uint32_t resetPolicy) noexcept {
}
}
-// ============================================================================
-// [asmjit::JitAllocator - Statistics]
-// ============================================================================
+// JitAllocator - Statistics
+// =========================
JitAllocator::Statistics JitAllocator::statistics() const noexcept {
Statistics statistics;
@@ -713,23 +702,24 @@ JitAllocator::Statistics JitAllocator::statistics() const noexcept {
statistics._usedSize += size_t(pool.totalAreaUsed) * pool.granularity;
statistics._overheadSize += size_t(pool.totalOverheadBytes);
}
+
+ statistics._allocationCount = impl->allocationCount;
}
return statistics;
}
-// ============================================================================
-// [asmjit::JitAllocator - Alloc / Release]
-// ============================================================================
+// JitAllocator - Alloc & Release
+// ==============================
-Error JitAllocator::alloc(void** roPtrOut, void** rwPtrOut, size_t size) noexcept {
+Error JitAllocator::alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept {
if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
return DebugUtils::errored(kErrorNotInitialized);
JitAllocatorPrivateImpl* impl = static_cast<JitAllocatorPrivateImpl*>(_impl);
constexpr uint32_t kNoIndex = std::numeric_limits<uint32_t>::max();
- *roPtrOut = nullptr;
+ *rxPtrOut = nullptr;
*rwPtrOut = nullptr;
// Align to the minimum granularity by default.
@@ -815,49 +805,56 @@ Error JitAllocator::alloc(void** roPtrOut, void** rwPtrOut, size_t size) noexcep
}
// Update statistics.
+ impl->allocationCount++;
block->markAllocatedArea(areaIndex, areaIndex + areaSize);
// Return a pointer to the allocated memory.
size_t offset = pool->byteSizeFromAreaSize(areaIndex);
ASMJIT_ASSERT(offset <= block->blockSize() - size);
- *roPtrOut = block->roPtr() + offset;
+ *rxPtrOut = block->rxPtr() + offset;
*rwPtrOut = block->rwPtr() + offset;
return kErrorOk;
}
-Error JitAllocator::release(void* roPtr) noexcept {
+Error JitAllocator::release(void* rxPtr) noexcept {
if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
return DebugUtils::errored(kErrorNotInitialized);
- if (ASMJIT_UNLIKELY(!roPtr))
+ if (ASMJIT_UNLIKELY(!rxPtr))
return DebugUtils::errored(kErrorInvalidArgument);
JitAllocatorPrivateImpl* impl = static_cast<JitAllocatorPrivateImpl*>(_impl);
LockGuard guard(impl->lock);
- JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(roPtr));
+ JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rxPtr));
if (ASMJIT_UNLIKELY(!block))
return DebugUtils::errored(kErrorInvalidState);
// Offset relative to the start of the block.
JitAllocatorPool* pool = block->pool();
- size_t offset = (size_t)((uint8_t*)roPtr - block->roPtr());
+ size_t offset = (size_t)((uint8_t*)rxPtr - block->rxPtr());
// The first bit representing the allocated area and its size.
uint32_t areaIndex = uint32_t(offset >> pool->granularityLog2);
uint32_t areaEnd = uint32_t(Support::bitVectorIndexOf(block->_stopBitVector, areaIndex, true)) + 1;
uint32_t areaSize = areaEnd - areaIndex;
+ impl->allocationCount--;
block->markReleasedArea(areaIndex, areaEnd);
// Fill the released memory if the secure mode is enabled.
- if (impl->options & kOptionFillUnusedMemory)
- JitAllocatorImpl_fillPattern(block->rwPtr() + areaIndex * pool->granularity, impl->fillPattern, areaSize * pool->granularity);
+ if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory)) {
+ uint8_t* spanPtr = block->rwPtr() + areaIndex * pool->granularity;
+ size_t spanSize = areaSize * pool->granularity;
+
+ VirtMem::ProtectJitReadWriteScope scope(spanPtr, spanSize);
+ JitAllocatorImpl_fillPattern(spanPtr, impl->fillPattern, spanSize);
+ }
// Release the whole block if it became empty.
if (block->areaUsed() == 0) {
- if (pool->emptyBlockCount || (impl->options & kOptionImmediateRelease)) {
+ if (pool->emptyBlockCount || Support::test(impl->options, JitAllocatorOptions::kImmediateRelease)) {
JitAllocatorImpl_removeBlock(impl, block);
JitAllocatorImpl_deleteBlock(impl, block);
}
@@ -869,26 +866,26 @@ Error JitAllocator::release(void* roPtr) noexcept {
return kErrorOk;
}
-Error JitAllocator::shrink(void* roPtr, size_t newSize) noexcept {
+Error JitAllocator::shrink(void* rxPtr, size_t newSize) noexcept {
if (ASMJIT_UNLIKELY(_impl == &JitAllocatorImpl_none))
return DebugUtils::errored(kErrorNotInitialized);
- if (ASMJIT_UNLIKELY(!roPtr))
+ if (ASMJIT_UNLIKELY(!rxPtr))
return DebugUtils::errored(kErrorInvalidArgument);
if (ASMJIT_UNLIKELY(newSize == 0))
- return release(roPtr);
+ return release(rxPtr);
JitAllocatorPrivateImpl* impl = static_cast<JitAllocatorPrivateImpl*>(_impl);
LockGuard guard(impl->lock);
- JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(roPtr));
+ JitAllocatorBlock* block = impl->tree.get(static_cast<uint8_t*>(rxPtr));
if (ASMJIT_UNLIKELY(!block))
return DebugUtils::errored(kErrorInvalidArgument);
// Offset relative to the start of the block.
JitAllocatorPool* pool = block->pool();
- size_t offset = (size_t)((uint8_t*)roPtr - block->roPtr());
+ size_t offset = (size_t)((uint8_t*)rxPtr - block->rxPtr());
// The first bit representing the allocated area and its size.
uint32_t areaStart = uint32_t(offset >> pool->granularityLog2);
@@ -905,16 +902,15 @@ Error JitAllocator::shrink(void* roPtr, size_t newSize) noexcept {
block->markShrunkArea(areaStart + areaShrunkSize, areaEnd);
// Fill released memory if the secure mode is enabled.
- if (impl->options & kOptionFillUnusedMemory)
+ if (Support::test(impl->options, JitAllocatorOptions::kFillUnusedMemory))
JitAllocatorImpl_fillPattern(block->rwPtr() + (areaStart + areaShrunkSize) * pool->granularity, fillPattern(), areaDiff * pool->granularity);
}
return kErrorOk;
}
-// ============================================================================
-// [asmjit::JitAllocator - Unit]
-// ============================================================================
+// JitAllocator - Tests
+// ====================
#if defined(ASMJIT_TEST)
// A pseudo random number generator based on a paper by Sebastiano Vigna:
@@ -1034,14 +1030,14 @@ public:
}
void* alloc(size_t size) noexcept {
- void* roPtr;
+ void* rxPtr;
void* rwPtr;
- Error err = _allocator.alloc(&roPtr, &rwPtr, size);
+ Error err = _allocator.alloc(&rxPtr, &rwPtr, size);
EXPECT(err == kErrorOk, "JitAllocator failed to allocate %zu bytes\n", size);
- _insert(roPtr, size);
- return roPtr;
+ _insert(rxPtr, size);
+ return rxPtr;
}
void release(void* p) noexcept {
@@ -1099,7 +1095,7 @@ static void BitVectorRangeIterator_testRandom(Random& rnd, size_t count) noexcep
}
for (size_t j = 0; j < kPatternSize; j++) {
- EXPECT(in[j] == out[j], "Invalid pattern detected at [%zu] (%llX != %llX", j, (unsigned long long)in[j], (unsigned long long)out[j]);
+ EXPECT(in[j] == out[j], "Invalid pattern detected at [%zu] (%llX != %llX)", j, (unsigned long long)in[j], (unsigned long long)out[j]);
}
}
}
@@ -1109,20 +1105,20 @@ UNIT(jit_allocator) {
struct TestParams {
const char* name;
- uint32_t options;
+ JitAllocatorOptions options;
uint32_t blockSize;
uint32_t granularity;
};
static TestParams testParams[] = {
- { "Default", 0, 0, 0 },
- { "16MB blocks", 0, 16 * 1024 * 1024, 0 },
- { "256B granularity", 0, 0, 256 },
- { "kOptionUseDualMapping", JitAllocator::kOptionUseDualMapping, 0, 0 },
- { "kOptionUseMultiplePools", JitAllocator::kOptionUseMultiplePools, 0, 0 },
- { "kOptionFillUnusedMemory", JitAllocator::kOptionFillUnusedMemory, 0, 0 },
- { "kOptionImmediateRelease", JitAllocator::kOptionImmediateRelease, 0, 0 },
- { "kOptionUseDualMapping | kOptionFillUnusedMemory", JitAllocator::kOptionUseDualMapping | JitAllocator::kOptionFillUnusedMemory, 0, 0 }
+ { "Default", JitAllocatorOptions::kNone, 0, 0 },
+ { "16MB blocks", JitAllocatorOptions::kNone, 16 * 1024 * 1024, 0 },
+ { "256B granularity", JitAllocatorOptions::kNone, 0, 256 },
+ { "kUseDualMapping", JitAllocatorOptions::kUseDualMapping, 0, 0 },
+ { "kUseMultiplePools", JitAllocatorOptions::kUseMultiplePools, 0, 0 },
+ { "kFillUnusedMemory", JitAllocatorOptions::kFillUnusedMemory, 0, 0 },
+ { "kImmediateRelease", JitAllocatorOptions::kImmediateRelease, 0, 0 },
+ { "kUseDualMapping | kFillUnusedMemory", JitAllocatorOptions::kUseDualMapping | JitAllocatorOptions::kFillUnusedMemory, 0, 0 }
};
INFO("BitVectorRangeIterator<uint32_t>");
diff --git a/src/asmjit/core/jitallocator.h b/src/asmjit/core/jitallocator.h
index c9eea2a..e8fe695 100644
--- a/src/asmjit/core/jitallocator.h
+++ b/src/asmjit/core/jitallocator.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
#define ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
@@ -35,37 +17,67 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_virtual_memory
//! \{
-// ============================================================================
-// [asmjit::JitAllocator]
-// ============================================================================
+//! Options used by \ref JitAllocator.
+enum class JitAllocatorOptions : uint32_t {
+ //! No options.
+ kNone = 0,
+
+ //! Enables the use of an anonymous memory-mapped memory that is mapped into two buffers having a different pointer.
+ //! The first buffer has read and execute permissions and the second buffer has read+write permissions.
+ //!
+ //! See \ref VirtMem::allocDualMapping() for more details about this feature.
+ kUseDualMapping = 0x00000001u,
+
+ //! Enables the use of multiple pools with increasing granularity instead of a single pool. This flag would enable
+ //! 3 internal pools in total having 64, 128, and 256 bytes granularity.
+ //!
+ //! This feature is only recommended for users that generate a lot of code and would like to minimize the overhead
+ //! of `JitAllocator` itself by having blocks of different allocation granularities. Using this feature only for
+ //! few allocations won't pay off as the allocator may need to create more blocks initially before it can take the
+ //! advantage of variable block granularity.
+ kUseMultiplePools = 0x00000002u,
+
+ //! Always fill reserved memory by a fill-pattern.
+ //!
+ //! Causes a new block to be cleared by the fill pattern and freshly released memory to be cleared before making
+ //! it ready for another use.
+ kFillUnusedMemory = 0x00000004u,
+
+ //! When this flag is set the allocator would immediately release unused blocks during `release()` or `reset()`.
+ //! When this flag is not set the allocator would keep one empty block in each pool to prevent excessive virtual
+ //! memory allocations and deallocations in border cases, which involve constantly allocating and deallocating a
+ //! single block caused by repetitive calling `alloc()` and `release()` when the allocator has either no blocks
+ //! or have all blocks fully occupied.
+ kImmediateRelease = 0x00000008u,
+
+ //! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`.
+ kCustomFillPattern = 0x10000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(JitAllocatorOptions)
//! A simple implementation of memory manager that uses `asmjit::VirtMem`
//! functions to manage virtual memory for JIT compiled code.
//!
//! Implementation notes:
//!
-//! - Granularity of allocated blocks is different than granularity for a typical
-//! C malloc. In addition, the allocator can use several memory pools having a
-//! different granularity to minimize the maintenance overhead. Multiple pools
+//! - Granularity of allocated blocks is different than granularity for a typical C malloc. In addition, the allocator
+//! can use several memory pools having a different granularity to minimize the maintenance overhead. Multiple pools
//! feature requires `kFlagUseMultiplePools` flag to be set.
//!
-//! - The allocator doesn't store any information in executable memory, instead,
-//! the implementation uses two bit-vectors to manage allocated memory of each
-//! allocator-block. The first bit-vector called 'used' is used to track used
-//! memory (where each bit represents memory size defined by granularity) and
-//! the second bit vector called 'stop' is used as a sentinel to mark where
-//! the allocated area ends.
+//! - The allocator doesn't store any information in executable memory, instead, the implementation uses two
+//! bit-vectors to manage allocated memory of each allocator-block. The first bit-vector called 'used' is used to
+//! track used memory (where each bit represents memory size defined by granularity) and the second bit vector called
+//! 'stop' is used as a sentinel to mark where the allocated area ends.
//!
-//! - Internally, the allocator also uses RB tree to keep track of all blocks
-//! across all pools. Each inserted block is added to the tree so it can be
-//! matched fast during `release()` and `shrink()`.
+//! - Internally, the allocator also uses RB tree to keep track of all blocks across all pools. Each inserted block is
+//! added to the tree so it can be matched fast during `release()` and `shrink()`.
class JitAllocator {
public:
ASMJIT_NONCOPYABLE(JitAllocator)
struct Impl {
- //! Allocator options, see \ref JitAllocator::Options.
- uint32_t options;
+ //! Allocator options.
+ JitAllocatorOptions options;
//! Base block size (0 if the allocator is not initialized).
uint32_t blockSize;
//! Base granularity (0 if the allocator is not initialized).
@@ -77,45 +89,6 @@ public:
//! Allocator implementation (private).
Impl* _impl;
- enum Options : uint32_t {
- //! Enables the use of an anonymous memory-mapped memory that is mapped into
- //! two buffers having a different pointer. The first buffer has read and
- //! execute permissions and the second buffer has read+write permissions.
- //!
- //! See \ref VirtMem::allocDualMapping() for more details about this feature.
- kOptionUseDualMapping = 0x00000001u,
-
- //! Enables the use of multiple pools with increasing granularity instead of
- //! a single pool. This flag would enable 3 internal pools in total having
- //! 64, 128, and 256 bytes granularity.
- //!
- //! This feature is only recommended for users that generate a lot of code
- //! and would like to minimize the overhead of `JitAllocator` itself by
- //! having blocks of different allocation granularities. Using this feature
- //! only for few allocations won't pay off as the allocator may need to
- //! create more blocks initially before it can take the advantage of
- //! variable block granularity.
- kOptionUseMultiplePools = 0x00000002u,
-
- //! Always fill reserved memory by a fill-pattern.
- //!
- //! Causes a new block to be cleared by the fill pattern and freshly
- //! released memory to be cleared before making it ready for another use.
- kOptionFillUnusedMemory = 0x00000004u,
-
- //! When this flag is set the allocator would immediately release unused
- //! blocks during `release()` or `reset()`. When this flag is not set the
- //! allocator would keep one empty block in each pool to prevent excessive
- //! virtual memory allocations and deallocations in border cases, which
- //! involve constantly allocating and deallocating a single block caused
- //! by repetitive calling `alloc()` and `release()` when the allocator has
- //! either no blocks or have all blocks fully occupied.
- kOptionImmediateRelease = 0x00000008u,
-
- //! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`.
- kOptionCustomFillPattern = 0x10000000u
- };
-
//! \name Construction & Destruction
//! \{
@@ -132,39 +105,35 @@ public:
//! JitAllocator allocator(&params);
//! ```
struct CreateParams {
- //! Allocator options, see \ref JitAllocator::Options.
+ //! Allocator options.
//!
//! No options are used by default.
- uint32_t options;
+ JitAllocatorOptions options = JitAllocatorOptions::kNone;
//! Base size of a single block in bytes (default 64kB).
//!
- //! \remarks Block size must be equal or greater to page size and must be
- //! power of 2. If the input is not valid then the default block size will
- //! be used instead.
- uint32_t blockSize;
+ //! \remarks Block size must be equal to or greater than page size and must be power of 2. If the input is not
+ //! valid then the default block size will be used instead.
+ uint32_t blockSize = 0;
- //! Base granularity (and also natural alignment) of allocations in bytes
- //! (default 64).
+ //! Base granularity (and also natural alignment) of allocations in bytes (default 64).
//!
- //! Since the `JitAllocator` uses bit-arrays to mark used memory the
- //! granularity also specifies how many bytes correspond to a single bit in
- //! such bit-array. Higher granularity means more waste of virtual memory
- //! (as it increases the natural alignment), but smaller bit-arrays as less
- //! bits would be required per a single block.
- uint32_t granularity;
+ //! Since the `JitAllocator` uses bit-arrays to mark used memory the granularity also specifies how many bytes
+ //! correspond to a single bit in such bit-array. Higher granularity means more waste of virtual memory (as it
+ //! increases the natural alignment), but smaller bit-arrays as less bits would be required per a single block.
+ uint32_t granularity = 0;
//! Patter to use to fill unused memory.
//!
- //! Only used if \ref kOptionCustomFillPattern is set.
- uint32_t fillPattern;
+ //! Only used if \ref JitAllocatorOptions::kCustomFillPattern is set.
+ uint32_t fillPattern = 0;
// Reset the content of `CreateParams`.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
};
//! Creates a `JitAllocator` instance.
- explicit ASMJIT_API JitAllocator(const CreateParams* params = nullptr) noexcept;
+ ASMJIT_API explicit JitAllocator(const CreateParams* params = nullptr) noexcept;
//! Destroys the `JitAllocator` instance and release all blocks held.
ASMJIT_API ~JitAllocator() noexcept;
@@ -172,10 +141,9 @@ public:
//! Free all allocated memory - makes all pointers returned by `alloc()` invalid.
//!
- //! \remarks This function is not thread-safe as it's designed to be used when
- //! nobody else is using allocator. The reason is that there is no point of
- //1 calling `reset()` when the allocator is still in use.
- ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept;
+ //! \remarks This function is not thread-safe as it's designed to be used when nobody else is using allocator.
+ //! The reason is that there is no point of calling `reset()` when the allocator is still in use.
+ ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
//! \}
@@ -183,9 +151,9 @@ public:
//! \{
//! Returns allocator options, see `Flags`.
- inline uint32_t options() const noexcept { return _impl->options; }
+ inline JitAllocatorOptions options() const noexcept { return _impl->options; }
//! Tests whether the allocator has the given `option` set.
- inline bool hasOption(uint32_t option) const noexcept { return (_impl->options & option) != 0; }
+ inline bool hasOption(JitAllocatorOptions option) const noexcept { return uint32_t(_impl->options & option) != 0; }
//! Returns a base block size (a minimum size of block that the allocator would allocate).
inline uint32_t blockSize() const noexcept { return _impl->blockSize; }
@@ -199,20 +167,31 @@ public:
//! \name Alloc & Release
//! \{
- //! Allocate `size` bytes of virtual memory.
+ //! Allocates a new memory block of the requested `size`.
//!
- //! \remarks This function is thread-safe.
- ASMJIT_API Error alloc(void** roPtrOut, void** rwPtrOut, size_t size) noexcept;
+ //! When the function is successful it stores two pointers in `rxPtrOut` and `rwPtrOut`. The pointers will be
+ //! different only if `kOptionUseDualMapping` was used to setup the allocator (in that case the `rxPtrOut` would
+ //! point to a Read+Execute region and `rwPtrOut` would point to a Read+Write region of the same memory-mapped block.
+ ASMJIT_API Error alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept;
- //! Release a memory returned by `alloc()`.
+ //! Releases a memory block returned by `alloc()`.
//!
//! \remarks This function is thread-safe.
- ASMJIT_API Error release(void* roPtr) noexcept;
+ ASMJIT_API Error release(void* rxPtr) noexcept;
- //! Free extra memory allocated with `p` by restricting it to `newSize` size.
+ //! Frees extra memory allocated with `rxPtr` by shrinking it to the given `newSize`.
//!
//! \remarks This function is thread-safe.
- ASMJIT_API Error shrink(void* roPtr, size_t newSize) noexcept;
+ ASMJIT_API Error shrink(void* rxPtr, size_t newSize) noexcept;
+
+ //! Queries information about an allocated memory block that contains the given `rxPtr`.
+ //!
+ //! The function returns `kErrorOk` when `rxPtr` is matched and fills `rxPtrOut`, `rwPtrOut`, and `sizeOut` output
+ //! arguments. The returned `rxPtrOut` and `rwPtrOut` pointers point to the beginning of the block, and `sizeOut`
+ //! describes the total amount of bytes this allocation uses - `sizeOut` will always be aligned to the allocation
+ //! granularity, so for example if an allocation was 1 byte and the size granularity is 64, the returned `sizeOut`
+ //! will be 64 bytes, because that's what the allocator sees.
+ ASMJIT_API Error query(void* rxPtr, void** rxPtrOut, void** rwPtrOut, size_t* sizeOut) const noexcept;
//! \}
@@ -223,6 +202,8 @@ public:
struct Statistics {
//! Number of blocks `JitAllocator` maintains.
size_t _blockCount;
+ //! Number of active allocations.
+ size_t _allocationCount;
//! How many bytes are currently used / allocated.
size_t _usedSize;
//! How many bytes are currently reserved by the allocator.
@@ -239,6 +220,8 @@ public:
//! Returns count of blocks managed by `JitAllocator` at the moment.
inline size_t blockCount() const noexcept { return _blockCount; }
+ //! Returns the number of active allocations.
+ inline size_t allocationCount() const noexcept { return _allocationCount; }
//! Returns how many bytes are currently used.
inline size_t usedSize() const noexcept { return _usedSize; }
diff --git a/src/asmjit/core/jitruntime.cpp b/src/asmjit/core/jitruntime.cpp
index a2b46d7..85fbdc4 100644
--- a/src/asmjit/core/jitruntime.cpp
+++ b/src/asmjit/core/jitruntime.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_JIT
@@ -29,44 +11,14 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::JitRuntime - Utilities]
-// ============================================================================
-
-// Only useful on non-x86 architectures.
-static inline void JitRuntime_flushInstructionCache(const void* p, size_t size) noexcept {
-#if ASMJIT_ARCH_X86
- DebugUtils::unused(p, size);
-#else
-# if defined(_WIN32)
- // Windows has a built-in support in `kernel32.dll`.
- ::FlushInstructionCache(::GetCurrentProcess(), p, size);
-# elif defined(__GNUC__)
- char* start = static_cast<char*>(const_cast<void*>(p));
- char* end = start + size;
- __builtin___clear_cache(start, end);
-# else
- DebugUtils::unused(p, size);
-# endif
-#endif
-}
-
-// ============================================================================
-// [asmjit::JitRuntime - Construction / Destruction]
-// ============================================================================
-
JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept
: _allocator(params) {
- _environment = hostEnvironment();
- _environment.setFormat(Environment::kFormatJIT);
+ _environment = Environment::host();
+ _environment.setObjectFormat(ObjectFormat::kJIT);
}
JitRuntime::~JitRuntime() noexcept {}
-// ============================================================================
-// [asmjit::JitRuntime - Interface]
-// ============================================================================
-
Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
*dst = nullptr;
@@ -77,14 +29,14 @@ Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
if (ASMJIT_UNLIKELY(estimatedCodeSize == 0))
return DebugUtils::errored(kErrorNoCodeGenerated);
- uint8_t* ro;
+ uint8_t* rx;
uint8_t* rw;
- ASMJIT_PROPAGATE(_allocator.alloc((void**)&ro, (void**)&rw, estimatedCodeSize));
+ ASMJIT_PROPAGATE(_allocator.alloc((void**)&rx, (void**)&rw, estimatedCodeSize));
// Relocate the code.
- Error err = code->relocateToBase(uintptr_t((void*)ro));
+ Error err = code->relocateToBase(uintptr_t((void*)rx));
if (ASMJIT_UNLIKELY(err)) {
- _allocator.release(ro);
+ _allocator.release(rx);
return err;
}
@@ -92,26 +44,28 @@ Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
// in case that some relocations didn't require records in an address table.
size_t codeSize = code->codeSize();
- for (Section* section : code->_sections) {
- size_t offset = size_t(section->offset());
- size_t bufferSize = size_t(section->bufferSize());
- size_t virtualSize = size_t(section->virtualSize());
+ if (codeSize < estimatedCodeSize)
+ _allocator.shrink(rx, codeSize);
- ASMJIT_ASSERT(offset + bufferSize <= codeSize);
- memcpy(rw + offset, section->data(), bufferSize);
+ {
+ VirtMem::ProtectJitReadWriteScope rwScope(rx, codeSize);
- if (virtualSize > bufferSize) {
- ASMJIT_ASSERT(offset + virtualSize <= codeSize);
- memset(rw + offset + bufferSize, 0, virtualSize - bufferSize);
- }
- }
+ for (Section* section : code->_sections) {
+ size_t offset = size_t(section->offset());
+ size_t bufferSize = size_t(section->bufferSize());
+ size_t virtualSize = size_t(section->virtualSize());
- if (codeSize < estimatedCodeSize)
- _allocator.shrink(ro, codeSize);
+ ASMJIT_ASSERT(offset + bufferSize <= codeSize);
+ memcpy(rw + offset, section->data(), bufferSize);
- flush(ro, codeSize);
- *dst = ro;
+ if (virtualSize > bufferSize) {
+ ASMJIT_ASSERT(offset + virtualSize <= codeSize);
+ memset(rw + offset + bufferSize, 0, virtualSize - bufferSize);
+ }
+ }
+ }
+ *dst = rx;
return kErrorOk;
}
@@ -119,10 +73,6 @@ Error JitRuntime::_release(void* p) noexcept {
return _allocator.release(p);
}
-void JitRuntime::flush(const void* p, size_t size) noexcept {
- JitRuntime_flushInstructionCache(p, size);
-}
-
ASMJIT_END_NAMESPACE
#endif
diff --git a/src/asmjit/core/jitruntime.h b/src/asmjit/core/jitruntime.h
index 91880e6..6f35e21 100644
--- a/src/asmjit/core/jitruntime.h
+++ b/src/asmjit/core/jitruntime.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_JITRUNTIME_H_INCLUDED
#define ASMJIT_CORE_JITRUNTIME_H_INCLUDED
@@ -38,10 +20,6 @@ class CodeHolder;
//! \addtogroup asmjit_virtual_memory
//! \{
-// ============================================================================
-// [asmjit::JitRuntime]
-// ============================================================================
-
//! JIT execution runtime is a special `Target` that is designed to store and
//! execute the generated code.
class ASMJIT_VIRTAPI JitRuntime : public Target {
@@ -55,11 +33,11 @@ public:
//! \{
//! Creates a `JitRuntime` instance.
- explicit ASMJIT_API JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept;
+ ASMJIT_API explicit JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept;
//! Destroys the `JitRuntime` instance.
ASMJIT_API virtual ~JitRuntime() noexcept;
- inline void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept {
+ inline void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
_allocator.reset(resetPolicy);
}
@@ -79,12 +57,10 @@ public:
// NOTE: To allow passing function pointers to `add()` and `release()` the
// virtual methods are prefixed with `_` and called from templates instead.
- //! Allocates memory needed for a code stored in the `CodeHolder` and relocates
- //! the code to the pointer allocated.
+ //! Allocates memory needed for a code stored in the `CodeHolder` and relocates the code to the pointer allocated.
//!
- //! The beginning of the memory allocated for the function is returned in `dst`.
- //! If failed `Error` code is returned and `dst` is explicitly set to `nullptr`
- //! (this means that you don't have to set it to null before calling `add()`).
+ //! The beginning of the memory allocated for the function is returned in `dst`. If failed `Error` code is returned
+ //! and `dst` is explicitly set to `nullptr` (this means that you don't have to set it to null before calling `add()`).
template<typename Func>
inline Error add(Func* dst, CodeHolder* code) noexcept {
return _add(Support::ptr_cast_impl<void**, Func*>(dst), code);
@@ -102,19 +78,6 @@ public:
//! Type-unsafe version of `release()`.
ASMJIT_API virtual Error _release(void* p) noexcept;
- //! Flushes an instruction cache.
- //!
- //! This member function is called after the code has been copied to the
- //! destination buffer. It is only useful for JIT code generation as it
- //! causes a flush of the processor's cache.
- //!
- //! Flushing is basically a NOP under X86, but is needed by architectures
- //! that do not have a transparent instruction cache like ARM.
- //!
- //! This function can also be overridden to improve compatibility with tools
- //! such as Valgrind, however, it's not an official part of AsmJit.
- ASMJIT_API virtual void flush(const void* p, size_t size) noexcept;
-
//! \}
};
diff --git a/src/asmjit/core/logger.cpp b/src/asmjit/core/logger.cpp
index 90b17e3..4567b3c 100644
--- a/src/asmjit/core/logger.cpp
+++ b/src/asmjit/core/logger.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_LOGGING
@@ -30,18 +12,13 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Logger - Construction / Destruction]
-// ============================================================================
+// Logger - Implementation
+// =======================
Logger::Logger() noexcept
: _options() {}
Logger::~Logger() noexcept {}
-// ============================================================================
-// [asmjit::Logger - Logging]
-// ============================================================================
-
Error Logger::logf(const char* fmt, ...) noexcept {
Error err;
va_list ap;
@@ -59,18 +36,13 @@ Error Logger::logv(const char* fmt, va_list ap) noexcept {
return log(sb);
}
-// ============================================================================
-// [asmjit::FileLogger - Construction / Destruction]
-// ============================================================================
+// FileLogger - Implementation
+// ===========================
FileLogger::FileLogger(FILE* file) noexcept
: _file(file) {}
FileLogger::~FileLogger() noexcept {}
-// ============================================================================
-// [asmjit::FileLogger - Logging]
-// ============================================================================
-
Error FileLogger::_log(const char* data, size_t size) noexcept {
if (!_file)
return kErrorOk;
@@ -82,17 +54,12 @@ Error FileLogger::_log(const char* data, size_t size) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::StringLogger - Construction / Destruction]
-// ============================================================================
+// StringLogger - Implementation
+// =============================
StringLogger::StringLogger() noexcept {}
StringLogger::~StringLogger() noexcept {}
-// ============================================================================
-// [asmjit::StringLogger - Logging]
-// ============================================================================
-
Error StringLogger::_log(const char* data, size_t size) noexcept {
return _content.append(data, size);
}
diff --git a/src/asmjit/core/logger.h b/src/asmjit/core/logger.h
index ddc1cfc..d416a50 100644
--- a/src/asmjit/core/logger.h
+++ b/src/asmjit/core/logger.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_LOGGING_H_INCLUDED
#define ASMJIT_CORE_LOGGING_H_INCLUDED
@@ -35,15 +17,10 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_logging
//! \{
-// ============================================================================
-// [asmjit::Logger]
-// ============================================================================
-
//! Logging interface.
//!
-//! This class can be inherited and reimplemented to fit into your own logging
-//! needs. When reimplementing a logger use \ref Logger::_log() method to log
-//! customize the output.
+//! This class can be inherited and reimplemented to fit into your own logging needs. When reimplementing a logger
+//! use \ref Logger::_log() method to log customize the output.
//!
//! There are two `Logger` implementations offered by AsmJit:
//! - \ref FileLogger - logs into a `FILE*`.
@@ -73,25 +50,35 @@ public:
inline FormatOptions& options() noexcept { return _options; }
//! \overload
inline const FormatOptions& options() const noexcept { return _options; }
+ //! Sets formatting options of this Logger to `options`.
+ inline void setOptions(const FormatOptions& options) noexcept { _options = options; }
+ //! Resets formatting options of this Logger to defaults.
+ inline void resetOptions() noexcept { _options.reset(); }
- //! Returns formatting flags, see \ref FormatOptions::Flags.
- inline uint32_t flags() const noexcept { return _options.flags(); }
+ //! Returns formatting flags.
+ inline FormatFlags flags() const noexcept { return _options.flags(); }
//! Tests whether the logger has the given `flag` enabled.
- inline bool hasFlag(uint32_t flag) const noexcept { return _options.hasFlag(flag); }
- //! Sets formatting flags to `flags`, see \ref FormatOptions::Flags.
- inline void setFlags(uint32_t flags) noexcept { _options.setFlags(flags); }
- //! Enables the given formatting `flags`, see \ref FormatOptions::Flags.
- inline void addFlags(uint32_t flags) noexcept { _options.addFlags(flags); }
- //! Disables the given formatting `flags`, see \ref FormatOptions::Flags.
- inline void clearFlags(uint32_t flags) noexcept { _options.clearFlags(flags); }
-
- //! Returns indentation of `type`, see \ref FormatOptions::IndentationType.
- inline uint32_t indentation(uint32_t type) const noexcept { return _options.indentation(type); }
- //! Sets indentation of the given indentation `type` to `n` spaces, see \ref
- //! FormatOptions::IndentationType.
- inline void setIndentation(uint32_t type, uint32_t n) noexcept { _options.setIndentation(type, n); }
- //! Resets indentation of the given indentation `type` to 0 spaces.
- inline void resetIndentation(uint32_t type) noexcept { _options.resetIndentation(type); }
+ inline bool hasFlag(FormatFlags flag) const noexcept { return _options.hasFlag(flag); }
+ //! Sets formatting flags to `flags`.
+ inline void setFlags(FormatFlags flags) noexcept { _options.setFlags(flags); }
+ //! Enables the given formatting `flags`.
+ inline void addFlags(FormatFlags flags) noexcept { _options.addFlags(flags); }
+ //! Disables the given formatting `flags`.
+ inline void clearFlags(FormatFlags flags) noexcept { _options.clearFlags(flags); }
+
+ //! Returns indentation of a given indentation `group`.
+ inline uint32_t indentation(FormatIndentationGroup type) const noexcept { return _options.indentation(type); }
+ //! Sets indentation of the given indentation `group` to `n` spaces.
+ inline void setIndentation(FormatIndentationGroup type, uint32_t n) noexcept { _options.setIndentation(type, n); }
+ //! Resets indentation of the given indentation `group` to 0 spaces.
+ inline void resetIndentation(FormatIndentationGroup type) noexcept { _options.resetIndentation(type); }
+
+ //! Returns padding of a given padding `group`.
+ inline size_t padding(FormatPaddingGroup type) const noexcept { return _options.padding(type); }
+ //! Sets padding of a given padding `group` to `n`.
+ inline void setPadding(FormatPaddingGroup type, uint32_t n) noexcept { _options.setPadding(type, n); }
+ //! Resets padding of a given padding `group` to 0, which means that a default will be used.
+ inline void resetPadding(FormatPaddingGroup type) noexcept { _options.resetPadding(type); }
//! \}
@@ -100,9 +87,8 @@ public:
//! Logs `str` - must be reimplemented.
//!
- //! The function can accept either a null terminated string if `size` is
- //! `SIZE_MAX` or a non-null terminated string of the given `size`. The
- //! function cannot assume that the data is null terminated and must handle
+ //! The function can accept either a null terminated string if `size` is `SIZE_MAX` or a non-null terminated
+ //! string of the given `size`. The function cannot assume that the data is null terminated and must handle
//! non-null terminated inputs.
virtual Error _log(const char* data, size_t size) noexcept = 0;
@@ -111,21 +97,15 @@ public:
//! Logs content of a string `str`.
inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); }
- //! Formats the message by using `snprintf()` and then passes the formatted
- //! string to \ref _log().
+ //! Formats the message by using `snprintf()` and then passes the formatted string to \ref _log().
ASMJIT_API Error logf(const char* fmt, ...) noexcept;
- //! Formats the message by using `vsnprintf()` and then passes the formatted
- //! string to \ref _log().
+ //! Formats the message by using `vsnprintf()` and then passes the formatted string to \ref _log().
ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
//! \}
};
-// ============================================================================
-// [asmjit::FileLogger]
-// ============================================================================
-
//! Logger that can log to a `FILE*`.
class ASMJIT_VIRTAPI FileLogger : public Logger {
public:
@@ -146,17 +126,14 @@ public:
//! \name Accessors
//! \{
- //! Returns the logging output stream or null if the logger has no output
- //! stream.
+ //! Returns the logging output stream or null if the logger has no output stream.
inline FILE* file() const noexcept { return _file; }
//! Sets the logging output stream to `stream` or null.
//!
- //! \note If the `file` is null the logging will be disabled. When a logger
- //! is attached to `CodeHolder` or any emitter the logging API will always
- //! be called regardless of the output file. This means that if you really
- //! want to disable logging at emitter level you must not attach a logger
- //! to it.
+ //! \note If the `file` is null the logging will be disabled. When a logger is attached to `CodeHolder` or any
+ //! emitter the logging API will always be called regardless of the output file. This means that if you really
+ //! want to disable logging at emitter level you must not attach a logger to it.
inline void setFile(FILE* file) noexcept { _file = file; }
//! \}
@@ -164,10 +141,6 @@ public:
ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
};
-// ============================================================================
-// [asmjit::StringLogger]
-// ============================================================================
-
//! Logger that stores everything in an internal string buffer.
class ASMJIT_VIRTAPI StringLogger : public Logger {
public:
diff --git a/src/asmjit/core/misc_p.h b/src/asmjit/core/misc_p.h
index 225ba6a..5cd934e 100644
--- a/src/asmjit/core/misc_p.h
+++ b/src/asmjit/core/misc_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_MISC_P_H_INCLUDED
#define ASMJIT_CORE_MISC_P_H_INCLUDED
diff --git a/src/asmjit/core/operand.cpp b/src/asmjit/core/operand.cpp
index cd5931f..ee02681 100644
--- a/src/asmjit/core/operand.cpp
+++ b/src/asmjit/core/operand.cpp
@@ -1,36 +1,22 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/operand.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Operand - Unit]
-// ============================================================================
+// Operand - Tests
+// ===============
#if defined(ASMJIT_TEST)
+enum class StrongEnumForImmTests : uint32_t {
+ kValue0,
+ kValue0xFFFFFFFF = 0xFFFFFFFFu
+};
+
UNIT(operand) {
INFO("Checking operand sizes");
EXPECT(sizeof(Operand) == 16);
@@ -65,22 +51,23 @@ UNIT(operand) {
EXPECT(dummy.as<BaseReg>().isValid() == false);
// Create some register (not specific to any architecture).
- uint32_t rSig = Operand::kOpReg | (1 << Operand::kSignatureRegTypeShift ) |
- (2 << Operand::kSignatureRegGroupShift) |
- (8 << Operand::kSignatureSizeShift ) ;
- BaseReg r1 = BaseReg::fromSignatureAndId(rSig, 5);
+ OperandSignature rSig = OperandSignature::fromOpType(OperandType::kReg) |
+ OperandSignature::fromRegType(RegType::kVec128) |
+ OperandSignature::fromRegGroup(RegGroup::kVec) |
+ OperandSignature::fromSize(8);
+ BaseReg r1(rSig, 5);
EXPECT(r1.isValid() == true);
EXPECT(r1.isReg() == true);
- EXPECT(r1.isReg(1) == true);
+ EXPECT(r1.isReg(RegType::kVec128) == true);
EXPECT(r1.isPhysReg() == true);
EXPECT(r1.isVirtReg() == false);
EXPECT(r1.signature() == rSig);
- EXPECT(r1.type() == 1);
- EXPECT(r1.group() == 2);
+ EXPECT(r1.type() == RegType::kVec128);
+ EXPECT(r1.group() == RegGroup::kVec);
EXPECT(r1.size() == 8);
EXPECT(r1.id() == 5);
- EXPECT(r1.isReg(1, 5) == true); // RegType and Id.
+ EXPECT(r1.isReg(RegType::kVec128, 5) == true); // RegType and Id.
EXPECT(r1._data[0] == 0);
EXPECT(r1._data[1] == 0);
@@ -88,7 +75,7 @@ UNIT(operand) {
BaseReg r2(r1, 6);
EXPECT(r2.isValid() == true);
EXPECT(r2.isReg() == true);
- EXPECT(r2.isReg(1) == true);
+ EXPECT(r2.isReg(RegType::kVec128) == true);
EXPECT(r2.isPhysReg() == true);
EXPECT(r2.isVirtReg() == false);
EXPECT(r2.signature() == rSig);
@@ -96,7 +83,7 @@ UNIT(operand) {
EXPECT(r2.group() == r1.group());
EXPECT(r2.size() == r1.size());
EXPECT(r2.id() == 6);
- EXPECT(r2.isReg(1, 6) == true);
+ EXPECT(r2.isReg(RegType::kVec128, 6) == true);
r1.reset();
EXPECT(!r1.isReg());
@@ -126,17 +113,19 @@ UNIT(operand) {
INFO("Checking basic functionality of Imm");
Imm immValue(-42);
- EXPECT(immValue.type() == Imm::kTypeInteger);
+ EXPECT(immValue.type() == ImmType::kInt);
EXPECT(Imm(-1).value() == -1);
EXPECT(imm(-1).value() == -1);
EXPECT(immValue.value() == -42);
EXPECT(imm(0xFFFFFFFF).value() == int64_t(0xFFFFFFFF));
Imm immDouble(0.4);
- EXPECT(immDouble.type() == Imm::kTypeDouble);
+ EXPECT(immDouble.type() == ImmType::kDouble);
EXPECT(immDouble.valueAs<double>() == 0.4);
EXPECT(immDouble == imm(0.4));
+ EXPECT(Imm(StrongEnumForImmTests::kValue0).value() == 0);
+ EXPECT(Imm(StrongEnumForImmTests::kValue0xFFFFFFFF).value() == 0xFFFFFFFFu);
}
#endif
diff --git a/src/asmjit/core/operand.h b/src/asmjit/core/operand.h
index 61a81bd..96ef3ba 100644
--- a/src/asmjit/core/operand.h
+++ b/src/asmjit/core/operand.h
@@ -1,236 +1,466 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_OPERAND_H_INCLUDED
#define ASMJIT_CORE_OPERAND_H_INCLUDED
#include "../core/archcommons.h"
#include "../core/support.h"
+#include "../core/type.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [Macros]
-// ============================================================================
-
-//! Adds a template specialization for `REG_TYPE` into the local `RegTraits`.
-#define ASMJIT_DEFINE_REG_TRAITS(REG, REG_TYPE, GROUP, SIZE, COUNT, TYPE_ID) \
-template<> \
-struct RegTraits<REG_TYPE> { \
- typedef REG RegT; \
- \
- static constexpr uint32_t kValid = 1; \
- static constexpr uint32_t kCount = COUNT; \
- static constexpr uint32_t kTypeId = TYPE_ID; \
- \
- static constexpr uint32_t kType = REG_TYPE; \
- static constexpr uint32_t kGroup = GROUP; \
- static constexpr uint32_t kSize = SIZE; \
- \
- static constexpr uint32_t kSignature = \
- (Operand::kOpReg << Operand::kSignatureOpTypeShift ) | \
- (kType << Operand::kSignatureRegTypeShift ) | \
- (kGroup << Operand::kSignatureRegGroupShift) | \
- (kSize << Operand::kSignatureSizeShift ) ; \
-}
-
-//! Adds constructors and member functions to a class that implements abstract
-//! register. Abstract register is register that doesn't have type or signature
-//! yet, it's a base class like `x86::Reg` or `arm::Reg`.
-#define ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
-public: \
- /*! Default constructor that only setups basics. */ \
- constexpr REG() noexcept \
- : BASE(SignatureAndId(kSignature, kIdBad)) {} \
- \
- /*! Makes a copy of the `other` register operand. */ \
- constexpr REG(const REG& other) noexcept \
- : BASE(other) {} \
- \
- /*! Makes a copy of the `other` register having id set to `rId` */ \
- constexpr REG(const BaseReg& other, uint32_t rId) noexcept \
- : BASE(other, rId) {} \
- \
- /*! Creates a register based on `signature` and `rId`. */ \
- constexpr explicit REG(const SignatureAndId& sid) noexcept \
- : BASE(sid) {} \
- \
- /*! Creates a completely uninitialized REG register operand (garbage). */ \
- inline explicit REG(Globals::NoInit_) noexcept \
- : BASE(Globals::NoInit) {} \
- \
- /*! Creates a new register from register type and id. */ \
- static inline REG fromTypeAndId(uint32_t rType, uint32_t rId) noexcept { \
- return REG(SignatureAndId(signatureOf(rType), rId)); \
- } \
- \
- /*! Creates a new register from register signature and id. */ \
- static inline REG fromSignatureAndId(uint32_t rSgn, uint32_t rId) noexcept {\
- return REG(SignatureAndId(rSgn, rId)); \
- } \
- \
- /*! Clones the register operand. */ \
- constexpr REG clone() const noexcept { return REG(*this); } \
- \
- inline REG& operator=(const REG& other) noexcept = default;
-
-//! Adds constructors and member functions to a class that implements final
-//! register. Final registers MUST HAVE a valid signature.
-#define ASMJIT_DEFINE_FINAL_REG(REG, BASE, TRAITS) \
-public: \
- static constexpr uint32_t kThisType = TRAITS::kType; \
- static constexpr uint32_t kThisGroup = TRAITS::kGroup; \
- static constexpr uint32_t kThisSize = TRAITS::kSize; \
- static constexpr uint32_t kSignature = TRAITS::kSignature; \
- \
- ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
- \
- /*! Creates a register operand having its id set to `rId`. */ \
- constexpr explicit REG(uint32_t rId) noexcept \
- : BASE(SignatureAndId(kSignature, rId)) {}
-
//! \addtogroup asmjit_assembler
//! \{
-// ============================================================================
-// [asmjit::Operand_]
-// ============================================================================
+//! Operand type used by \ref Operand_.
+enum class OperandType : uint32_t {
+ //! Not an operand or not initialized.
+ kNone = 0,
+ //! Operand is a register.
+ kReg = 1,
+ //! Operand is a memory.
+ kMem = 2,
+ //! Operand is an immediate value.
+ kImm = 3,
+ //! Operand is a label.
+ kLabel = 4,
+
+ //! Maximum value of `OperandType`.
+ kMaxValue = kLabel
+};
-//! Constructor-less `Operand`.
-//!
-//! Contains no initialization code and can be used safely to define an array
-//! of operands that won't be initialized. This is an `Operand` compatible
-//! data structure designed to be statically initialized, static const, or to
-//! be used by the user to define an array of operands without having them
-//! default initialized.
-//!
-//! The key difference between `Operand` and `Operand_`:
+static_assert(uint32_t(OperandType::kMem) == uint32_t(OperandType::kReg) + 1,
+ "AsmJit requires that `OperandType::kMem` equals to `OperandType::kReg + 1`");
+
+//! Register mask is a convenience typedef that describes a mask where each bit describes a physical register id
+//! in the same \ref RegGroup. At the moment 32 bits are enough as AsmJit doesn't support any architecture that
+//! would provide more than 32 registers for a register group.
+typedef uint32_t RegMask;
+
+//! Register type.
//!
-//! ```
-//! Operand_ xArray[10]; // Not initialized, contains garbage.
-//! Operand yArray[10]; // All operands initialized to none.
-//! ```
-struct Operand_ {
- //! Operand's signature that provides operand type and additional information.
- uint32_t _signature;
- //! Either base id as used by memory operand or any id as used by others.
- uint32_t _baseId;
+//! Provides a unique type that can be used to identify a register or its view.
+enum class RegType : uint8_t {
+ //! No register - unused, invalid, multiple meanings.
+ kNone = 0,
- //! Data specific to the operand type.
+ //! This is not a register type. This value is reserved for a \ref Label that used in \ref BaseMem as a base.
//!
- //! The reason we don't use union is that we have `constexpr` constructors that
- //! construct operands and other `constexpr` functions that return whether another
- //! Operand or something else. These cannot generally work with unions so we also
- //! cannot use `union` if we want to be standard compliant.
- uint32_t _data[2];
+ //! Label tag is used as a sub-type, forming a unique signature across all operand types as 0x1 is never associated
+ //! with any register type. This means that a memory operand's BASE register can be constructed from virtually any
+ //! operand (register vs. label) by just assigning its type (register type or label-tag) and operand id.
+ kLabelTag = 1,
+
+ //! Universal type describing program counter (PC) or instruction pointer (IP) register, if the target architecture
+ //! actually exposes it as a separate register type, which most modern targets do.
+ kPC = 2,
+
+ //! 8-bit low general purpose register (X86).
+ kGp8Lo = 3,
+ //! 8-bit high general purpose register (X86).
+ kGp8Hi = 4,
+ //! 16-bit general purpose register (X86).
+ kGp16 = 5,
+ //! 32-bit general purpose register (X86|ARM).
+ kGp32 = 6,
+ //! 64-bit general purpose register (X86|ARM).
+ kGp64 = 7,
+ //! 8-bit view of a vector register (ARM).
+ kVec8 = 8,
+ //! 16-bit view of a vector register (ARM).
+ kVec16 = 9,
+ //! 32-bit view of a vector register (ARM).
+ kVec32 = 10,
+ //! 64-bit view of a vector register (ARM).
+ //!
+ //! \note This is never used for MMX registers on X86, MMX registers have its own category.
+ kVec64 = 11,
+ //! 128-bit view of a vector register (X86|ARM).
+ kVec128 = 12,
+ //! 256-bit view of a vector register (X86).
+ kVec256 = 13,
+ //! 512-bit view of a vector register (X86).
+ kVec512 = 14,
+ //! 1024-bit view of a vector register (future).
+ kVec1024 = 15,
+ //! View of a vector register, which width is implementation specific (AArch64).
+ kVecNLen = 16,
+
+ //! Mask register (X86).
+ kMask = 17,
+
+ //! Start of architecture dependent register types.
+ kExtra = 18,
+
+ // X86 Specific Register Types
+ // ---------------------------
+
+ //! Instruction pointer (RIP), only addressable in \ref x86::Mem in 64-bit targets.
+ kX86_Rip = kPC,
+ //! Low GPB register (AL, BL, CL, DL, ...).
+ kX86_GpbLo = kGp8Lo,
+ //! High GPB register (AH, BH, CH, DH only).
+ kX86_GpbHi = kGp8Hi,
+ //! GPW register.
+ kX86_Gpw = kGp16,
+ //! GPD register.
+ kX86_Gpd = kGp32,
+ //! GPQ register (64-bit).
+ kX86_Gpq = kGp64,
+ //! XMM register (SSE+).
+ kX86_Xmm = kVec128,
+ //! YMM register (AVX+).
+ kX86_Ymm = kVec256,
+ //! ZMM register (AVX512+).
+ kX86_Zmm = kVec512,
+ //! K register (AVX512+).
+ kX86_KReg = kMask,
+ //! MMX register.
+ kX86_Mm = kExtra + 0,
+ //! Segment register (None, ES, CS, SS, DS, FS, GS).
+ kX86_SReg = kExtra + 1,
+ //! Control register (CR).
+ kX86_CReg = kExtra + 2,
+ //! Debug register (DR).
+ kX86_DReg = kExtra + 3,
+ //! FPU (x87) register.
+ kX86_St = kExtra + 4,
+ //! Bound register (BND).
+ kX86_Bnd = kExtra + 5,
+ //! TMM register (AMX_TILE)
+ kX86_Tmm = kExtra + 6,
+
+ //! Maximum value of `RegType`.
+ kMaxValue = 31
+};
+ASMJIT_DEFINE_ENUM_COMPARE(RegType)
- //! Indexes to `_data` array.
- enum DataIndex : uint32_t {
- kDataMemIndexId = 0,
- kDataMemOffsetLo = 1,
+//! Register group.
+//!
+//! Provides a unique value that identifies groups of registers and their views.
+enum class RegGroup : uint8_t {
+ //! General purpose register group compatible with all backends.
+ kGp = 0,
+ //! Vector register group compatible with all backends.
+ //!
+ //! Describes X86 XMM|YMM|ZMM registers ARM/AArch64 V registers.
+ kVec = 1,
+
+ //! Extra virtual group #2 that can be used by Compiler for register allocation.
+ kExtraVirt2 = 2,
+ //! Extra virtual group #3 that can be used by Compiler for register allocation.
+ kExtraVirt3 = 3,
+
+ //! Program counter group.
+ kPC = 4,
+
+ //! Extra non-virtual group that can be used by registers not managed by Compiler.
+ kExtraNonVirt = 5,
+
+ // X86 Specific Register Groups
+ // ----------------------------
+
+ //! K register group (KReg) - maps to \ref RegGroup::kExtraVirt2 (X86, X86_64).
+ kX86_K = kExtraVirt2,
+ //! MMX register group (MM) - maps to \ref RegGroup::kExtraVirt3 (X86, X86_64).
+ kX86_MM = kExtraVirt3,
+
+ //! Instruction pointer (X86, X86_64).
+ kX86_Rip = kPC,
+ //! Segment register group (X86, X86_64).
+ kX86_SReg = kExtraNonVirt + 0,
+ //! CR register group (X86, X86_64).
+ kX86_CReg = kExtraNonVirt + 1,
+ //! DR register group (X86, X86_64).
+ kX86_DReg = kExtraNonVirt + 2,
+ //! FPU register group (X86, X86_64).
+ kX86_St = kExtraNonVirt + 3,
+ //! BND register group (X86, X86_64).
+ kX86_Bnd = kExtraNonVirt + 4,
+ //! TMM register group (X86, X86_64).
+ kX86_Tmm = kExtraNonVirt + 5,
+
+ //! First group - only used in loops.
+ k0 = 0,
+ //! Last value of a virtual register that is managed by \ref BaseCompiler.
+ kMaxVirt = Globals::kNumVirtGroups - 1,
+ //! Maximum value of `RegGroup`.
+ kMaxValue = 15
+};
+ASMJIT_DEFINE_ENUM_COMPARE(RegGroup)
- kDataImmValueLo = ASMJIT_ARCH_LE ? 0 : 1,
- kDataImmValueHi = ASMJIT_ARCH_LE ? 1 : 0
- };
+typedef Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kMaxVirt> RegGroupVirtValues;
- //! Operand types that can be encoded in `Operand`.
- enum OpType : uint32_t {
- //! Not an operand or not initialized.
- kOpNone = 0,
- //! Operand is a register.
- kOpReg = 1,
- //! Operand is a memory.
- kOpMem = 2,
- //! Operand is an immediate value.
- kOpImm = 3,
- //! Operand is a label.
- kOpLabel = 4
- };
- static_assert(kOpMem == kOpReg + 1, "asmjit::Operand requires `kOpMem` to be `kOpReg+1`.");
-
- //! Label tag.
- enum LabelTag {
- //! Label tag is used as a sub-type, forming a unique signature across all
- //! operand types as 0x1 is never associated with any register type. This
- //! means that a memory operand's BASE register can be constructed from
- //! virtually any operand (register vs. label) by just assigning its type
- //! (register type or label-tag) and operand id.
- kLabelTag = 0x1
- };
+//! Operand signature is a 32-bit number describing \ref Operand and some of its payload.
+//!
+//! In AsmJit operand signature is used to store additional payload of register, memory, and immediate operands.
+//! In practice the biggest pressure on OperandSignature is from \ref BaseMem and architecture specific memory
+//! operands that need to store additional payload that cannot be stored elsewhere as values of all other members
+//! are fully specified by \ref BaseMem.
+struct OperandSignature {
+ //! \name Constants
+ //! \{
- // \cond INTERNAL
- enum SignatureBits : uint32_t {
+ enum : uint32_t {
// Operand type (3 least significant bits).
// |........|........|........|.....XXX|
- kSignatureOpTypeShift = 0,
- kSignatureOpTypeMask = 0x07u << kSignatureOpTypeShift,
+ kOpTypeShift = 0,
+ kOpTypeMask = 0x07u << kOpTypeShift,
// Register type (5 bits).
// |........|........|........|XXXXX...|
- kSignatureRegTypeShift = 3,
- kSignatureRegTypeMask = 0x1Fu << kSignatureRegTypeShift,
+ kRegTypeShift = 3,
+ kRegTypeMask = 0x1Fu << kRegTypeShift,
// Register group (4 bits).
// |........|........|....XXXX|........|
- kSignatureRegGroupShift = 8,
- kSignatureRegGroupMask = 0x0Fu << kSignatureRegGroupShift,
+ kRegGroupShift = 8,
+ kRegGroupMask = 0x0Fu << kRegGroupShift,
// Memory base type (5 bits).
// |........|........|........|XXXXX...|
- kSignatureMemBaseTypeShift = 3,
- kSignatureMemBaseTypeMask = 0x1Fu << kSignatureMemBaseTypeShift,
+ kMemBaseTypeShift = 3,
+ kMemBaseTypeMask = 0x1Fu << kMemBaseTypeShift,
// Memory index type (5 bits).
// |........|........|...XXXXX|........|
- kSignatureMemIndexTypeShift = 8,
- kSignatureMemIndexTypeMask = 0x1Fu << kSignatureMemIndexTypeShift,
+ kMemIndexTypeShift = 8,
+ kMemIndexTypeMask = 0x1Fu << kMemIndexTypeShift,
// Memory base+index combined (10 bits).
// |........|........|...XXXXX|XXXXX...|
- kSignatureMemBaseIndexShift = 3,
- kSignatureMemBaseIndexMask = 0x3FFu << kSignatureMemBaseIndexShift,
+ kMemBaseIndexShift = 3,
+ kMemBaseIndexMask = 0x3FFu << kMemBaseIndexShift,
// This memory operand represents a home-slot or stack (Compiler) (1 bit).
// |........|........|..X.....|........|
- kSignatureMemRegHomeShift = 13,
- kSignatureMemRegHomeFlag = 0x01u << kSignatureMemRegHomeShift,
+ kMemRegHomeShift = 13,
+ kMemRegHomeFlag = 0x01u << kMemRegHomeShift,
// Immediate type (1 bit).
// |........|........|........|....X...|
- kSignatureImmTypeShift = 4,
- kSignatureImmTypeMask = 0x01u << kSignatureImmTypeShift,
+ kImmTypeShift = 3,
+ kImmTypeMask = 0x01u << kImmTypeShift,
// Predicate used by either registers or immediate values (4 bits).
// |........|XXXX....|........|........|
- kSignaturePredicateShift = 20,
- kSignaturePredicateMask = 0x0Fu << kSignaturePredicateShift,
+ kPredicateShift = 20,
+ kPredicateMask = 0x0Fu << kPredicateShift,
// Operand size (8 most significant bits).
// |XXXXXXXX|........|........|........|
- kSignatureSizeShift = 24,
- kSignatureSizeMask = 0xFFu << kSignatureSizeShift
+ kSizeShift = 24,
+ kSizeMask = 0xFFu << kSizeShift
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ uint32_t _bits;
+
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
+
+ inline OperandSignature() noexcept = default;
+ inline constexpr OperandSignature(const OperandSignature& other) noexcept = default;
+ inline constexpr explicit OperandSignature(uint32_t bits) noexcept : _bits(bits) {}
+
+ //! \{
+
+ //! \name Overloaded Operators
+ //!
+ //! Overloaded operators make `OperandSignature` behave like regular integer.
+ //!
+ //! \{
+
+ inline constexpr bool operator!() const noexcept { return _bits != 0; }
+ inline constexpr explicit operator bool() const noexcept { return _bits != 0; }
+
+ inline OperandSignature& operator=(uint32_t x) noexcept { _bits = x; return *this; }
+ inline OperandSignature& operator|=(uint32_t x) noexcept { _bits |= x; return *this; }
+ inline OperandSignature& operator&=(uint32_t x) noexcept { _bits &= x; return *this; }
+ inline OperandSignature& operator^=(uint32_t x) noexcept { _bits ^= x; return *this; }
+
+ inline OperandSignature& operator=(const OperandSignature& other) noexcept { return operator=(other._bits); }
+ inline OperandSignature& operator|=(const OperandSignature& other) noexcept { return operator|=(other._bits); }
+ inline OperandSignature& operator&=(const OperandSignature& other) noexcept { return operator&=(other._bits); }
+ inline OperandSignature& operator^=(const OperandSignature& other) noexcept { return operator^=(other._bits); }
+
+ inline constexpr OperandSignature operator~() const noexcept { return OperandSignature(~_bits); }
+
+ inline constexpr OperandSignature operator|(uint32_t x) const noexcept { return OperandSignature(_bits | x); }
+ inline constexpr OperandSignature operator&(uint32_t x) const noexcept { return OperandSignature(_bits & x); }
+ inline constexpr OperandSignature operator^(uint32_t x) const noexcept { return OperandSignature(_bits ^ x); }
+
+ inline constexpr OperandSignature operator|(const OperandSignature& other) const noexcept { return OperandSignature(_bits | other._bits); }
+ inline constexpr OperandSignature operator&(const OperandSignature& other) const noexcept { return OperandSignature(_bits & other._bits); }
+ inline constexpr OperandSignature operator^(const OperandSignature& other) const noexcept { return OperandSignature(_bits ^ other._bits); }
+
+ inline constexpr bool operator==(uint32_t x) const noexcept { return _bits == x; }
+ inline constexpr bool operator!=(uint32_t x) const noexcept { return _bits != x; }
+
+ inline constexpr bool operator==(const OperandSignature& other) const noexcept { return _bits == other._bits; }
+ inline constexpr bool operator!=(const OperandSignature& other) const noexcept { return _bits != other._bits; }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ inline void reset() noexcept { _bits = 0; }
+
+ inline constexpr uint32_t bits() const noexcept { return _bits; }
+ inline void setBits(uint32_t bits) noexcept { _bits = bits; }
+
+ template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
+ inline constexpr bool hasField() const noexcept {
+ return (_bits & kFieldMask) != 0;
+ }
+
+ template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
+ inline constexpr bool hasField(uint32_t value) const noexcept {
+ return (_bits & kFieldMask) != value << kFieldShift;
+ }
+
+ template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
+ inline constexpr uint32_t getField() const noexcept {
+ return (_bits >> kFieldShift) & (kFieldMask >> kFieldShift);
+ }
+
+ template<uint32_t kFieldMask, uint32_t kFieldShift = Support::ConstCTZ<kFieldMask>::value>
+ inline void setField(uint32_t value) noexcept {
+ ASMJIT_ASSERT((value & ~(kFieldMask >> kFieldShift)) == 0);
+ _bits = (_bits & ~kFieldMask) | (value << kFieldShift);
+ }
+
+ inline constexpr OperandSignature subset(uint32_t mask) const noexcept { return OperandSignature(_bits & mask); }
+
+ template<uint32_t kFieldMask>
+ inline constexpr bool matchesSignature(const OperandSignature& signature) const noexcept {
+ return (_bits & kFieldMask) == signature._bits;
+ }
+
+ template<uint32_t kFieldMask>
+ inline constexpr bool matchesFields(uint32_t bits) const noexcept {
+ return (_bits & kFieldMask) == bits;
+ }
+
+ template<uint32_t kFieldMask>
+ inline constexpr bool matchesFields(const OperandSignature& fields) const noexcept {
+ return (_bits & kFieldMask) == fields._bits;
+ }
+
+ inline constexpr bool isValid() const noexcept { return _bits != 0; }
+
+ inline constexpr OperandType opType() const noexcept { return (OperandType)getField<kOpTypeMask>(); }
+
+ inline constexpr RegType regType() const noexcept { return (RegType)getField<kRegTypeMask>(); }
+ inline constexpr RegGroup regGroup() const noexcept { return (RegGroup)getField<kRegGroupMask>(); }
+
+ inline constexpr RegType memBaseType() const noexcept { return (RegType)getField<kMemBaseTypeMask>(); }
+ inline constexpr RegType memIndexType() const noexcept { return (RegType)getField<kMemIndexTypeMask>(); }
+
+ inline constexpr uint32_t predicate() const noexcept { return getField<kPredicateMask>(); }
+ inline constexpr uint32_t size() const noexcept { return getField<kSizeMask>(); }
+
+ inline void setOpType(OperandType opType) noexcept { setField<kOpTypeMask>(uint32_t(opType)); }
+ inline void setRegType(RegType regType) noexcept { setField<kRegTypeMask>(uint32_t(regType)); }
+ inline void setRegGroup(RegGroup regGroup) noexcept { setField<kRegGroupMask>(uint32_t(regGroup)); }
+
+ inline void setMemBaseType(RegGroup baseType) noexcept { setField<kMemBaseTypeMask>(uint32_t(baseType)); }
+ inline void setMemIndexType(RegGroup indexType) noexcept { setField<kMemIndexTypeMask>(uint32_t(indexType)); }
+
+ inline void setPredicate(uint32_t predicate) noexcept { setField<kPredicateMask>(predicate); }
+ inline void setSize(uint32_t size) noexcept { setField<kSizeMask>(size); }
+
+ //! \}
+
+ //! \name Static Constructors
+ //! \{
+
+ static inline constexpr OperandSignature fromBits(uint32_t bits) noexcept {
+ return OperandSignature(bits);
+ }
+
+ template<uint32_t kFieldMask, typename T>
+ static inline constexpr OperandSignature fromValue(const T& value) noexcept {
+ return OperandSignature(uint32_t(value) << Support::ConstCTZ<kFieldMask>::value);
+ }
+
+ static inline constexpr OperandSignature fromOpType(OperandType opType) noexcept {
+ return OperandSignature(uint32_t(opType) << kOpTypeShift);
+ }
+
+ static inline constexpr OperandSignature fromRegType(RegType regType) noexcept {
+ return OperandSignature(uint32_t(regType) << kRegTypeShift);
+ }
+
+ static inline constexpr OperandSignature fromRegGroup(RegGroup regGroup) noexcept {
+ return OperandSignature(uint32_t(regGroup) << kRegGroupShift);
+ }
+
+ static inline constexpr OperandSignature fromRegTypeAndGroup(RegType regType, RegGroup regGroup) noexcept {
+ return fromRegType(regType) | fromRegGroup(regGroup);
+ }
+
+ static inline constexpr OperandSignature fromMemBaseType(RegType baseType) noexcept {
+ return OperandSignature(uint32_t(baseType) << kMemBaseTypeShift);
+ }
+
+ static inline constexpr OperandSignature fromMemIndexType(RegType indexType) noexcept {
+ return OperandSignature(uint32_t(indexType) << kMemIndexTypeShift);
+ }
+
+ static inline constexpr OperandSignature fromPredicate(uint32_t predicate) noexcept {
+ return OperandSignature(predicate << kPredicateShift);
+ }
+
+ static inline constexpr OperandSignature fromSize(uint32_t size) noexcept {
+ return OperandSignature(size << kSizeShift);
+ }
+
+ //! \}
+};
+
+//! Base class representing an operand in AsmJit (non-default constructed version).
+//!
+//! Contains no initialization code and can be used safely to define an array of operands that won't be initialized.
+//! This is a \ref Operand base structure designed to be statically initialized, static const, or to be used by user
+//! code to define an array of operands without having them default initialized at construction time.
+//!
+//! The key difference between \ref Operand and \ref Operand_ is:
+//!
+//! ```
+//! Operand_ xArray[10]; // Not initialized, contains garbage.
+//! Operand_ yArray[10] {}; // All operands initialized to none explicitly (zero initialized).
+//! Operand yArray[10]; // All operands initialized to none implicitly (zero initialized).
+//! ```
+struct Operand_ {
+ //! \name Types
+ //! \{
+
+ typedef OperandSignature Signature;
+
+ //! \}
+
+ //! \name Constants
+ //! \{
+
+ // Indexes to `_data` array.
+ enum DataIndex : uint32_t {
+ kDataMemIndexId = 0,
+ kDataMemOffsetLo = 1,
+
+ kDataImmValueLo = ASMJIT_ARCH_LE ? 0 : 1,
+ kDataImmValueHi = ASMJIT_ARCH_LE ? 1 : 0
};
- //! \endcond
//! Constants useful for VirtId <-> Index translation.
enum VirtIdConstants : uint32_t {
@@ -242,22 +472,40 @@ struct Operand_ {
kVirtIdCount = uint32_t(kVirtIdMax - kVirtIdMin + 1)
};
- //! Tests whether the given `id` is a valid virtual register id. Since AsmJit
- //! supports both physical and virtual registers it must be able to distinguish
- //! between these two. The idea is that physical registers are always limited
- //! in size, so virtual identifiers start from `kVirtIdMin` and end at `kVirtIdMax`.
- static ASMJIT_INLINE bool isVirtId(uint32_t id) noexcept { return id - kVirtIdMin < uint32_t(kVirtIdCount); }
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ //! Provides operand type and additional payload.
+ Signature _signature;
+ //! Either base id as used by memory operand or any id as used by others.
+ uint32_t _baseId;
+
+ //! Data specific to the operand type.
+ //!
+ //! The reason we don't use union is that we have `constexpr` constructors that construct operands and other
+ //!`constexpr` functions that return whether another Operand or something else. These cannot generally work with
+ //! unions so we also cannot use `union` if we want to be standard compliant.
+ uint32_t _data[2];
+
+ //! \}
+
+ //! Tests whether the given `id` is a valid virtual register id. Since AsmJit supports both physical and virtual
+ //! registers it must be able to distinguish between these two. The idea is that physical registers are always
+ //! limited in size, so virtual identifiers start from `kVirtIdMin` and end at `kVirtIdMax`.
+ static inline bool isVirtId(uint32_t id) noexcept { return id - kVirtIdMin < uint32_t(kVirtIdCount); }
//! Converts a real-id into a packed-id that can be stored in Operand.
- static ASMJIT_INLINE uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
+ static inline uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
//! Converts a packed-id back to real-id.
- static ASMJIT_INLINE uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; }
+ static inline uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; }
//! \name Construction & Destruction
//! \{
//! \cond INTERNAL
//! Initializes a `BaseReg` operand from `signature` and register `id`.
- inline void _initReg(uint32_t signature, uint32_t id) noexcept {
+ inline void _initReg(const Signature& signature, uint32_t id) noexcept {
_signature = signature;
_baseId = id;
_data[0] = 0;
@@ -271,14 +519,13 @@ struct Operand_ {
//! Resets the `Operand` to none.
//!
//! None operand is defined the following way:
- //! - Its signature is zero (kOpNone, and the rest zero as well).
+ //! - Its signature is zero (OperandType::kNone, and the rest zero as well).
//! - Its id is `0`.
//! - The reserved8_4 field is set to `0`.
//! - The reserved12_4 field is set to zero.
//!
- //! In other words, reset operands have all members set to zero. Reset operand
- //! must match the Operand state right after its construction. Alternatively,
- //! if you have an array of operands, you can simply use `memset()`.
+ //! In other words, reset operands have all members set to zero. Reset operand must match the Operand state
+ //! right after its construction. Alternatively, if you have an array of operands, you can simply use `memset()`.
//!
//! ```
//! using namespace asmjit;
@@ -305,13 +552,13 @@ struct Operand_ {
//! \}
- //! \name Operator Overloads
+ //! \name Overloaded Operators
//! \{
//! Tests whether this operand is the same as `other`.
- constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); }
+ inline constexpr bool operator==(const Operand_& other) const noexcept { return equals(other); }
//! Tests whether this operand is not the same as `other`.
- constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); }
+ inline constexpr bool operator!=(const Operand_& other) const noexcept { return !equals(other); }
//! \}
@@ -331,153 +578,116 @@ struct Operand_ {
//! \name Accessors
//! \{
- //! Tests whether the operand's signature matches the given signature `sign`.
- constexpr bool hasSignature(uint32_t signature) const noexcept { return _signature == signature; }
//! Tests whether the operand's signature matches the signature of the `other` operand.
- constexpr bool hasSignature(const Operand_& other) const noexcept { return _signature == other.signature(); }
+ inline constexpr bool hasSignature(const Operand_& other) const noexcept { return _signature == other._signature; }
+ //! Tests whether the operand's signature matches the given signature `sign`.
+ inline constexpr bool hasSignature(const Signature& other) const noexcept { return _signature == other; }
//! Returns operand signature as unsigned 32-bit integer.
//!
- //! Signature is first 4 bytes of the operand data. It's used mostly for
- //! operand checking as it's much faster to check 4 bytes at once than having
- //! to check these bytes individually.
- constexpr uint32_t signature() const noexcept { return _signature; }
+ //! Signature is first 4 bytes of the operand data. It's used mostly for operand checking as it's
+ //! much faster to check packed 4 bytes at once than having to check these bytes individually.
+ inline constexpr Signature signature() const noexcept { return _signature; }
//! Sets the operand signature, see `signature()`.
//!
//! \note Improper use of `setSignature()` can lead to hard-to-debug errors.
- inline void setSignature(uint32_t signature) noexcept { _signature = signature; }
-
- //! \cond INTERNAL
- template<uint32_t mask>
- constexpr bool _hasSignaturePart() const noexcept {
- return (_signature & mask) != 0;
- }
-
- template<uint32_t mask>
- constexpr bool _hasSignaturePart(uint32_t signature) const noexcept {
- return (_signature & mask) == signature;
- }
-
- template<uint32_t mask>
- constexpr uint32_t _getSignaturePart() const noexcept {
- return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
- }
-
- template<uint32_t mask>
- inline void _setSignaturePart(uint32_t value) noexcept {
- ASMJIT_ASSERT((value & ~(mask >> Support::constCtz(mask))) == 0);
- _signature = (_signature & ~mask) | (value << Support::constCtz(mask));
- }
- //! \endcond
+ inline void setSignature(const Signature& signature) noexcept { _signature = signature; }
//! Returns the type of the operand, see `OpType`.
- constexpr uint32_t opType() const noexcept { return _getSignaturePart<kSignatureOpTypeMask>(); }
- //! Tests whether the operand is none (`kOpNone`).
- constexpr bool isNone() const noexcept { return _signature == 0; }
- //! Tests whether the operand is a register (`kOpReg`).
- constexpr bool isReg() const noexcept { return opType() == kOpReg; }
- //! Tests whether the operand is a memory location (`kOpMem`).
- constexpr bool isMem() const noexcept { return opType() == kOpMem; }
- //! Tests whether the operand is an immediate (`kOpImm`).
- constexpr bool isImm() const noexcept { return opType() == kOpImm; }
- //! Tests whether the operand is a label (`kOpLabel`).
- constexpr bool isLabel() const noexcept { return opType() == kOpLabel; }
+ inline constexpr OperandType opType() const noexcept { return _signature.opType(); }
+ //! Tests whether the operand is none (`OperandType::kNone`).
+ inline constexpr bool isNone() const noexcept { return _signature == Signature::fromBits(0); }
+ //! Tests whether the operand is a register (`OperandType::kReg`).
+ inline constexpr bool isReg() const noexcept { return opType() == OperandType::kReg; }
+ //! Tests whether the operand is a memory location (`OperandType::kMem`).
+ inline constexpr bool isMem() const noexcept { return opType() == OperandType::kMem; }
+ //! Tests whether the operand is an immediate (`OperandType::kImm`).
+ inline constexpr bool isImm() const noexcept { return opType() == OperandType::kImm; }
+ //! Tests whether the operand is a label (`OperandType::kLabel`).
+ inline constexpr bool isLabel() const noexcept { return opType() == OperandType::kLabel; }
//! Tests whether the operand is a physical register.
- constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; }
+ inline constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; }
//! Tests whether the operand is a virtual register.
- constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; }
+ inline constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; }
//! Tests whether the operand specifies a size (i.e. the size is not zero).
- constexpr bool hasSize() const noexcept { return _hasSignaturePart<kSignatureSizeMask>(); }
+ inline constexpr bool hasSize() const noexcept { return _signature.hasField<Signature::kSizeMask>(); }
//! Tests whether the size of the operand matches `size`.
- constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
+ inline constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
//! Returns the size of the operand in bytes.
//!
//! The value returned depends on the operand type:
//! * None - Should always return zero size.
- //! * Reg - Should always return the size of the register. If the register
- //! size depends on architecture (like `x86::CReg` and `x86::DReg`)
- //! the size returned should be the greatest possible (so it should
- //! return 64-bit size in such case).
+ //! * Reg - Should always return the size of the register. If the register size depends on architecture
+ //! (like `x86::CReg` and `x86::DReg`) the size returned should be the greatest possible (so it
+ //! should return 64-bit size in such case).
//! * Mem - Size is optional and will be in most cases zero.
//! * Imm - Should always return zero size.
//! * Label - Should always return zero size.
- constexpr uint32_t size() const noexcept { return _getSignaturePart<kSignatureSizeMask>(); }
+ inline constexpr uint32_t size() const noexcept { return _signature.getField<Signature::kSizeMask>(); }
//! Returns the operand id.
//!
//! The value returned should be interpreted accordingly to the operand type:
//! * None - Should be `0`.
//! * Reg - Physical or virtual register id.
- //! * Mem - Multiple meanings - BASE address (register or label id), or
- //! high value of a 64-bit absolute address.
+ //! * Mem - Multiple meanings - BASE address (register or label id), or high value of a 64-bit absolute address.
//! * Imm - Should be `0`.
- //! * Label - Label id if it was created by using `newLabel()` or
- //! `Globals::kInvalidId` if the label is invalid or not
- //! initialized.
- constexpr uint32_t id() const noexcept { return _baseId; }
+ //! * Label - Label id if it was created by using `newLabel()` or `Globals::kInvalidId` if the label is invalid or
+ //! not initialized.
+ inline constexpr uint32_t id() const noexcept { return _baseId; }
//! Tests whether the operand is 100% equal to `other` operand.
//!
//! \note This basically performs a binary comparison, if aby bit is
//! different the operands are not equal.
- constexpr bool equals(const Operand_& other) const noexcept {
+ inline constexpr bool equals(const Operand_& other) const noexcept {
return (_signature == other._signature) &
(_baseId == other._baseId ) &
(_data[0] == other._data[0] ) &
(_data[1] == other._data[1] ) ;
}
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use equals() instead")
- constexpr bool isEqual(const Operand_& other) const noexcept { return equals(other); }
-#endif //!ASMJIT_NO_DEPRECATED
-
- //! Tests whether the operand is a register matching `rType`.
- constexpr bool isReg(uint32_t rType) const noexcept {
- return (_signature & (kSignatureOpTypeMask | kSignatureRegTypeMask)) ==
- ((kOpReg << kSignatureOpTypeShift) | (rType << kSignatureRegTypeShift));
+ //! Tests whether the operand is a register matching the given register `type`.
+ inline constexpr bool isReg(RegType type) const noexcept {
+ return _signature.subset(Signature::kOpTypeMask | Signature::kRegTypeMask) == (Signature::fromOpType(OperandType::kReg) | Signature::fromRegType(type));
}
- //! Tests whether the operand is register and of `rType` and `rId`.
- constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept {
- return isReg(rType) && id() == rId;
+ //! Tests whether the operand is register and of register `type` and `id`.
+ inline constexpr bool isReg(RegType type, uint32_t id) const noexcept {
+ return isReg(type) && this->id() == id;
}
//! Tests whether the operand is a register or memory.
- constexpr bool isRegOrMem() const noexcept {
- return Support::isBetween<uint32_t>(opType(), kOpReg, kOpMem);
+ inline constexpr bool isRegOrMem() const noexcept {
+ return Support::isBetween<uint32_t>(uint32_t(opType()), uint32_t(OperandType::kReg), uint32_t(OperandType::kMem));
}
//! \}
};
-// ============================================================================
-// [asmjit::Operand]
-// ============================================================================
-
-//! Operand can contain register, memory location, immediate, or label.
+//! Base class representing an operand in AsmJit (default constructed version).
class Operand : public Operand_ {
public:
//! \name Construction & Destruction
//! \{
//! Creates `kOpNone` operand having all members initialized to zero.
- constexpr Operand() noexcept
- : Operand_{ kOpNone, 0u, { 0u, 0u }} {}
+ inline constexpr Operand() noexcept
+ : Operand_{ Signature::fromOpType(OperandType::kNone), 0u, { 0u, 0u }} {}
//! Creates a cloned `other` operand.
- constexpr Operand(const Operand& other) noexcept = default;
+ inline constexpr Operand(const Operand& other) noexcept = default;
//! Creates a cloned `other` operand.
- constexpr explicit Operand(const Operand_& other)
+ inline constexpr explicit Operand(const Operand_& other)
: Operand_(other) {}
//! Creates an operand initialized to raw `[u0, u1, u2, u3]` values.
- constexpr Operand(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
+ inline constexpr Operand(Globals::Init_, const Signature& u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
: Operand_{ u0, u1, { u2, u3 }} {}
//! Creates an uninitialized operand (dangerous).
@@ -485,7 +695,7 @@ public:
//! \}
- //! \name Operator Overloads
+ //! \name Overloaded Operators
//! \{
inline Operand& operator=(const Operand& other) noexcept = default;
@@ -493,26 +703,21 @@ public:
//! \}
- //! \name Utilities
+ //! \name Clone
//! \{
//! Clones this operand and returns its copy.
- constexpr Operand clone() const noexcept { return Operand(*this); }
+ inline constexpr Operand clone() const noexcept { return Operand(*this); }
//! \}
};
static_assert(sizeof(Operand) == 16, "asmjit::Operand must be exactly 16 bytes long");
-// ============================================================================
-// [asmjit::Label]
-// ============================================================================
-
//! Label (jump target or data location).
//!
-//! Label represents a location in code typically used as a jump target, but
-//! may be also a reference to some data or a static variable. Label has to be
-//! explicitly created by BaseEmitter.
+//! Label represents a location in code typically used as a jump target, but may be also a reference to some data or
+//! a static variable. Label has to be explicitly created by BaseEmitter.
//!
//! Example of using labels:
//!
@@ -535,41 +740,27 @@ static_assert(sizeof(Operand) == 16, "asmjit::Operand must be exactly 16 bytes l
//! ```
class Label : public Operand {
public:
- //! Type of the Label.
- enum LabelType : uint32_t {
- //! Anonymous (unnamed) label.
- kTypeAnonymous = 0,
- //! Local label (always has parentId).
- kTypeLocal = 1,
- //! Global label (never has parentId).
- kTypeGlobal = 2,
- //! External label (references an external symbol).
- kTypeExternal = 3,
- //! Number of label types.
- kTypeCount = 4
- };
-
//! \name Construction & Destruction
//! \{
//! Creates a label operand without ID (you must set the ID to make it valid).
- constexpr Label() noexcept
- : Operand(Globals::Init, kOpLabel, Globals::kInvalidId, 0, 0) {}
+ inline constexpr Label() noexcept
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kLabel), Globals::kInvalidId, 0, 0) {}
//! Creates a cloned label operand of `other`.
- constexpr Label(const Label& other) noexcept
+ inline constexpr Label(const Label& other) noexcept
: Operand(other) {}
//! Creates a label operand of the given `id`.
- constexpr explicit Label(uint32_t id) noexcept
- : Operand(Globals::Init, kOpLabel, id, 0, 0) {}
+ inline constexpr explicit Label(uint32_t id) noexcept
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kLabel), id, 0, 0) {}
inline explicit Label(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
//! Resets the label, will reset all properties and set its ID to `Globals::kInvalidId`.
inline void reset() noexcept {
- _signature = kOpLabel;
+ _signature = Signature::fromOpType(OperandType::kLabel);
_baseId = Globals::kInvalidId;
_data[0] = 0;
_data[1] = 0;
@@ -588,190 +779,81 @@ public:
//! \{
//! Tests whether the label was created by CodeHolder and/or an attached emitter.
- constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; }
+ inline constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; }
//! Sets the label `id`.
inline void setId(uint32_t id) noexcept { _baseId = id; }
//! \}
};
-// ============================================================================
-// [asmjit::BaseRegTraits]
-// ============================================================================
-
//! \cond INTERNAL
//! Default register traits.
struct BaseRegTraits {
- //! RegType is not valid by default.
- static constexpr uint32_t kValid = 0;
- //! Count of registers (0 if none).
- static constexpr uint32_t kCount = 0;
- //! Everything is void by default.
- static constexpr uint32_t kTypeId = 0;
-
- //! Zero type by default.
- static constexpr uint32_t kType = 0;
- //! Zero group by default.
- static constexpr uint32_t kGroup = 0;
- //! No size by default.
- static constexpr uint32_t kSize = 0;
-
- //! Empty signature by default (not even having operand type set to register).
- static constexpr uint32_t kSignature = 0;
+ enum : uint32_t {
+ //! \ref TypeId representing this register type, could be \ref TypeId::kVoid if such type doesn't exist.
+ kTypeId = uint32_t(TypeId::kVoid),
+ //! RegType is not valid by default.
+ kValid = 0,
+ //! Count of registers (0 if none).
+ kCount = 0,
+
+ //! Zero type by default (defeaults to None).
+ kType = uint32_t(RegType::kNone),
+ //! Zero group by default (defaults to GP).
+ kGroup = uint32_t(RegGroup::kGp),
+ //! No size by default.
+ kSize = 0,
+
+ //! Empty signature by default (not even having operand type set to register).
+ kSignature = 0
+ };
};
//! \endcond
-// ============================================================================
-// [asmjit::BaseReg]
-// ============================================================================
-
-//! Structure that allows to extract a register information based on the signature.
-//!
-//! This information is compatible with operand's signature (32-bit integer)
-//! and `RegInfo` just provides easy way to access it.
-struct RegInfo {
- inline void reset(uint32_t signature = 0) noexcept { _signature = signature; }
- inline void setSignature(uint32_t signature) noexcept { _signature = signature; }
-
- template<uint32_t mask>
- constexpr uint32_t _getSignaturePart() const noexcept {
- return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
- }
-
- constexpr bool isValid() const noexcept { return _signature != 0; }
- constexpr uint32_t signature() const noexcept { return _signature; }
- constexpr uint32_t opType() const noexcept { return _getSignaturePart<Operand::kSignatureOpTypeMask>(); }
- constexpr uint32_t group() const noexcept { return _getSignaturePart<Operand::kSignatureRegGroupMask>(); }
- constexpr uint32_t type() const noexcept { return _getSignaturePart<Operand::kSignatureRegTypeMask>(); }
- constexpr uint32_t size() const noexcept { return _getSignaturePart<Operand::kSignatureSizeMask>(); }
-
- uint32_t _signature;
-};
-
//! Physical or virtual register operand.
class BaseReg : public Operand {
public:
- static constexpr uint32_t kBaseSignature =
- kSignatureOpTypeMask |
- kSignatureRegTypeMask |
- kSignatureRegGroupMask |
- kSignatureSizeMask ;
-
- //! Architecture neutral register types.
- //!
- //! These must be reused by any platform that contains that types. All GP
- //! and VEC registers are also allowed by design to be part of a BASE|INDEX
- //! of a memory operand.
- enum RegType : uint32_t {
- //! No register - unused, invalid, multiple meanings.
- kTypeNone = 0,
-
- // (1 is used as a LabelTag)
-
- //! 8-bit low general purpose register (X86).
- kTypeGp8Lo = 2,
- //! 8-bit high general purpose register (X86).
- kTypeGp8Hi = 3,
- //! 16-bit general purpose register (X86).
- kTypeGp16 = 4,
- //! 32-bit general purpose register (X86|ARM).
- kTypeGp32 = 5,
- //! 64-bit general purpose register (X86|ARM).
- kTypeGp64 = 6,
- //! 8-bit view of a vector register (ARM).
- kTypeVec8 = 7,
- //! 16-bit view of a vector register (ARM).
- kTypeVec16 = 8,
- //! 32-bit view of a vector register (ARM).
- kTypeVec32 = 9,
- //! 64-bit view of a vector register (ARM).
- kTypeVec64 = 10,
- //! 128-bit view of a vector register (X86|ARM).
- kTypeVec128 = 11,
- //! 256-bit view of a vector register (X86).
- kTypeVec256 = 12,
- //! 512-bit view of a vector register (X86).
- kTypeVec512 = 13,
- //! 1024-bit view of a vector register (future).
- kTypeVec1024 = 14,
- //! Other0 register, should match `kOther0` group.
- kTypeOther0 = 15,
- //! Other1 register, should match `kOther1` group.
- kTypeOther1 = 16,
- //! Universal id of IP/PC register (if separate).
- kTypeIP = 17,
- //! Start of platform dependent register types.
- kTypeCustom = 18,
- //! Maximum possible register type value.
- kTypeMax = 31
- };
-
- //! Register group (architecture neutral), and some limits.
- enum RegGroup : uint32_t {
- //! General purpose register group compatible with all backends.
- kGroupGp = 0,
- //! Vector register group compatible with all backends.
- kGroupVec = 1,
- //! Group that is architecture dependent.
- kGroupOther0 = 2,
- //! Group that is architecture dependent.
- kGroupOther1 = 3,
- //! Count of register groups used by physical and virtual registers.
- kGroupVirt = 4,
- //! Count of register groups used by physical registers only.
- kGroupCount = 16
- };
+ //! \name Constants
+ //! \{
- enum Id : uint32_t {
+ enum : uint32_t {
//! None or any register (mostly internal).
- kIdBad = 0xFFu
- };
+ kIdBad = 0xFFu,
- //! A helper used by constructors.
- struct SignatureAndId {
- uint32_t _signature;
- uint32_t _id;
+ kBaseSignatureMask =
+ Signature::kOpTypeMask |
+ Signature::kRegTypeMask |
+ Signature::kRegGroupMask |
+ Signature::kSizeMask,
- inline SignatureAndId() noexcept = default;
- constexpr SignatureAndId(const SignatureAndId& other) noexcept = default;
-
- constexpr explicit SignatureAndId(uint32_t signature, uint32_t id) noexcept
- : _signature(signature),
- _id(id) {}
-
- constexpr uint32_t signature() const noexcept { return _signature; }
- constexpr uint32_t id() const noexcept { return _id; }
+ kTypeNone = uint32_t(RegType::kNone),
+ kSignature = Signature::fromOpType(OperandType::kReg).bits()
};
- static constexpr uint32_t kSignature = kOpReg;
+ //! \}
//! \name Construction & Destruction
//! \{
//! Creates a dummy register operand.
- constexpr BaseReg() noexcept
- : Operand(Globals::Init, kSignature, kIdBad, 0, 0) {}
+ inline constexpr BaseReg() noexcept
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kReg), kIdBad, 0, 0) {}
//! Creates a new register operand which is the same as `other` .
- constexpr BaseReg(const BaseReg& other) noexcept
+ inline constexpr BaseReg(const BaseReg& other) noexcept
: Operand(other) {}
- //! Creates a new register operand compatible with `other`, but with a different `rId`.
- constexpr BaseReg(const BaseReg& other, uint32_t rId) noexcept
- : Operand(Globals::Init, other._signature, rId, 0, 0) {}
+ //! Creates a new register operand compatible with `other`, but with a different `id`.
+ inline constexpr BaseReg(const BaseReg& other, uint32_t id) noexcept
+ : Operand(Globals::Init, other._signature, id, 0, 0) {}
- //! Creates a register initialized to `signature` and `rId`.
- constexpr explicit BaseReg(const SignatureAndId& sid) noexcept
- : Operand(Globals::Init, sid._signature, sid._id, 0, 0) {}
+ //! Creates a register initialized to the given `signature` and `id`.
+ inline constexpr BaseReg(const Signature& signature, uint32_t id) noexcept
+ : Operand(Globals::Init, signature, id, 0, 0) {}
inline explicit BaseReg(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
- /*! Creates a new register from register signature `rSgn` and id. */
- static inline BaseReg fromSignatureAndId(uint32_t rSgn, uint32_t rId) noexcept {
- return BaseReg(SignatureAndId(rSgn, rId));
- }
-
//! \}
//! \name Overloaded Operators
@@ -786,103 +868,100 @@ public:
//! Returns base signature of the register associated with each register type.
//!
- //! Base signature only contains the operand type, register type, register
- //! group, and register size. It doesn't contain element type, predicate, or
- //! other architecture-specific data. Base signature is a signature that is
+ //! Base signature only contains the operand type, register type, register group, and register size. It doesn't
+ //! contain element type, predicate, or other architecture-specific data. Base signature is a signature that is
//! provided by architecture-specific `RegTraits`, like \ref x86::RegTraits.
- constexpr uint32_t baseSignature() const noexcept {
- return _signature & (kBaseSignature);
- }
+ inline constexpr OperandSignature baseSignature() const noexcept { return _signature & kBaseSignatureMask; }
//! Tests whether the operand's base signature matches the given signature `sign`.
- constexpr bool hasBaseSignature(uint32_t signature) const noexcept { return baseSignature() == signature; }
+ inline constexpr bool hasBaseSignature(uint32_t signature) const noexcept { return baseSignature() == signature; }
+ //! Tests whether the operand's base signature matches the given signature `sign`.
+ inline constexpr bool hasBaseSignature(const OperandSignature& signature) const noexcept { return baseSignature() == signature; }
//! Tests whether the operand's base signature matches the base signature of the `other` operand.
- constexpr bool hasBaseSignature(const BaseReg& other) const noexcept { return baseSignature() == other.baseSignature(); }
+ inline constexpr bool hasBaseSignature(const BaseReg& other) const noexcept { return baseSignature() == other.baseSignature(); }
//! Tests whether this register is the same as `other`.
//!
- //! This is just an optimization. Registers by default only use the first
- //! 8 bytes of Operand data, so this method takes advantage of this knowledge
- //! and only compares these 8 bytes. If both operands were created correctly
- //! both \ref equals() and \ref isSame() should give the same answer, however,
- //! if any of these two contains garbage or other metadata in the upper 8
- //! bytes then \ref isSame() may return `true` in cases in which \ref equals()
+ //! This is just an optimization. Registers by default only use the first 8 bytes of Operand data, so this method
+ //! takes advantage of this knowledge and only compares these 8 bytes. If both operands were created correctly
+ //! both \ref equals() and \ref isSame() should give the same answer, however, if any of these two contains garbage
+ //! or other metadata in the upper 8 bytes then \ref isSame() may return `true` in cases in which \ref equals()
//! returns false.
- constexpr bool isSame(const BaseReg& other) const noexcept {
+ inline constexpr bool isSame(const BaseReg& other) const noexcept {
return (_signature == other._signature) & (_baseId == other._baseId);
}
//! Tests whether the register is valid (either virtual or physical).
- constexpr bool isValid() const noexcept { return (_signature != 0) & (_baseId != kIdBad); }
+ inline constexpr bool isValid() const noexcept { return (_signature != 0) & (_baseId != kIdBad); }
//! Tests whether this is a physical register.
- constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; }
+ inline constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; }
//! Tests whether this is a virtual register.
- constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; }
+ inline constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; }
//! Tests whether the register type matches `type` - same as `isReg(type)`, provided for convenience.
- constexpr bool isType(uint32_t type) const noexcept { return (_signature & kSignatureRegTypeMask) == (type << kSignatureRegTypeShift); }
+ inline constexpr bool isType(RegType type) const noexcept { return _signature.subset(Signature::kRegTypeMask) == Signature::fromRegType(type); }
//! Tests whether the register group matches `group`.
- constexpr bool isGroup(uint32_t group) const noexcept { return (_signature & kSignatureRegGroupMask) == (group << kSignatureRegGroupShift); }
+ inline constexpr bool isGroup(RegGroup group) const noexcept { return _signature.subset(Signature::kRegGroupMask) == Signature::fromRegGroup(group); }
//! Tests whether the register is a general purpose register (any size).
- constexpr bool isGp() const noexcept { return isGroup(kGroupGp); }
+ inline constexpr bool isGp() const noexcept { return isGroup(RegGroup::kGp); }
//! Tests whether the register is a vector register.
- constexpr bool isVec() const noexcept { return isGroup(kGroupVec); }
+ inline constexpr bool isVec() const noexcept { return isGroup(RegGroup::kVec); }
using Operand_::isReg;
//! Same as `isType()`, provided for convenience.
- constexpr bool isReg(uint32_t rType) const noexcept { return isType(rType); }
- //! Tests whether the register type matches `type` and register id matches `rId`.
- constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept { return isType(rType) && id() == rId; }
+ inline constexpr bool isReg(RegType rType) const noexcept { return isType(rType); }
+ //! Tests whether the register type matches `type` and register id matches `id`.
+ inline constexpr bool isReg(RegType rType, uint32_t id) const noexcept { return isType(rType) && this->id() == id; }
- //! Returns the type of the register.
- constexpr uint32_t type() const noexcept { return _getSignaturePart<kSignatureRegTypeMask>(); }
+ //! Returns the register type.
+ inline constexpr RegType type() const noexcept { return _signature.regType(); }
//! Returns the register group.
- constexpr uint32_t group() const noexcept { return _getSignaturePart<kSignatureRegGroupMask>(); }
+ inline constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
//! Returns operation predicate of the register (ARM/AArch64).
//!
- //! The meaning depends on architecture, for example on ARM hardware this
- //! describes \ref arm::Predicate::ShiftOp of the register.
- constexpr uint32_t predicate() const noexcept { return _getSignaturePart<kSignaturePredicateMask>(); }
+ //! The meaning depends on architecture, for example on ARM hardware this describes \ref arm::ShiftOp
+ //! of the register.
+ inline constexpr uint32_t predicate() const noexcept { return _signature.getField<Signature::kPredicateMask>(); }
//! Sets operation predicate of the register to `predicate` (ARM/AArch64).
//!
- //! The meaning depends on architecture, for example on ARM hardware this
- //! describes \ref arm::Predicate::ShiftOp of the register.
- inline void setPredicate(uint32_t predicate) noexcept { _setSignaturePart<kSignaturePredicateMask>(predicate); }
+ //! The meaning depends on architecture, for example on ARM hardware this describes \ref arm::ShiftOp
+ //! of the register.
+ inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<Signature::kPredicateMask>(predicate); }
//! Resets shift operation type of the register to the default value (ARM/AArch64).
- inline void resetPredicate() noexcept { _setSignaturePart<kSignaturePredicateMask>(0); }
+ inline void resetPredicate() noexcept { _signature.setField<Signature::kPredicateMask>(0); }
//! Clones the register operand.
- constexpr BaseReg clone() const noexcept { return BaseReg(*this); }
+ inline constexpr BaseReg clone() const noexcept { return BaseReg(*this); }
//! Casts this register to `RegT` by also changing its signature.
//!
//! \note Improper use of `cloneAs()` can lead to hard-to-debug errors.
template<typename RegT>
- constexpr RegT cloneAs() const noexcept { return RegT(RegT::kSignature, id()); }
+ inline constexpr RegT cloneAs() const noexcept { return RegT(Signature(RegT::kSignature), id()); }
//! Casts this register to `other` by also changing its signature.
//!
//! \note Improper use of `cloneAs()` can lead to hard-to-debug errors.
template<typename RegT>
- constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(SignatureAndId(other.signature(), id())); }
+ inline constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(other.signature(), id()); }
- //! Sets the register id to `rId`.
- inline void setId(uint32_t rId) noexcept { _baseId = rId; }
+ //! Sets the register id to `id`.
+ inline void setId(uint32_t id) noexcept { _baseId = id; }
//! Sets a 32-bit operand signature based on traits of `RegT`.
template<typename RegT>
inline void setSignatureT() noexcept { _signature = RegT::kSignature; }
- //! Sets the register `signature` and `rId`.
- inline void setSignatureAndId(uint32_t signature, uint32_t rId) noexcept {
+ //! Sets the register `signature` and `id`.
+ inline void setSignatureAndId(const OperandSignature& signature, uint32_t id) noexcept {
_signature = signature;
- _baseId = rId;
+ _baseId = id;
}
//! \}
@@ -893,39 +972,36 @@ public:
//! Tests whether the `op` operand is a general purpose register.
static inline bool isGp(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
- const uint32_t kSgn = (kOpReg << kSignatureOpTypeShift ) |
- (kGroupGp << kSignatureRegGroupShift) ;
- return (op.signature() & (kSignatureOpTypeMask | kSignatureRegGroupMask)) == kSgn;
+ return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask) == (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kGp));
}
//! Tests whether the `op` operand is a vector register.
static inline bool isVec(const Operand_& op) noexcept {
// Check operand type and register group. Not interested in register type and size.
- const uint32_t kSgn = (kOpReg << kSignatureOpTypeShift ) |
- (kGroupVec << kSignatureRegGroupShift) ;
- return (op.signature() & (kSignatureOpTypeMask | kSignatureRegGroupMask)) == kSgn;
+ return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask) == (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kVec));
}
- //! Tests whether the `op` is a general purpose register of the given `rId`.
- static inline bool isGp(const Operand_& op, uint32_t rId) noexcept { return isGp(op) & (op.id() == rId); }
- //! Tests whether the `op` is a vector register of the given `rId`.
- static inline bool isVec(const Operand_& op, uint32_t rId) noexcept { return isVec(op) & (op.id() == rId); }
+ //! Tests whether the `op` is a general purpose register of the given `id`.
+ static inline bool isGp(const Operand_& op, uint32_t id) noexcept { return isGp(op) & (op.id() == id); }
+ //! Tests whether the `op` is a vector register of the given `id`.
+ static inline bool isVec(const Operand_& op, uint32_t id) noexcept { return isVec(op) & (op.id() == id); }
//! \}
};
-// ============================================================================
-// [asmjit::RegOnly]
-// ============================================================================
-
-//! RegOnly is 8-byte version of `BaseReg` that allows to store either register
-//! or nothing.
+//! RegOnly is 8-byte version of `BaseReg` that allows to store either register or nothing.
//!
-//! This class was designed to decrease the space consumed by each extra "operand"
-//! in `BaseEmitter` and `InstNode` classes.
+//! It's designed to decrease the space consumed by an extra "operand" in \ref BaseEmitter and \ref InstNode.
struct RegOnly {
- //! Type of the operand, either `kOpNone` or `kOpReg`.
- uint32_t _signature;
+ //! \name Types
+ //! \{
+
+ typedef OperandSignature Signature;
+
+ //! \}
+
+ //! Operand signature - only \ref OperandType::kNone and \ref OperandType::kReg are supported.
+ Signature _signature;
//! Physical or virtual register id.
uint32_t _id;
@@ -933,7 +1009,7 @@ struct RegOnly {
//! \{
//! Initializes the `RegOnly` instance to hold register `signature` and `id`.
- inline void init(uint32_t signature, uint32_t id) noexcept {
+ inline void init(const OperandSignature& signature, uint32_t id) noexcept {
_signature = signature;
_id = id;
}
@@ -942,7 +1018,7 @@ struct RegOnly {
inline void init(const RegOnly& reg) noexcept { init(reg.signature(), reg.id()); }
//! Resets the `RegOnly` members to zeros (none).
- inline void reset() noexcept { init(0, 0); }
+ inline void reset() noexcept { init(Signature::fromBits(0), 0); }
//! \}
@@ -950,40 +1026,30 @@ struct RegOnly {
//! \{
//! Tests whether this ExtraReg is none (same as calling `Operand_::isNone()`).
- constexpr bool isNone() const noexcept { return _signature == 0; }
+ inline constexpr bool isNone() const noexcept { return _signature == 0; }
//! Tests whether the register is valid (either virtual or physical).
- constexpr bool isReg() const noexcept { return _signature != 0; }
+ inline constexpr bool isReg() const noexcept { return _signature != 0; }
//! Tests whether this is a physical register.
- constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; }
+ inline constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; }
//! Tests whether this is a virtual register (used by `BaseCompiler`).
- constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; }
+ inline constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; }
//! Returns the register signature or 0 if no register is assigned.
- constexpr uint32_t signature() const noexcept { return _signature; }
+ inline constexpr OperandSignature signature() const noexcept { return _signature; }
//! Returns the register id.
//!
- //! \note Always check whether the register is assigned before using the
- //! returned identifier as non-assigned `RegOnly` instance would return
- //! zero id, which is still a valid register id.
- constexpr uint32_t id() const noexcept { return _id; }
+ //! \note Always check whether the register is assigned before using the returned identifier as
+ //! non-assigned `RegOnly` instance would return zero id, which is still a valid register id.
+ inline constexpr uint32_t id() const noexcept { return _id; }
//! Sets the register id.
inline void setId(uint32_t id) noexcept { _id = id; }
- //! \cond INTERNAL
- //!
- //! Extracts information from operand's signature.
- template<uint32_t mask>
- constexpr uint32_t _getSignaturePart() const noexcept {
- return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
- }
- //! \endcond
-
- //! Returns the type of the register.
- constexpr uint32_t type() const noexcept { return _getSignaturePart<Operand::kSignatureRegTypeMask>(); }
+ //! Returns the register type.
+ inline constexpr RegType type() const noexcept { return _signature.regType(); }
//! Returns the register group.
- constexpr uint32_t group() const noexcept { return _getSignaturePart<Operand::kSignatureRegGroupMask>(); }
+ inline constexpr RegGroup group() const noexcept { return _signature.regGroup(); }
//! \}
@@ -992,94 +1058,132 @@ struct RegOnly {
//! Converts this ExtraReg to a real `RegT` operand.
template<typename RegT>
- constexpr RegT toReg() const noexcept { return RegT(BaseReg::SignatureAndId(_signature, _id)); }
+ inline constexpr RegT toReg() const noexcept { return RegT(_signature, _id); }
//! \}
};
-// ============================================================================
-// [asmjit::BaseMem]
-// ============================================================================
+//! \cond INTERNAL
+//! Adds a template specialization for `REG_TYPE` into the local `RegTraits`.
+#define ASMJIT_DEFINE_REG_TRAITS(REG, REG_TYPE, GROUP, SIZE, COUNT, TYPE_ID) \
+template<> \
+struct RegTraits<REG_TYPE> { \
+ typedef REG RegT; \
+ \
+ enum : uint32_t { \
+ kValid = uint32_t(true), \
+ kCount = uint32_t(COUNT), \
+ kType = uint32_t(REG_TYPE), \
+ kGroup = uint32_t(GROUP), \
+ kSize = uint32_t(SIZE), \
+ kTypeId = uint32_t(TYPE_ID), \
+ \
+ kSignature = (OperandSignature::fromOpType(OperandType::kReg) | \
+ OperandSignature::fromRegType(REG_TYPE) | \
+ OperandSignature::fromRegGroup(GROUP) | \
+ OperandSignature::fromSize(kSize)).bits(), \
+ }; \
+}
+
+//! Adds constructors and member functions to a class that implements abstract register. Abstract register is register
+//! that doesn't have type or signature yet, it's a base class like `x86::Reg` or `arm::Reg`.
+#define ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
+public: \
+ /*! Default constructor that only setups basics. */ \
+ inline constexpr REG() noexcept \
+ : BASE(Signature(kSignature), kIdBad) {} \
+ \
+ /*! Makes a copy of the `other` register operand. */ \
+ inline constexpr REG(const REG& other) noexcept \
+ : BASE(other) {} \
+ \
+ /*! Makes a copy of the `other` register having id set to `id` */ \
+ inline constexpr REG(const BaseReg& other, uint32_t id) noexcept \
+ : BASE(other, id) {} \
+ \
+ /*! Creates a register based on `signature` and `id`. */ \
+ inline constexpr REG(const OperandSignature& sgn, uint32_t id) noexcept \
+ : BASE(sgn, id) {} \
+ \
+ /*! Creates a completely uninitialized REG register operand (garbage). */ \
+ inline explicit REG(Globals::NoInit_) noexcept \
+ : BASE(Globals::NoInit) {} \
+ \
+ /*! Creates a new register from register type and id. */ \
+ static inline REG fromTypeAndId(RegType type, uint32_t id) noexcept { \
+ return REG(signatureOf(type), id); \
+ } \
+ \
+ /*! Clones the register operand. */ \
+ inline constexpr REG clone() const noexcept { return REG(*this); } \
+ \
+ inline REG& operator=(const REG& other) noexcept = default;
+
+//! Adds constructors and member functions to a class that implements final register. Final registers MUST HAVE a valid
+//! signature.
+#define ASMJIT_DEFINE_FINAL_REG(REG, BASE, TRAITS) \
+public: \
+ enum : uint32_t { \
+ kThisType = TRAITS::kType, \
+ kThisGroup = TRAITS::kGroup, \
+ kThisSize = TRAITS::kSize, \
+ kSignature = TRAITS::kSignature \
+ }; \
+ \
+ ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
+ \
+ /*! Creates a register operand having its id set to `id`. */ \
+ inline constexpr explicit REG(uint32_t id) noexcept \
+ : BASE(Signature(kSignature), id) {}
+//! \endcond
//! Base class for all memory operands.
//!
-//! \note It's tricky to pack all possible cases that define a memory operand
-//! into just 16 bytes. The `BaseMem` splits data into the following parts:
+//! The data is split into the following parts:
//!
-//! - BASE - Base register or label - requires 36 bits total. 4 bits are used
-//! to encode the type of the BASE operand (label vs. register type) and the
-//! remaining 32 bits define the BASE id, which can be a physical or virtual
-//! register index. If BASE type is zero, which is never used as a register
-//! type and label doesn't use it as well then BASE field contains a high
-//! DWORD of a possible 64-bit absolute address, which is possible on X64.
+//! - BASE - Base register or label - requires 36 bits total. 4 bits are used to encode the type of the BASE operand
+//! (label vs. register type) and the remaining 32 bits define the BASE id, which can be a physical or virtual
+//! register index. If BASE type is zero, which is never used as a register type and label doesn't use it as well
+//! then BASE field contains a high DWORD of a possible 64-bit absolute address, which is possible on X64.
//!
-//! - INDEX - Index register (or theoretically Label, which doesn't make sense).
-//! Encoding is similar to BASE - it also requires 36 bits and splits the
-//! encoding to INDEX type (4 bits defining the register type) and id (32-bits).
+//! - INDEX - Index register (or theoretically Label, which doesn't make sense). Encoding is similar to BASE - it
+//! also requires 36 bits and splits the encoding to INDEX type (4 bits defining the register type) and 32-bit id.
//!
-//! - OFFSET - A relative offset of the address. Basically if BASE is specified
-//! the relative displacement adjusts BASE and an optional INDEX. if BASE is
-//! not specified then the OFFSET should be considered as ABSOLUTE address (at
-//! least on X86). In that case its low 32 bits are stored in DISPLACEMENT
-//! field and the remaining high 32 bits are stored in BASE.
+//! - OFFSET - A relative offset of the address. Basically if BASE is specified the relative displacement adjusts
+//! BASE and an optional INDEX. if BASE is not specified then the OFFSET should be considered as ABSOLUTE address
+//! (at least on X86). In that case its low 32 bits are stored in DISPLACEMENT field and the remaining high 32
+//! bits are stored in BASE.
//!
-//! - OTHER - There is rest 8 bits that can be used for whatever purpose. For
-//! example \ref x86::Mem operand uses these bits to store segment override
-//! prefix and index shift (or scale).
+//! - OTHER - There is rest 8 bits that can be used for whatever purpose. For example \ref x86::Mem operand uses
+//! these bits to store segment override prefix and index shift (or scale).
class BaseMem : public Operand {
public:
- //! \cond INTERNAL
- //! Used internally to construct `BaseMem` operand from decomposed data.
- struct Decomposed {
- uint32_t baseType;
- uint32_t baseId;
- uint32_t indexType;
- uint32_t indexId;
- int32_t offset;
- uint32_t size;
- uint32_t flags;
- };
- //! \endcond
-
//! \name Construction & Destruction
//! \{
//! Creates a default `BaseMem` operand, that points to [0].
- constexpr BaseMem() noexcept
- : Operand(Globals::Init, kOpMem, 0, 0, 0) {}
+ inline constexpr BaseMem() noexcept
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kMem), 0, 0, 0) {}
//! Creates a `BaseMem` operand that is a clone of `other`.
- constexpr BaseMem(const BaseMem& other) noexcept
+ inline constexpr BaseMem(const BaseMem& other) noexcept
: Operand(other) {}
//! Creates a `BaseMem` operand from `baseReg` and `offset`.
//!
- //! \note This is an architecture independent constructor that can be used to
- //! create an architecture independent memory operand to be used in portable
- //! code that can handle multiple architectures.
- constexpr explicit BaseMem(const BaseReg& baseReg, int32_t offset = 0) noexcept
+ //! \note This is an architecture independent constructor that can be used to create an architecture
+ //! independent memory operand to be used in portable code that can handle multiple architectures.
+ inline constexpr explicit BaseMem(const BaseReg& baseReg, int32_t offset = 0) noexcept
: Operand(Globals::Init,
- kOpMem | (baseReg.type() << kSignatureMemBaseTypeShift),
+ Signature::fromOpType(OperandType::kMem) | Signature::fromMemBaseType(baseReg.type()),
baseReg.id(),
0,
uint32_t(offset)) {}
//! \cond INTERNAL
-
//! Creates a `BaseMem` operand from 4 integers as used by `Operand_` struct.
- constexpr BaseMem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
- : Operand(Globals::Init, u0, u1, u2, u3) {}
-
- constexpr BaseMem(const Decomposed& d) noexcept
- : Operand(Globals::Init,
- kOpMem | (d.baseType << kSignatureMemBaseTypeShift )
- | (d.indexType << kSignatureMemIndexTypeShift)
- | (d.size << kSignatureSizeShift )
- | d.flags,
- d.baseId,
- d.indexId,
- uint32_t(d.offset)) {}
-
+ inline constexpr BaseMem(const OperandSignature& u0, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ : Operand(Globals::Init, u0, baseId, indexId, uint32_t(offset)) {}
//! \endcond
//! Creates a completely uninitialized `BaseMem` operand.
@@ -1088,7 +1192,7 @@ public:
//! Resets the memory operand - after the reset the memory points to [0].
inline void reset() noexcept {
- _signature = kOpMem;
+ _signature = Signature::fromOpType(OperandType::kMem);
_baseId = 0;
_data[0] = 0;
_data[1] = 0;
@@ -1107,7 +1211,7 @@ public:
//! \{
//! Clones the memory operand.
- constexpr BaseMem clone() const noexcept { return BaseMem(*this); }
+ inline constexpr BaseMem clone() const noexcept { return BaseMem(*this); }
//! Creates a new copy of this memory operand adjusted by `off`.
inline BaseMem cloneAdjusted(int64_t off) const noexcept {
@@ -1117,57 +1221,72 @@ public:
}
//! Tests whether this memory operand is a register home (only used by \ref asmjit_compiler)
- constexpr bool isRegHome() const noexcept { return _hasSignaturePart<kSignatureMemRegHomeFlag>(); }
+ inline constexpr bool isRegHome() const noexcept { return _signature.hasField<Signature::kMemRegHomeFlag>(); }
//! Mark this memory operand as register home (only used by \ref asmjit_compiler).
- inline void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
+ inline void setRegHome() noexcept { _signature |= Signature::kMemRegHomeFlag; }
//! Marks this operand to not be a register home (only used by \ref asmjit_compiler).
- inline void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
+ inline void clearRegHome() noexcept { _signature &= ~Signature::kMemRegHomeFlag; }
//! Tests whether the memory operand has a BASE register or label specified.
- constexpr bool hasBase() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0; }
+ inline constexpr bool hasBase() const noexcept {
+ return (_signature & Signature::kMemBaseTypeMask) != 0;
+ }
+
//! Tests whether the memory operand has an INDEX register specified.
- constexpr bool hasIndex() const noexcept { return (_signature & kSignatureMemIndexTypeMask) != 0; }
+ inline constexpr bool hasIndex() const noexcept {
+ return (_signature & Signature::kMemIndexTypeMask) != 0;
+ }
+
//! Tests whether the memory operand has BASE or INDEX register.
- constexpr bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
+ inline constexpr bool hasBaseOrIndex() const noexcept {
+ return (_signature & Signature::kMemBaseIndexMask) != 0;
+ }
+
//! Tests whether the memory operand has BASE and INDEX register.
- constexpr bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
+ inline constexpr bool hasBaseAndIndex() const noexcept {
+ return (_signature & Signature::kMemBaseTypeMask) != 0 && (_signature & Signature::kMemIndexTypeMask) != 0;
+ }
- //! Tests whether the BASE operand is a register (registers start after `kLabelTag`).
- constexpr bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); }
//! Tests whether the BASE operand is a label.
- constexpr bool hasBaseLabel() const noexcept { return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift); }
- //! Tests whether the INDEX operand is a register (registers start after `kLabelTag`).
- constexpr bool hasIndexReg() const noexcept { return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift); }
+ inline constexpr bool hasBaseLabel() const noexcept {
+ return _signature.subset(Signature::kMemBaseTypeMask) == Signature::fromMemBaseType(RegType::kLabelTag);
+ }
- //! Returns the type of the BASE register (0 if this memory operand doesn't
- //! use the BASE register).
+ //! Tests whether the BASE operand is a register (registers start after `RegType::kLabelTag`).
+ inline constexpr bool hasBaseReg() const noexcept {
+ return _signature.subset(Signature::kMemBaseTypeMask).bits() > Signature::fromMemBaseType(RegType::kLabelTag).bits();
+ }
+
+ //! Tests whether the INDEX operand is a register (registers start after `RegType::kLabelTag`).
+ inline constexpr bool hasIndexReg() const noexcept {
+ return _signature.subset(Signature::kMemIndexTypeMask).bits() > Signature::fromMemIndexType(RegType::kLabelTag).bits();
+ }
+
+ //! Returns the type of the BASE register (0 if this memory operand doesn't use the BASE register).
//!
- //! \note If the returned type is one (a value never associated to a register
- //! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
- //! You should always check `hasBaseLabel()` before using `baseId()` result.
- constexpr uint32_t baseType() const noexcept { return _getSignaturePart<kSignatureMemBaseTypeMask>(); }
+ //! \note If the returned type is one (a value never associated to a register type) the BASE is not register, but it
+ //! is a label. One equals to `kLabelTag`. You should always check `hasBaseLabel()` before using `baseId()` result.
+ inline constexpr RegType baseType() const noexcept { return _signature.memBaseType(); }
//! Returns the type of an INDEX register (0 if this memory operand doesn't
//! use the INDEX register).
- constexpr uint32_t indexType() const noexcept { return _getSignaturePart<kSignatureMemIndexTypeMask>(); }
+ inline constexpr RegType indexType() const noexcept { return _signature.memIndexType(); }
//! This is used internally for BASE+INDEX validation.
- constexpr uint32_t baseAndIndexTypes() const noexcept { return _getSignaturePart<kSignatureMemBaseIndexMask>(); }
+ inline constexpr uint32_t baseAndIndexTypes() const noexcept { return _signature.getField<Signature::kMemBaseIndexMask>(); }
- //! Returns both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a
- //! single value.
+ //! Returns both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a single value.
//!
- //! \remarks Returns id of the BASE register or label (if the BASE was
- //! specified as label).
- constexpr uint32_t baseId() const noexcept { return _baseId; }
+ //! \remarks Returns id of the BASE register or label (if the BASE was specified as label).
+ inline constexpr uint32_t baseId() const noexcept { return _baseId; }
//! Returns the id of the INDEX register.
- constexpr uint32_t indexId() const noexcept { return _data[kDataMemIndexId]; }
+ inline constexpr uint32_t indexId() const noexcept { return _data[kDataMemIndexId]; }
//! Sets the id of the BASE register (without modifying its type).
- inline void setBaseId(uint32_t rId) noexcept { _baseId = rId; }
+ inline void setBaseId(uint32_t id) noexcept { _baseId = id; }
//! Sets the id of the INDEX register (without modifying its type).
- inline void setIndexId(uint32_t rId) noexcept { _data[kDataMemIndexId] = rId; }
+ inline void setIndexId(uint32_t id) noexcept { _data[kDataMemIndexId] = id; }
//! Sets the base register to type and id of the given `base` operand.
inline void setBase(const BaseReg& base) noexcept { return _setBase(base.type(), base.id()); }
@@ -1175,56 +1294,54 @@ public:
inline void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); }
//! \cond INTERNAL
- inline void _setBase(uint32_t rType, uint32_t rId) noexcept {
- _setSignaturePart<kSignatureMemBaseTypeMask>(rType);
- _baseId = rId;
+ inline void _setBase(RegType type, uint32_t id) noexcept {
+ _signature.setField<Signature::kMemBaseTypeMask>(uint32_t(type));
+ _baseId = id;
}
- inline void _setIndex(uint32_t rType, uint32_t rId) noexcept {
- _setSignaturePart<kSignatureMemIndexTypeMask>(rType);
- _data[kDataMemIndexId] = rId;
+ inline void _setIndex(RegType type, uint32_t id) noexcept {
+ _signature.setField<Signature::kMemIndexTypeMask>(uint32_t(type));
+ _data[kDataMemIndexId] = id;
}
//! \endcond
//! Resets the memory operand's BASE register or label.
- inline void resetBase() noexcept { _setBase(0, 0); }
+ inline void resetBase() noexcept { _setBase(RegType::kNone, 0); }
//! Resets the memory operand's INDEX register.
- inline void resetIndex() noexcept { _setIndex(0, 0); }
+ inline void resetIndex() noexcept { _setIndex(RegType::kNone, 0); }
//! Sets the memory operand size (in bytes).
- inline void setSize(uint32_t size) noexcept { _setSignaturePart<kSignatureSizeMask>(size); }
+ inline void setSize(uint32_t size) noexcept { _signature.setField<Signature::kSizeMask>(size); }
//! Tests whether the memory operand has a 64-bit offset or absolute address.
//!
//! If this is true then `hasBase()` must always report false.
- constexpr bool isOffset64Bit() const noexcept { return baseType() == 0; }
+ inline constexpr bool isOffset64Bit() const noexcept { return baseType() == RegType::kNone; }
//! Tests whether the memory operand has a non-zero offset or absolute address.
- constexpr bool hasOffset() const noexcept {
+ inline constexpr bool hasOffset() const noexcept {
return (_data[kDataMemOffsetLo] | uint32_t(_baseId & Support::bitMaskFromBool<uint32_t>(isOffset64Bit()))) != 0;
}
//! Returns either relative offset or absolute address as 64-bit integer.
- constexpr int64_t offset() const noexcept {
+ inline constexpr int64_t offset() const noexcept {
return isOffset64Bit() ? int64_t(uint64_t(_data[kDataMemOffsetLo]) | (uint64_t(_baseId) << 32))
: int64_t(int32_t(_data[kDataMemOffsetLo])); // Sign extend 32-bit offset.
}
//! Returns a 32-bit low part of a 64-bit offset or absolute address.
- constexpr int32_t offsetLo32() const noexcept { return int32_t(_data[kDataMemOffsetLo]); }
+ inline constexpr int32_t offsetLo32() const noexcept { return int32_t(_data[kDataMemOffsetLo]); }
//! Returns a 32-but high part of a 64-bit offset or absolute address.
//!
//! \note This function is UNSAFE and returns garbage if `isOffset64Bit()`
//! returns false. Never use it blindly without checking it first.
- constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); }
+ inline constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); }
//! Sets a 64-bit offset or an absolute address to `offset`.
//!
- //! \note This functions attempts to set both high and low parts of a 64-bit
- //! offset, however, if the operand has a BASE register it will store only the
- //! low 32 bits of the offset / address as there is no way to store both BASE
- //! and 64-bit offset, and there is currently no architecture that has such
- //! capability targeted by AsmJit.
+ //! \note This functions attempts to set both high and low parts of a 64-bit offset, however, if the operand has
+ //! a BASE register it will store only the low 32 bits of the offset / address as there is no way to store both
+ //! BASE and 64-bit offset, and there is currently no architecture that has such capability targeted by AsmJit.
inline void setOffset(int64_t offset) noexcept {
uint32_t lo = uint32_t(uint64_t(offset) & 0xFFFFFFFFu);
uint32_t hi = uint32_t(uint64_t(offset) >> 32);
@@ -1238,9 +1355,8 @@ public:
//! Adjusts the offset by `offset`.
//!
- //! \note This is a fast function that doesn't use the HI 32-bits of a
- //! 64-bit offset. Use it only if you know that there is a BASE register
- //! and the offset is only 32 bits anyway.
+ //! \note This is a fast function that doesn't use the HI 32-bits of a 64-bit offset. Use it only if you know that
+ //! there is a BASE register and the offset is only 32 bits anyway.
//! Adjusts the memory operand offset by a `offset`.
inline void addOffset(int64_t offset) noexcept {
@@ -1254,48 +1370,49 @@ public:
}
}
- //! Adds `offset` to a low 32-bit offset part (don't use without knowing how
- //! BaseMem works).
+ //! Adds `offset` to a low 32-bit offset part (don't use without knowing how BaseMem works).
inline void addOffsetLo32(int32_t offset) noexcept { _data[kDataMemOffsetLo] += uint32_t(offset); }
//! Resets the memory offset to zero.
inline void resetOffset() noexcept { setOffset(0); }
- //! Resets the lo part of the memory offset to zero (don't use without knowing
- //! how BaseMem works).
+ //! Resets the lo part of the memory offset to zero (don't use without knowing how BaseMem works).
inline void resetOffsetLo32() noexcept { setOffsetLo32(0); }
//! \}
};
-// ============================================================================
-// [asmjit::Imm]
-// ============================================================================
+//! Type of the an immediate value.
+enum class ImmType : uint32_t {
+ //! Immediate is integer.
+ kInt = 0,
+ //! Immediate is a floating point stored as double-precision.
+ kDouble = 1
+};
-//! Immediate operand.
-//!
-//! Immediate operand is usually part of instruction itself. It's inlined after
-//! or before the instruction opcode. Immediates can be only signed or unsigned
-//! integers.
-//!
-//! To create an immediate operand use `asmjit::imm()` helper, which can be used
-//! with any type, not just the default 64-bit int.
+//! Immediate operands are encoded with instruction data.
class Imm : public Operand {
public:
- //! Type of the immediate.
- enum Type : uint32_t {
- //! Immediate is integer.
- kTypeInteger = 0,
- //! Immediate is a floating point stored as double-precision.
- kTypeDouble = 1
- };
+ //! \cond INTERNAL
+ template<typename T>
+ struct IsConstexprConstructibleAsImmType
+ : public std::integral_constant<bool, std::is_enum<T>::value ||
+ std::is_pointer<T>::value ||
+ std::is_integral<T>::value ||
+ std::is_function<T>::value> {};
+
+ template<typename T>
+ struct IsConvertibleToImmType
+ : public std::integral_constant<bool, IsConstexprConstructibleAsImmType<T>::value ||
+ std::is_floating_point<T>::value> {};
+ //! \endcond
//! \name Construction & Destruction
//! \{
//! Creates a new immediate value (initial value is 0).
inline constexpr Imm() noexcept
- : Operand(Globals::Init, kOpImm, 0, 0, 0) {}
+ : Operand(Globals::Init, Signature::fromOpType(OperandType::kImm), 0, 0, 0) {}
//! Creates a new immediate value from `other`.
inline constexpr Imm(const Imm& other) noexcept
@@ -1303,27 +1420,37 @@ public:
//! Creates a new immediate value from ARM/AArch64 specific `shift`.
inline constexpr Imm(const arm::Shift& shift) noexcept
- : Operand(Globals::Init, kOpImm | (shift.op() << kSignaturePredicateShift),
+ : Operand(Globals::Init,
+ Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(uint32_t(shift.op())),
0,
Support::unpackU32At0(shift.value()),
Support::unpackU32At1(shift.value())) {}
- //! Creates a new signed immediate value, assigning the value to `val` and
- //! an architecture-specific predicate to `predicate`.
+ //! Creates a new signed immediate value, assigning the value to `val` and an architecture-specific predicate
+ //! to `predicate`.
//!
//! \note Predicate is currently only used by ARM architectures.
- template<typename T>
+ template<typename T, typename = typename std::enable_if<IsConstexprConstructibleAsImmType<typename std::decay<T>::type>::value>::type>
inline constexpr Imm(const T& val, const uint32_t predicate = 0) noexcept
- : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift),
+ : Operand(Globals::Init,
+ Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(predicate),
0,
Support::unpackU32At0(int64_t(val)),
Support::unpackU32At1(int64_t(val))) {}
inline Imm(const float& val, const uint32_t predicate = 0) noexcept
- : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift), 0, 0, 0) { setValue(val); }
+ : Operand(Globals::Init,
+ Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(predicate),
+ 0,
+ 0,
+ 0) { setValue(val); }
inline Imm(const double& val, const uint32_t predicate = 0) noexcept
- : Operand(Globals::Init, kOpImm | (predicate << kSignaturePredicateShift), 0, 0, 0) { setValue(val); }
+ : Operand(Globals::Init,
+ Signature::fromOpType(OperandType::kImm) | Signature::fromPredicate(predicate),
+ 0,
+ 0,
+ 0) { setValue(val); }
inline explicit Imm(Globals::NoInit_) noexcept
: Operand(Globals::NoInit) {}
@@ -1341,75 +1468,74 @@ public:
//! \name Accessors
//! \{
- //! Returns immediate type, see \ref Type.
- constexpr uint32_t type() const noexcept { return _getSignaturePart<kSignatureImmTypeMask>(); }
- //! Sets the immediate type to `type`, see \ref Type.
- inline void setType(uint32_t type) noexcept { _setSignaturePart<kSignatureImmTypeMask>(type); }
- //! Resets immediate type to `kTypeInteger`.
- inline void resetType() noexcept { setType(kTypeInteger); }
+ //! Returns immediate type.
+ inline constexpr ImmType type() const noexcept { return (ImmType)_signature.getField<Signature::kImmTypeMask>(); }
+ //! Sets the immediate type to `type`.
+ inline void setType(ImmType type) noexcept { _signature.setField<Signature::kImmTypeMask>(uint32_t(type)); }
+ //! Resets immediate type to \ref ImmType::kInt.
+ inline void resetType() noexcept { setType(ImmType::kInt); }
//! Returns operation predicate of the immediate.
//!
- //! The meaning depends on architecture, for example on ARM hardware this
- //! describes \ref arm::Predicate::ShiftOp of the immediate.
- constexpr uint32_t predicate() const noexcept { return _getSignaturePart<kSignaturePredicateMask>(); }
+ //! The meaning depends on architecture, for example on ARM hardware this describes \ref arm::ShiftOp
+ //! of the immediate.
+ inline constexpr uint32_t predicate() const noexcept { return _signature.getField<Signature::kPredicateMask>(); }
//! Sets operation predicate of the immediate to `predicate`.
//!
- //! The meaning depends on architecture, for example on ARM hardware this
- //! describes \ref arm::Predicate::ShiftOp of the immediate.
- inline void setPredicate(uint32_t predicate) noexcept { _setSignaturePart<kSignaturePredicateMask>(predicate); }
+ //! The meaning depends on architecture, for example on ARM hardware this describes \ref arm::ShiftOp
+ //! of the immediate.
+ inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<Signature::kPredicateMask>(predicate); }
//! Resets the shift operation type of the immediate to the default value (no operation).
- inline void resetPredicate() noexcept { _setSignaturePart<kSignaturePredicateMask>(0); }
+ inline void resetPredicate() noexcept { _signature.setField<Signature::kPredicateMask>(0); }
//! Returns the immediate value as `int64_t`, which is the internal format Imm uses.
- constexpr int64_t value() const noexcept {
+ inline constexpr int64_t value() const noexcept {
return int64_t((uint64_t(_data[kDataImmValueHi]) << 32) | _data[kDataImmValueLo]);
}
//! Tests whether this immediate value is integer of any size.
- constexpr uint32_t isInteger() const noexcept { return type() == kTypeInteger; }
+ inline constexpr uint32_t isInt() const noexcept { return type() == ImmType::kInt; }
//! Tests whether this immediate value is a double precision floating point value.
- constexpr uint32_t isDouble() const noexcept { return type() == kTypeDouble; }
+ inline constexpr uint32_t isDouble() const noexcept { return type() == ImmType::kDouble; }
//! Tests whether the immediate can be casted to 8-bit signed integer.
- constexpr bool isInt8() const noexcept { return type() == kTypeInteger && Support::isInt8(value()); }
+ inline constexpr bool isInt8() const noexcept { return type() == ImmType::kInt && Support::isInt8(value()); }
//! Tests whether the immediate can be casted to 8-bit unsigned integer.
- constexpr bool isUInt8() const noexcept { return type() == kTypeInteger && Support::isUInt8(value()); }
+ inline constexpr bool isUInt8() const noexcept { return type() == ImmType::kInt && Support::isUInt8(value()); }
//! Tests whether the immediate can be casted to 16-bit signed integer.
- constexpr bool isInt16() const noexcept { return type() == kTypeInteger && Support::isInt16(value()); }
+ inline constexpr bool isInt16() const noexcept { return type() == ImmType::kInt && Support::isInt16(value()); }
//! Tests whether the immediate can be casted to 16-bit unsigned integer.
- constexpr bool isUInt16() const noexcept { return type() == kTypeInteger && Support::isUInt16(value()); }
+ inline constexpr bool isUInt16() const noexcept { return type() == ImmType::kInt && Support::isUInt16(value()); }
//! Tests whether the immediate can be casted to 32-bit signed integer.
- constexpr bool isInt32() const noexcept { return type() == kTypeInteger && Support::isInt32(value()); }
+ inline constexpr bool isInt32() const noexcept { return type() == ImmType::kInt && Support::isInt32(value()); }
//! Tests whether the immediate can be casted to 32-bit unsigned integer.
- constexpr bool isUInt32() const noexcept { return type() == kTypeInteger && _data[kDataImmValueHi] == 0; }
+ inline constexpr bool isUInt32() const noexcept { return type() == ImmType::kInt && _data[kDataImmValueHi] == 0; }
//! Returns the immediate value casted to `T`.
//!
- //! The value is masked before it's casted to `T` so the returned value is
- //! simply the representation of `T` considering the original value's lowest
- //! bits.
+ //! The value is masked before it's casted to `T` so the returned value is simply the representation of `T`
+ //! considering the original value's lowest bits.
template<typename T>
inline T valueAs() const noexcept { return Support::immediateToT<T>(value()); }
//! Returns low 32-bit signed integer.
- constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
+ inline constexpr int32_t int32Lo() const noexcept { return int32_t(_data[kDataImmValueLo]); }
//! Returns high 32-bit signed integer.
- constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
+ inline constexpr int32_t int32Hi() const noexcept { return int32_t(_data[kDataImmValueHi]); }
//! Returns low 32-bit signed integer.
- constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; }
+ inline constexpr uint32_t uint32Lo() const noexcept { return _data[kDataImmValueLo]; }
//! Returns high 32-bit signed integer.
- constexpr uint32_t uint32Hi() const noexcept { return _data[kDataImmValueHi]; }
+ inline constexpr uint32_t uint32Hi() const noexcept { return _data[kDataImmValueHi]; }
//! Sets immediate value to `val`, the value is casted to a signed 64-bit integer.
template<typename T>
inline void setValue(const T& val) noexcept {
- _setValueInternal(Support::immediateFromT(val), std::is_floating_point<T>::value ? kTypeDouble : kTypeInteger);
+ _setValueInternal(Support::immediateFromT(val), std::is_floating_point<T>::value ? ImmType::kDouble : ImmType::kInt);
}
- inline void _setValueInternal(int64_t val, uint32_t type) noexcept {
+ inline void _setValueInternal(int64_t val, ImmType type) noexcept {
setType(type);
_data[kDataImmValueHi] = uint32_t(uint64_t(val) >> 32);
_data[kDataImmValueLo] = uint32_t(uint64_t(val) & 0xFFFFFFFFu);
@@ -1421,7 +1547,7 @@ public:
//! \{
//! Clones the immediate operand.
- constexpr Imm clone() const noexcept { return Imm(*this); }
+ inline constexpr Imm clone() const noexcept { return Imm(*this); }
inline void signExtend8Bits() noexcept { setValue(int64_t(valueAs<int8_t>())); }
inline void signExtend16Bits() noexcept { setValue(int64_t(valueAs<int16_t>())); }
@@ -1432,65 +1558,14 @@ public:
inline void zeroExtend32Bits() noexcept { _data[kDataImmValueHi] = 0u; }
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use valueAs<int8_t>() instead")
- inline int8_t i8() const noexcept { return valueAs<int8_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<uint8_t>() instead")
- inline uint8_t u8() const noexcept { return valueAs<uint8_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<int16_t>() instead")
- inline int16_t i16() const noexcept { return valueAs<int16_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<uint16_t>() instead")
- inline uint16_t u16() const noexcept { return valueAs<uint16_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<int32_t>() instead")
- inline int32_t i32() const noexcept { return valueAs<int32_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<uint32_t>() instead")
- inline uint32_t u32() const noexcept { return valueAs<uint32_t>(); }
-
- ASMJIT_DEPRECATED("Use value() instead")
- inline int64_t i64() const noexcept { return value(); }
-
- ASMJIT_DEPRECATED("Use valueAs<uint64_t>() instead")
- inline uint64_t u64() const noexcept { return valueAs<uint64_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<intptr_t>() instead")
- inline intptr_t iptr() const noexcept { return valueAs<intptr_t>(); }
-
- ASMJIT_DEPRECATED("Use valueAs<uintptr_t>() instead")
- inline uintptr_t uptr() const noexcept { return valueAs<uintptr_t>(); }
-
- ASMJIT_DEPRECATED("Use int32Lo() instead")
- inline int32_t i32Lo() const noexcept { return int32Lo(); }
-
- ASMJIT_DEPRECATED("Use uint32Lo() instead")
- inline uint32_t u32Lo() const noexcept { return uint32Lo(); }
-
- ASMJIT_DEPRECATED("Use int32Hi() instead")
- inline int32_t i32Hi() const noexcept { return int32Hi(); }
-
- ASMJIT_DEPRECATED("Use uint32Hi() instead")
- inline uint32_t u32Hi() const noexcept { return uint32Hi(); }
-#endif // !ASMJIT_NO_DEPRECATED
};
//! Creates a new immediate operand.
-//!
-//! Using `imm(x)` is much nicer than using `Imm(x)` as this is a template
-//! which can accept any integer including pointers and function pointers.
template<typename T>
-static constexpr Imm imm(const T& val) noexcept { return Imm(val); }
+static inline constexpr Imm imm(const T& val) noexcept { return Imm(val); }
//! \}
-// ============================================================================
-// [asmjit::Globals::none]
-// ============================================================================
-
namespace Globals {
//! \ingroup asmjit_assembler
//!
@@ -1498,31 +1573,25 @@ namespace Globals {
static constexpr const Operand none;
}
-// ============================================================================
-// [asmjit::Support::ForwardOp]
-// ============================================================================
-
//! \cond INTERNAL
namespace Support {
-template<typename T, bool IsIntegral>
+template<typename T, bool kIsImm>
struct ForwardOpImpl {
- static ASMJIT_INLINE const T& forward(const T& value) noexcept { return value; }
+ static inline const T& forward(const T& value) noexcept { return value; }
};
template<typename T>
struct ForwardOpImpl<T, true> {
- static ASMJIT_INLINE Imm forward(const T& value) noexcept { return Imm(value); }
+ static inline Imm forward(const T& value) noexcept { return Imm(value); }
};
-//! Either forwards operand T or returns a new operand for T if T is a type
-//! convertible to operand. At the moment this is only used to convert integers
-//! to \ref Imm operands.
+//! Either forwards operand T or returns a new operand that wraps it if T is a type convertible to operand.
+//! At the moment this is only used to convert integers, floats, and enumarations to \ref Imm operands.
template<typename T>
-struct ForwardOp : public ForwardOpImpl<T, std::is_integral<typename std::decay<T>::type>::value> {};
-
-}
+struct ForwardOp : public ForwardOpImpl<T, Imm::IsConvertibleToImmType<typename std::decay<T>::type>::value> {};
+} // {Support}
//! \endcond
ASMJIT_END_NAMESPACE
diff --git a/src/asmjit/core/osutils.cpp b/src/asmjit/core/osutils.cpp
index e2f34ef..fa900bf 100644
--- a/src/asmjit/core/osutils.cpp
+++ b/src/asmjit/core/osutils.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/osutils.h"
@@ -36,10 +18,6 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::OSUtils - GetTickCount]
-// ============================================================================
-
uint32_t OSUtils::getTickCount() noexcept {
#if defined(_WIN32)
enum HiResStatus : uint32_t {
diff --git a/src/asmjit/core/osutils.h b/src/asmjit/core/osutils.h
index a469129..3c5c3d9 100644
--- a/src/asmjit/core/osutils.h
+++ b/src/asmjit/core/osutils.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_OSUTILS_H_INCLUDED
#define ASMJIT_CORE_OSUTILS_H_INCLUDED
@@ -31,22 +13,14 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
-// ============================================================================
-// [asmjit::OSUtils]
-// ============================================================================
-
//! Operating system utilities.
namespace OSUtils {
//! Gets the current CPU tick count, used for benchmarking (1ms resolution).
ASMJIT_API uint32_t getTickCount() noexcept;
};
-// ============================================================================
-// [asmjit::Lock]
-// ============================================================================
//! \cond INTERNAL
-
//! Lock.
//!
//! Lock is internal, it cannot be used outside of AsmJit, however, its internal
@@ -72,11 +46,11 @@ public:
Handle _handle;
#endif
- inline Lock() noexcept;
- inline ~Lock() noexcept;
+ ASMJIT_FORCE_INLINE Lock() noexcept;
+ ASMJIT_FORCE_INLINE ~Lock() noexcept;
- inline void lock() noexcept;
- inline void unlock() noexcept;
+ ASMJIT_FORCE_INLINE void lock() noexcept;
+ ASMJIT_FORCE_INLINE void unlock() noexcept;
};
//! \endcond
diff --git a/src/asmjit/core/osutils_p.h b/src/asmjit/core/osutils_p.h
index 31db308..fd87e73 100644
--- a/src/asmjit/core/osutils_p.h
+++ b/src/asmjit/core/osutils_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_OSUTILS_P_H_INCLUDED
#define ASMJIT_CORE_OSUTILS_P_H_INCLUDED
@@ -32,47 +14,39 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
-// ============================================================================
-// [asmjit::Lock]
-// ============================================================================
-
#if defined(_WIN32)
// Windows implementation.
static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION");
static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION");
-inline Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
-inline void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_FORCE_INLINE Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_FORCE_INLINE Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_FORCE_INLINE void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
+ASMJIT_FORCE_INLINE void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
#elif !defined(__EMSCRIPTEN__)
// PThread implementation.
#ifdef PTHREAD_MUTEX_INITIALIZER
-inline Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
+ASMJIT_FORCE_INLINE Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
#else
-inline Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+ASMJIT_FORCE_INLINE Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
#endif
-inline Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
-inline void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
-inline void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
+ASMJIT_FORCE_INLINE Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+ASMJIT_FORCE_INLINE void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
+ASMJIT_FORCE_INLINE void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
#else
// Dummy implementation - Emscripten or other unsupported platform.
-inline Lock::Lock() noexcept {}
-inline Lock::~Lock() noexcept {}
-inline void Lock::lock() noexcept {}
-inline void Lock::unlock() noexcept {}
+ASMJIT_FORCE_INLINE Lock::Lock() noexcept {}
+ASMJIT_FORCE_INLINE Lock::~Lock() noexcept {}
+ASMJIT_FORCE_INLINE void Lock::lock() noexcept {}
+ASMJIT_FORCE_INLINE void Lock::unlock() noexcept {}
#endif
-// ============================================================================
-// [asmjit::LockGuard]
-// ============================================================================
-
//! Scoped lock.
class LockGuard {
public:
diff --git a/src/asmjit/core/raassignment_p.h b/src/asmjit/core/raassignment_p.h
index 6b5df54..22a97e2 100644
--- a/src/asmjit/core/raassignment_p.h
+++ b/src/asmjit/core/raassignment_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED
#define ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED
@@ -35,10 +17,12 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RAAssignment]
-// ============================================================================
-
+//! Holds the current register assignment.
+//!
+//! Has two purposes:
+//!
+//! 1. Holds register assignment of a local register allocator (see \ref RALocalAllocator).
+//! 2. Holds register assignment of the entry of basic blocks (see \ref RABlock).
class RAAssignment {
public:
ASMJIT_NONCOPYABLE(RAAssignment)
@@ -120,6 +104,9 @@ public:
}
};
+ //! \name Members
+ //! \{
+
//! Physical registers layout.
Layout _layout;
//! WorkReg to PhysReg mapping.
@@ -127,7 +114,9 @@ public:
//! PhysReg to WorkReg mapping and assigned/dirty bits.
PhysToWorkMap* _physToWorkMap;
//! Optimization to translate PhysRegs to WorkRegs faster.
- uint32_t* _physToWorkIds[BaseReg::kGroupVirt];
+ Support::Array<uint32_t*, Globals::kNumVirtGroups> _physToWorkIds;
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -137,31 +126,30 @@ public:
resetMaps();
}
- inline void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept {
+ ASMJIT_FORCE_INLINE void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept {
// Layout must be initialized before data.
ASMJIT_ASSERT(_physToWorkMap == nullptr);
ASMJIT_ASSERT(_workToPhysMap == nullptr);
_layout.physIndex.buildIndexes(physCount);
_layout.physCount = physCount;
- _layout.physTotal = uint32_t(_layout.physIndex[BaseReg::kGroupVirt - 1]) +
- uint32_t(_layout.physCount[BaseReg::kGroupVirt - 1]) ;
+ _layout.physTotal = uint32_t(_layout.physIndex[RegGroup::kMaxVirt]) +
+ uint32_t(_layout.physCount[RegGroup::kMaxVirt]) ;
_layout.workCount = workRegs.size();
_layout.workRegs = &workRegs;
}
- inline void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
+ ASMJIT_FORCE_INLINE void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
_physToWorkMap = physToWorkMap;
_workToPhysMap = workToPhysMap;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
+ for (RegGroup group : RegGroupVirtValues{})
_physToWorkIds[group] = physToWorkMap->workIds + _layout.physIndex.get(group);
}
- inline void resetMaps() noexcept {
+ ASMJIT_FORCE_INLINE void resetMaps() noexcept {
_physToWorkMap = nullptr;
_workToPhysMap = nullptr;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- _physToWorkIds[group] = nullptr;
+ _physToWorkIds.fill(nullptr);
}
//! \}
@@ -174,30 +162,30 @@ public:
inline RARegMask& assigned() noexcept { return _physToWorkMap->assigned; }
inline const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; }
- inline uint32_t assigned(uint32_t group) const noexcept { return _physToWorkMap->assigned[group]; }
+ inline uint32_t assigned(RegGroup group) const noexcept { return _physToWorkMap->assigned[group]; }
inline RARegMask& dirty() noexcept { return _physToWorkMap->dirty; }
inline const RARegMask& dirty() const noexcept { return _physToWorkMap->dirty; }
- inline uint32_t dirty(uint32_t group) const noexcept { return _physToWorkMap->dirty[group]; }
+ inline RegMask dirty(RegGroup group) const noexcept { return _physToWorkMap->dirty[group]; }
- inline uint32_t workToPhysId(uint32_t group, uint32_t workId) const noexcept {
+ inline uint32_t workToPhysId(RegGroup group, uint32_t workId) const noexcept {
DebugUtils::unused(group);
ASMJIT_ASSERT(workId != kWorkNone);
ASMJIT_ASSERT(workId < _layout.workCount);
return _workToPhysMap->physIds[workId];
}
- inline uint32_t physToWorkId(uint32_t group, uint32_t physId) const noexcept {
+ inline uint32_t physToWorkId(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return _physToWorkIds[group][physId];
}
- inline bool isPhysAssigned(uint32_t group, uint32_t physId) const noexcept {
+ inline bool isPhysAssigned(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return Support::bitTest(_physToWorkMap->assigned[group], physId);
}
- inline bool isPhysDirty(uint32_t group, uint32_t physId) const noexcept {
+ inline bool isPhysDirty(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return Support::bitTest(_physToWorkMap->dirty[group], physId);
}
@@ -205,15 +193,15 @@ public:
//! \}
//! \name Assignment
+ //!
+ //! These are low-level allocation helpers that are used to update the current mappings between physical and
+ //! virt/work registers and also to update masks that represent allocated and dirty registers. These functions
+ //! don't emit any code; they are only used to update and keep all mappings in sync.
+ //!
//! \{
- // These are low-level allocation helpers that are used to update the current
- // mappings between physical and virt/work registers and also to update masks
- // that represent allocated and dirty registers. These functions don't emit
- // any code; they are only used to update and keep all mappings in sync.
-
//! Assign [VirtReg/WorkReg] to a physical register.
- ASMJIT_INLINE void assign(uint32_t group, uint32_t workId, uint32_t physId, uint32_t dirty) noexcept {
+ inline void assign(RegGroup group, uint32_t workId, uint32_t physId, bool dirty) noexcept {
ASMJIT_ASSERT(workToPhysId(group, workId) == kPhysNone);
ASMJIT_ASSERT(physToWorkId(group, physId) == kWorkNone);
ASMJIT_ASSERT(!isPhysAssigned(group, physId));
@@ -222,15 +210,15 @@ public:
_workToPhysMap->physIds[workId] = uint8_t(physId);
_physToWorkIds[group][physId] = workId;
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->assigned[group] |= regMask;
- _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool<uint32_t>(dirty);
+ _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool<RegMask>(dirty);
verify();
}
//! Reassign [VirtReg/WorkReg] to `dstPhysId` from `srcPhysId`.
- ASMJIT_INLINE void reassign(uint32_t group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
+ inline void reassign(RegGroup group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
ASMJIT_ASSERT(dstPhysId != srcPhysId);
ASMJIT_ASSERT(workToPhysId(group, workId) == srcPhysId);
ASMJIT_ASSERT(physToWorkId(group, srcPhysId) == workId);
@@ -241,19 +229,19 @@ public:
_physToWorkIds[group][srcPhysId] = kWorkNone;
_physToWorkIds[group][dstPhysId] = workId;
- uint32_t srcMask = Support::bitMask(srcPhysId);
- uint32_t dstMask = Support::bitMask(dstPhysId);
+ RegMask srcMask = Support::bitMask(srcPhysId);
+ RegMask dstMask = Support::bitMask(dstPhysId);
- uint32_t dirty = (_physToWorkMap->dirty[group] & srcMask) != 0;
- uint32_t regMask = dstMask | srcMask;
+ bool dirty = (_physToWorkMap->dirty[group] & srcMask) != 0;
+ RegMask regMask = dstMask | srcMask;
_physToWorkMap->assigned[group] ^= regMask;
- _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool<uint32_t>(dirty);
+ _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool<RegMask>(dirty);
verify();
}
- ASMJIT_INLINE void swap(uint32_t group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
+ inline void swap(RegGroup group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
ASMJIT_ASSERT(aPhysId != bPhysId);
ASMJIT_ASSERT(workToPhysId(group, aWorkId) == aPhysId);
ASMJIT_ASSERT(workToPhysId(group, bWorkId) == bPhysId);
@@ -267,21 +255,17 @@ public:
_physToWorkIds[group][aPhysId] = bWorkId;
_physToWorkIds[group][bPhysId] = aWorkId;
- uint32_t aMask = Support::bitMask(aPhysId);
- uint32_t bMask = Support::bitMask(bPhysId);
-
- uint32_t flipMask = Support::bitMaskFromBool<uint32_t>(
- ((_physToWorkMap->dirty[group] & aMask) != 0) ^
- ((_physToWorkMap->dirty[group] & bMask) != 0));
-
- uint32_t regMask = aMask | bMask;
+ RegMask aMask = Support::bitMask(aPhysId);
+ RegMask bMask = Support::bitMask(bPhysId);
+ RegMask flipMask = Support::bitMaskFromBool<RegMask>(((_physToWorkMap->dirty[group] & aMask) != 0) ^ ((_physToWorkMap->dirty[group] & bMask) != 0));
+ RegMask regMask = aMask | bMask;
_physToWorkMap->dirty[group] ^= regMask & flipMask;
verify();
}
//! Unassign [VirtReg/WorkReg] from a physical register.
- ASMJIT_INLINE void unassign(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void unassign(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
ASMJIT_ASSERT(workToPhysId(group, workId) == physId);
ASMJIT_ASSERT(physToWorkId(group, physId) == workId);
@@ -290,22 +274,22 @@ public:
_workToPhysMap->physIds[workId] = kPhysNone;
_physToWorkIds[group][physId] = kWorkNone;
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->assigned[group] &= ~regMask;
_physToWorkMap->dirty[group] &= ~regMask;
verify();
}
- inline void makeClean(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void makeClean(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
DebugUtils::unused(workId);
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->dirty[group] &= ~regMask;
}
- inline void makeDirty(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void makeDirty(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
DebugUtils::unused(workId);
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->dirty[group] |= regMask;
}
@@ -314,12 +298,10 @@ public:
//! \name Utilities
//! \{
- inline void swap(RAAssignment& other) noexcept {
+ ASMJIT_FORCE_INLINE void swap(RAAssignment& other) noexcept {
std::swap(_workToPhysMap, other._workToPhysMap);
std::swap(_physToWorkMap, other._physToWorkMap);
-
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- std::swap(_physToWorkIds[group], other._physToWorkIds[group]);
+ _physToWorkIds.swap(other._physToWorkIds);
}
inline void copyFrom(const PhysToWorkMap* physToWorkMap, const WorkToPhysMap* workToPhysMap) noexcept {
@@ -373,7 +355,7 @@ public:
uint32_t physId = _workToPhysMap->physIds[workId];
if (physId != kPhysNone) {
const RAWorkReg* workReg = _layout.workRegs->at(workId);
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
ASMJIT_ASSERT(_physToWorkIds[group][physId] == workId);
}
}
@@ -381,7 +363,7 @@ public:
// Verify PhysToWorkMap.
{
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
uint32_t physCount = _layout.physCount[group];
for (uint32_t physId = 0; physId < physCount; physId++) {
uint32_t workId = _physToWorkIds[group][physId];
diff --git a/src/asmjit/core/rabuilders_p.h b/src/asmjit/core/rabuilders_p.h
index 3d387a0..1b76303 100644
--- a/src/asmjit/core/rabuilders_p.h
+++ b/src/asmjit/core/rabuilders_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RABUILDERS_P_H_INCLUDED
#define ASMJIT_CORE_RABUILDERS_P_H_INCLUDED
@@ -36,13 +18,22 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RACFGBuilderT]
-// ============================================================================
-
template<typename This>
class RACFGBuilderT {
public:
+ enum : uint32_t {
+ kRootIndentation = 2,
+ kCodeIndentation = 4,
+
+ // NOTE: This is a bit hacky. There are some nodes which are processed twice (see `onBeforeInvoke()` and
+ // `onBeforeRet()`) as they can insert some nodes around them. Since we don't have any flags to mark these
+ // we just use their position that is [at that time] unassigned.
+ kNodePositionDidOnBefore = 0xFFFFFFFFu
+ };
+
+ //! \name Members
+ //! \{
+
BaseRAPass* _pass = nullptr;
BaseCompiler* _cc = nullptr;
RABlock* _curBlock = nullptr;
@@ -58,38 +49,30 @@ public:
#ifndef ASMJIT_NO_LOGGING
Logger* _logger = nullptr;
- uint32_t _logFlags = FormatOptions::kFlagPositions;
+ FormatOptions _formatOptions {};
StringTmp<512> _sb;
#endif
- static constexpr uint32_t kRootIndentation = 2;
- static constexpr uint32_t kCodeIndentation = 4;
-
- // NOTE: This is a bit hacky. There are some nodes which are processed twice
- // (see `onBeforeInvoke()` and `onBeforeRet()`) as they can insert some nodes
- // around them. Since we don't have any flags to mark these we just use their
- // position that is [at that time] unassigned.
- static constexpr uint32_t kNodePositionDidOnBefore = 0xFFFFFFFFu;
+ //! \}
inline RACFGBuilderT(BaseRAPass* pass) noexcept
: _pass(pass),
_cc(pass->cc()) {
#ifndef ASMJIT_NO_LOGGING
- _logger = _pass->debugLogger();
+ _logger = _pass->hasDiagnosticOption(DiagnosticOptions::kRADebugCFG) ? _pass->logger() : nullptr;
if (_logger)
- _logFlags |= _logger->flags();
+ _formatOptions = _logger->options();
#endif
}
inline BaseCompiler* cc() const noexcept { return _cc; }
- // --------------------------------------------------------------------------
- // [Run]
- // --------------------------------------------------------------------------
+ //! \name Run
+ //! \{
//! Called per function by an architecture-specific CFG builder.
Error run() noexcept {
- log("[RAPass::BuildCFG]\n");
+ log("[BuildCFG]\n");
ASMJIT_PROPAGATE(prepare());
logNode(_funcNode, kRootIndentation);
@@ -114,12 +97,11 @@ public:
// Instruction | Jump | Invoke | Return
// ------------------------------------
- // Handle `InstNode`, `InvokeNode`, and `FuncRetNode`. All of them
- // share the same interface that provides operands that have read/write
- // semantics.
+ // Handle `InstNode`, `InvokeNode`, and `FuncRetNode`. All of them share the same interface that provides
+ // operands that have read/write semantics.
if (ASMJIT_UNLIKELY(!_curBlock)) {
- // Unreachable code has to be removed, we cannot allocate registers
- // in such code as we cannot do proper liveness analysis in such case.
+ // Unreachable code has to be removed, we cannot allocate registers in such code as we cannot do proper
+ // liveness analysis in such case.
removeNode(node);
node = next;
continue;
@@ -129,15 +111,13 @@ public:
if (node->isInvoke() || node->isFuncRet()) {
if (node->position() != kNodePositionDidOnBefore) {
- // Call and Reg are complicated as they may insert some surrounding
- // code around them. The simplest approach is to get the previous
- // node, call the `onBefore()` handlers and then check whether
- // anything changed and restart if so. By restart we mean that the
- // current `node` would go back to the first possible inserted node
- // by `onBeforeInvoke()` or `onBeforeRet()`.
+ // Call and Reg are complicated as they may insert some surrounding code around them. The simplest
+ // approach is to get the previous node, call the `onBefore()` handlers and then check whether
+ // anything changed and restart if so. By restart we mean that the current `node` would go back to
+ // the first possible inserted node by `onBeforeInvoke()` or `onBeforeRet()`.
BaseNode* prev = node->prev();
- if (node->type() == BaseNode::kNodeInvoke)
+ if (node->type() == NodeType::kInvoke)
ASMJIT_PROPAGATE(static_cast<This*>(this)->onBeforeInvoke(node->as<InvokeNode>()));
else
ASMJIT_PROPAGATE(static_cast<This*>(this)->onBeforeRet(node->as<FuncRetNode>()));
@@ -167,9 +147,9 @@ public:
InstNode* inst = node->as<InstNode>();
logNode(inst, kCodeIndentation);
- uint32_t controlType = BaseInst::kControlNone;
+ InstControlFlow cf = InstControlFlow::kRegular;
ib.reset();
- ASMJIT_PROPAGATE(static_cast<This*>(this)->onInst(inst, controlType, ib));
+ ASMJIT_PROPAGATE(static_cast<This*>(this)->onInst(inst, cf, ib));
if (node->isInvoke()) {
ASMJIT_PROPAGATE(static_cast<This*>(this)->onInvoke(inst->as<InvokeNode>(), ib));
@@ -177,20 +157,20 @@ public:
if (node->isFuncRet()) {
ASMJIT_PROPAGATE(static_cast<This*>(this)->onRet(inst->as<FuncRetNode>(), ib));
- controlType = BaseInst::kControlReturn;
+ cf = InstControlFlow::kReturn;
}
- if (controlType == BaseInst::kControlJump) {
+ if (cf == InstControlFlow::kJump) {
uint32_t fixedRegCount = 0;
for (RATiedReg& tiedReg : ib) {
RAWorkReg* workReg = _pass->workRegById(tiedReg.workId());
- if (workReg->group() == BaseReg::kGroupGp) {
+ if (workReg->group() == RegGroup::kGp) {
uint32_t useId = tiedReg.useId();
if (useId == BaseReg::kIdBad) {
useId = _pass->_scratchRegIndexes[fixedRegCount++];
tiedReg.setUseId(useId);
}
- _curBlock->addExitScratchGpRegs(Support::bitMask<uint32_t>(useId));
+ _curBlock->addExitScratchGpRegs(Support::bitMask(useId));
}
}
}
@@ -198,14 +178,14 @@ public:
ASMJIT_PROPAGATE(_pass->assignRAInst(inst, _curBlock, ib));
_blockRegStats.combineWith(ib._stats);
- if (controlType != BaseInst::kControlNone) {
+ if (cf != InstControlFlow::kRegular) {
// Support for conditional and unconditional jumps.
- if (controlType == BaseInst::kControlJump || controlType == BaseInst::kControlBranch) {
+ if (cf == InstControlFlow::kJump || cf == InstControlFlow::kBranch) {
_curBlock->setLast(node);
- _curBlock->addFlags(RABlock::kFlagHasTerminator);
+ _curBlock->addFlags(RABlockFlags::kHasTerminator);
_curBlock->makeConstructed(_blockRegStats);
- if (!(inst->instOptions() & BaseInst::kOptionUnfollow)) {
+ if (!inst->hasOption(InstOptions::kUnfollow)) {
// Jmp/Jcc/Call/Loop/etc...
uint32_t opCount = inst->opCount();
const Operand* opArray = inst->operands();
@@ -227,14 +207,13 @@ public:
ASMJIT_PROPAGATE(_curBlock->appendSuccessor(targetBlock));
}
else {
- // Not a label - could be jump with reg/mem operand, which
- // means that it can go anywhere. Such jumps must either be
- // annotated so the CFG can be properly constructed, otherwise
- // we assume the worst case - can jump to any basic block.
+ // Not a label - could be jump with reg/mem operand, which means that it can go anywhere. Such jumps
+ // must either be annotated so the CFG can be properly constructed, otherwise we assume the worst case
+ // - can jump to any basic block.
JumpAnnotation* jumpAnnotation = nullptr;
- _curBlock->addFlags(RABlock::kFlagHasJumpTable);
+ _curBlock->addFlags(RABlockFlags::kHasJumpTable);
- if (inst->type() == BaseNode::kNodeJump)
+ if (inst->type() == NodeType::kJump)
jumpAnnotation = inst->as<JumpNode>()->annotation();
if (jumpAnnotation) {
@@ -262,13 +241,11 @@ public:
}
}
- if (controlType == BaseInst::kControlJump) {
- // Unconditional jump makes the code after the jump unreachable,
- // which will be removed instantly during the CFG construction;
- // as we cannot allocate registers for instructions that are not
- // part of any block. Of course we can leave these instructions
- // as they are, however, that would only postpone the problem as
- // assemblers can't encode instructions that use virtual registers.
+ if (cf == InstControlFlow::kJump) {
+ // Unconditional jump makes the code after the jump unreachable, which will be removed instantly during
+ // the CFG construction; as we cannot allocate registers for instructions that are not part of any block.
+ // Of course we can leave these instructions as they are, however, that would only postpone the problem
+ // as assemblers can't encode instructions that use virtual registers.
_curBlock = nullptr;
}
else {
@@ -277,7 +254,7 @@ public:
return DebugUtils::errored(kErrorInvalidState);
RABlock* consecutiveBlock;
- if (node->type() == BaseNode::kNodeLabel) {
+ if (node->type() == NodeType::kLabel) {
if (node->hasPassData()) {
consecutiveBlock = node->passData<RABlock>();
}
@@ -294,7 +271,7 @@ public:
return DebugUtils::errored(kErrorOutOfMemory);
}
- _curBlock->addFlags(RABlock::kFlagHasConsecutive);
+ _curBlock->addFlags(RABlockFlags::kHasConsecutive);
ASMJIT_PROPAGATE(_curBlock->prependSuccessor(consecutiveBlock));
_curBlock = consecutiveBlock;
@@ -310,7 +287,7 @@ public:
}
}
- if (controlType == BaseInst::kControlReturn) {
+ if (cf == InstControlFlow::kReturn) {
_curBlock->setLast(node);
_curBlock->makeConstructed(_blockRegStats);
ASMJIT_PROPAGATE(_curBlock->appendSuccessor(_retBlock));
@@ -319,19 +296,18 @@ public:
}
}
}
- else if (node->type() == BaseNode::kNodeLabel) {
+ else if (node->type() == NodeType::kLabel) {
// Label - Basic-Block Management
// ------------------------------
if (!_curBlock) {
- // If the current code is unreachable the label makes it reachable
- // again. We may remove the whole block in the future if it's not
- // referenced though.
+ // If the current code is unreachable the label makes it reachable again. We may remove the whole block in
+ // the future if it's not referenced though.
_curBlock = node->passData<RABlock>();
if (_curBlock) {
- // If the label has a block assigned we can either continue with
- // it or skip it if the block has been constructed already.
+ // If the label has a block assigned we can either continue with it or skip it if the block has been
+ // constructed already.
if (_curBlock->isConstructed())
break;
}
@@ -354,20 +330,18 @@ public:
consecutive->makeTargetable();
if (_curBlock == consecutive) {
- // The label currently processed is part of the current block. This
- // is only possible for multiple labels that are right next to each
- // other or labels that are separated by non-code nodes like directives
- // and comments.
+ // The label currently processed is part of the current block. This is only possible for multiple labels
+ // that are right next to each other or labels that are separated by non-code nodes like directives and
+ // comments.
if (ASMJIT_UNLIKELY(_hasCode))
return DebugUtils::errored(kErrorInvalidState);
}
else {
- // Label makes the current block constructed. There is a chance that the
- // Label is not used, but we don't know that at this point. In the worst
- // case there would be two blocks next to each other, it's just fine.
+ // Label makes the current block constructed. There is a chance that the Label is not used, but we don't
+ // know that at this point. In the worst case there would be two blocks next to each other, it's just fine.
ASMJIT_ASSERT(_curBlock->last() != node);
_curBlock->setLast(node->prev());
- _curBlock->addFlags(RABlock::kFlagHasConsecutive);
+ _curBlock->addFlags(RABlockFlags::kHasConsecutive);
_curBlock->makeConstructed(_blockRegStats);
ASMJIT_PROPAGATE(_curBlock->appendSuccessor(consecutive));
@@ -381,12 +355,11 @@ public:
else {
// First time we see this label.
if (_hasCode || _curBlock == entryBlock) {
- // Cannot continue the current block if it already contains some
- // code or it's a block entry. We need to create a new block and
- // make it a successor.
+ // Cannot continue the current block if it already contains some code or it's a block entry. We need to
+ // create a new block and make it a successor.
ASMJIT_ASSERT(_curBlock->last() != node);
_curBlock->setLast(node->prev());
- _curBlock->addFlags(RABlock::kFlagHasConsecutive);
+ _curBlock->addFlags(RABlockFlags::kHasConsecutive);
_curBlock->makeConstructed(_blockRegStats);
RABlock* consecutive = _pass->newBlock(node);
@@ -425,7 +398,7 @@ public:
logNode(node, kCodeIndentation);
- if (node->type() == BaseNode::kNodeSentinel) {
+ if (node->type() == NodeType::kSentinel) {
if (node == _funcNode->endNode()) {
// Make sure we didn't flow here if this is the end of the function sentinel.
if (ASMJIT_UNLIKELY(_curBlock))
@@ -433,7 +406,7 @@ public:
break;
}
}
- else if (node->type() == BaseNode::kNodeFunc) {
+ else if (node->type() == NodeType::kFunc) {
// RAPass can only compile a single function at a time. If we
// encountered a function it must be the current one, bail if not.
if (ASMJIT_UNLIKELY(node != _funcNode))
@@ -448,10 +421,9 @@ public:
// Advance to the next node.
node = next;
- // NOTE: We cannot encounter a NULL node, because every function must be
- // terminated by a sentinel (`stop`) node. If we encountered a NULL node it
- // means that something went wrong and this node list is corrupted; bail in
- // such case.
+ // NOTE: We cannot encounter a NULL node, because every function must be terminated by a sentinel (`stop`)
+ // node. If we encountered a NULL node it means that something went wrong and this node list is corrupted;
+ // bail in such case.
if (ASMJIT_UNLIKELY(!node))
return DebugUtils::errored(kErrorInvalidState);
}
@@ -465,9 +437,10 @@ public:
return _pass->initSharedAssignments(_sharedAssignmentsMap);
}
- // --------------------------------------------------------------------------
- // [Prepare]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Prepare
+ //! \{
//! Prepares the CFG builder of the current function.
Error prepare() noexcept {
@@ -504,9 +477,10 @@ public:
return _pass->addBlock(_curBlock);
}
- // --------------------------------------------------------------------------
- // [Utilities]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Utilities
+ //! \{
//! Called when a `node` is removed, e.g. because of a dead code elimination.
void removeNode(BaseNode* node) noexcept {
@@ -516,9 +490,8 @@ public:
//! Handles block with unknown jump, which could be a jump to a jump table.
//!
- //! If we encounter such block we basically insert all existing blocks as
- //! successors except the function entry block and a natural successor, if
- //! such block exists.
+ //! If we encounter such block we basically insert all existing blocks as successors except the function entry
+ //! block and a natural successor, if such block exists.
Error handleBlockWithUnknownJump(RABlock* block) noexcept {
RABlocks& blocks = _pass->blocks();
size_t blockCount = blocks.size();
@@ -570,9 +543,10 @@ public:
return kErrorOk;
}
- // --------------------------------------------------------------------------
- // [Logging]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Logging
+ //! \{
#ifndef ASMJIT_NO_LOGGING
template<typename... Args>
@@ -606,7 +580,7 @@ public:
_sb.append(action);
_sb.append(' ');
}
- Formatter::formatNode(_sb, _logFlags, cc(), node);
+ Formatter::formatNode(_sb, _formatOptions, cc(), node);
_sb.append('\n');
_logger->log(_sb);
}
@@ -625,6 +599,8 @@ public:
DebugUtils::unused(node, indentation, action);
}
#endif
+
+ //! \}
};
//! \}
diff --git a/src/asmjit/core/radefs_p.h b/src/asmjit/core/radefs_p.h
index 53d2c71..426ac29 100644
--- a/src/asmjit/core/radefs_p.h
+++ b/src/asmjit/core/radefs_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RADEFS_P_H_INCLUDED
#define ASMJIT_CORE_RADEFS_P_H_INCLUDED
@@ -40,10 +22,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [Logging]
-// ============================================================================
-
#ifndef ASMJIT_NO_LOGGING
# define ASMJIT_RA_LOG_FORMAT(...) \
do { \
@@ -61,10 +39,6 @@ ASMJIT_BEGIN_NAMESPACE
# define ASMJIT_RA_LOG_COMPLEX(...) ((void)0)
#endif
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class BaseRAPass;
class RABlock;
class BaseNode;
@@ -73,33 +47,36 @@ struct RAStackSlot;
typedef ZoneVector<RABlock*> RABlocks;
typedef ZoneVector<RAWorkReg*> RAWorkRegs;
-// ============================================================================
-// [asmjit::RAConstraints]
-// ============================================================================
+//! Maximum number of consecutive registers aggregated from all supported backends.
+static constexpr uint32_t kMaxConsecutiveRegs = 4;
+//! Provides architecture constraints used by register allocator.
class RAConstraints {
public:
- uint32_t _availableRegs[BaseReg::kGroupVirt] {};
+ //! \name Members
+ //! \{
+
+ Support::Array<RegMask, Globals::kNumVirtGroups> _availableRegs {};
- inline RAConstraints() noexcept {}
+ //! \}
- ASMJIT_NOINLINE Error init(uint32_t arch) noexcept {
+ ASMJIT_NOINLINE Error init(Arch arch) noexcept {
switch (arch) {
- case Environment::kArchX86:
- case Environment::kArchX64: {
- uint32_t registerCount = arch == Environment::kArchX86 ? 8 : 16;
- _availableRegs[BaseReg::kGroupGp] = Support::lsbMask<uint32_t>(registerCount) & ~Support::bitMask(4u);
- _availableRegs[BaseReg::kGroupVec] = Support::lsbMask<uint32_t>(registerCount);
- _availableRegs[BaseReg::kGroupOther0] = Support::lsbMask<uint32_t>(8);
- _availableRegs[BaseReg::kGroupOther1] = Support::lsbMask<uint32_t>(8);
+ case Arch::kX86:
+ case Arch::kX64: {
+ uint32_t registerCount = arch == Arch::kX86 ? 8 : 16;
+ _availableRegs[RegGroup::kGp] = Support::lsbMask<RegMask>(registerCount) & ~Support::bitMask(4u);
+ _availableRegs[RegGroup::kVec] = Support::lsbMask<RegMask>(registerCount);
+ _availableRegs[RegGroup::kExtraVirt2] = Support::lsbMask<RegMask>(8);
+ _availableRegs[RegGroup::kExtraVirt3] = Support::lsbMask<RegMask>(8);
return kErrorOk;
}
- case Environment::kArchAArch64: {
- _availableRegs[BaseReg::kGroupGp] = 0xFFFFFFFFu & ~Support::bitMask(18, 31u);
- _availableRegs[BaseReg::kGroupVec] = 0xFFFFFFFFu;
- _availableRegs[BaseReg::kGroupOther0] = 0;
- _availableRegs[BaseReg::kGroupOther1] = 0;
+ case Arch::kAArch64: {
+ _availableRegs[RegGroup::kGp] = 0xFFFFFFFFu & ~Support::bitMask(18, 31u);
+ _availableRegs[RegGroup::kVec] = 0xFFFFFFFFu;
+ _availableRegs[RegGroup::kExtraVirt2] = 0;
+ _availableRegs[RegGroup::kExtraVirt3] = 0;
return kErrorOk;
}
@@ -108,48 +85,70 @@ public:
}
}
- inline uint32_t availableRegs(uint32_t group) const noexcept { return _availableRegs[group]; }
+ inline RegMask availableRegs(RegGroup group) const noexcept { return _availableRegs[group]; }
};
-// ============================================================================
-// [asmjit::RAStrategy]
-// ============================================================================
+enum class RAStrategyType : uint8_t {
+ kSimple = 0,
+ kComplex = 1
+};
+ASMJIT_DEFINE_ENUM_COMPARE(RAStrategyType)
+
+enum class RAStrategyFlags : uint8_t {
+ kNone = 0
+};
+ASMJIT_DEFINE_ENUM_FLAGS(RAStrategyFlags)
+//! Register allocation strategy.
+//!
+//! The idea is to select the best register allocation strategy for each virtual register group based on the
+//! complexity of the code.
struct RAStrategy {
- uint8_t _type;
+ //! \name Members
+ //! \{
- enum StrategyType : uint32_t {
- kStrategySimple = 0,
- kStrategyComplex = 1
- };
+ RAStrategyType _type = RAStrategyType::kSimple;
+ RAStrategyFlags _flags = RAStrategyFlags::kNone;
- inline RAStrategy() noexcept { reset(); }
- inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
+ //! \}
- inline uint32_t type() const noexcept { return _type; }
- inline void setType(uint32_t type) noexcept { _type = uint8_t(type); }
+ //! \name Accessors
+ //! \{
- inline bool isSimple() const noexcept { return _type == kStrategySimple; }
- inline bool isComplex() const noexcept { return _type >= kStrategyComplex; }
-};
+ inline void reset() noexcept {
+ _type = RAStrategyType::kSimple;
+ _flags = RAStrategyFlags::kNone;
+ }
+ inline RAStrategyType type() const noexcept { return _type; }
+ inline void setType(RAStrategyType type) noexcept { _type = type; }
-// ============================================================================
-// [asmjit::RARegCount]
-// ============================================================================
+ inline bool isSimple() const noexcept { return _type == RAStrategyType::kSimple; }
+ inline bool isComplex() const noexcept { return _type >= RAStrategyType::kComplex; }
+
+ inline RAStrategyFlags flags() const noexcept { return _flags; }
+ inline bool hasFlag(RAStrategyFlags flag) const noexcept { return Support::test(_flags, flag); }
+ inline void addFlags(RAStrategyFlags flags) noexcept { _flags |= flags; }
+
+ //! \}
+};
//! Count of virtual or physical registers per group.
//!
-//! \note This class uses 8-bit integers to represent counters, it's only used
-//! in places where this is sufficient - for example total count of machine's
-//! physical registers, count of virtual registers per instruction, etc. There
-//! is also `RALiveCount`, which uses 32-bit integers and is indeed much safer.
+//! \note This class uses 8-bit integers to represent counters, it's only used in places where this is sufficient,
+//! for example total count of machine's physical registers, count of virtual registers per instruction, etc...
+//! There is also `RALiveCount`, which uses 32-bit integers and is indeed much safer.
struct RARegCount {
+ //! \name Members
+ //! \{
+
union {
uint8_t _regs[4];
uint32_t _packed;
};
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -161,62 +160,57 @@ struct RARegCount {
//! \name Overloaded Operators
//! \{
- inline uint8_t& operator[](uint32_t index) noexcept {
- ASMJIT_ASSERT(index < BaseReg::kGroupVirt);
- return _regs[index];
+ inline uint8_t& operator[](RegGroup group) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ return _regs[size_t(group)];
}
- inline const uint8_t& operator[](uint32_t index) const noexcept {
- ASMJIT_ASSERT(index < BaseReg::kGroupVirt);
- return _regs[index];
+ inline const uint8_t& operator[](RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ return _regs[size_t(group)];
}
- inline RARegCount& operator=(const RARegCount& other) noexcept = default;
-
inline bool operator==(const RARegCount& other) const noexcept { return _packed == other._packed; }
inline bool operator!=(const RARegCount& other) const noexcept { return _packed != other._packed; }
//! \}
- //! \name Utilities
+ //! \name Accessors
//! \{
//! Returns the count of registers by the given register `group`.
- inline uint32_t get(uint32_t group) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline uint32_t get(RegGroup group) const noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
- uint32_t shift = Support::byteShiftOfDWordStruct(group);
+ uint32_t shift = Support::byteShiftOfDWordStruct(uint32_t(group));
return (_packed >> shift) & uint32_t(0xFF);
}
//! Sets the register count by a register `group`.
- inline void set(uint32_t group, uint32_t n) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline void set(RegGroup group, uint32_t n) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
ASMJIT_ASSERT(n <= 0xFF);
- uint32_t shift = Support::byteShiftOfDWordStruct(group);
+ uint32_t shift = Support::byteShiftOfDWordStruct(uint32_t(group));
_packed = (_packed & ~uint32_t(0xFF << shift)) + (n << shift);
}
//! Adds the register count by a register `group`.
- inline void add(uint32_t group, uint32_t n = 1) noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
- ASMJIT_ASSERT(0xFF - uint32_t(_regs[group]) >= n);
+ inline void add(RegGroup group, uint32_t n = 1) noexcept {
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
+ ASMJIT_ASSERT(0xFF - uint32_t(_regs[size_t(group)]) >= n);
- uint32_t shift = Support::byteShiftOfDWordStruct(group);
+ uint32_t shift = Support::byteShiftOfDWordStruct(uint32_t(group));
_packed += n << shift;
}
//! \}
};
-// ============================================================================
-// [asmjit::RARegIndex]
-// ============================================================================
-
+//! Provides mapping that can be used to fast index architecture register groups.
struct RARegIndex : public RARegCount {
//! Build register indexes based on the given `count` of registers.
- inline void buildIndexes(const RARegCount& count) noexcept {
+ ASMJIT_FORCE_INLINE void buildIndexes(const RARegCount& count) noexcept {
uint32_t x = uint32_t(count._regs[0]);
uint32_t y = uint32_t(count._regs[1]) + x;
uint32_t z = uint32_t(count._regs[2]) + y;
@@ -227,55 +221,35 @@ struct RARegIndex : public RARegCount {
}
};
-// ============================================================================
-// [asmjit::RARegMask]
-// ============================================================================
-
//! Registers mask.
struct RARegMask {
- uint32_t _masks[BaseReg::kGroupVirt];
+ //! \name Members
+ //! \{
+
+ Support::Array<RegMask, Globals::kNumVirtGroups> _masks;
+
+ //! \}
//! \name Construction & Destruction
//! \{
- inline void init(const RARegMask& other) noexcept {
- for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++)
- _masks[i] = other._masks[i];
- }
-
+ inline void init(const RARegMask& other) noexcept { _masks = other._masks; }
//! Reset all register masks to zero.
- inline void reset() noexcept {
- for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++)
- _masks[i] = 0;
- }
+ inline void reset() noexcept { _masks.fill(0); }
//! \}
//! \name Overloaded Operators
//! \{
- inline RARegMask& operator=(const RARegMask& other) noexcept = default;
-
- inline bool operator==(const RARegMask& other) const noexcept {
- return _masks[0] == other._masks[0] &&
- _masks[1] == other._masks[1] &&
- _masks[2] == other._masks[2] &&
- _masks[3] == other._masks[3] ;
- }
-
- inline bool operator!=(const RARegMask& other) const noexcept {
- return !operator==(other);
- }
+ inline bool operator==(const RARegMask& other) const noexcept { return _masks == other._masks; }
+ inline bool operator!=(const RARegMask& other) const noexcept { return _masks != other._masks; }
- inline uint32_t& operator[](uint32_t index) noexcept {
- ASMJIT_ASSERT(index < BaseReg::kGroupVirt);
- return _masks[index];
- }
+ template<typename Index>
+ inline uint32_t& operator[](const Index& index) noexcept { return _masks[index]; }
- inline const uint32_t& operator[](uint32_t index) const noexcept {
- ASMJIT_ASSERT(index < BaseReg::kGroupVirt);
- return _masks[index];
- }
+ template<typename Index>
+ inline const uint32_t& operator[](const Index& index) const noexcept { return _masks[index]; }
//! \}
@@ -284,43 +258,34 @@ struct RARegMask {
//! Tests whether all register masks are zero (empty).
inline bool empty() const noexcept {
- uint32_t m = 0;
- for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++)
- m |= _masks[i];
- return m == 0;
+ return _masks.aggregate<Support::Or>() == 0;
}
- inline bool has(uint32_t group, uint32_t mask = 0xFFFFFFFFu) const noexcept {
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ inline bool has(RegGroup group, RegMask mask = 0xFFFFFFFFu) const noexcept {
return (_masks[group] & mask) != 0;
}
template<class Operator>
inline void op(const RARegMask& other) noexcept {
- for (uint32_t i = 0; i < BaseReg::kGroupVirt; i++)
- _masks[i] = Operator::op(_masks[i], other._masks[i]);
+ _masks.combine<Operator>(other._masks);
}
template<class Operator>
- inline void op(uint32_t group, uint32_t input) noexcept {
+ inline void op(RegGroup group, uint32_t input) noexcept {
_masks[group] = Operator::op(_masks[group], input);
}
//! \}
};
-// ============================================================================
-// [asmjit::RARegsStats]
-// ============================================================================
-
-//! Information associated with each instruction, propagated to blocks, loops,
-//! and the whole function. This information can be used to do minor decisions
-//! before the register allocator tries to do its job. For example to use fast
-//! register allocation inside a block or loop it cannot have clobbered and/or
-//! fixed registers, etc...
+//! Information associated with each instruction, propagated to blocks, loops, and the whole function. This
+//! information can be used to do minor decisions before the register allocator tries to do its job. For
+//! example to use fast register allocation inside a block or loop it cannot have clobbered and/or fixed
+//! registers, etc...
class RARegsStats {
public:
- uint32_t _packed = 0;
+ //! \name Constants
+ //! \{
enum Index : uint32_t {
kIndexUsed = 0,
@@ -334,30 +299,45 @@ public:
kMaskClobbered = 0xFFu << kIndexClobbered
};
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ uint32_t _packed = 0;
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
inline void reset() noexcept { _packed = 0; }
inline void combineWith(const RARegsStats& other) noexcept { _packed |= other._packed; }
inline bool hasUsed() const noexcept { return (_packed & kMaskUsed) != 0u; }
- inline bool hasUsed(uint32_t group) const noexcept { return (_packed & Support::bitMask(kIndexUsed + group)) != 0u; }
- inline void makeUsed(uint32_t group) noexcept { _packed |= Support::bitMask(kIndexUsed + group); }
+ inline bool hasUsed(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexUsed + uint32_t(group))) != 0u; }
+ inline void makeUsed(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexUsed + uint32_t(group)); }
inline bool hasFixed() const noexcept { return (_packed & kMaskFixed) != 0u; }
- inline bool hasFixed(uint32_t group) const noexcept { return (_packed & Support::bitMask(kIndexFixed + group)) != 0u; }
- inline void makeFixed(uint32_t group) noexcept { _packed |= Support::bitMask(kIndexFixed + group); }
+ inline bool hasFixed(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexFixed + uint32_t(group))) != 0u; }
+ inline void makeFixed(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexFixed + uint32_t(group)); }
inline bool hasClobbered() const noexcept { return (_packed & kMaskClobbered) != 0u; }
- inline bool hasClobbered(uint32_t group) const noexcept { return (_packed & Support::bitMask(kIndexClobbered + group)) != 0u; }
- inline void makeClobbered(uint32_t group) noexcept { _packed |= Support::bitMask(kIndexClobbered + group); }
-};
+ inline bool hasClobbered(RegGroup group) const noexcept { return (_packed & Support::bitMask(kIndexClobbered + uint32_t(group))) != 0u; }
+ inline void makeClobbered(RegGroup group) noexcept { _packed |= Support::bitMask(kIndexClobbered + uint32_t(group)); }
-// ============================================================================
-// [asmjit::RALiveCount]
-// ============================================================================
+ //! \}
+};
//! Count of live registers, per group.
class RALiveCount {
public:
- uint32_t n[BaseReg::kGroupVirt] {};
+ //! \name Members
+ //! \{
+
+ Support::Array<uint32_t, Globals::kNumVirtGroups> n {};
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -365,15 +345,8 @@ public:
inline RALiveCount() noexcept = default;
inline RALiveCount(const RALiveCount& other) noexcept = default;
- inline void init(const RALiveCount& other) noexcept {
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- n[group] = other.n[group];
- }
-
- inline void reset() noexcept {
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- n[group] = 0;
- }
+ inline void init(const RALiveCount& other) noexcept { n = other.n; }
+ inline void reset() noexcept { n.fill(0); }
//! \}
@@ -382,8 +355,8 @@ public:
inline RALiveCount& operator=(const RALiveCount& other) noexcept = default;
- inline uint32_t& operator[](uint32_t group) noexcept { return n[group]; }
- inline const uint32_t& operator[](uint32_t group) const noexcept { return n[group]; }
+ inline uint32_t& operator[](RegGroup group) noexcept { return n[group]; }
+ inline const uint32_t& operator[](RegGroup group) const noexcept { return n[group]; }
//! \}
@@ -391,26 +364,29 @@ public:
//! \{
template<class Operator>
- inline void op(const RALiveCount& other) noexcept {
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- n[group] = Operator::op(n[group], other.n[group]);
- }
+ inline void op(const RALiveCount& other) noexcept { n.combine<Operator>(other.n); }
//! \}
};
-// ============================================================================
-// [asmjit::RALiveInterval]
-// ============================================================================
-
struct RALiveInterval {
- uint32_t a, b;
+ //! \name Constants
+ //! \{
- enum Misc : uint32_t {
+ enum : uint32_t {
kNaN = 0,
kInf = 0xFFFFFFFFu
};
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ uint32_t a, b;
+
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -443,15 +419,17 @@ struct RALiveInterval {
//! \}
};
-// ============================================================================
-// [asmjit::RALiveSpan<T>]
-// ============================================================================
-
+//! Live span with payload of type `T`.
template<typename T>
class RALiveSpan : public RALiveInterval, public T {
public:
+ //! \name Types
+ //! \{
+
typedef T DataType;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -489,10 +467,7 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::RALiveSpans<T>]
-// ============================================================================
-
+//! Vector of `RALiveSpan<T>` with additional convenience API.
template<typename T>
class RALiveSpans {
public:
@@ -533,12 +508,12 @@ public:
inline void swap(RALiveSpans<T>& other) noexcept { _data.swap(other._data); }
//! Open the current live span.
- ASMJIT_INLINE Error openAt(ZoneAllocator* allocator, uint32_t start, uint32_t end) noexcept {
+ ASMJIT_FORCE_INLINE Error openAt(ZoneAllocator* allocator, uint32_t start, uint32_t end) noexcept {
bool wasOpen;
return openAt(allocator, start, end, wasOpen);
}
- ASMJIT_INLINE Error openAt(ZoneAllocator* allocator, uint32_t start, uint32_t end, bool& wasOpen) noexcept {
+ ASMJIT_FORCE_INLINE Error openAt(ZoneAllocator* allocator, uint32_t start, uint32_t end, bool& wasOpen) noexcept {
uint32_t size = _data.size();
wasOpen = false;
@@ -554,7 +529,7 @@ public:
return _data.append(allocator, T(start, end));
}
- inline void closeAt(uint32_t end) noexcept {
+ ASMJIT_FORCE_INLINE void closeAt(uint32_t end) noexcept {
ASMJIT_ASSERT(!empty());
uint32_t size = _data.size();
@@ -563,9 +538,8 @@ public:
//! Returns the sum of width of all spans.
//!
- //! \note Don't overuse, this iterates over all spans so it's O(N).
- //! It should be only called once and then cached.
- ASMJIT_INLINE uint32_t width() const noexcept {
+ //! \note Don't overuse, this iterates over all spans so it's O(N). It should be only called once and then cached.
+ inline uint32_t width() const noexcept {
uint32_t width = 0;
for (const T& span : _data)
width += span.width();
@@ -579,7 +553,7 @@ public:
return intersects(*this, other);
}
- ASMJIT_INLINE Error nonOverlappingUnionOf(ZoneAllocator* allocator, const RALiveSpans<T>& x, const RALiveSpans<T>& y, const DataType& yData) noexcept {
+ ASMJIT_FORCE_INLINE Error nonOverlappingUnionOf(ZoneAllocator* allocator, const RALiveSpans<T>& x, const RALiveSpans<T>& y, const DataType& yData) noexcept {
uint32_t finalSize = x.size() + y.size();
ASMJIT_PROPAGATE(_data.reserve(allocator, finalSize));
@@ -590,9 +564,8 @@ public:
const T* xEnd = xSpan + x.size();
const T* yEnd = ySpan + y.size();
- // Loop until we have intersection or either `xSpan == xEnd` or `ySpan == yEnd`,
- // which means that there is no intersection. We advance either `xSpan` or `ySpan`
- // depending on their ranges.
+ // Loop until we have intersection or either `xSpan == xEnd` or `ySpan == yEnd`, which means that there is no
+ // intersection. We advance either `xSpan` or `ySpan` depending on their ranges.
if (xSpan != xEnd && ySpan != yEnd) {
uint32_t xa, ya;
xa = xSpan->a;
@@ -633,16 +606,15 @@ public:
return kErrorOk;
}
- static ASMJIT_INLINE bool intersects(const RALiveSpans<T>& x, const RALiveSpans<T>& y) noexcept {
+ static ASMJIT_FORCE_INLINE bool intersects(const RALiveSpans<T>& x, const RALiveSpans<T>& y) noexcept {
const T* xSpan = x.data();
const T* ySpan = y.data();
const T* xEnd = xSpan + x.size();
const T* yEnd = ySpan + y.size();
- // Loop until we have intersection or either `xSpan == xEnd` or `ySpan == yEnd`,
- // which means that there is no intersection. We advance either `xSpan` or `ySpan`
- // depending on their end positions.
+ // Loop until we have intersection or either `xSpan == xEnd` or `ySpan == yEnd`, which means that there is no
+ // intersection. We advance either `xSpan` or `ySpan` depending on their end positions.
if (xSpan == xEnd || ySpan == yEnd)
return false;
@@ -669,10 +641,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::RALiveStats]
-// ============================================================================
-
//! Statistics about a register liveness.
class RALiveStats {
public:
@@ -690,10 +658,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::LiveRegData]
-// ============================================================================
-
struct LiveRegData {
uint32_t id;
@@ -709,177 +673,255 @@ struct LiveRegData {
typedef RALiveSpan<LiveRegData> LiveRegSpan;
typedef RALiveSpans<LiveRegSpan> LiveRegSpans;
-// ============================================================================
-// [asmjit::RATiedReg]
-// ============================================================================
+//! Flags used by \ref RATiedReg.
+//!
+//! Register access information is encoded in 4 flags in total:
+//!
+//! - `kRead` - Register is Read (ReadWrite if combined with `kWrite`).
+//! - `kWrite` - Register is Written (ReadWrite if combined with `kRead`).
+//! - `kUse` - Encoded as Read or ReadWrite.
+//! - `kOut` - Encoded as WriteOnly.
+//!
+//! Let's describe all of these on two X86 instructions:
+//!
+//! - ADD x{R|W|Use}, x{R|Use} -> {x:R|W|Use }
+//! - LEA x{ W|Out}, [x{R|Use} + x{R|Out}] -> {x:R|W|Use|Out }
+//! - ADD x{R|W|Use}, y{R|Use} -> {x:R|W|Use y:R|Use}
+//! - LEA x{ W|Out}, [x{R|Use} + y{R|Out}] -> {x:R|W|Use|Out y:R|Use}
+//!
+//! It should be obvious from the example above how these flags get created. Each operand contains READ/WRITE
+//! information, which is then merged to RATiedReg's flags. However, we also need to represent the possitility
+//! to view the operation as two independent operations - USE and OUT, because the register allocator first
+//! allocates USE registers, and then assigns OUT registers independently of USE registers.
+enum class RATiedFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
+ // Access Flags
+ // ------------
+
+ //! Register is read.
+ kRead = uint32_t(OpRWFlags::kRead),
+ //! Register is written.
+ kWrite = uint32_t(OpRWFlags::kWrite),
+ //! Register both read and written.
+ kRW = uint32_t(OpRWFlags::kRW),
+
+ // Use / Out Flags
+ // ---------------
+
+ //! Register has a USE slot (read/rw).
+ kUse = 0x00000004u,
+ //! Register has an OUT slot (write-only).
+ kOut = 0x00000008u,
+ //! Register in USE slot can be patched to memory.
+ kUseRM = 0x00000010u,
+ //! Register in OUT slot can be patched to memory.
+ kOutRM = 0x00000020u,
+
+ //! Register has a fixed USE slot.
+ kUseFixed = 0x00000040u,
+ //! Register has a fixed OUT slot.
+ kOutFixed = 0x00000080u,
+ //! Register USE slot has been allocated.
+ kUseDone = 0x00000100u,
+ //! Register OUT slot has been allocated.
+ kOutDone = 0x00000200u,
+
+ // Consecutive Flags / Data
+ // ------------------------
+
+ kUseConsecutive = 0x00000400u,
+ kOutConsecutive = 0x00000800u,
+ kLeadConsecutive = 0x00001000u,
+ kConsecutiveData = 0x00006000u,
+
+ // Liveness Flags
+ // --------------
+
+ //! Register must be duplicated (function call only).
+ kDuplicate = 0x00010000u,
+ //! Last occurrence of this VirtReg in basic block.
+ kLast = 0x00020000u,
+ //! Kill this VirtReg after use.
+ kKill = 0x00040000u,
+
+ // X86 Specific Flags
+ // ------------------
+
+ // Architecture specific flags are used during RATiedReg building to ensure that architecture-specific constraints
+ // are handled properly. These flags are not really needed after RATiedReg[] is built and copied to `RAInst`.
+
+ //! This RATiedReg references GPB-LO or GPB-HI.
+ kX86_Gpb = 0x01000000u,
+
+ // Instruction Flags (Never used by RATiedReg)
+ // -------------------------------------------
+
+ //! Instruction is transformable to another instruction if necessary.
+ //!
+ //! This is flag that is only used by \ref RAInst to inform register allocator that the instruction has some
+ //! constraints that can only be solved by transforming the instruction into another instruction, most likely
+ //! by changing its InstId.
+ kInst_IsTransformable = 0x80000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(RATiedFlags)
+
+static_assert(uint32_t(RATiedFlags::kRead ) == 0x1, "RATiedFlags::kRead must be 0x1");
+static_assert(uint32_t(RATiedFlags::kWrite) == 0x2, "RATiedFlags::kWrite must be 0x2");
+static_assert(uint32_t(RATiedFlags::kRW ) == 0x3, "RATiedFlags::kRW must be 0x3");
-//! Tied register merges one ore more register operand into a single entity. It
-//! contains information about its access (Read|Write) and allocation slots
-//! (Use|Out) that are used by the register allocator and liveness analysis.
+//! Tied register merges one ore more register operand into a single entity. It contains information about its access
+//! (Read|Write) and allocation slots (Use|Out) that are used by the register allocator and liveness analysis.
struct RATiedReg {
+ //! \name Members
+ //! \{
+
//! WorkReg id.
uint32_t _workId;
+ //! WorkReg id that is an immediate consecutive parent of this register, or Globals::kInvalidId if it has no parent.
+ uint32_t _consecutiveParent;
//! Allocation flags.
- uint32_t _flags;
- //! Registers where input {R|X} can be allocated to.
- uint32_t _allocableRegs;
- //! Indexes used to rewrite USE regs.
- uint32_t _useRewriteMask;
- //! Indexes used to rewrite OUT regs.
- uint32_t _outRewriteMask;
+ RATiedFlags _flags;
union {
struct {
//! How many times the VirtReg is referenced in all operands.
uint8_t _refCount;
+ //! Size of a memory operand in case that it's use instead of the register.
+ uint8_t _rmSize;
//! Physical register for use operation (ReadOnly / ReadWrite).
uint8_t _useId;
//! Physical register for out operation (WriteOnly).
uint8_t _outId;
- //! Reserved for future use (padding).
- uint8_t _rmSize;
};
//! Packed data.
uint32_t _packed;
};
- //! Flags.
- //!
- //! Register access information is encoded in 4 flags in total:
- //!
- //! - `kRead` - Register is Read (ReadWrite if combined with `kWrite`).
- //! - `kWrite` - Register is Written (ReadWrite if combined with `kRead`).
- //! - `kUse` - Encoded as Read or ReadWrite.
- //! - `kOut` - Encoded as WriteOnly.
- //!
- //! Let's describe all of these on two X86 instructions:
- //!
- //! - ADD x{R|W|Use}, x{R|Use} -> {x:R|W|Use }
- //! - LEA x{ W|Out}, [x{R|Use} + x{R|Out}] -> {x:R|W|Use|Out }
- //! - ADD x{R|W|Use}, y{R|Use} -> {x:R|W|Use y:R|Use}
- //! - LEA x{ W|Out}, [x{R|Use} + y{R|Out}] -> {x:R|W|Use|Out y:R|Use}
- //!
- //! It should be obvious from the example above how these flags get created.
- //! Each operand contains READ/WRITE information, which is then merged to
- //! RATiedReg's flags. However, we also need to represent the possitility to
- //! use see the operation as two independent operations - USE and OUT, because
- //! the register allocator will first allocate USE registers, and then assign
- //! OUT registers independently of USE registers.
- enum Flags : uint32_t {
- kRead = OpRWInfo::kRead, //!< Register is read.
- kWrite = OpRWInfo::kWrite, //!< Register is written.
- kRW = OpRWInfo::kRW, //!< Register both read and written.
-
- kUse = 0x00000100u, //!< Register has a USE slot (read/rw).
- kOut = 0x00000200u, //!< Register has an OUT slot (write-only).
- kUseRM = 0x00000400u, //!< Register in USE slot can be patched to memory.
- kOutRM = 0x00000800u, //!< Register in OUT slot can be patched to memory.
-
- kUseFixed = 0x00001000u, //!< Register has a fixed USE slot.
- kOutFixed = 0x00002000u, //!< Register has a fixed OUT slot.
- kUseDone = 0x00004000u, //!< Register USE slot has been allocated.
- kOutDone = 0x00008000u, //!< Register OUT slot has been allocated.
-
- kDuplicate = 0x00010000u, //!< Register must be duplicated (function call only).
- kLast = 0x00020000u, //!< Last occurrence of this VirtReg in basic block.
- kKill = 0x00040000u, //!< Kill this VirtReg after use.
-
- // Architecture specific flags are used during RATiedReg building to ensure
- // that architecture-specific constraints are handled properly. These flags
- // are not really needed after RATiedReg[] is built and copied to `RAInst`.
-
- kX86Gpb = 0x01000000u //!< This RATiedReg references GPB-LO or GPB-HI.
- };
+ //! Registers where inputs {R|X} can be allocated to.
+ RegMask _useRegMask;
+ //! Registers where outputs {W} can be allocated to.
+ RegMask _outRegMask;
+ //! Indexes used to rewrite USE regs.
+ uint32_t _useRewriteMask;
+ //! Indexes used to rewrite OUT regs.
+ uint32_t _outRewriteMask;
+
+ //! \}
+
+ //! \name Statics
+ //! \{
+
+ static inline RATiedFlags consecutiveDataToFlags(uint32_t offset) noexcept {
+ ASMJIT_ASSERT(offset < 4);
+ constexpr uint32_t kOffsetShift = Support::ConstCTZ<uint32_t(RATiedFlags::kConsecutiveData)>::value;
+ return (RATiedFlags)(offset << kOffsetShift);
+ }
+
+ static inline uint32_t consecutiveDataFromFlags(RATiedFlags flags) noexcept {
+ constexpr uint32_t kOffsetShift = Support::ConstCTZ<uint32_t(RATiedFlags::kConsecutiveData)>::value;
+ return uint32_t(flags & RATiedFlags::kConsecutiveData) >> kOffsetShift;
+ }
- static_assert(kRead == 0x1, "RATiedReg::kRead flag must be 0x1");
- static_assert(kWrite == 0x2, "RATiedReg::kWrite flag must be 0x2");
- static_assert(kRW == 0x3, "RATiedReg::kRW combination must be 0x3");
+ //! \}
//! \name Construction & Destruction
//! \{
- ASMJIT_INLINE void init(uint32_t workId, uint32_t flags, uint32_t allocableRegs, uint32_t useId, uint32_t useRewriteMask, uint32_t outId, uint32_t outRewriteMask, uint32_t rmSize = 0) noexcept {
+ inline void init(uint32_t workId, RATiedFlags flags, RegMask useRegMask, uint32_t useId, uint32_t useRewriteMask, RegMask outRegMask, uint32_t outId, uint32_t outRewriteMask, uint32_t rmSize = 0, uint32_t consecutiveParent = Globals::kInvalidId) noexcept {
_workId = workId;
+ _consecutiveParent = consecutiveParent;
_flags = flags;
- _allocableRegs = allocableRegs;
- _useRewriteMask = useRewriteMask;
- _outRewriteMask = outRewriteMask;
_refCount = 1;
+ _rmSize = uint8_t(rmSize);
_useId = uint8_t(useId);
_outId = uint8_t(outId);
- _rmSize = uint8_t(rmSize);
+ _useRegMask = useRegMask;
+ _outRegMask = outRegMask;
+ _useRewriteMask = useRewriteMask;
+ _outRewriteMask = outRewriteMask;
}
//! \}
- //! \name Overloaded Operators
- //! \{
-
- inline RATiedReg& operator=(const RATiedReg& other) noexcept = default;
-
- //! \}
-
//! \name Accessors
//! \{
//! Returns the associated WorkReg id.
inline uint32_t workId() const noexcept { return _workId; }
- //! Checks if the given `flag` is set, see `Flags`.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasConsecutiveParent() const noexcept { return _consecutiveParent != Globals::kInvalidId; }
+ inline uint32_t consecutiveParent() const noexcept { return _consecutiveParent; }
+ inline uint32_t consecutiveData() const noexcept { return consecutiveDataFromFlags(_flags); }
- //! Returns TiedReg flags, see `RATiedReg::Flags`.
- inline uint32_t flags() const noexcept { return _flags; }
- //! Adds tied register flags, see `Flags`.
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ //! Returns TiedReg flags.
+ inline RATiedFlags flags() const noexcept { return _flags; }
+ //! Checks if the given `flag` is set.
+ inline bool hasFlag(RATiedFlags flag) const noexcept { return Support::test(_flags, flag); }
+ //! Adds tied register flags.
+ inline void addFlags(RATiedFlags flags) noexcept { _flags |= flags; }
//! Tests whether the register is read (writes `true` also if it's Read/Write).
- inline bool isRead() const noexcept { return hasFlag(kRead); }
+ inline bool isRead() const noexcept { return hasFlag(RATiedFlags::kRead); }
//! Tests whether the register is written (writes `true` also if it's Read/Write).
- inline bool isWrite() const noexcept { return hasFlag(kWrite); }
+ inline bool isWrite() const noexcept { return hasFlag(RATiedFlags::kWrite); }
//! Tests whether the register is read only.
- inline bool isReadOnly() const noexcept { return (_flags & kRW) == kRead; }
+ inline bool isReadOnly() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kRead; }
//! Tests whether the register is write only.
- inline bool isWriteOnly() const noexcept { return (_flags & kRW) == kWrite; }
+ inline bool isWriteOnly() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kWrite; }
//! Tests whether the register is read and written.
- inline bool isReadWrite() const noexcept { return (_flags & kRW) == kRW; }
+ inline bool isReadWrite() const noexcept { return (_flags & RATiedFlags::kRW) == RATiedFlags::kRW; }
//! Tests whether the tied register has use operand (Read/ReadWrite).
- inline bool isUse() const noexcept { return hasFlag(kUse); }
+ inline bool isUse() const noexcept { return hasFlag(RATiedFlags::kUse); }
//! Tests whether the tied register has out operand (Write).
- inline bool isOut() const noexcept { return hasFlag(kOut); }
+ inline bool isOut() const noexcept { return hasFlag(RATiedFlags::kOut); }
+
+ //! Tests whether the tied register has \ref RATiedFlags::kLeadConsecutive flag set.
+ inline bool isLeadConsecutive() const noexcept { return hasFlag(RATiedFlags::kLeadConsecutive); }
+ //! Tests whether the tied register has \ref RATiedFlags::kUseConsecutive flag set.
+ inline bool isUseConsecutive() const noexcept { return hasFlag(RATiedFlags::kUseConsecutive); }
+ //! Tests whether the tied register has \ref RATiedFlags::kOutConsecutive flag set.
+ inline bool isOutConsecutive() const noexcept { return hasFlag(RATiedFlags::kOutConsecutive); }
+
+ //! Tests whether the tied register has any consecutive flag.
+ inline bool hasAnyConsecutiveFlag() const noexcept { return hasFlag(RATiedFlags::kLeadConsecutive | RATiedFlags::kUseConsecutive | RATiedFlags::kOutConsecutive); }
//! Tests whether the USE slot can be patched to memory operand.
- inline bool hasUseRM() const noexcept { return hasFlag(kUseRM); }
+ inline bool hasUseRM() const noexcept { return hasFlag(RATiedFlags::kUseRM); }
//! Tests whether the OUT slot can be patched to memory operand.
- inline bool hasOutRM() const noexcept { return hasFlag(kOutRM); }
+ inline bool hasOutRM() const noexcept { return hasFlag(RATiedFlags::kOutRM); }
inline uint32_t rmSize() const noexcept { return _rmSize; }
inline void makeReadOnly() noexcept {
- _flags = (_flags & ~(kOut | kWrite)) | kUse;
+ _flags = (_flags & ~(RATiedFlags::kOut | RATiedFlags::kWrite)) | RATiedFlags::kUse;
_useRewriteMask |= _outRewriteMask;
_outRewriteMask = 0;
}
inline void makeWriteOnly() noexcept {
- _flags = (_flags & ~(kUse | kRead)) | kOut;
+ _flags = (_flags & ~(RATiedFlags::kUse | RATiedFlags::kRead)) | RATiedFlags::kOut;
_outRewriteMask |= _useRewriteMask;
_useRewriteMask = 0;
}
//! Tests whether the register would duplicate.
- inline bool isDuplicate() const noexcept { return hasFlag(kDuplicate); }
+ inline bool isDuplicate() const noexcept { return hasFlag(RATiedFlags::kDuplicate); }
//! Tests whether the register (and the instruction it's part of) appears last in the basic block.
- inline bool isLast() const noexcept { return hasFlag(kLast); }
+ inline bool isLast() const noexcept { return hasFlag(RATiedFlags::kLast); }
//! Tests whether the register should be killed after USEd and/or OUTed.
- inline bool isKill() const noexcept { return hasFlag(kKill); }
+ inline bool isKill() const noexcept { return hasFlag(RATiedFlags::kKill); }
//! Tests whether the register is OUT or KILL (used internally by local register allocator).
- inline bool isOutOrKill() const noexcept { return hasFlag(kOut | kKill); }
+ inline bool isOutOrKill() const noexcept { return hasFlag(RATiedFlags::kOut | RATiedFlags::kKill); }
- inline uint32_t allocableRegs() const noexcept { return _allocableRegs; }
+ //! Returns a register mask that describes allocable USE registers (Read/ReadWrite access).
+ inline RegMask useRegMask() const noexcept { return _useRegMask; }
+ //! Returns a register mask that describes allocable OUT registers (WriteOnly access).
+ inline RegMask outRegMask() const noexcept { return _outRegMask; }
inline uint32_t refCount() const noexcept { return _refCount; }
inline void addRefCount(uint32_t n = 1) noexcept { _refCount = uint8_t(_refCount + n); }
@@ -902,23 +944,67 @@ struct RATiedReg {
//! Sets a physical register used for 'out' operation.
inline void setOutId(uint32_t index) noexcept { _outId = uint8_t(index); }
- inline bool isUseDone() const noexcept { return hasFlag(kUseDone); }
- inline bool isOutDone() const noexcept { return hasFlag(kUseDone); }
+ inline bool isUseDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
+ inline bool isOutDone() const noexcept { return hasFlag(RATiedFlags::kUseDone); }
- inline void markUseDone() noexcept { addFlags(kUseDone); }
- inline void markOutDone() noexcept { addFlags(kUseDone); }
+ inline void markUseDone() noexcept { addFlags(RATiedFlags::kUseDone); }
+ inline void markOutDone() noexcept { addFlags(RATiedFlags::kUseDone); }
//! \}
};
-// ============================================================================
-// [asmjit::RAWorkReg]
-// ============================================================================
+//! Flags used by \ref RAWorkReg.
+enum class RAWorkRegFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
+ //! This register has already been allocated.
+ kAllocated = 0x00000001u,
+ //! Has been coalesced to another WorkReg.
+ kCoalesced = 0x00000002u,
+
+ //! Set when this register is used as a LEAD consecutive register at least once.
+ kLeadConsecutive = 0x00000004u,
+ //! Used to mark consecutive registers during processing.
+ kProcessedConsecutive = 0x00000008u,
+
+ //! Stack slot has to be allocated.
+ kStackUsed = 0x00000010u,
+ //! Stack allocation is preferred.
+ kStackPreferred = 0x00000020u,
+ //! Marked for stack argument reassignment.
+ kStackArgToStack = 0x00000040u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(RAWorkRegFlags)
+//! Work register provides additional data of \ref VirtReg that is used by register allocator.
+//!
+//! In general when a virtual register is found by register allocator it maps it to \ref RAWorkReg
+//! and then only works with it. The reason for such mapping is that users can create many virtual
+//! registers, which are not used inside a register allocation scope (which is currently always a
+//! function). So register allocator basically scans the function for virtual registers and maps
+//! them into WorkRegs, which receive a temporary ID (workId), which starts from zero. This WorkId
+//! is then used in bit-arrays and other mappings.
class RAWorkReg {
public:
ASMJIT_NONCOPYABLE(RAWorkReg)
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ kIdNone = 0xFFFFFFFFu
+ };
+
+ enum : uint32_t {
+ kNoArgIndex = 0xFFu
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! RAPass specific ID used during analysis and allocation.
uint32_t _workId = 0;
//! Copy of ID used by \ref VirtReg.
@@ -932,17 +1018,31 @@ public:
RAStackSlot* _stackSlot = nullptr;
//! Copy of a signature used by \ref VirtReg.
- RegInfo _info {};
+ OperandSignature _signature {};
//! RAPass specific flags used during analysis and allocation.
- uint32_t _flags = 0;
- //! IDs of all physical registers this WorkReg has been allocated to.
- uint32_t _allocatedMask = 0;
- //! IDs of all physical registers that are clobbered during the lifetime of
- //! this WorkReg.
+ RAWorkRegFlags _flags = RAWorkRegFlags::kNone;
+
+ //! Constains all USE ids collected from all instructions.
//!
- //! This mask should be updated by `RAPass::buildLiveness()`, because it's
- //! global and should be updated after unreachable code has been removed.
- uint32_t _clobberSurvivalMask = 0;
+ //! If this mask is non-zero and not a power of two, it means that the register is used multiple times in
+ //! instructions where it requires to have a different use ID. This means that in general it's not possible
+ //! to keep this register in a single home.
+ RegMask _useIdMask = 0;
+ //! Preferred mask of registers (if non-zero) to allocate this register to.
+ //!
+ //! If this mask is zero it means that either there is no intersection of preferred registers collected from all
+ //! TiedRegs or there is no preference at all (the register can be allocated to any register all the time).
+ RegMask _preferredMask = 0xFFFFFFFFu;
+ //! Consecutive mask, which was collected from all instructions where this register was used as a lead consecutive
+ //! register.
+ RegMask _consecutiveMask = 0xFFFFFFFFu;
+ //! IDs of all physical registers that are clobbered during the lifetime of this WorkReg.
+ //!
+ //! This mask should be updated by `RAPass::buildLiveness()`, because it's global and should
+ //! be updated after unreachable code has been removed.
+ RegMask _clobberSurvivalMask = 0;
+ //! IDs of all physical registers this WorkReg has been allocated to.
+ RegMask _allocatedMask = 0;
//! A byte-mask where each bit represents one valid byte of the register.
uint64_t _regByteMask = 0;
@@ -962,37 +1062,27 @@ public:
RALiveStats _liveStats {};
//! All nodes that read/write this VirtReg/WorkReg.
- ZoneVector<BaseNode*> _refs;
+ ZoneVector<BaseNode*> _refs {};
//! All nodes that write to this VirtReg/WorkReg.
- ZoneVector<BaseNode*> _writes;
-
- enum Ids : uint32_t {
- kIdNone = 0xFFFFFFFFu
- };
+ ZoneVector<BaseNode*> _writes {};
- enum Flags : uint32_t {
- //! Has been coalesced to another WorkReg.
- kFlagCoalesced = 0x00000001u,
- //! Stack slot has to be allocated.
- kFlagStackUsed = 0x00000002u,
- //! Stack allocation is preferred.
- kFlagStackPreferred = 0x00000004u,
- //! Marked for stack argument reassignment.
- kFlagStackArgToStack = 0x00000008u
- };
+ //! Contains work IDs of all immediate consecutive registers of this register.
+ //!
+ //! \note This bit array only contains immediate consecutives. This means that if this is a register that is
+ //! followed by 3 more registers, then it would still have only a single immediate. The rest registers would
+ //! have immediate consecutive registers as well, except the last one.
+ ZoneBitVector _immediateConsecutives {};
- enum ArgIndex : uint32_t {
- kNoArgIndex = 0xFFu
- };
+ //! \}
//! \name Construction & Destruction
//! \{
- ASMJIT_INLINE RAWorkReg(VirtReg* vReg, uint32_t workId) noexcept
+ inline RAWorkReg(VirtReg* vReg, uint32_t workId) noexcept
: _workId(workId),
_virtId(vReg->id()),
_virtReg(vReg),
- _info(vReg->info()) {}
+ _signature(vReg->signature()) {}
//! \}
@@ -1005,24 +1095,33 @@ public:
inline const char* name() const noexcept { return _virtReg->name(); }
inline uint32_t nameSize() const noexcept { return _virtReg->nameSize(); }
- inline uint32_t typeId() const noexcept { return _virtReg->typeId(); }
+ inline TypeId typeId() const noexcept { return _virtReg->typeId(); }
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
- inline uint32_t flags() const noexcept { return _flags; }
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ inline RAWorkRegFlags flags() const noexcept { return _flags; }
+ inline bool hasFlag(RAWorkRegFlags flag) const noexcept { return Support::test(_flags, flag); }
+ inline void addFlags(RAWorkRegFlags flags) noexcept { _flags |= flags; }
- inline bool isStackUsed() const noexcept { return hasFlag(kFlagStackUsed); }
- inline void markStackUsed() noexcept { addFlags(kFlagStackUsed); }
+ inline bool isAllocated() const noexcept { return hasFlag(RAWorkRegFlags::kAllocated); }
+ inline void markAllocated() noexcept { addFlags(RAWorkRegFlags::kAllocated); }
- inline bool isStackPreferred() const noexcept { return hasFlag(kFlagStackPreferred); }
- inline void markStackPreferred() noexcept { addFlags(kFlagStackPreferred); }
+ inline bool isLeadConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kLeadConsecutive); }
+ inline void markLeadConsecutive() noexcept { addFlags(RAWorkRegFlags::kLeadConsecutive); }
+
+ inline bool isProcessedConsecutive() const noexcept { return hasFlag(RAWorkRegFlags::kProcessedConsecutive); }
+ inline void markProcessedConsecutive() noexcept { addFlags(RAWorkRegFlags::kProcessedConsecutive); }
+
+ inline bool isStackUsed() const noexcept { return hasFlag(RAWorkRegFlags::kStackUsed); }
+ inline void markStackUsed() noexcept { addFlags(RAWorkRegFlags::kStackUsed); }
+
+ inline bool isStackPreferred() const noexcept { return hasFlag(RAWorkRegFlags::kStackPreferred); }
+ inline void markStackPreferred() noexcept { addFlags(RAWorkRegFlags::kStackPreferred); }
//! Tests whether this RAWorkReg has been coalesced with another one (cannot be used anymore).
- inline bool isCoalesced() const noexcept { return hasFlag(kFlagCoalesced); }
+ inline bool isCoalesced() const noexcept { return hasFlag(RAWorkRegFlags::kCoalesced); }
- inline const RegInfo& info() const noexcept { return _info; }
- inline uint32_t group() const noexcept { return _info.group(); }
- inline uint32_t signature() const noexcept { return _info.signature(); }
+ inline OperandSignature signature() const noexcept { return _signature; }
+ inline RegType type() const noexcept { return _signature.regType(); }
+ inline RegGroup group() const noexcept { return _signature.regGroup(); }
inline VirtReg* virtReg() const noexcept { return _virtReg; }
@@ -1057,15 +1156,39 @@ public:
inline uint32_t hintRegId() const noexcept { return _hintRegId; }
inline void setHintRegId(uint32_t physId) noexcept { _hintRegId = uint8_t(physId); }
- inline uint32_t allocatedMask() const noexcept { return _allocatedMask; }
- inline void addAllocatedMask(uint32_t mask) noexcept { _allocatedMask |= mask; }
+ inline RegMask useIdMask() const noexcept { return _useIdMask; }
+ inline bool hasUseIdMask() const noexcept { return _useIdMask != 0u; }
+ inline bool hasMultipleUseIds() const noexcept { return _useIdMask != 0u && !Support::isPowerOf2(_useIdMask); }
+ inline void addUseIdMask(RegMask mask) noexcept { _useIdMask |= mask; }
+
+ inline RegMask preferredMask() const noexcept { return _preferredMask; }
+ inline bool hasPrereffedMask() const noexcept { return _preferredMask != 0xFFFFFFFFu; }
+ inline void restrictPreferredMask(RegMask mask) noexcept { _preferredMask &= mask; }
+
+ inline RegMask consecutiveMask() const noexcept { return _consecutiveMask; }
+ inline bool hasConsecutiveMask() const noexcept { return _consecutiveMask != 0xFFFFFFFFu; }
+ inline void restrictConsecutiveMask(RegMask mask) noexcept { _consecutiveMask &= mask; }
+
+ inline RegMask clobberSurvivalMask() const noexcept { return _clobberSurvivalMask; }
+ inline void addClobberSurvivalMask(RegMask mask) noexcept { _clobberSurvivalMask |= mask; }
- inline uint32_t clobberSurvivalMask() const noexcept { return _clobberSurvivalMask; }
- inline void addClobberSurvivalMask(uint32_t mask) noexcept { _clobberSurvivalMask |= mask; }
+ inline RegMask allocatedMask() const noexcept { return _allocatedMask; }
+ inline void addAllocatedMask(RegMask mask) noexcept { _allocatedMask |= mask; }
inline uint64_t regByteMask() const noexcept { return _regByteMask; }
inline void setRegByteMask(uint64_t mask) noexcept { _regByteMask = mask; }
+ inline bool hasImmediateConsecutives() const noexcept { return !_immediateConsecutives.empty(); }
+ inline const ZoneBitVector& immediateConsecutives() const noexcept { return _immediateConsecutives; }
+
+ inline Error addImmediateConsecutive(ZoneAllocator* allocator, uint32_t workId) noexcept {
+ if (_immediateConsecutives.size() <= workId)
+ ASMJIT_PROPAGATE(_immediateConsecutives.resize(allocator, workId + 1));
+
+ _immediateConsecutives.setBit(workId, true);
+ return kErrorOk;
+ }
+
//! \}
};
diff --git a/src/asmjit/core/ralocal.cpp b/src/asmjit/core/ralocal.cpp
index 5e06d5b..54bc524 100644
--- a/src/asmjit/core/ralocal.cpp
+++ b/src/asmjit/core/ralocal.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_COMPILER
@@ -29,20 +11,18 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::RALocalAllocator - Utilities]
-// ============================================================================
+// RALocalAllocator - Utilities
+// ============================
-static ASMJIT_INLINE RATiedReg* RALocal_findTiedRegByWorkId(RATiedReg* tiedRegs, size_t count, uint32_t workId) noexcept {
+static ASMJIT_FORCE_INLINE RATiedReg* RALocal_findTiedRegByWorkId(RATiedReg* tiedRegs, size_t count, uint32_t workId) noexcept {
for (size_t i = 0; i < count; i++)
if (tiedRegs[i].workId() == workId)
return &tiedRegs[i];
return nullptr;
}
-// ============================================================================
-// [asmjit::RALocalAllocator - Init / Reset]
-// ============================================================================
+// RALocalAllocator - Init & Reset
+// ===============================
Error RALocalAllocator::init() noexcept {
PhysToWorkMap* physToWorkMap;
@@ -67,9 +47,8 @@ Error RALocalAllocator::init() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::RALocalAllocator - Assignment]
-// ============================================================================
+// RALocalAllocator - Assignment
+// =============================
Error RALocalAllocator::makeInitialAssignment() noexcept {
FuncNode* func = _pass->func();
@@ -83,10 +62,12 @@ Error RALocalAllocator::makeInitialAssignment() noexcept {
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
// Unassigned argument.
- VirtReg* virtReg = func->argPack(argIndex)[valueIndex];
- if (!virtReg)
+ const RegOnly& regArg = func->argPack(argIndex)[valueIndex];
+ if (!regArg.isReg() || !_cc->isVirtIdValid(regArg.id()))
continue;
+ VirtReg* virtReg = _cc->virtRegById(regArg.id());
+
// Unreferenced argument.
RAWorkReg* workReg = virtReg->workReg();
if (!workReg)
@@ -97,18 +78,18 @@ Error RALocalAllocator::makeInitialAssignment() noexcept {
if (!liveIn.bitAt(workId))
continue;
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
if (_curAssignment.workToPhysId(group, workId) != RAAssignment::kPhysNone)
continue;
- uint32_t allocableRegs = _availableRegs[group] & ~_curAssignment.assigned(group);
+ RegMask allocableRegs = _availableRegs[group] & ~_curAssignment.assigned(group);
if (iter == 0) {
// First iteration: Try to allocate to home RegId.
if (workReg->hasHomeRegId()) {
uint32_t physId = workReg->homeRegId();
if (Support::bitTest(allocableRegs, physId)) {
_curAssignment.assign(group, workId, physId, true);
- _pass->_argsAssignment.assignRegInPack(argIndex, valueIndex, workReg->info().type(), physId, workReg->typeId());
+ _pass->_argsAssignment.assignRegInPack(argIndex, valueIndex, workReg->type(), physId, workReg->typeId());
continue;
}
}
@@ -120,7 +101,7 @@ Error RALocalAllocator::makeInitialAssignment() noexcept {
if (allocableRegs) {
uint32_t physId = Support::ctz(allocableRegs);
_curAssignment.assign(group, workId, physId, true);
- _pass->_argsAssignment.assignRegInPack(argIndex, valueIndex, workReg->info().type(), physId, workReg->typeId());
+ _pass->_argsAssignment.assignRegInPack(argIndex, valueIndex, workReg->type(), physId, workReg->typeId());
}
else {
// This register will definitely need stack, create the slot now and assign also `argIndex`
@@ -130,7 +111,7 @@ Error RALocalAllocator::makeInitialAssignment() noexcept {
return DebugUtils::errored(kErrorOutOfMemory);
// This means STACK_ARG may be moved to STACK.
- workReg->addFlags(RAWorkReg::kFlagStackArgToStack);
+ workReg->addFlags(RAWorkRegFlags::kStackArgToStack);
_pass->_numStackArgsToStackSlots++;
}
}
@@ -165,15 +146,15 @@ Error RALocalAllocator::switchToAssignment(
if (tryMode)
return kErrorOk;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
- // ------------------------------------------------------------------------
- // STEP 1:
+ for (RegGroup group : RegGroupVirtValues{}) {
+ // STEP 1
+ // ------
+ //
// - KILL all registers that are not live at `dst`,
// - SPILL all registers that are not assigned at `dst`.
- // ------------------------------------------------------------------------
if (!tryMode) {
- Support::BitWordIterator<uint32_t> it(cur.assigned(group));
+ Support::BitWordIterator<RegMask> it(cur.assigned(group));
while (it.hasNext()) {
uint32_t physId = it.next();
uint32_t workId = cur.physToWorkId(group, physId);
@@ -195,19 +176,18 @@ Error RALocalAllocator::switchToAssignment(
}
}
- // ------------------------------------------------------------------------
- // STEP 2:
- // - MOVE and SWAP registers from their current assignments into their
- // DST assignments.
+ // STEP 2
+ // ------
+ //
+ // - MOVE and SWAP registers from their current assignments into their DST assignments.
// - Build `willLoadRegs` mask of registers scheduled for `onLoadReg()`.
- // ------------------------------------------------------------------------
// Current run-id (1 means more aggressive decisions).
int32_t runId = -1;
// Remaining registers scheduled for `onLoadReg()`.
- uint32_t willLoadRegs = 0;
+ RegMask willLoadRegs = 0;
// Remaining registers to be allocated in this loop.
- uint32_t affectedRegs = dst.assigned(group);
+ RegMask affectedRegs = dst.assigned(group);
while (affectedRegs) {
if (++runId == 2) {
@@ -218,10 +198,10 @@ Error RALocalAllocator::switchToAssignment(
break;
}
- Support::BitWordIterator<uint32_t> it(affectedRegs);
+ Support::BitWordIterator<RegMask> it(affectedRegs);
while (it.hasNext()) {
uint32_t physId = it.next();
- uint32_t physMask = Support::bitMask(physId);
+ RegMask physMask = Support::bitMask<RegMask>(physId);
uint32_t curWorkId = cur.physToWorkId(group, physId);
uint32_t dstWorkId = dst.physToWorkId(group, physId);
@@ -243,7 +223,7 @@ Error RALocalAllocator::switchToAssignment(
// Reset as we will do some changes to the current assignment.
runId = -1;
- if (_archTraits->hasSwap(group)) {
+ if (_archTraits->hasInstRegSwap(group)) {
ASMJIT_PROPAGATE(onSwapReg(group, curWorkId, physId, dstWorkId, altPhysId));
}
else {
@@ -252,7 +232,7 @@ Error RALocalAllocator::switchToAssignment(
ASMJIT_PROPAGATE(onKillReg(group, curWorkId, physId));
}
else {
- uint32_t allocableRegs = _pass->_availableRegs[group] & ~cur.assigned(group);
+ RegMask allocableRegs = _pass->_availableRegs[group] & ~cur.assigned(group);
// If possible don't conflict with assigned regs at DST.
if (allocableRegs & ~dst.assigned(group))
@@ -294,9 +274,8 @@ Cleared:
// CUR dirty, DST not dirty (the assert is just to visualize the condition).
ASMJIT_ASSERT(!dst.isPhysDirty(group, physId) && cur.isPhysDirty(group, physId));
- // If `dstReadOnly` is true it means that that block was already
- // processed and we cannot change from CLEAN to DIRTY. In that case
- // the register has to be saved as it cannot enter the block DIRTY.
+ // If `dstReadOnly` is true it means that that block was already processed and we cannot change from
+ // CLEAN to DIRTY. In that case the register has to be saved as it cannot enter the block DIRTY.
if (dstReadOnly)
ASMJIT_PROPAGATE(onSaveReg(group, dstWorkId, physId));
else
@@ -319,13 +298,13 @@ Cleared:
}
}
- // ------------------------------------------------------------------------
- // STEP 3:
+ // STEP 3
+ // ------
+ //
// - Load registers specified by `willLoadRegs`.
- // ------------------------------------------------------------------------
{
- Support::BitWordIterator<uint32_t> it(willLoadRegs);
+ Support::BitWordIterator<RegMask> it(willLoadRegs);
while (it.hasNext()) {
uint32_t physId = it.next();
@@ -349,7 +328,7 @@ Cleared:
}
if (!tryMode) {
- // Hre is a code that dumps the conflicting part if something fails here:
+ // Here is a code that dumps the conflicting part if something fails here:
// if (!dst.equals(cur)) {
// uint32_t physTotal = dst._layout.physTotal;
// uint32_t workCount = dst._layout.workCount;
@@ -374,9 +353,9 @@ Cleared:
return kErrorOk;
}
-Error RALocalAllocator::spillScratchGpRegsBeforeEntry(uint32_t scratchRegs) noexcept {
- uint32_t group = BaseReg::kGroupGp;
- Support::BitWordIterator<uint32_t> it(scratchRegs);
+Error RALocalAllocator::spillScratchGpRegsBeforeEntry(RegMask scratchRegs) noexcept {
+ RegGroup group = RegGroup::kGp;
+ Support::BitWordIterator<RegMask> it(scratchRegs);
while (it.hasNext()) {
uint32_t physId = it.next();
@@ -389,15 +368,15 @@ Error RALocalAllocator::spillScratchGpRegsBeforeEntry(uint32_t scratchRegs) noex
return kErrorOk;
}
-// ============================================================================
-// [asmjit::RALocalAllocator - Allocation]
-// ============================================================================
+// RALocalAllocator - Allocation
+// =============================
Error RALocalAllocator::allocInst(InstNode* node) noexcept {
RAInst* raInst = node->passData<RAInst>();
RATiedReg* outTiedRegs[Globals::kMaxPhysRegs];
RATiedReg* dupTiedRegs[Globals::kMaxPhysRegs];
+ RATiedReg* consecutiveRegs[kMaxConsecutiveRegs];
// The cursor must point to the previous instruction for a possible instruction insertion.
_cc->_setCursor(node->prev());
@@ -410,34 +389,43 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
// Whether we already replaced register operand with memory operand.
bool rmAllocated = false;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
uint32_t i, count = this->tiedCount(group);
RATiedReg* tiedRegs = this->tiedRegs(group);
- uint32_t willUse = _raInst->_usedRegs[group];
- uint32_t willOut = _raInst->_clobberedRegs[group];
- uint32_t willFree = 0;
- uint32_t usePending = count;
+ RegMask willUse = _raInst->_usedRegs[group];
+ RegMask willOut = _raInst->_clobberedRegs[group];
+ RegMask willFree = 0;
+ uint32_t usePending = count;
uint32_t outTiedCount = 0;
uint32_t dupTiedCount = 0;
+ uint32_t consecutiveMask = 0;
- // ------------------------------------------------------------------------
- // STEP 1:
+ // STEP 1
+ // ------
//
- // Calculate `willUse` and `willFree` masks based on tied registers we have.
+ // Calculate `willUse` and `willFree` masks based on tied registers we have. In addition, aggregate information
+ // regarding consecutive registers used by this instruction. We need that to make USE/OUT assignments.
//
- // We don't do any assignment decisions at this stage as we just need to
- // collect some information first. Then, after we populate all masks needed
- // we can finally make some decisions in the second loop. The main reason
- // for this is that we really need `willFree` to make assignment decisions
- // for `willUse`, because if we mark some registers that will be freed, we
- // can consider them in decision making afterwards.
- // ------------------------------------------------------------------------
+ // We don't do any assignment decisions at this stage as we just need to collect some information first. Then,
+ // after we populate all masks needed we can finally make some decisions in the second loop. The main reason
+ // for this is that we really need `willFree` to make assignment decisions for `willUse`, because if we mark
+ // some registers that will be freed, we can consider them in decision making afterwards.
for (i = 0; i < count; i++) {
RATiedReg* tiedReg = &tiedRegs[i];
+ if (tiedReg->hasAnyConsecutiveFlag()) {
+ uint32_t consecutiveOffset = tiedReg->isLeadConsecutive() ? uint32_t(0) : tiedReg->consecutiveData();
+
+ if (ASMJIT_UNLIKELY(Support::bitTest(consecutiveMask, consecutiveOffset)))
+ return DebugUtils::errored(kErrorInvalidState);
+
+ consecutiveMask |= Support::bitMask(consecutiveOffset);
+ consecutiveRegs[consecutiveOffset] = tiedReg;
+ }
+
// Add OUT and KILL to `outPending` for CLOBBERing and/or OUT assignment.
if (tiedReg->isOutOrKill())
outTiedRegs[outTiedCount++] = tiedReg;
@@ -451,12 +439,16 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
continue;
}
+ // Don't assign anything here if this is a consecutive USE - we will handle this in STEP 2 instead.
+ if (tiedReg->isUseConsecutive())
+ continue;
+
uint32_t workId = tiedReg->workId();
uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
if (tiedReg->hasUseId()) {
// If the register has `useId` it means it can only be allocated in that register.
- uint32_t useMask = Support::bitMask(tiedReg->useId());
+ RegMask useMask = Support::bitMask(tiedReg->useId());
// RAInstBuilder must have collected `usedRegs` on-the-fly.
ASMJIT_ASSERT((willUse & useMask) != 0);
@@ -475,9 +467,9 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
else {
// Check if the register must be moved to `allocableRegs`.
- uint32_t allocableRegs = tiedReg->allocableRegs();
+ RegMask allocableRegs = tiedReg->useRegMask();
if (assignedId != RAAssignment::kPhysNone) {
- uint32_t assignedMask = Support::bitMask(assignedId);
+ RegMask assignedMask = Support::bitMask(assignedId);
if ((allocableRegs & ~willUse) & assignedMask) {
tiedReg->setUseId(assignedId);
tiedReg->markUseDone();
@@ -493,24 +485,107 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
}
- // ------------------------------------------------------------------------
- // STEP 2:
+ // STEP 2
+ // ------
//
- // Do some decision making to find the best candidates of registers that
- // need to be assigned, moved, and/or spilled. Only USE registers are
- // considered here, OUT will be decided later after all CLOBBERed and OUT
+ // Verify that all the consecutive registers are really consecutive. Terminate if there is a gap. In addition,
+ // decide which USE ids will be used in case that this consecutive sequence is USE (OUT registers are allocated
+ // in a different step).
+ uint32_t consecutiveCount = 0;
+
+ if (consecutiveMask) {
+ if ((consecutiveMask & (consecutiveMask + 1u)) != 0)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ // Count of trailing ones is the count of consecutive registers. There cannot be gap.
+ consecutiveCount = Support::ctz(~consecutiveMask);
+
+ // Prioritize allocation that would result in least moves even when moving registers away from their homes.
+ RATiedReg* lead = consecutiveRegs[0];
+
+ // Assign the best possible USE Ids to all consecutives.
+ if (lead->isUseConsecutive()) {
+ uint32_t bestScore = 0;
+ uint32_t bestLeadReg = 0xFFFFFFFF;
+ RegMask allocableRegs = (_availableRegs[group] | willFree) & ~willUse;
+
+ uint32_t assignments[kMaxConsecutiveRegs];
+
+ for (i = 0; i < consecutiveCount; i++)
+ assignments[i] = _curAssignment.workToPhysId(group, consecutiveRegs[i]->workId());
+
+ Support::BitWordIterator<uint32_t> it(lead->useRegMask());
+ while (it.hasNext()) {
+ uint32_t regIndex = it.next();
+ if (Support::bitTest(lead->useRegMask(), regIndex)) {
+ uint32_t score = 15;
+
+ for (i = 0; i < consecutiveCount; i++) {
+ uint32_t consecutiveIndex = regIndex + i;
+ if (!Support::bitTest(allocableRegs, consecutiveIndex)) {
+ score = 0;
+ break;
+ }
+
+ RAWorkReg* workReg = workRegById(consecutiveRegs[i]->workId());
+ score += uint32_t(workReg->homeRegId() == consecutiveIndex);
+ score += uint32_t(assignments[i] == consecutiveIndex) * 2;
+ }
+
+ if (score > bestScore) {
+ bestScore = score;
+ bestLeadReg = regIndex;
+ }
+ }
+ }
+
+ if (bestLeadReg == 0xFFFFFFFF)
+ return DebugUtils::errored(kErrorConsecutiveRegsAllocation);
+
+ for (i = 0; i < consecutiveCount; i++) {
+ uint32_t consecutiveIndex = bestLeadReg + i;
+
+ RATiedReg* tiedReg = consecutiveRegs[i];
+ RegMask useMask = Support::bitMask(consecutiveIndex);
+
+ uint32_t workId = tiedReg->workId();
+ uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
+
+ tiedReg->setUseId(consecutiveIndex);
+
+ if (assignedId == consecutiveIndex) {
+ // If the register is already allocated in this one, mark it done and continue.
+ tiedReg->markUseDone();
+ if (tiedReg->isWrite())
+ _curAssignment.makeDirty(group, workId, assignedId);
+ usePending--;
+ willUse |= useMask;
+ }
+ else {
+ willUse |= useMask;
+ willFree |= useMask & _curAssignment.assigned(group);
+ }
+ }
+ }
+ }
+
+ // STEP 3
+ // ------
+ //
+ // Do some decision making to find the best candidates of registers that need to be assigned, moved, and/or
+ // spilled. Only USE registers are considered here, OUT will be decided later after all CLOBBERed and OUT
// registers are unassigned.
- // ------------------------------------------------------------------------
if (usePending) {
// TODO: Not sure `liveRegs` should be used, maybe willUse and willFree would be enough and much more clear.
// All registers that are currently alive without registers that will be freed.
- uint32_t liveRegs = _curAssignment.assigned(group) & ~willFree;
+ RegMask liveRegs = _curAssignment.assigned(group) & ~willFree;
for (i = 0; i < count; i++) {
RATiedReg* tiedReg = &tiedRegs[i];
- if (tiedReg->isUseDone()) continue;
+ if (tiedReg->isUseDone())
+ continue;
uint32_t workId = tiedReg->workId();
uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
@@ -538,18 +613,17 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
if (!tiedReg->hasUseId()) {
- uint32_t allocableRegs = tiedReg->allocableRegs() & ~(willFree | willUse);
-
// DECIDE where to assign the USE register.
+ RegMask allocableRegs = tiedReg->useRegMask() & ~(willFree | willUse);
uint32_t useId = decideOnAssignment(group, workId, assignedId, allocableRegs);
- uint32_t useMask = Support::bitMask(useId);
+ RegMask useMask = Support::bitMask(useId);
willUse |= useMask;
willFree |= useMask & liveRegs;
tiedReg->setUseId(useId);
if (assignedId != RAAssignment::kPhysNone) {
- uint32_t assignedMask = Support::bitMask(assignedId);
+ RegMask assignedMask = Support::bitMask(assignedId);
willFree |= assignedMask;
liveRegs &= ~assignedMask;
@@ -579,19 +653,18 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
}
- // Initially all used regs will be marked clobbered.
- uint32_t clobberedByInst = willUse | willOut;
+ // Initially all used regs will be marked as clobbered.
+ RegMask clobberedByInst = willUse | willOut;
- // ------------------------------------------------------------------------
- // STEP 3:
+ // STEP 4
+ // ------
//
- // Free all registers that we marked as `willFree`. Only registers that are not
- // USEd by the instruction are considered as we don't want to free regs we need.
- // ------------------------------------------------------------------------
+ // Free all registers that we marked as `willFree`. Only registers that are not USEd by the instruction are
+ // considered as we don't want to free regs we need.
if (willFree) {
- uint32_t allocableRegs = _availableRegs[group] & ~(_curAssignment.assigned(group) | willFree | willUse | willOut);
- Support::BitWordIterator<uint32_t> it(willFree);
+ RegMask allocableRegs = _availableRegs[group] & ~(_curAssignment.assigned(group) | willFree | willUse | willOut);
+ Support::BitWordIterator<RegMask> it(willFree);
do {
uint32_t assignedId = it.next();
@@ -613,21 +686,17 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
} while (it.hasNext());
}
- // ------------------------------------------------------------------------
- // STEP 4:
+ // STEP 5
+ // ------
//
- // ALLOCATE / SHUFFLE all registers that we marked as `willUse` and weren't
- // allocated yet. This is a bit complicated as the allocation is iterative.
- // In some cases we have to wait before allocating a particual physical
- // register as it's still occupied by some other one, which we need to move
- // before we can use it. In this case we skip it and allocate another some
- // other instead (making it free for another iteration).
+ // ALLOCATE / SHUFFLE all registers that we marked as `willUse` and weren't allocated yet. This is a bit
+ // complicated as the allocation is iterative. In some cases we have to wait before allocating a particual
+ // physical register as it's still occupied by some other one, which we need to move before we can use it.
+ // In this case we skip it and allocate another some other instead (making it free for another iteration).
//
- // NOTE: Iterations are mostly important for complicated allocations like
- // function calls, where there can be up to N registers used at once. Asm
- // instructions won't run the loop more than once in 99.9% of cases as they
- // use 2..3 registers in average.
- // ------------------------------------------------------------------------
+ // NOTE: Iterations are mostly important for complicated allocations like function calls, where there can
+ // be up to N registers used at once. Asm instructions won't run the loop more than once in 99.9% of cases
+ // as they use 2..3 registers in average.
if (usePending) {
bool mustSwap = false;
@@ -636,7 +705,8 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
for (i = 0; i < count; i++) {
RATiedReg* thisTiedReg = &tiedRegs[i];
- if (thisTiedReg->isUseDone()) continue;
+ if (thisTiedReg->isUseDone())
+ continue;
uint32_t thisWorkId = thisTiedReg->workId();
uint32_t thisPhysId = _curAssignment.workToPhysId(group, thisWorkId);
@@ -649,11 +719,10 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
if (targetWorkId != RAAssignment::kWorkNone) {
RAWorkReg* targetWorkReg = workRegById(targetWorkId);
- // Swapping two registers can solve two allocation tasks by emitting
- // just a single instruction. However, swap is only available on few
- // architectures and it's definitely not available for each register
- // group. Calling `onSwapReg()` before checking these would be fatal.
- if (_archTraits->hasSwap(group) && thisPhysId != RAAssignment::kPhysNone) {
+ // Swapping two registers can solve two allocation tasks by emitting just a single instruction. However,
+ // swap is only available on few architectures and it's definitely not available for each register group.
+ // Calling `onSwapReg()` before checking these would be fatal.
+ if (_archTraits->hasInstRegSwap(group) && thisPhysId != RAAssignment::kPhysNone) {
ASMJIT_PROPAGATE(onSwapReg(group, thisWorkId, thisPhysId, targetWorkId, targetPhysId));
thisTiedReg->markUseDone();
@@ -675,10 +744,9 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
if (!mustSwap)
continue;
- // Only branched here if the previous iteration did nothing. This is
- // essentially a SWAP operation without having a dedicated instruction
- // for that purpose (vector registers, etc). The simplest way to
- // handle such case is to SPILL the target register.
+ // Only branched here if the previous iteration did nothing. This is essentially a SWAP operation without
+ // having a dedicated instruction for that purpose (vector registers, etc). The simplest way to handle
+ // such case is to SPILL the target register.
ASMJIT_PROPAGATE(onSpillReg(group, targetWorkId, targetPhysId));
}
@@ -704,11 +772,10 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
} while (usePending);
}
- // ------------------------------------------------------------------------
- // STEP 5:
+ // STEP 6
+ // ------
//
// KILL registers marked as KILL/OUT.
- // ------------------------------------------------------------------------
uint32_t outPending = outTiedCount;
if (outTiedCount) {
@@ -718,28 +785,27 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
uint32_t workId = tiedReg->workId();
uint32_t physId = _curAssignment.workToPhysId(group, workId);
- // Must check if it's allocated as KILL can be related to OUT (like KILL
- // immediately after OUT, which could mean the register is not assigned).
+ // Must check if it's allocated as KILL can be related to OUT (like KILL immediately after OUT, which could
+ // mean the register is not assigned).
if (physId != RAAssignment::kPhysNone) {
ASMJIT_PROPAGATE(onKillReg(group, workId, physId));
willOut &= ~Support::bitMask(physId);
}
- // We still maintain number of pending registers for OUT assignment.
- // So, if this is only KILL, not OUT, we can safely decrement it.
+ // We still maintain number of pending registers for OUT assignment. So, if this is only KILL, not OUT, we
+ // can safely decrement it.
outPending -= !tiedReg->isOut();
}
}
- // ------------------------------------------------------------------------
- // STEP 6:
+ // STEP 7
+ // ------
//
- // SPILL registers that will be CLOBBERed. Since OUT and KILL were
- // already processed this is used mostly to handle function CALLs.
- // ------------------------------------------------------------------------
+ // SPILL registers that will be CLOBBERed. Since OUT and KILL were already processed this is used mostly to
+ // handle function CALLs.
if (willOut) {
- Support::BitWordIterator<uint32_t> it(willOut);
+ Support::BitWordIterator<RegMask> it(willOut);
do {
uint32_t physId = it.next();
uint32_t workId = _curAssignment.physToWorkId(group, physId);
@@ -751,18 +817,17 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
} while (it.hasNext());
}
- // ------------------------------------------------------------------------
- // STEP 7:
+ // STEP 8
+ // ------
//
// Duplication.
- // ------------------------------------------------------------------------
for (i = 0; i < dupTiedCount; i++) {
RATiedReg* tiedReg = dupTiedRegs[i];
uint32_t workId = tiedReg->workId();
uint32_t srcId = tiedReg->useId();
- Support::BitWordIterator<uint32_t> it(tiedReg->_allocableRegs);
+ Support::BitWordIterator<RegMask> it(tiedReg->useRegMask());
while (it.hasNext()) {
uint32_t dstId = it.next();
if (dstId == srcId)
@@ -771,27 +836,71 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
}
- // ------------------------------------------------------------------------
- // STEP 8:
+ // STEP 9
+ // ------
//
// Assign OUT registers.
- // ------------------------------------------------------------------------
if (outPending) {
- // Live registers, we need a separate variable (outside of `_curAssignment)
- // to hold these because of KILLed registers. If we KILL a register here it
- // will go out from `_curAssignment`, but we cannot assign to it in here.
- uint32_t liveRegs = _curAssignment.assigned(group);
+ // Live registers, we need a separate register (outside of `_curAssignment) to hold these because of KILLed
+ // registers. If we KILL a register here it will go out from `_curAssignment`, but we cannot assign to it in
+ // here.
+ RegMask liveRegs = _curAssignment.assigned(group);
// Must avoid as they have been already OUTed (added during the loop).
- uint32_t outRegs = 0;
+ RegMask outRegs = 0;
// Must avoid as they collide with already allocated ones.
- uint32_t avoidRegs = willUse & ~clobberedByInst;
+ RegMask avoidRegs = willUse & ~clobberedByInst;
+
+ // Assign the best possible OUT ids of all consecutives.
+ if (consecutiveCount) {
+ RATiedReg* lead = consecutiveRegs[0];
+ if (lead->isOutConsecutive()) {
+ uint32_t bestScore = 0;
+ uint32_t bestLeadReg = 0xFFFFFFFF;
+ RegMask allocableRegs = _availableRegs[group] & ~(outRegs | avoidRegs);
+
+ Support::BitWordIterator<uint32_t> it(lead->outRegMask());
+ while (it.hasNext()) {
+ uint32_t regIndex = it.next();
+ if (Support::bitTest(lead->outRegMask(), regIndex)) {
+ uint32_t score = 15;
+
+ for (i = 0; i < consecutiveCount; i++) {
+ uint32_t consecutiveIndex = regIndex + i;
+ if (!Support::bitTest(allocableRegs, consecutiveIndex)) {
+ score = 0;
+ break;
+ }
+
+ RAWorkReg* workReg = workRegById(consecutiveRegs[i]->workId());
+ score += uint32_t(workReg->homeRegId() == consecutiveIndex);
+ }
+
+ if (score > bestScore) {
+ bestScore = score;
+ bestLeadReg = regIndex;
+ }
+ }
+ }
+
+ if (bestLeadReg == 0xFFFFFFFF)
+ return DebugUtils::errored(kErrorConsecutiveRegsAllocation);
+
+ for (i = 0; i < consecutiveCount; i++) {
+ uint32_t consecutiveIndex = bestLeadReg + i;
+ RATiedReg* tiedReg = consecutiveRegs[i];
+ tiedReg->setOutId(consecutiveIndex);
+ }
+ }
+ }
+ // Allocate OUT registers.
for (i = 0; i < outTiedCount; i++) {
RATiedReg* tiedReg = outTiedRegs[i];
- if (!tiedReg->isOut()) continue;
+ if (!tiedReg->isOut())
+ continue;
uint32_t workId = tiedReg->workId();
uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
@@ -801,7 +910,7 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
uint32_t physId = tiedReg->outId();
if (physId == RAAssignment::kPhysNone) {
- uint32_t allocableRegs = tiedReg->_allocableRegs & ~(outRegs | avoidRegs);
+ RegMask allocableRegs = tiedReg->outRegMask() & ~(outRegs | avoidRegs);
if (!(allocableRegs & ~liveRegs)) {
// There are no more registers, decide which one to spill.
@@ -839,9 +948,8 @@ Error RALocalAllocator::allocInst(InstNode* node) noexcept {
}
Error RALocalAllocator::spillAfterAllocation(InstNode* node) noexcept {
- // This is experimental feature that would spill registers that don't have
- // home-id and are last in this basic block. This prevents saving these regs
- // in other basic blocks and then restoring them (mostly relevant for loops).
+ // This is experimental feature that would spill registers that don't have home-id and are last in this basic block.
+ // This prevents saving these regs in other basic blocks and then restoring them (mostly relevant for loops).
RAInst* raInst = node->passData<RAInst>();
uint32_t count = raInst->tiedCount();
@@ -851,7 +959,7 @@ Error RALocalAllocator::spillAfterAllocation(InstNode* node) noexcept {
uint32_t workId = tiedReg->workId();
RAWorkReg* workReg = workRegById(workId);
if (!workReg->hasHomeRegId()) {
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
uint32_t assignedId = _curAssignment.workToPhysId(group, workId);
if (assignedId != RAAssignment::kPhysNone) {
_cc->_setCursor(node);
@@ -898,9 +1006,8 @@ Error RALocalAllocator::allocBranch(InstNode* node, RABlock* target, RABlock* co
BaseNode* curCursor = _cc->cursor();
if (curCursor != injectionPoint) {
- // Additional instructions emitted to switch from the current state to
- // the `target` state. This means that we have to move these instructions
- // into an independent code block and patch the jump location.
+ // Additional instructions emitted to switch from the current state to the `target` state. This means
+ // that we have to move these instructions into an independent code block and patch the jump location.
Operand& targetOp = node->op(node->opCount() - 1);
if (ASMJIT_UNLIKELY(!targetOp.isLabel()))
return DebugUtils::errored(kErrorInvalidState);
@@ -911,9 +1018,9 @@ Error RALocalAllocator::allocBranch(InstNode* node, RABlock* target, RABlock* co
// Patch `target` to point to the `trampoline` we just created.
targetOp = trampoline;
- // Clear a possible SHORT form as we have no clue now if the SHORT form would
- // be encodable after patching the target to `trampoline` (X86 specific).
- node->clearInstOptions(BaseInst::kOptionShortForm);
+ // Clear a possible SHORT form as we have no clue now if the SHORT form would be encodable after patching
+ // the target to `trampoline` (X86 specific).
+ node->clearOptions(InstOptions::kShortForm);
// Finalize the switch assignment sequence.
ASMJIT_PROPAGATE(_pass->emitJump(savedTarget));
@@ -969,11 +1076,10 @@ Error RALocalAllocator::allocJumpTable(InstNode* node, const RABlocks& targets,
return kErrorOk;
}
-// ============================================================================
-// [asmjit::RALocalAllocator - Decision Making]
-// ============================================================================
+// RALocalAllocator - Decision Making
+// ==================================
-uint32_t RALocalAllocator::decideOnAssignment(uint32_t group, uint32_t workId, uint32_t physId, uint32_t allocableRegs) const noexcept {
+uint32_t RALocalAllocator::decideOnAssignment(RegGroup group, uint32_t workId, uint32_t physId, RegMask allocableRegs) const noexcept {
ASMJIT_ASSERT(allocableRegs != 0);
DebugUtils::unused(group, physId);
@@ -987,14 +1093,14 @@ uint32_t RALocalAllocator::decideOnAssignment(uint32_t group, uint32_t workId, u
}
// Prefer registers used upon block entries.
- uint32_t previouslyAssignedRegs = workReg->allocatedMask();
+ RegMask previouslyAssignedRegs = workReg->allocatedMask();
if (allocableRegs & previouslyAssignedRegs)
allocableRegs &= previouslyAssignedRegs;
return Support::ctz(allocableRegs);
}
-uint32_t RALocalAllocator::decideOnReassignment(uint32_t group, uint32_t workId, uint32_t physId, uint32_t allocableRegs) const noexcept {
+uint32_t RALocalAllocator::decideOnReassignment(RegGroup group, uint32_t workId, uint32_t physId, RegMask allocableRegs) const noexcept {
ASMJIT_ASSERT(allocableRegs != 0);
DebugUtils::unused(group, physId);
@@ -1012,12 +1118,12 @@ uint32_t RALocalAllocator::decideOnReassignment(uint32_t group, uint32_t workId,
return RAAssignment::kPhysNone;
}
-uint32_t RALocalAllocator::decideOnSpillFor(uint32_t group, uint32_t workId, uint32_t spillableRegs, uint32_t* spillWorkId) const noexcept {
+uint32_t RALocalAllocator::decideOnSpillFor(RegGroup group, uint32_t workId, RegMask spillableRegs, uint32_t* spillWorkId) const noexcept {
// May be used in the future to decide which register would be best to spill so `workId` can be assigned.
DebugUtils::unused(workId);
ASMJIT_ASSERT(spillableRegs != 0);
- Support::BitWordIterator<uint32_t> it(spillableRegs);
+ Support::BitWordIterator<RegMask> it(spillableRegs);
uint32_t bestPhysId = it.next();
uint32_t bestWorkId = _curAssignment.physToWorkId(group, bestPhysId);
diff --git a/src/asmjit/core/ralocal_p.h b/src/asmjit/core/ralocal_p.h
index eebecc9..05467c5 100644
--- a/src/asmjit/core/ralocal_p.h
+++ b/src/asmjit/core/ralocal_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RALOCAL_P_H_INCLUDED
#define ASMJIT_CORE_RALOCAL_P_H_INCLUDED
@@ -38,10 +20,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RALocalAllocator]
-// ============================================================================
-
//! Local register allocator.
class RALocalAllocator {
public:
@@ -119,14 +97,14 @@ public:
//! Returns all tied regs as `RATiedReg` array.
inline RATiedReg* tiedRegs() const noexcept { return _raInst->tiedRegs(); }
//! Returns tied registers grouped by the given `group`.
- inline RATiedReg* tiedRegs(uint32_t group) const noexcept { return _raInst->tiedRegs(group); }
+ inline RATiedReg* tiedRegs(RegGroup group) const noexcept { return _raInst->tiedRegs(group); }
//! Returns count of all TiedRegs used by the instruction.
inline uint32_t tiedCount() const noexcept { return _tiedTotal; }
//! Returns count of TiedRegs used by the given register `group`.
- inline uint32_t tiedCount(uint32_t group) const noexcept { return _tiedCount.get(group); }
+ inline uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount.get(group); }
- inline bool isGroupUsed(uint32_t group) const noexcept { return _tiedCount[group] != 0; }
+ inline bool isGroupUsed(RegGroup group) const noexcept { return _tiedCount[group] != 0; }
//! \}
@@ -139,14 +117,12 @@ public:
const PhysToWorkMap* physToWorkMap,
const WorkToPhysMap* workToPhysMap) noexcept;
- //! Switch to the given assignment by reassigning all register and emitting
- //! code that reassigns them. This is always used to switch to a previously
- //! stored assignment.
+ //! Switch to the given assignment by reassigning all register and emitting code that reassigns them.
+ //! This is always used to switch to a previously stored assignment.
//!
- //! If `tryMode` is true then the final assignment doesn't have to be exactly
- //! same as specified by `dstPhysToWorkMap` and `dstWorkToPhysMap`. This mode
- //! is only used before conditional jumps that already have assignment to
- //! generate a code sequence that is always executed regardless of the flow.
+ //! If `tryMode` is true then the final assignment doesn't have to be exactly same as specified by `dstPhysToWorkMap`
+ //! and `dstWorkToPhysMap`. This mode is only used before conditional jumps that already have assignment to generate
+ //! a code sequence that is always executed regardless of the flow.
Error switchToAssignment(
PhysToWorkMap* dstPhysToWorkMap,
WorkToPhysMap* dstWorkToPhysMap,
@@ -185,7 +161,7 @@ public:
return uint32_t(int32_t(freq * float(kCostOfFrequency)));
}
- inline uint32_t calculateSpillCost(uint32_t group, uint32_t workId, uint32_t assignedId) const noexcept {
+ inline uint32_t calculateSpillCost(RegGroup group, uint32_t workId, uint32_t assignedId) const noexcept {
RAWorkReg* workReg = workRegById(workId);
uint32_t cost = costByFrequency(workReg->liveStats().freq());
@@ -196,18 +172,18 @@ public:
}
//! Decides on register assignment.
- uint32_t decideOnAssignment(uint32_t group, uint32_t workId, uint32_t assignedId, uint32_t allocableRegs) const noexcept;
+ uint32_t decideOnAssignment(RegGroup group, uint32_t workId, uint32_t assignedId, RegMask allocableRegs) const noexcept;
- //! Decides on whether to MOVE or SPILL the given WorkReg, because it's allocated
- //! in a physical register that have to be used by another WorkReg.
+ //! Decides on whether to MOVE or SPILL the given WorkReg, because it's allocated in a physical register that have
+ //! to be used by another WorkReg.
//!
- //! The function must return either `RAAssignment::kPhysNone`, which means that
- //! the WorkReg of `workId` should be spilled, or a valid physical register ID,
- //! which means that the register should be moved to that physical register instead.
- uint32_t decideOnReassignment(uint32_t group, uint32_t workId, uint32_t assignedId, uint32_t allocableRegs) const noexcept;
+ //! The function must return either `RAAssignment::kPhysNone`, which means that the WorkReg of `workId` should be
+ //! spilled, or a valid physical register ID, which means that the register should be moved to that physical register
+ //! instead.
+ uint32_t decideOnReassignment(RegGroup group, uint32_t workId, uint32_t assignedId, RegMask allocableRegs) const noexcept;
//! Decides on best spill given a register mask `spillableRegs`
- uint32_t decideOnSpillFor(uint32_t group, uint32_t workId, uint32_t spillableRegs, uint32_t* spillWorkId) const noexcept;
+ uint32_t decideOnSpillFor(RegGroup group, uint32_t workId, RegMask spillableRegs, uint32_t* spillWorkId) const noexcept;
//! \}
@@ -216,7 +192,7 @@ public:
//! Emits a move between a destination and source register, and fixes the
//! register assignment.
- inline Error onMoveReg(uint32_t group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
+ inline Error onMoveReg(RegGroup group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
if (dstPhysId == srcPhysId) return kErrorOk;
_curAssignment.reassign(group, workId, dstPhysId, srcPhysId);
return _pass->emitMove(workId, dstPhysId, srcPhysId);
@@ -225,21 +201,21 @@ public:
//! Emits a swap between two physical registers and fixes their assignment.
//!
//! \note Target must support this operation otherwise this would ASSERT.
- inline Error onSwapReg(uint32_t group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
+ inline Error onSwapReg(RegGroup group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
_curAssignment.swap(group, aWorkId, aPhysId, bWorkId, bPhysId);
return _pass->emitSwap(aWorkId, aPhysId, bWorkId, bPhysId);
}
//! Emits a load from [VirtReg/WorkReg]'s spill slot to a physical register
//! and makes it assigned and clean.
- inline Error onLoadReg(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline Error onLoadReg(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
_curAssignment.assign(group, workId, physId, RAAssignment::kClean);
return _pass->emitLoad(workId, physId);
}
//! Emits a save a physical register to a [VirtReg/WorkReg]'s spill slot,
//! keeps it assigned, and makes it clean.
- inline Error onSaveReg(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline Error onSaveReg(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
ASMJIT_ASSERT(_curAssignment.workToPhysId(group, workId) == physId);
ASMJIT_ASSERT(_curAssignment.physToWorkId(group, physId) == workId);
@@ -248,24 +224,24 @@ public:
}
//! Assigns a register, the content of it is undefined at this point.
- inline Error onAssignReg(uint32_t group, uint32_t workId, uint32_t physId, uint32_t dirty) noexcept {
+ inline Error onAssignReg(RegGroup group, uint32_t workId, uint32_t physId, bool dirty) noexcept {
_curAssignment.assign(group, workId, physId, dirty);
return kErrorOk;
}
//! Spills a variable/register, saves the content to the memory-home if modified.
- inline Error onSpillReg(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline Error onSpillReg(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
if (_curAssignment.isPhysDirty(group, physId))
ASMJIT_PROPAGATE(onSaveReg(group, workId, physId));
return onKillReg(group, workId, physId);
}
- inline Error onDirtyReg(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline Error onDirtyReg(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
_curAssignment.makeDirty(group, workId, physId);
return kErrorOk;
}
- inline Error onKillReg(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline Error onKillReg(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
_curAssignment.unassign(group, workId, physId);
return kErrorOk;
}
diff --git a/src/asmjit/core/rapass.cpp b/src/asmjit/core/rapass.cpp
index 5e55584..9d714cd 100644
--- a/src/asmjit/core/rapass.cpp
+++ b/src/asmjit/core/rapass.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_COMPILER
@@ -33,16 +15,14 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::RABlock - Control Flow]
-// ============================================================================
+// RABlock - Control Flow
+// ======================
Error RABlock::appendSuccessor(RABlock* successor) noexcept {
RABlock* predecessor = this;
- if (predecessor->_successors.contains(successor))
+ if (predecessor->hasSuccessor(successor))
return kErrorOk;
- ASMJIT_ASSERT(!successor->_predecessors.contains(predecessor));
ASMJIT_PROPAGATE(successor->_predecessors.willGrow(allocator()));
ASMJIT_PROPAGATE(predecessor->_successors.willGrow(allocator()));
@@ -56,9 +36,8 @@ Error RABlock::appendSuccessor(RABlock* successor) noexcept {
Error RABlock::prependSuccessor(RABlock* successor) noexcept {
RABlock* predecessor = this;
- if (predecessor->_successors.contains(successor))
+ if (predecessor->hasSuccessor(successor))
return kErrorOk;
- ASMJIT_ASSERT(!successor->_predecessors.contains(predecessor));
ASMJIT_PROPAGATE(successor->_predecessors.willGrow(allocator()));
ASMJIT_PROPAGATE(predecessor->_successors.willGrow(allocator()));
@@ -69,18 +48,16 @@ Error RABlock::prependSuccessor(RABlock* successor) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Construction / Destruction]
-// ============================================================================
+// BaseRAPass - Construction & Destruction
+// =======================================
BaseRAPass::BaseRAPass() noexcept : FuncPass("BaseRAPass") {}
BaseRAPass::~BaseRAPass() noexcept {}
-// ============================================================================
-// [asmjit::BaseRAPass - RunOnFunction]
-// ============================================================================
+// BaseRAPass - RunOnFunction
+// ==========================
-static void RAPass_reset(BaseRAPass* self, FuncDetail* funcDetail) noexcept {
+static void BaseRAPass_reset(BaseRAPass* self, FuncDetail* funcDetail) noexcept {
ZoneAllocator* allocator = self->allocator();
self->_blocks.reset();
@@ -97,20 +74,16 @@ static void RAPass_reset(BaseRAPass* self, FuncDetail* funcDetail) noexcept {
self->_physRegIndex.reset();
self->_physRegCount.reset();
self->_physRegTotal = 0;
-
- for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(self->_scratchRegIndexes); i++)
- self->_scratchRegIndexes[i] = BaseReg::kIdBad;
+ self->_scratchRegIndexes.fill(BaseReg::kIdBad);
self->_availableRegs.reset();
self->_availableRegCount.reset();
self->_clobberedRegs.reset();
self->_workRegs.reset();
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
- self->_workRegsOfGroup[group].reset();
- self->_strategy[group].reset();
- self->_globalLiveSpans[group] = nullptr;
- }
+ self->_workRegsOfGroup.forEach([](RAWorkRegs& regs) { regs.reset(); });
+ self->_strategy.forEach([](RAStrategy& strategy) { strategy.reset(); });
+ self->_globalLiveSpans.fill(nullptr);
self->_globalMaxLiveCount.reset();
self->_temporaryMem.reset();
@@ -120,7 +93,7 @@ static void RAPass_reset(BaseRAPass* self, FuncDetail* funcDetail) noexcept {
self->_maxWorkRegNameSize = 0;
}
-static void RAPass_resetVirtRegData(BaseRAPass* self) noexcept {
+static void BaseRAPass_resetVirtRegData(BaseRAPass* self) noexcept {
// Zero everything so it cannot be used by accident.
for (RAWorkReg* wReg : self->_workRegs) {
VirtReg* vReg = wReg->virtReg();
@@ -133,12 +106,12 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
#ifndef ASMJIT_NO_LOGGING
_logger = logger;
- _debugLogger = nullptr;
+ _formatOptions.reset();
+ _diagnosticOptions = DiagnosticOptions::kNone;
if (logger) {
- _loggerFlags = logger->flags();
- if (_loggerFlags & FormatOptions::kFlagDebugPasses)
- _debugLogger = logger;
+ _formatOptions = logger->options();
+ _diagnosticOptions = _cb->diagnosticOptions();
}
#else
DebugUtils::unused(logger);
@@ -150,7 +123,7 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
_stop = end->next();
_extraBlock = end;
- RAPass_reset(this, &_func->_funcDetail);
+ BaseRAPass_reset(this, &_func->_funcDetail);
// Initialize architecture-specific members.
onInit();
@@ -162,16 +135,16 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
onDone();
// Reset possible connections introduced by the register allocator.
- RAPass_resetVirtRegData(this);
+ BaseRAPass_resetVirtRegData(this);
// Reset all core structures and everything that depends on the passed `Zone`.
- RAPass_reset(this, nullptr);
+ BaseRAPass_reset(this, nullptr);
_allocator.reset(nullptr);
#ifndef ASMJIT_NO_LOGGING
_logger = nullptr;
- _debugLogger = nullptr;
- _loggerFlags = 0;
+ _formatOptions.reset();
+ _diagnosticOptions = DiagnosticOptions::kNone;
#endif
_func = nullptr;
@@ -181,9 +154,8 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
// Reset `Zone` as nothing should persist between `runOnFunction()` calls.
zone->reset();
- // We alter the compiler cursor, because it doesn't make sense to reference
- // it after the compilation - some nodes may disappear and the old cursor
- // can go out anyway.
+ // We alter the compiler cursor, because it doesn't make sense to reference it after the compilation - some
+ // nodes may disappear and the old cursor can go out anyway.
cc()->_setCursor(cc()->lastNode());
return err;
@@ -191,15 +163,15 @@ Error BaseRAPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
Error BaseRAPass::onPerformAllSteps() noexcept {
ASMJIT_PROPAGATE(buildCFG());
- ASMJIT_PROPAGATE(buildViews());
- ASMJIT_PROPAGATE(removeUnreachableBlocks());
+ ASMJIT_PROPAGATE(buildCFGViews());
+ ASMJIT_PROPAGATE(removeUnreachableCode());
- ASMJIT_PROPAGATE(buildDominators());
+ ASMJIT_PROPAGATE(buildCFGDominators());
ASMJIT_PROPAGATE(buildLiveness());
ASMJIT_PROPAGATE(assignArgIndexToWorkRegs());
#ifndef ASMJIT_NO_LOGGING
- if (logger() && logger()->hasFlag(FormatOptions::kFlagAnnotations))
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate))
ASMJIT_PROPAGATE(annotateCode());
#endif
@@ -214,9 +186,8 @@ Error BaseRAPass::onPerformAllSteps() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - CFG - Basic Block Management]
-// ============================================================================
+// BaseRAPass - CFG - Basic Block Management
+// =========================================
RABlock* BaseRAPass::newBlock(BaseNode* initialNode) noexcept {
RABlock* block = zone()->newT<RABlock>(this);
@@ -238,9 +209,8 @@ RABlock* BaseRAPass::newBlockOrExistingAt(LabelNode* cbLabel, BaseNode** stopped
BaseNode* node = cbLabel->prev();
RABlock* block = nullptr;
- // Try to find some label, but terminate the loop on any code. We try hard to
- // coalesce code that contains two consecutive labels or a combination of
- // non-code nodes between 2 or more labels.
+ // Try to find some label, but terminate the loop on any code. We try hard to coalesce code that contains two
+ // consecutive labels or a combination of non-code nodes between 2 or more labels.
//
// Possible cases that would share the same basic block:
//
@@ -256,16 +226,15 @@ RABlock* BaseRAPass::newBlockOrExistingAt(LabelNode* cbLabel, BaseNode** stopped
size_t nPendingLabels = 0;
while (node) {
- if (node->type() == BaseNode::kNodeLabel) {
- // Function has a different NodeType, just make sure this was not messed
- // up as we must never associate BasicBlock with a `func` itself.
+ if (node->type() == NodeType::kLabel) {
+ // Function has a different NodeType, just make sure this was not messed up as we must never associate
+ // BasicBlock with a `func` itself.
ASMJIT_ASSERT(node != func);
block = node->passData<RABlock>();
if (block) {
- // Exit node has always a block associated with it. If we went here it
- // means that `cbLabel` passed here is after the end of the function
- // and cannot be merged with the function exit block.
+ // Exit node has always a block associated with it. If we went here it means that `cbLabel` passed here
+ // is after the end of the function and cannot be merged with the function exit block.
if (node == func->exitNode())
block = nullptr;
break;
@@ -273,7 +242,7 @@ RABlock* BaseRAPass::newBlockOrExistingAt(LabelNode* cbLabel, BaseNode** stopped
nPendingLabels++;
}
- else if (node->type() == BaseNode::kNodeAlign) {
+ else if (node->type() == NodeType::kAlign) {
// Align node is fine.
}
else {
@@ -298,7 +267,7 @@ RABlock* BaseRAPass::newBlockOrExistingAt(LabelNode* cbLabel, BaseNode** stopped
while (nPendingLabels) {
node = node->prev();
for (;;) {
- if (node->type() == BaseNode::kNodeLabel) {
+ if (node->type() == NodeType::kLabel) {
node->setPassData<RABlock>(block);
nPendingLabels--;
break;
@@ -325,9 +294,8 @@ Error BaseRAPass::addBlock(RABlock* block) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - CFG - Build]
-// ============================================================================
+// BaseRAPass - CFG - Build
+// ========================
Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssignmentsMap) noexcept {
if (sharedAssignmentsMap.empty())
@@ -344,16 +312,15 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
ASMJIT_PROPAGATE(_sharedAssignments.resize(allocator(), count));
- // Aggregate all entry scratch GP regs from blocks of the same assignment to
- // the assignment itself. It will then be used instead of RABlock's own scratch
- // regs mask, as shared assignments have precedence.
+ // Aggregate all entry scratch GP regs from blocks of the same assignment to the assignment itself. It will then be
+ // used instead of RABlock's own scratch regs mask, as shared assignments have precedence.
for (RABlock* block : _blocks) {
if (block->hasJumpTable()) {
const RABlocks& successors = block->successors();
if (!successors.empty()) {
RABlock* firstSuccessor = successors[0];
- // NOTE: Shared assignments connect all possible successors so we only
- // need the first to propagate exit scratch gp registers.
+ // NOTE: Shared assignments connect all possible successors so we only need the first to propagate exit scratch
+ // GP registers.
ASMJIT_ASSERT(firstSuccessor->hasSharedAssignmentId());
RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()];
sa.addEntryScratchGpRegs(block->exitScratchGpRegs());
@@ -368,9 +335,8 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - CFG - Views Order]
-// ============================================================================
+// BaseRAPass - CFG - Views Order
+// ==============================
class RABlockVisitItem {
public:
@@ -391,10 +357,10 @@ public:
uint32_t _index;
};
-Error BaseRAPass::buildViews() noexcept {
+Error BaseRAPass::buildCFGViews() noexcept {
#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
- ASMJIT_RA_LOG_FORMAT("[RAPass::BuildViews]\n");
+ Logger* logger = getLoggerIf(DiagnosticOptions::kRADebugCFG);
+ ASMJIT_RA_LOG_FORMAT("[BuildCFGViews]\n");
#endif
uint32_t count = blockCount();
@@ -462,11 +428,10 @@ Error BaseRAPass::buildViews() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - CFG - Dominators]
-// ============================================================================
+// BaseRAPass - CFG - Dominators
+// =============================
-static ASMJIT_INLINE RABlock* intersectBlocks(RABlock* b1, RABlock* b2) noexcept {
+static ASMJIT_FORCE_INLINE RABlock* intersectBlocks(RABlock* b1, RABlock* b2) noexcept {
while (b1 != b2) {
while (b2->povOrder() > b1->povOrder()) b1 = b1->iDom();
while (b1->povOrder() > b2->povOrder()) b2 = b2->iDom();
@@ -475,10 +440,10 @@ static ASMJIT_INLINE RABlock* intersectBlocks(RABlock* b1, RABlock* b2) noexcept
}
// Based on "A Simple, Fast Dominance Algorithm".
-Error BaseRAPass::buildDominators() noexcept {
+Error BaseRAPass::buildCFGDominators() noexcept {
#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
- ASMJIT_RA_LOG_FORMAT("[RAPass::BuildDominators]\n");
+ Logger* logger = getLoggerIf(DiagnosticOptions::kRADebugCFG);
+ ASMJIT_RA_LOG_FORMAT("[BuildCFGDominators]\n");
#endif
if (_blocks.empty())
@@ -576,11 +541,10 @@ const RABlock* BaseRAPass::_nearestCommonDominator(const RABlock* a, const RABlo
return entryBlock;
}
-// ============================================================================
-// [asmjit::BaseRAPass - CFG - Utilities]
-// ============================================================================
+// BaseRAPass - CFG - Utilities
+// ============================
-Error BaseRAPass::removeUnreachableBlocks() noexcept {
+Error BaseRAPass::removeUnreachableCode() noexcept {
uint32_t numAllBlocks = blockCount();
uint32_t numReachableBlocks = reachableBlockCount();
@@ -589,8 +553,9 @@ Error BaseRAPass::removeUnreachableBlocks() noexcept {
return kErrorOk;
#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
- ASMJIT_RA_LOG_FORMAT("[RAPass::RemoveUnreachableBlocks (%u of %u unreachable)]\n", numAllBlocks - numReachableBlocks, numAllBlocks);
+ StringTmp<256> sb;
+ Logger* logger = getLoggerIf(DiagnosticOptions::kRADebugUnreachable);
+ ASMJIT_RA_LOG_FORMAT("[RemoveUnreachableCode - detected %u of %u unreachable blocks]\n", numAllBlocks - numReachableBlocks, numAllBlocks);
#endif
for (uint32_t i = 0; i < numAllBlocks; i++) {
@@ -598,7 +563,7 @@ Error BaseRAPass::removeUnreachableBlocks() noexcept {
if (block->isReachable())
continue;
- ASMJIT_RA_LOG_FORMAT(" Removing block {%u}\n", i);
+ ASMJIT_RA_LOG_FORMAT(" Removing code from unreachable block {%u}\n", i);
BaseNode* first = block->first();
BaseNode* last = block->last();
@@ -609,8 +574,16 @@ Error BaseRAPass::removeUnreachableBlocks() noexcept {
while (node != afterLast) {
BaseNode* next = node->next();
- if (node->isCode() || node->isRemovable())
+ if (node->isCode() || node->isRemovable()) {
+#ifndef ASMJIT_NO_LOGGING
+ if (logger) {
+ sb.clear();
+ Formatter::formatNode(sb, _formatOptions, cc(), node);
+ logger->logf(" %s\n", sb.data());
+ }
+#endif
cc()->removeNode(node);
+ }
node = next;
}
@@ -647,16 +620,15 @@ bool BaseRAPass::isNextTo(BaseNode* node, BaseNode* target) noexcept {
}
}
-// ============================================================================
-// [asmjit::BaseRAPass - ?]
-// ============================================================================
+// BaseRAPass - Registers - VirtReg / WorkReg Mapping
+// ==================================================
Error BaseRAPass::_asWorkReg(VirtReg* vReg, RAWorkReg** out) noexcept {
// Checked by `asWorkReg()` - must be true.
ASMJIT_ASSERT(vReg->_workReg == nullptr);
- uint32_t group = vReg->group();
- ASMJIT_ASSERT(group < BaseReg::kGroupVirt);
+ RegGroup group = vReg->group();
+ ASMJIT_ASSERT(group <= RegGroup::kMaxVirt);
RAWorkRegs& wRegs = workRegs();
RAWorkRegs& wRegsByGroup = workRegs(group);
@@ -712,22 +684,21 @@ RAAssignment::PhysToWorkMap* BaseRAPass::newPhysToWorkMap() noexcept {
return map;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Registers - Liveness Analysis and Statistics]
-// ============================================================================
+// BaseRAPass - Registers - Liveness Analysis and Statistics
+// =========================================================
namespace LiveOps {
typedef ZoneBitVector::BitWord BitWord;
struct In {
- static ASMJIT_INLINE BitWord op(BitWord dst, BitWord out, BitWord gen, BitWord kill) noexcept {
+ static ASMJIT_FORCE_INLINE BitWord op(BitWord dst, BitWord out, BitWord gen, BitWord kill) noexcept {
DebugUtils::unused(dst);
return (out | gen) & ~kill;
}
};
template<typename Operator>
- static ASMJIT_INLINE bool op(BitWord* dst, const BitWord* a, uint32_t n) noexcept {
+ static ASMJIT_FORCE_INLINE bool op(BitWord* dst, const BitWord* a, uint32_t n) noexcept {
BitWord changed = 0;
for (uint32_t i = 0; i < n; i++) {
@@ -742,7 +713,7 @@ namespace LiveOps {
}
template<typename Operator>
- static ASMJIT_INLINE bool op(BitWord* dst, const BitWord* a, const BitWord* b, uint32_t n) noexcept {
+ static ASMJIT_FORCE_INLINE bool op(BitWord* dst, const BitWord* a, const BitWord* b, uint32_t n) noexcept {
BitWord changed = 0;
for (uint32_t i = 0; i < n; i++) {
@@ -757,7 +728,7 @@ namespace LiveOps {
}
template<typename Operator>
- static ASMJIT_INLINE bool op(BitWord* dst, const BitWord* a, const BitWord* b, const BitWord* c, uint32_t n) noexcept {
+ static ASMJIT_FORCE_INLINE bool op(BitWord* dst, const BitWord* a, const BitWord* b, const BitWord* c, uint32_t n) noexcept {
BitWord changed = 0;
for (uint32_t i = 0; i < n; i++) {
@@ -771,7 +742,7 @@ namespace LiveOps {
return changed != 0;
}
- static ASMJIT_INLINE bool recalcInOut(RABlock* block, uint32_t numBitWords, bool initial = false) noexcept {
+ static ASMJIT_FORCE_INLINE bool recalcInOut(RABlock* block, uint32_t numBitWords, bool initial = false) noexcept {
bool changed = initial;
const RABlocks& successors = block->successors();
@@ -791,11 +762,11 @@ namespace LiveOps {
ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
+ Logger* logger = getLoggerIf(DiagnosticOptions::kRADebugLiveness);
StringTmp<512> sb;
#endif
- ASMJIT_RA_LOG_FORMAT("[RAPass::BuildLiveness]\n");
+ ASMJIT_RA_LOG_FORMAT("[BuildLiveness]\n");
uint32_t i;
@@ -819,9 +790,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
ASMJIT_PROPAGATE(nOutsPerWorkReg.resize(allocator(), numWorkRegs));
ASMJIT_PROPAGATE(nInstsPerBlock.resize(allocator(), numAllBlocks));
- // --------------------------------------------------------------------------
- // Calculate GEN/KILL of each block.
- // --------------------------------------------------------------------------
+ // Calculate GEN/KILL of Each Block
+ // --------------------------------
for (i = 0; i < numReachableBlocks; i++) {
RABlock* block = _pov[i];
@@ -852,9 +822,9 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
// KILL - if this VirtReg is killed afterwards.
// LAST - if this VirtReg is last in this basic block.
if (block->kill().bitAt(workId))
- tiedReg->addFlags(RATiedReg::kKill);
+ tiedReg->addFlags(RATiedFlags::kKill);
else if (!block->gen().bitAt(workId))
- tiedReg->addFlags(RATiedReg::kLast);
+ tiedReg->addFlags(RATiedFlags::kLast);
if (tiedReg->isWriteOnly()) {
// KILL.
@@ -865,6 +835,16 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
block->kill().setBit(workId, false);
block->gen().setBit(workId, true);
}
+
+ if (tiedReg->isLeadConsecutive()) {
+ RAWorkReg* workReg = workRegById(workId);
+ workReg->markLeadConsecutive();
+ }
+
+ if (tiedReg->hasConsecutiveParent()) {
+ RAWorkReg* consecutiveParentReg = workRegById(tiedReg->consecutiveParent());
+ consecutiveParentReg->addImmediateConsecutive(allocator(), workId);
+ }
}
nInsts++;
@@ -880,9 +860,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
nInstsPerBlock[block->blockId()] = nInsts;
}
- // --------------------------------------------------------------------------
- // Calculate IN/OUT of each block.
- // --------------------------------------------------------------------------
+ // Calculate IN/OUT of Each Block
+ // ------------------------------
{
ZoneStack<RABlock*> workList;
@@ -933,9 +912,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
}
});
- // --------------------------------------------------------------------------
- // Reserve the space in each `RAWorkReg` for references.
- // --------------------------------------------------------------------------
+ // Reserve the space in each `RAWorkReg` for references
+ // ----------------------------------------------------
for (i = 0; i < numWorkRegs; i++) {
RAWorkReg* workReg = workRegById(i);
@@ -943,9 +921,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
ASMJIT_PROPAGATE(workReg->_writes.reserve(allocator(), nOutsPerWorkReg[i]));
}
- // --------------------------------------------------------------------------
- // Assign block and instruction positions, build LiveCount and LiveSpans.
- // --------------------------------------------------------------------------
+ // Assign block and instruction positions, build LiveCount and LiveSpans
+ // ---------------------------------------------------------------------
uint32_t position = 2;
for (i = 0; i < numAllBlocks; i++) {
@@ -993,17 +970,17 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
if (tiedReg->isWrite())
workReg->_writes.appendUnsafe(node);
- // We couldn't calculate this in previous steps, but since we know all LIVE-OUT
- // at this point it becomes trivial. If this is the last instruction that uses
- // this `workReg` and it's not LIVE-OUT then it is KILLed here.
+ // We couldn't calculate this in previous steps, but since we know all LIVE-OUT at this point it becomes
+ // trivial. If this is the last instruction that uses this `workReg` and it's not LIVE-OUT then it is
+ // KILLed here.
if (tiedReg->isLast() && !block->liveOut().bitAt(workId))
- tiedReg->addFlags(RATiedReg::kKill);
+ tiedReg->addFlags(RATiedFlags::kKill);
LiveRegSpans& liveSpans = workReg->liveSpans();
bool wasOpen;
ASMJIT_PROPAGATE(liveSpans.openAt(allocator(), position + !tiedReg->isRead(), endPosition, wasOpen));
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
if (!wasOpen) {
curLiveCount[group]++;
raInst->_liveCount[group]++;
@@ -1014,16 +991,30 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
curLiveCount[group]--;
}
- // Update `RAWorkReg::hintRegId`.
- if (tiedReg->hasUseId() && !workReg->hasHintRegId()) {
+ // Update `RAWorkReg::useIdMask` and `RAWorkReg::hintRegId`.
+ if (tiedReg->hasUseId()) {
uint32_t useId = tiedReg->useId();
- if (!(raInst->_clobberedRegs[group] & Support::bitMask(useId)))
+ workReg->addUseIdMask(Support::bitMask(useId));
+ if (!workReg->hasHintRegId() && !Support::bitTest(raInst->_clobberedRegs[group], useId))
workReg->setHintRegId(useId);
}
+ if (tiedReg->useRegMask()) {
+ workReg->restrictPreferredMask(tiedReg->useRegMask());
+ if (workReg->isLeadConsecutive())
+ workReg->restrictConsecutiveMask(tiedReg->useRegMask());
+ }
+
+ if (tiedReg->outRegMask()) {
+ workReg->restrictPreferredMask(tiedReg->outRegMask());
+ if (workReg->isLeadConsecutive())
+ workReg->restrictConsecutiveMask(tiedReg->outRegMask());
+ }
+
// Update `RAWorkReg::clobberedSurvivalMask`.
- if (raInst->_clobberedRegs[group] && !tiedReg->isOutOrKill())
+ if (raInst->_clobberedRegs[group] && !tiedReg->isOutOrKill()) {
workReg->addClobberSurvivalMask(raInst->_clobberedRegs[group]);
+ }
}
position += 2;
@@ -1042,9 +1033,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::buildLiveness() noexcept {
ASMJIT_ASSERT(position == block->endPosition());
}
- // --------------------------------------------------------------------------
- // Calculate WorkReg statistics.
- // --------------------------------------------------------------------------
+ // Calculate WorkReg statistics
+ // ----------------------------
for (i = 0; i < numWorkRegs; i++) {
RAWorkReg* workReg = _workRegs[i];
@@ -1079,7 +1069,11 @@ Error BaseRAPass::assignArgIndexToWorkRegs() noexcept {
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
// Unassigned argument.
- VirtReg* virtReg = func()->argPack(argIndex)[valueIndex];
+ const RegOnly& regArg = func()->argPack(argIndex)[valueIndex];
+ if (!regArg.isReg() || !cc()->isVirtIdValid(regArg.id()))
+ continue;
+
+ VirtReg* virtReg = cc()->virtRegById(regArg.id());
if (!virtReg)
continue;
@@ -1105,9 +1099,8 @@ Error BaseRAPass::assignArgIndexToWorkRegs() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Allocation - Global]
-// ============================================================================
+// BaseRAPass - Allocation - Global
+// ================================
#ifndef ASMJIT_NO_LOGGING
static void RAPass_dumpSpans(String& sb, uint32_t index, const LiveRegSpans& liveSpans) noexcept {
@@ -1126,7 +1119,7 @@ static void RAPass_dumpSpans(String& sb, uint32_t index, const LiveRegSpans& liv
Error BaseRAPass::runGlobalAllocator() noexcept {
ASMJIT_PROPAGATE(initGlobalLiveSpans());
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
ASMJIT_PROPAGATE(binPack(group));
}
@@ -1134,7 +1127,7 @@ Error BaseRAPass::runGlobalAllocator() noexcept {
}
ASMJIT_FAVOR_SPEED Error BaseRAPass::initGlobalLiveSpans() noexcept {
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
size_t physCount = _physRegCount[group];
LiveRegSpans* liveSpans = nullptr;
@@ -1153,24 +1146,31 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::initGlobalLiveSpans() noexcept {
return kErrorOk;
}
-ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
+struct RAConsecutiveReg {
+ RAWorkReg* workReg;
+ RAWorkReg* parentReg;
+};
+
+ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(RegGroup group) noexcept {
if (workRegCount(group) == 0)
return kErrorOk;
#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
+ Logger* logger = getLoggerIf(DiagnosticOptions::kRADebugAssignment);
StringTmp<512> sb;
- ASMJIT_RA_LOG_FORMAT("[RAPass::BinPack] Available=%u (0x%08X) Count=%u\n",
+ ASMJIT_RA_LOG_FORMAT("[BinPack] Available=%u (0x%08X) Count=%u RegGroup=%u\n",
Support::popcnt(_availableRegs[group]),
_availableRegs[group],
- workRegCount(group));
+ workRegCount(group),
+ uint32_t(group));
#endif
uint32_t i;
uint32_t physCount = _physRegCount[group];
RAWorkRegs workRegs;
+ ZoneVector<RAConsecutiveReg> consecutiveRegs;
LiveRegSpans tmpSpans;
ASMJIT_PROPAGATE(workRegs.concat(allocator(), this->workRegs(group)));
@@ -1179,28 +1179,35 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
});
uint32_t numWorkRegs = workRegs.size();
- uint32_t availableRegs = _availableRegs[group];
+ RegMask availableRegs = _availableRegs[group];
- // First try to pack everything that provides register-id hint as these are
- // most likely function arguments and fixed (precolored) virtual registers.
+ // First try to pack everything that provides register-id hint as these are most likely function arguments and fixed
+ // (precolored) virtual registers.
if (!workRegs.empty()) {
uint32_t dstIndex = 0;
for (i = 0; i < numWorkRegs; i++) {
RAWorkReg* workReg = workRegs[i];
+
+ if (workReg->isLeadConsecutive()) {
+ ASMJIT_PROPAGATE(consecutiveRegs.append(allocator(), RAConsecutiveReg{workReg, nullptr}));
+ workReg->markProcessedConsecutive();
+ }
+
if (workReg->hasHintRegId()) {
uint32_t physId = workReg->hintRegId();
- if (availableRegs & Support::bitMask(physId)) {
+ if (Support::bitTest(availableRegs, physId)) {
LiveRegSpans& live = _globalLiveSpans[group][physId];
Error err = tmpSpans.nonOverlappingUnionOf(allocator(), live, workReg->liveSpans(), LiveRegData(workReg->virtId()));
if (err == kErrorOk) {
- workReg->setHomeRegId(physId);
live.swap(tmpSpans);
+ workReg->setHomeRegId(physId);
+ workReg->markAllocated();
continue;
}
- if (ASMJIT_UNLIKELY(err != 0xFFFFFFFFu))
+ if (err != 0xFFFFFFFFu)
return err;
}
}
@@ -1212,18 +1219,108 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
numWorkRegs = dstIndex;
}
+ // Allocate consecutive registers - both leads and all consecutives. This is important and prioritized over the rest,
+ // because once a lead is allocated we really need to allocate its consecutives, otherwise we may bin pack other
+ // registers into their places, which would result in wrong hints to the local allocator, and then into many moves
+ // or spills.
+ if (!consecutiveRegs.empty()) {
+ // This loop appends all other consecutive registers into `consecutiveRegs` array. Leads are at the beginning,
+ // non-leads follow.
+ i = 0;
+ for (;;) {
+ uint32_t stop = consecutiveRegs.size();
+ if (i == stop)
+ break;
+
+ while (i < stop) {
+ RAWorkReg* workReg = consecutiveRegs[i].workReg;
+ if (workReg->hasImmediateConsecutives()) {
+ ZoneBitVector::ForEachBitSet it(workReg->immediateConsecutives());
+ while (it.hasNext()) {
+ uint32_t consecutiveWorkId = uint32_t(it.next());
+ RAWorkReg* consecutiveReg = workRegById(consecutiveWorkId);
+ if (!consecutiveReg->isProcessedConsecutive()) {
+ ASMJIT_PROPAGATE(consecutiveRegs.append(allocator(), RAConsecutiveReg{consecutiveReg, workReg}));
+ consecutiveReg->markProcessedConsecutive();
+ }
+ }
+ }
+ i++;
+ }
+ }
+
+ uint32_t numConsecutiveRegs = consecutiveRegs.size();
+ for (i = 0; i < numConsecutiveRegs; i++) {
+ RAWorkReg* workReg = consecutiveRegs[i].workReg;
+ if (workReg->isAllocated())
+ continue;
+
+ RAWorkReg* parentReg = consecutiveRegs[i].parentReg;
+ RegMask physRegs = 0;
+
+ if (!parentReg) {
+ physRegs = availableRegs & workReg->preferredMask();
+ if (!physRegs) {
+ physRegs = availableRegs & workReg->consecutiveMask();
+
+ // NOTE: This should never be true as it would mean we would never allocate this virtual register
+ // (not here, and not later when local register allocator processes RATiedReg sets).
+ if (ASMJIT_UNLIKELY(!physRegs))
+ return DebugUtils::errored(kErrorConsecutiveRegsAllocation);
+ }
+ }
+ else if (parentReg->hasHomeRegId()) {
+ uint32_t consecutiveId = parentReg->homeRegId() + 1;
+
+ // NOTE: We don't support wrapping. If this goes beyond all allocable registers there is something wrong.
+ if (consecutiveId > 31 || !Support::bitTest(availableRegs, consecutiveId))
+ return DebugUtils::errored(kErrorConsecutiveRegsAllocation);
+
+ workReg->setHintRegId(consecutiveId);
+ physRegs = Support::bitMask(consecutiveId);
+ }
+
+ while (physRegs) {
+ uint32_t physId = Support::bitSizeOf<RegMask>() - 1 - Support::clz(physRegs);
+
+ LiveRegSpans& live = _globalLiveSpans[group][physId];
+ Error err = tmpSpans.nonOverlappingUnionOf(allocator(), live, workReg->liveSpans(), LiveRegData(workReg->virtId()));
+
+ if (err == kErrorOk) {
+ workReg->setHomeRegId(physId);
+ workReg->markAllocated();
+ live.swap(tmpSpans);
+ break;
+ }
+
+ if (ASMJIT_UNLIKELY(err != 0xFFFFFFFFu))
+ return err;
+
+ physRegs ^= Support::bitMask(physId);
+ }
+ }
+ }
+
// Try to pack the rest.
if (!workRegs.empty()) {
uint32_t dstIndex = 0;
for (i = 0; i < numWorkRegs; i++) {
RAWorkReg* workReg = workRegs[i];
- uint32_t physRegs = availableRegs;
+
+ if (workReg->isAllocated())
+ continue;
+
+ RegMask physRegs = availableRegs;
+ if (physRegs & workReg->preferredMask())
+ physRegs &= workReg->preferredMask();
while (physRegs) {
- uint32_t physId = Support::ctz(physRegs);
+ RegMask preferredMask = physRegs;
+ uint32_t physId = Support::ctz(preferredMask);
+
if (workReg->clobberSurvivalMask()) {
- uint32_t preferredMask = physRegs & workReg->clobberSurvivalMask();
+ preferredMask &= workReg->clobberSurvivalMask();
if (preferredMask)
physId = Support::ctz(preferredMask);
}
@@ -1233,6 +1330,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
if (err == kErrorOk) {
workReg->setHomeRegId(physId);
+ workReg->markAllocated();
live.swap(tmpSpans);
break;
}
@@ -1271,7 +1369,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
ASMJIT_RA_LOG_FORMAT(" Completed.\n");
}
else {
- _strategy[group].setType(RAStrategy::kStrategyComplex);
+ _strategy[group].setType(RAStrategyType::kComplex);
for (RAWorkReg* workReg : workRegs)
workReg->markStackPreferred();
@@ -1292,9 +1390,8 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::binPack(uint32_t group) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Allocation - Local]
-// ============================================================================
+// BaseRAPass - Allocation - Local
+// ===============================
Error BaseRAPass::runLocalAllocator() noexcept {
RALocalAllocator lra(this);
@@ -1317,9 +1414,8 @@ Error BaseRAPass::runLocalAllocator() noexcept {
lra.makeInitialAssignment();
ASMJIT_PROPAGATE(setBlockEntryAssignment(block, block, lra._curAssignment));
- // The loop starts from the first block and iterates blocks in order, however,
- // the algorithm also allows to jump to any other block when finished if it's
- // a jump target. In-order iteration just makes sure that all blocks are visited.
+ // The loop starts from the first block and iterates blocks in order, however, the algorithm also allows to jump to
+ // any other block when finished if it's a jump target. In-order iteration just makes sure that all blocks are visited.
for (;;) {
BaseNode* first = block->first();
BaseNode* last = block->last();
@@ -1365,7 +1461,7 @@ Error BaseRAPass::runLocalAllocator() noexcept {
}
ASMJIT_PROPAGATE(lra.allocInst(inst));
- if (inst->type() == BaseNode::kNodeInvoke)
+ if (inst->type() == NodeType::kInvoke)
ASMJIT_PROPAGATE(emitPreCall(inst->as<InvokeNode>()));
else
ASMJIT_PROPAGATE(lra.spillAfterAllocation(inst));
@@ -1432,9 +1528,8 @@ Error BaseRAPass::setBlockEntryAssignment(RABlock* block, const RABlock* fromBlo
if (block->hasSharedAssignmentId()) {
uint32_t sharedAssignmentId = block->sharedAssignmentId();
- // Shouldn't happen. Entry assignment of a block that has a shared-state
- // will assign to all blocks with the same sharedAssignmentId. It's a bug if
- // the shared state has been already assigned.
+ // Shouldn't happen. Entry assignment of a block that has a shared-state will assign to all blocks
+ // with the same sharedAssignmentId. It's a bug if the shared state has been already assigned.
if (!_sharedAssignments[sharedAssignmentId].empty())
return DebugUtils::errored(kErrorInvalidState);
@@ -1473,7 +1568,7 @@ Error BaseRAPass::setBlockEntryAssignment(RABlock* block, const RABlock* fromBlo
uint32_t workId = uint32_t(it.next());
RAWorkReg* workReg = workRegById(workId);
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
uint32_t physId = as.workToPhysId(group, workId);
if (physId != RAAssignment::kPhysNone)
@@ -1500,7 +1595,7 @@ Error BaseRAPass::setSharedAssignment(uint32_t sharedAssignmentId, const RAAssig
RAAssignment as;
as.initLayout(_physRegCount, workRegs());
- uint32_t sharedAssigned[BaseReg::kGroupVirt] {};
+ Support::Array<uint32_t, Globals::kNumVirtGroups> sharedAssigned {};
for (RABlock* block : blocks()) {
if (block->sharedAssignmentId() == sharedAssignmentId) {
@@ -1518,9 +1613,9 @@ Error BaseRAPass::setSharedAssignment(uint32_t sharedAssignmentId, const RAAssig
const ZoneBitVector& liveIn = block->liveIn();
sharedLiveIn.or_(liveIn);
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
sharedAssigned[group] |= entryPhysToWorkMap->assigned[group];
- Support::BitWordIterator<uint32_t> it(entryPhysToWorkMap->assigned[group]);
+ Support::BitWordIterator<RegMask> it(entryPhysToWorkMap->assigned[group]);
while (it.hasNext()) {
uint32_t physId = it.next();
@@ -1536,8 +1631,8 @@ Error BaseRAPass::setSharedAssignment(uint32_t sharedAssignmentId, const RAAssig
{
as.initMaps(physToWorkMap, workToPhysMap);
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
- Support::BitWordIterator<uint32_t> it(_availableRegs[group] & ~sharedAssigned[group]);
+ for (RegGroup group : RegGroupVirtValues{}) {
+ Support::BitWordIterator<RegMask> it(_availableRegs[group] & ~sharedAssigned[group]);
while (it.hasNext()) {
uint32_t physId = it.next();
@@ -1553,13 +1648,12 @@ Error BaseRAPass::setSharedAssignment(uint32_t sharedAssignmentId, const RAAssig
}
Error BaseRAPass::blockEntryAssigned(const RAAssignment& as) noexcept {
- // Complex allocation strategy requires to record register assignments upon
- // block entry (or per shared state).
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ // Complex allocation strategy requires to record register assignments upon block entry (or per shared state).
+ for (RegGroup group : RegGroupVirtValues{}) {
if (!_strategy[group].isComplex())
continue;
- Support::BitWordIterator<uint32_t> it(as.assigned(group));
+ Support::BitWordIterator<RegMask> it(as.assigned(group));
while (it.hasNext()) {
uint32_t physId = it.next();
uint32_t workId = as.physToWorkId(group, physId);
@@ -1572,9 +1666,8 @@ Error BaseRAPass::blockEntryAssigned(const RAAssignment& as) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Allocation - Utilities]
-// ============================================================================
+// BaseRAPass - Allocation - Utilities
+// ===================================
Error BaseRAPass::useTemporaryMem(BaseMem& out, uint32_t size, uint32_t alignment) noexcept {
ASMJIT_ASSERT(alignment <= 64);
@@ -1596,22 +1689,19 @@ Error BaseRAPass::useTemporaryMem(BaseMem& out, uint32_t size, uint32_t alignmen
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Allocation - Prolog / Epilog]
-// ============================================================================
+// BaseRAPass - Allocation - Prolog & Epilog
+// =========================================
Error BaseRAPass::updateStackFrame() noexcept {
- // Update some StackFrame information that we updated during allocation. The
- // only information we don't have at the moment is final local stack size,
- // which is calculated last.
+ // Update some StackFrame information that we updated during allocation. The only information we don't have at the
+ // moment is final local stack size, which is calculated last.
FuncFrame& frame = func()->frame();
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
+ for (RegGroup group : RegGroupVirtValues{})
frame.addDirtyRegs(group, _clobberedRegs[group]);
frame.setLocalStackAlignment(_stackAllocator.alignment());
- // If there are stack arguments that are not assigned to registers upon entry
- // and the function doesn't require dynamic stack alignment we keep these
- // arguments where they are. This will also mark all stack slots that match
+ // If there are stack arguments that are not assigned to registers upon entry and the function doesn't require
+ // dynamic stack alignment we keep these arguments where they are. This will also mark all stack slots that match
// these arguments as allocated.
if (_numStackArgsToStackSlots)
ASMJIT_PROPAGATE(_markStackArgsToKeep());
@@ -1620,8 +1710,8 @@ Error BaseRAPass::updateStackFrame() noexcept {
ASMJIT_PROPAGATE(_stackAllocator.calculateStackFrame());
frame.setLocalStackSize(_stackAllocator.stackSize());
- // Update the stack frame based on `_argsAssignment` and finalize it.
- // Finalization means to apply final calculation to the stack layout.
+ // Update the stack frame based on `_argsAssignment` and finalize it. Finalization means to apply final calculation
+ // to the stack layout.
ASMJIT_PROPAGATE(_argsAssignment.updateFuncFrame(frame));
ASMJIT_PROPAGATE(frame.finalize());
@@ -1629,9 +1719,8 @@ Error BaseRAPass::updateStackFrame() noexcept {
if (frame.localStackOffset() != 0)
ASMJIT_PROPAGATE(_stackAllocator.adjustSlotOffsets(int32_t(frame.localStackOffset())));
- // Again, if there are stack arguments allocated in function's stack we have
- // to handle them. This handles all cases (either regular or dynamic stack
- // alignment).
+ // Again, if there are stack arguments allocated in function's stack we have to handle them. This handles all cases
+ // (either regular or dynamic stack alignment).
if (_numStackArgsToStackSlots)
ASMJIT_PROPAGATE(_updateStackArgs());
@@ -1647,28 +1736,26 @@ Error BaseRAPass::_markStackArgsToKeep() noexcept {
for (uint32_t workId = 0; workId < numWorkRegs; workId++) {
RAWorkReg* workReg = workRegs[workId];
- if (workReg->hasFlag(RAWorkReg::kFlagStackArgToStack)) {
+ if (workReg->hasFlag(RAWorkRegFlags::kStackArgToStack)) {
ASMJIT_ASSERT(workReg->hasArgIndex());
const FuncValue& srcArg = _func->detail().arg(workReg->argIndex());
- // If the register doesn't have stack slot then we failed. It doesn't
- // make much sense as it was marked as `kFlagStackArgToStack`, which
- // requires the WorkReg was live-in upon function entry.
+ // If the register doesn't have stack slot then we failed. It doesn't make much sense as it was marked as
+ // `kFlagStackArgToStack`, which requires the WorkReg was live-in upon function entry.
RAStackSlot* slot = workReg->stackSlot();
if (ASMJIT_UNLIKELY(!slot))
return DebugUtils::errored(kErrorInvalidState);
if (hasSAReg && srcArg.isStack() && !srcArg.isIndirect()) {
- uint32_t typeSize = Type::sizeOf(srcArg.typeId());
+ uint32_t typeSize = TypeUtils::sizeOf(srcArg.typeId());
if (typeSize == slot->size()) {
slot->addFlags(RAStackSlot::kFlagStackArg);
continue;
}
}
- // NOTE: Update StackOffset here so when `_argsAssignment.updateFuncFrame()`
- // is called it will take into consideration moving to stack slots. Without
- // this we may miss some scratch registers later.
+ // NOTE: Update StackOffset here so when `_argsAssignment.updateFuncFrame()` is called it will take into
+ // consideration moving to stack slots. Without this we may miss some scratch registers later.
FuncValue& dstArg = _argsAssignment.arg(workReg->argIndex(), workReg->argValueIndex());
dstArg.assignStackOffset(0);
}
@@ -1684,7 +1771,7 @@ Error BaseRAPass::_updateStackArgs() noexcept {
for (uint32_t workId = 0; workId < numWorkRegs; workId++) {
RAWorkReg* workReg = workRegs[workId];
- if (workReg->hasFlag(RAWorkReg::kFlagStackArgToStack)) {
+ if (workReg->hasFlag(RAWorkRegFlags::kStackArgToStack)) {
ASMJIT_ASSERT(workReg->hasArgIndex());
RAStackSlot* slot = workReg->stackSlot();
@@ -1724,25 +1811,18 @@ Error BaseRAPass::insertPrologEpilog() noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::BaseRAPass - Rewriter]
-// ============================================================================
+// BaseRAPass - Rewriter
+// =====================
Error BaseRAPass::rewrite() noexcept {
-#ifndef ASMJIT_NO_LOGGING
- Logger* logger = debugLogger();
- ASMJIT_RA_LOG_FORMAT("[RAPass::Rewrite]\n");
-#endif
-
return _rewrite(_func, _stop);
}
-// ============================================================================
-// [asmjit::BaseRAPass - Logging]
-// ============================================================================
+// BaseRAPass - Logging
+// ====================
#ifndef ASMJIT_NO_LOGGING
-static void RAPass_dumpRAInst(BaseRAPass* pass, String& sb, const RAInst* raInst) noexcept {
+static void RAPass_formatLiveness(BaseRAPass* pass, String& sb, const RAInst* raInst) noexcept {
const RATiedReg* tiedRegs = raInst->tiedRegs();
uint32_t tiedCount = raInst->tiedCount();
@@ -1757,16 +1837,25 @@ static void RAPass_dumpRAInst(BaseRAPass* pass, String& sb, const RAInst* raInst
tiedReg.isRead() ? 'R' :
tiedReg.isWrite() ? 'W' : '?');
+ if (tiedReg.isLeadConsecutive())
+ sb.appendFormat("|Lead[%u]", tiedReg.consecutiveData() + 1u);
+
if (tiedReg.hasUseId())
sb.appendFormat("|Use=%u", tiedReg.useId());
else if (tiedReg.isUse())
sb.append("|Use");
+ if (tiedReg.isUseConsecutive() && !tiedReg.isLeadConsecutive())
+ sb.appendFormat("+%u", tiedReg.consecutiveData());
+
if (tiedReg.hasOutId())
sb.appendFormat("|Out=%u", tiedReg.outId());
else if (tiedReg.isOut())
sb.append("|Out");
+ if (tiedReg.isOutConsecutive() && !tiedReg.isLeadConsecutive())
+ sb.appendFormat("+%u", tiedReg.consecutiveData());
+
if (tiedReg.isLast())
sb.append("|Last");
@@ -1778,7 +1867,6 @@ static void RAPass_dumpRAInst(BaseRAPass* pass, String& sb, const RAInst* raInst
}
ASMJIT_FAVOR_SIZE Error BaseRAPass::annotateCode() noexcept {
- uint32_t loggerFlags = _loggerFlags;
StringTmp<1024> sb;
for (const RABlock* block : _blocks) {
@@ -1788,21 +1876,18 @@ ASMJIT_FAVOR_SIZE Error BaseRAPass::annotateCode() noexcept {
BaseNode* last = block->last();
for (;;) {
sb.clear();
- Formatter::formatNode(sb, loggerFlags, cc(), node);
+ Formatter::formatNode(sb, _formatOptions, cc(), node);
- if ((loggerFlags & FormatOptions::kFlagDebugRA) != 0 && node->isInst() && node->hasPassData()) {
+ if (hasDiagnosticOption(DiagnosticOptions::kRADebugLiveness) && node->isInst() && node->hasPassData()) {
const RAInst* raInst = node->passData<RAInst>();
if (raInst->tiedCount() > 0) {
sb.padEnd(40);
sb.append(" | ");
- RAPass_dumpRAInst(this, sb, raInst);
+ RAPass_formatLiveness(this, sb, raInst);
}
}
- node->setInlineComment(
- static_cast<char*>(
- cc()->_dataZone.dup(sb.data(), sb.size(), true)));
-
+ node->setInlineComment(static_cast<char*>(cc()->_dataZone.dup(sb.data(), sb.size(), true)));
if (node == last)
break;
node = node->next();
diff --git a/src/asmjit/core/rapass_p.h b/src/asmjit/core/rapass_p.h
index 034ec07..098c5c9 100644
--- a/src/asmjit/core/rapass_p.h
+++ b/src/asmjit/core/rapass_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RAPASS_P_H_INCLUDED
#define ASMJIT_CORE_RAPASS_P_H_INCLUDED
@@ -40,9 +22,34 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RABlock]
-// ============================================================================
+//! Flags used by \ref RABlock.
+enum class RABlockFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
+ //! Block has been constructed from nodes.
+ kIsConstructed = 0x00000001u,
+ //! Block is reachable (set by `buildCFGViews()`).
+ kIsReachable = 0x00000002u,
+ //! Block is a target (has an associated label or multiple labels).
+ kIsTargetable = 0x00000004u,
+ //! Block has been allocated.
+ kIsAllocated = 0x00000008u,
+ //! Block is a function-exit.
+ kIsFuncExit = 0x00000010u,
+
+ //! Block has a terminator (jump, conditional jump, ret).
+ kHasTerminator = 0x00000100u,
+ //! Block naturally flows to the next block.
+ kHasConsecutive = 0x00000200u,
+ //! Block has a jump to a jump-table at the end.
+ kHasJumpTable = 0x00000400u,
+ //! Block contains fixed registers (precolored).
+ kHasFixedRegs = 0x00000800u,
+ //! Block contains function calls.
+ kHasFuncCalls = 0x00001000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(RABlockFlags)
//! Basic block used by register allocator pass.
class RABlock {
@@ -52,42 +59,34 @@ public:
typedef RAAssignment::PhysToWorkMap PhysToWorkMap;
typedef RAAssignment::WorkToPhysMap WorkToPhysMap;
- enum Id : uint32_t {
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ //! Unassigned block id.
kUnassignedId = 0xFFFFFFFFu
};
- //! Basic block flags.
- enum Flags : uint32_t {
- //! Block has been constructed from nodes.
- kFlagIsConstructed = 0x00000001u,
- //! Block is reachable (set by `buildViews()`).
- kFlagIsReachable = 0x00000002u,
- //! Block is a target (has an associated label or multiple labels).
- kFlagIsTargetable = 0x00000004u,
- //! Block has been allocated.
- kFlagIsAllocated = 0x00000008u,
- //! Block is a function-exit.
- kFlagIsFuncExit = 0x00000010u,
-
- //! Block has a terminator (jump, conditional jump, ret).
- kFlagHasTerminator = 0x00000100u,
- //! Block naturally flows to the next block.
- kFlagHasConsecutive = 0x00000200u,
- //! Block has a jump to a jump-table at the end.
- kFlagHasJumpTable = 0x00000400u,
- //! Block contains fixed registers (precolored).
- kFlagHasFixedRegs = 0x00000800u,
- //! Block contains function calls.
- kFlagHasFuncCalls = 0x00001000u
+ enum LiveType : uint32_t {
+ kLiveIn = 0,
+ kLiveOut = 1,
+ kLiveGen = 2,
+ kLiveKill = 3,
+ kLiveCount = 4
};
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! Register allocator pass.
BaseRAPass* _ra;
//! Block id (indexed from zero).
uint32_t _blockId = kUnassignedId;
//! Block flags, see `Flags`.
- uint32_t _flags = 0;
+ RABlockFlags _flags = RABlockFlags::kNone;
//! First `BaseNode` of this block (inclusive).
BaseNode* _first = nullptr;
@@ -119,30 +118,24 @@ public:
//! Block successors.
RABlocks _successors {};
- enum LiveType : uint32_t {
- kLiveIn = 0,
- kLiveOut = 1,
- kLiveGen = 2,
- kLiveKill = 3,
- kLiveCount = 4
- };
-
//! Liveness in/out/use/kill.
ZoneBitVector _liveBits[kLiveCount] {};
- //! Shared assignment it or `Globals::kInvalidId` if this block doesn't
- //! have shared assignment. See `RASharedAssignment` for more details.
+ //! Shared assignment it or `Globals::kInvalidId` if this block doesn't have shared assignment.
+ //! See \ref RASharedAssignment for more details.
uint32_t _sharedAssignmentId = Globals::kInvalidId;
//! Scratch registers that cannot be allocated upon block entry.
- uint32_t _entryScratchGpRegs = 0;
+ RegMask _entryScratchGpRegs = 0;
//! Scratch registers used at exit, by a terminator instruction.
- uint32_t _exitScratchGpRegs = 0;
+ RegMask _exitScratchGpRegs = 0;
//! Register assignment (PhysToWork) on entry.
PhysToWorkMap* _entryPhysToWorkMap = nullptr;
//! Register assignment (WorkToPhys) on entry.
WorkToPhysMap* _entryWorkToPhysMap = nullptr;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -158,37 +151,43 @@ public:
inline ZoneAllocator* allocator() const noexcept;
inline uint32_t blockId() const noexcept { return _blockId; }
- inline uint32_t flags() const noexcept { return _flags; }
+ inline RABlockFlags flags() const noexcept { return _flags; }
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ inline bool hasFlag(RABlockFlags flag) const noexcept { return Support::test(_flags, flag); }
+ inline void addFlags(RABlockFlags flags) noexcept { _flags |= flags; }
inline bool isAssigned() const noexcept { return _blockId != kUnassignedId; }
- inline bool isConstructed() const noexcept { return hasFlag(kFlagIsConstructed); }
- inline bool isReachable() const noexcept { return hasFlag(kFlagIsReachable); }
- inline bool isTargetable() const noexcept { return hasFlag(kFlagIsTargetable); }
- inline bool isAllocated() const noexcept { return hasFlag(kFlagIsAllocated); }
- inline bool isFuncExit() const noexcept { return hasFlag(kFlagIsFuncExit); }
+ inline bool isConstructed() const noexcept { return hasFlag(RABlockFlags::kIsConstructed); }
+ inline bool isReachable() const noexcept { return hasFlag(RABlockFlags::kIsReachable); }
+ inline bool isTargetable() const noexcept { return hasFlag(RABlockFlags::kIsTargetable); }
+ inline bool isAllocated() const noexcept { return hasFlag(RABlockFlags::kIsAllocated); }
+ inline bool isFuncExit() const noexcept { return hasFlag(RABlockFlags::kIsFuncExit); }
+ inline bool hasTerminator() const noexcept { return hasFlag(RABlockFlags::kHasTerminator); }
+ inline bool hasConsecutive() const noexcept { return hasFlag(RABlockFlags::kHasConsecutive); }
+ inline bool hasJumpTable() const noexcept { return hasFlag(RABlockFlags::kHasJumpTable); }
inline void makeConstructed(const RARegsStats& regStats) noexcept {
- _flags |= kFlagIsConstructed;
+ _flags |= RABlockFlags::kIsConstructed;
_regsStats.combineWith(regStats);
}
- inline void makeReachable() noexcept { _flags |= kFlagIsReachable; }
- inline void makeTargetable() noexcept { _flags |= kFlagIsTargetable; }
- inline void makeAllocated() noexcept { _flags |= kFlagIsAllocated; }
+ inline void makeReachable() noexcept { _flags |= RABlockFlags::kIsReachable; }
+ inline void makeTargetable() noexcept { _flags |= RABlockFlags::kIsTargetable; }
+ inline void makeAllocated() noexcept { _flags |= RABlockFlags::kIsAllocated; }
inline const RARegsStats& regsStats() const noexcept { return _regsStats; }
- inline bool hasTerminator() const noexcept { return hasFlag(kFlagHasTerminator); }
- inline bool hasConsecutive() const noexcept { return hasFlag(kFlagHasConsecutive); }
- inline bool hasJumpTable() const noexcept { return hasFlag(kFlagHasJumpTable); }
-
inline bool hasPredecessors() const noexcept { return !_predecessors.empty(); }
inline bool hasSuccessors() const noexcept { return !_successors.empty(); }
+ inline bool hasSuccessor(RABlock* block) noexcept {
+ if (block->_predecessors.size() < _successors.size())
+ return block->_predecessors.contains(this);
+ else
+ return _successors.contains(block);
+ }
+
inline const RABlocks& predecessors() const noexcept { return _predecessors; }
inline const RABlocks& successors() const noexcept { return _successors; }
@@ -206,11 +205,11 @@ public:
inline uint32_t povOrder() const noexcept { return _povOrder; }
- inline uint32_t entryScratchGpRegs() const noexcept;
- inline uint32_t exitScratchGpRegs() const noexcept { return _exitScratchGpRegs; }
+ inline RegMask entryScratchGpRegs() const noexcept;
+ inline RegMask exitScratchGpRegs() const noexcept { return _exitScratchGpRegs; }
- inline void addEntryScratchGpRegs(uint32_t regMask) noexcept { _entryScratchGpRegs |= regMask; }
- inline void addExitScratchGpRegs(uint32_t regMask) noexcept { _exitScratchGpRegs |= regMask; }
+ inline void addEntryScratchGpRegs(RegMask regMask) noexcept { _entryScratchGpRegs |= regMask; }
+ inline void addExitScratchGpRegs(RegMask regMask) noexcept { _exitScratchGpRegs |= regMask; }
inline bool hasSharedAssignmentId() const noexcept { return _sharedAssignmentId != Globals::kInvalidId; }
inline uint32_t sharedAssignmentId() const noexcept { return _sharedAssignmentId; }
@@ -261,11 +260,9 @@ public:
//! \name Utilities
//! \{
- //! Adds a successor to this block, and predecessor to `successor`, making
- //! connection on both sides.
+ //! Adds a successor to this block, and predecessor to `successor`, making connection on both sides.
//!
- //! This API must be used to manage successors and predecessors, never manage
- //! it manually.
+ //! This API must be used to manage successors and predecessors, never manage it manually.
Error appendSuccessor(RABlock* successor) noexcept;
//! Similar to `appendSuccessor()`, but does prepend instead append.
@@ -276,19 +273,18 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::RAInst]
-// ============================================================================
-
//! Register allocator's data associated with each `InstNode`.
class RAInst {
public:
ASMJIT_NONCOPYABLE(RAInst)
+ //! \name Members
+ //! \{
+
//! Parent block.
RABlock* _block;
- //! Instruction flags.
- uint32_t _flags;
+ //! Aggregated RATiedFlags from all operands & instruction specific flags.
+ RATiedFlags _flags;
//! Total count of RATiedReg's.
uint32_t _tiedTotal;
//! Index of RATiedReg's per register group.
@@ -304,14 +300,12 @@ public:
//! Tied registers.
RATiedReg _tiedRegs[1];
- enum Flags : uint32_t {
- kFlagIsTransformable = 0x80000000u
- };
+ //! \}
//! \name Construction & Destruction
//! \{
- ASMJIT_INLINE RAInst(RABlock* block, uint32_t flags, uint32_t tiedTotal, const RARegMask& clobberedRegs) noexcept {
+ inline RAInst(RABlock* block, RATiedFlags flags, uint32_t tiedTotal, const RARegMask& clobberedRegs) noexcept {
_block = block;
_flags = flags;
_tiedTotal = tiedTotal;
@@ -328,18 +322,18 @@ public:
//! \{
//! Returns the instruction flags.
- inline uint32_t flags() const noexcept { return _flags; }
+ inline RATiedFlags flags() const noexcept { return _flags; }
//! Tests whether the instruction has flag `flag`.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ inline bool hasFlag(RATiedFlags flag) const noexcept { return Support::test(_flags, flag); }
//! Replaces the existing instruction flags with `flags`.
- inline void setFlags(uint32_t flags) noexcept { _flags = flags; }
+ inline void setFlags(RATiedFlags flags) noexcept { _flags = flags; }
//! Adds instruction `flags` to this RAInst.
- inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+ inline void addFlags(RATiedFlags flags) noexcept { _flags |= flags; }
//! Clears instruction `flags` from this RAInst.
- inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
+ inline void clearFlags(RATiedFlags flags) noexcept { _flags &= ~flags; }
//! Tests whether this instruction can be transformed to another instruction if necessary.
- inline bool isTransformable() const noexcept { return hasFlag(kFlagIsTransformable); }
+ inline bool isTransformable() const noexcept { return hasFlag(RATiedFlags::kInst_IsTransformable); }
//! Returns the associated block with this RAInst.
inline RABlock* block() const noexcept { return _block; }
@@ -347,12 +341,12 @@ public:
//! Returns tied registers (all).
inline RATiedReg* tiedRegs() const noexcept { return const_cast<RATiedReg*>(_tiedRegs); }
//! Returns tied registers for a given `group`.
- inline RATiedReg* tiedRegs(uint32_t group) const noexcept { return const_cast<RATiedReg*>(_tiedRegs) + _tiedIndex.get(group); }
+ inline RATiedReg* tiedRegs(RegGroup group) const noexcept { return const_cast<RATiedReg*>(_tiedRegs) + _tiedIndex.get(group); }
//! Returns count of all tied registers.
inline uint32_t tiedCount() const noexcept { return _tiedTotal; }
//! Returns count of tied registers of a given `group`.
- inline uint32_t tiedCount(uint32_t group) const noexcept { return _tiedCount[group]; }
+ inline uint32_t tiedCount(RegGroup group) const noexcept { return _tiedCount[group]; }
//! Returns `RATiedReg` at the given `index`.
inline RATiedReg* tiedAt(uint32_t index) const noexcept {
@@ -361,8 +355,8 @@ public:
}
//! Returns `RATiedReg` at the given `index` of the given register `group`.
- inline RATiedReg* tiedOf(uint32_t group, uint32_t index) const noexcept {
- ASMJIT_ASSERT(index < _tiedCount._regs[group]);
+ inline RATiedReg* tiedOf(RegGroup group, uint32_t index) const noexcept {
+ ASMJIT_ASSERT(index < _tiedCount.get(group));
return tiedRegs(group) + index;
}
@@ -381,20 +375,18 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::RAInstBuilder]
-// ============================================================================
-
-//! A helper class that is used to build an array of RATiedReg items that are
-//! then copied to `RAInst`.
+//! A helper class that is used to build an array of RATiedReg items that are then copied to `RAInst`.
class RAInstBuilder {
public:
ASMJIT_NONCOPYABLE(RAInstBuilder)
+ //! \name Members
+ //! \{
+
//! Flags combined from all RATiedReg's.
- uint32_t _aggregatedFlags;
+ RATiedFlags _aggregatedFlags;
//! Flags that will be cleared before storing the aggregated flags to `RAInst`.
- uint32_t _forbiddenFlags;
+ RATiedFlags _forbiddenFlags;
RARegCount _count;
RARegsStats _stats;
@@ -406,6 +398,8 @@ public:
//! Array of temporary tied registers.
RATiedReg _tiedRegs[128];
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -413,8 +407,8 @@ public:
inline void init() noexcept { reset(); }
inline void reset() noexcept {
- _aggregatedFlags = 0;
- _forbiddenFlags = 0;
+ _aggregatedFlags = RATiedFlags::kNone;
+ _forbiddenFlags = RATiedFlags::kNone;
_count.reset();
_stats.reset();
_used.reset();
@@ -427,11 +421,11 @@ public:
//! \name Accessors
//! \{
- inline uint32_t aggregatedFlags() const noexcept { return _aggregatedFlags; }
- inline uint32_t forbiddenFlags() const noexcept { return _forbiddenFlags; }
+ inline RATiedFlags aggregatedFlags() const noexcept { return _aggregatedFlags; }
+ inline RATiedFlags forbiddenFlags() const noexcept { return _forbiddenFlags; }
- inline void addAggregatedFlags(uint32_t flags) noexcept { _aggregatedFlags |= flags; }
- inline void addForbiddenFlags(uint32_t flags) noexcept { _forbiddenFlags |= flags; }
+ inline void addAggregatedFlags(RATiedFlags flags) noexcept { _aggregatedFlags |= flags; }
+ inline void addForbiddenFlags(RATiedFlags flags) noexcept { _forbiddenFlags |= flags; }
//! Returns the number of tied registers added to the builder.
inline uint32_t tiedRegCount() const noexcept { return uint32_t((size_t)(_cur - _tiedRegs)); }
@@ -459,19 +453,26 @@ public:
//! \name Utilities
//! \{
- Error add(RAWorkReg* workReg, uint32_t flags, uint32_t allocable, uint32_t useId, uint32_t useRewriteMask, uint32_t outId, uint32_t outRewriteMask, uint32_t rmSize = 0) noexcept {
- uint32_t group = workReg->group();
+ Error add(
+ RAWorkReg* workReg,
+ RATiedFlags flags,
+ RegMask useRegMask, uint32_t useId, uint32_t useRewriteMask,
+ RegMask outRegMask, uint32_t outId, uint32_t outRewriteMask,
+ uint32_t rmSize = 0,
+ uint32_t consecutiveParent = Globals::kInvalidId) noexcept {
+
+ RegGroup group = workReg->group();
RATiedReg* tiedReg = workReg->tiedReg();
if (useId != BaseReg::kIdBad) {
_stats.makeFixed(group);
_used[group] |= Support::bitMask(useId);
- flags |= RATiedReg::kUseFixed;
+ flags |= RATiedFlags::kUseFixed;
}
if (outId != BaseReg::kIdBad) {
_clobbered[group] |= Support::bitMask(outId);
- flags |= RATiedReg::kOutFixed;
+ flags |= RATiedFlags::kOutFixed;
}
_aggregatedFlags |= flags;
@@ -482,13 +483,19 @@ public:
ASMJIT_ASSERT(tiedRegCount() < ASMJIT_ARRAY_SIZE(_tiedRegs));
tiedReg = _cur++;
- tiedReg->init(workReg->workId(), flags, allocable, useId, useRewriteMask, outId, outRewriteMask, rmSize);
+ tiedReg->init(workReg->workId(), flags, useRegMask, useId, useRewriteMask, outRegMask, outId, outRewriteMask, rmSize, consecutiveParent);
workReg->setTiedReg(tiedReg);
_count.add(group);
return kErrorOk;
}
else {
+ if (consecutiveParent != tiedReg->consecutiveParent()) {
+ if (tiedReg->consecutiveParent() != Globals::kInvalidId)
+ return DebugUtils::errored(kErrorInvalidState);
+ tiedReg->_consecutiveParent = consecutiveParent;
+ }
+
if (useId != BaseReg::kIdBad) {
if (ASMJIT_UNLIKELY(tiedReg->hasUseId()))
return DebugUtils::errored(kErrorOverlappedRegs);
@@ -503,8 +510,9 @@ public:
tiedReg->addRefCount();
tiedReg->addFlags(flags);
- tiedReg->_allocableRegs &= allocable;
+ tiedReg->_useRegMask &= useRegMask;
tiedReg->_useRewriteMask |= useRewriteMask;
+ tiedReg->_outRegMask &= outRegMask;
tiedReg->_outRewriteMask |= outRewriteMask;
tiedReg->_rmSize = uint8_t(Support::max<uint32_t>(tiedReg->rmSize(), rmSize));
return kErrorOk;
@@ -514,9 +522,9 @@ public:
Error addCallArg(RAWorkReg* workReg, uint32_t useId) noexcept {
ASMJIT_ASSERT(useId != BaseReg::kIdBad);
- uint32_t flags = RATiedReg::kUse | RATiedReg::kRead | RATiedReg::kUseFixed;
- uint32_t group = workReg->group();
- uint32_t allocable = Support::bitMask(useId);
+ RATiedFlags flags = RATiedFlags::kUse | RATiedFlags::kRead | RATiedFlags::kUseFixed;
+ RegGroup group = workReg->group();
+ RegMask allocable = Support::bitMask(useId);
_aggregatedFlags |= flags;
_used[group] |= allocable;
@@ -529,7 +537,7 @@ public:
ASMJIT_ASSERT(tiedRegCount() < ASMJIT_ARRAY_SIZE(_tiedRegs));
tiedReg = _cur++;
- tiedReg->init(workReg->workId(), flags, allocable, useId, 0, BaseReg::kIdBad, 0);
+ tiedReg->init(workReg->workId(), flags, allocable, useId, 0, allocable, BaseReg::kIdBad, 0);
workReg->setTiedReg(tiedReg);
_count.add(group);
@@ -537,12 +545,12 @@ public:
}
else {
if (tiedReg->hasUseId()) {
- flags |= RATiedReg::kDuplicate;
- tiedReg->_allocableRegs |= allocable;
+ flags |= RATiedFlags::kDuplicate;
+ tiedReg->_useRegMask |= allocable;
}
else {
tiedReg->setUseId(useId);
- tiedReg->_allocableRegs &= allocable;
+ tiedReg->_useRegMask &= allocable;
}
tiedReg->addRefCount();
@@ -554,12 +562,12 @@ public:
Error addCallRet(RAWorkReg* workReg, uint32_t outId) noexcept {
ASMJIT_ASSERT(outId != BaseReg::kIdBad);
- uint32_t flags = RATiedReg::kOut | RATiedReg::kWrite | RATiedReg::kOutFixed;
- uint32_t group = workReg->group();
- uint32_t allocable = Support::bitMask(outId);
+ RATiedFlags flags = RATiedFlags::kOut | RATiedFlags::kWrite | RATiedFlags::kOutFixed;
+ RegGroup group = workReg->group();
+ RegMask outRegs = Support::bitMask(outId);
_aggregatedFlags |= flags;
- _used[group] |= allocable;
+ _used[group] |= outRegs;
_stats.makeFixed(group);
_stats.makeUsed(group);
@@ -569,7 +577,7 @@ public:
ASMJIT_ASSERT(tiedRegCount() < ASMJIT_ARRAY_SIZE(_tiedRegs));
tiedReg = _cur++;
- tiedReg->init(workReg->workId(), flags, allocable, BaseReg::kIdBad, 0, outId, 0);
+ tiedReg->init(workReg->workId(), flags, Support::allOnes<RegMask>(), BaseReg::kIdBad, 0, outRegs, outId, 0);
workReg->setTiedReg(tiedReg);
_count.add(group);
@@ -589,21 +597,21 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::RASharedAssignment]
-// ============================================================================
-
+//! Intersection of multiple register assignments.
+//!
+//! See \ref RAAssignment for more information about register assignments.
class RASharedAssignment {
public:
typedef RAAssignment::PhysToWorkMap PhysToWorkMap;
typedef RAAssignment::WorkToPhysMap WorkToPhysMap;
- //! Bit-mask of registers that cannot be used upon a block entry, for each
- //! block that has this shared assignment. Scratch registers can come from
- //! ISA limits (like jecx/loop instructions on x86) or because the registers
- //! are used by jump/branch instruction that uses registers to perform an
- //! indirect jump.
- uint32_t _entryScratchGpRegs = 0;
+ //! \name Members
+ //! \{
+
+ //! Bit-mask of registers that cannot be used upon a block entry, for each block that has this shared assignment.
+ //! Scratch registers can come from ISA limits (like jecx/loop instructions on x86) or because the registers are
+ //! used by jump/branch instruction that uses registers to perform an indirect jump.
+ RegMask _entryScratchGpRegs = 0;
//! Union of all live-in registers.
ZoneBitVector _liveIn {};
//! Register assignment (PhysToWork).
@@ -611,30 +619,28 @@ public:
//! Register assignment (WorkToPhys).
WorkToPhysMap* _workToPhysMap = nullptr;
- //! Most likely never called as we initialize a vector of shared assignments to zero.
- inline RASharedAssignment() noexcept {}
+ //! \}
+
+ //! \name Accessors
+ //! \{
- inline uint32_t entryScratchGpRegs() const noexcept { return _entryScratchGpRegs; }
- inline void addEntryScratchGpRegs(uint32_t mask) noexcept { _entryScratchGpRegs |= mask; }
+ inline bool empty() const noexcept { return _physToWorkMap == nullptr; }
+
+ inline RegMask entryScratchGpRegs() const noexcept { return _entryScratchGpRegs; }
+ inline void addEntryScratchGpRegs(RegMask mask) noexcept { _entryScratchGpRegs |= mask; }
inline const ZoneBitVector& liveIn() const noexcept { return _liveIn; }
inline PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
inline WorkToPhysMap* workToPhysMap() const noexcept { return _workToPhysMap; }
- inline bool empty() const noexcept {
- return _physToWorkMap == nullptr;
- }
-
inline void assignMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
_physToWorkMap = physToWorkMap;
_workToPhysMap = workToPhysMap;
}
-};
-// ============================================================================
-// [asmjit::BaseRAPass]
-// ============================================================================
+ //! \}
+};
//! Register allocation pass used by `BaseCompiler`.
class BaseRAPass : public FuncPass {
@@ -642,13 +648,16 @@ public:
ASMJIT_NONCOPYABLE(BaseRAPass)
typedef FuncPass Base;
- enum Weights : uint32_t {
+ enum : uint32_t {
kCallArgWeight = 80
};
typedef RAAssignment::PhysToWorkMap PhysToWorkMap;
typedef RAAssignment::WorkToPhysMap WorkToPhysMap;
+ //! \name Members
+ //! \{
+
//! Allocator that uses zone passed to `runOnFunction()`.
ZoneAllocator _allocator {};
//! Emit helper.
@@ -656,10 +665,10 @@ public:
//! Logger, disabled if null.
Logger* _logger = nullptr;
- //! Debug logger, non-null only if `kOptionDebugPasses` option is set.
- Logger* _debugLogger = nullptr;
- //! Logger flags.
- uint32_t _loggerFlags = 0;
+ //! Format options, copied from Logger, or zeroed if there is no logger.
+ FormatOptions _formatOptions {};
+ //! Diagnostic options, copied from Emitter, or zeroed if there is no logger.
+ DiagnosticOptions _diagnosticOptions {};
//! Function being processed.
FuncNode* _func = nullptr;
@@ -680,7 +689,7 @@ public:
//! Number of created blocks (internal).
uint32_t _createdBlockCount = 0;
- //! SharedState blocks.
+ //! Shared assignment blocks.
ZoneVector<RASharedAssignment> _sharedAssignments {};
//! Timestamp generator (incremental).
@@ -695,7 +704,7 @@ public:
//! Total number of physical registers.
uint32_t _physRegTotal = 0;
//! Indexes of a possible scratch registers that can be selected if necessary.
- uint8_t _scratchRegIndexes[2] {};
+ Support::Array<uint8_t, 2> _scratchRegIndexes {};
//! Registers available for allocation.
RARegMask _availableRegs = RARegMask();
@@ -707,14 +716,14 @@ public:
//! Work registers (registers used by the function).
RAWorkRegs _workRegs;
//! Work registers per register group.
- RAWorkRegs _workRegsOfGroup[BaseReg::kGroupVirt];
+ Support::Array<RAWorkRegs, Globals::kNumVirtGroups> _workRegsOfGroup;
//! Register allocation strategy per register group.
- RAStrategy _strategy[BaseReg::kGroupVirt];
+ Support::Array<RAStrategy, Globals::kNumVirtGroups> _strategy;
//! Global max live-count (from all blocks) per register group.
RALiveCount _globalMaxLiveCount = RALiveCount();
//! Global live spans per register group.
- LiveRegSpans* _globalLiveSpans[BaseReg::kGroupVirt] {};
+ Support::Array<LiveRegSpans*, Globals::kNumVirtGroups> _globalLiveSpans {};
//! Temporary stack slot.
Operand _temporaryMem = Operand();
@@ -734,7 +743,9 @@ public:
//! Temporary string builder used to format comments.
StringTmp<80> _tmpString;
- //! \name Construction & Reset
+ //! \}
+
+ //! \name Construction & Destruction
//! \{
BaseRAPass() noexcept;
@@ -747,8 +758,14 @@ public:
//! Returns \ref Logger passed to \ref runOnFunction().
inline Logger* logger() const noexcept { return _logger; }
- //! Returns \ref Logger passed to \ref runOnFunction() or null if `kOptionDebugPasses` is not set.
- inline Logger* debugLogger() const noexcept { return _debugLogger; }
+
+ //! Returns either a valid logger if the given `option` is set and logging is enabled, or nullptr.
+ inline Logger* getLoggerIf(DiagnosticOptions option) const noexcept { return Support::test(_diagnosticOptions, option) ? _logger : nullptr; }
+
+ //! Returns whether the diagnostic `option` is enabled.
+ //!
+ //! \note Returns false if there is no logger (as diagnostics without logging make no sense).
+ inline bool hasDiagnosticOption(DiagnosticOptions option) const noexcept { return Support::test(_diagnosticOptions, option); }
//! Returns \ref Zone passed to \ref runOnFunction().
inline Zone* zone() const noexcept { return _allocator.zone(); }
@@ -778,7 +795,7 @@ public:
//! \name Utilities
//! \{
- inline void makeUnavailable(uint32_t group, uint32_t regId) noexcept {
+ inline void makeUnavailable(RegGroup group, uint32_t regId) noexcept {
_availableRegs[group] &= ~Support::bitMask(regId);
_availableRegCount[group]--;
}
@@ -829,12 +846,11 @@ public:
//! Returns the count of reachable basic blocks (returns size of `_pov` array).
inline uint32_t reachableBlockCount() const noexcept { return _pov.size(); }
- //! Tests whether the CFG has dangling blocks - these were created by `newBlock()`,
- //! but not added to CFG through `addBlocks()`. If `true` is returned and the
- //! CFG is constructed it means that something is missing and it's incomplete.
+ //! Tests whether the CFG has dangling blocks - these were created by `newBlock()`, but not added to CFG through
+ //! `addBlocks()`. If `true` is returned and the CFG is constructed it means that something is missing and it's
+ //! incomplete.
//!
- //! \note This is only used to check if the number of created blocks matches
- //! the number of added blocks.
+ //! \note This is only used to check if the number of created blocks matches the number of added blocks.
inline bool hasDanglingBlocks() const noexcept { return _createdBlockCount != blockCount(); }
//! Gest a next timestamp to be used to mark CFG blocks.
@@ -842,31 +858,29 @@ public:
//! Createss a new `RABlock` instance.
//!
- //! \note New blocks don't have ID assigned until they are added to the block
- //! array by calling `addBlock()`.
+ //! \note New blocks don't have ID assigned until they are added to the block array by calling `addBlock()`.
RABlock* newBlock(BaseNode* initialNode = nullptr) noexcept;
- //! Tries to find a neighboring LabelNode (without going through code) that is
- //! already connected with `RABlock`. If no label is found then a new RABlock
- //! is created and assigned to all possible labels in a backward direction.
+ //! Tries to find a neighboring LabelNode (without going through code) that is already connected with `RABlock`.
+ //! If no label is found then a new RABlock is created and assigned to all possible labels in a backward direction.
RABlock* newBlockOrExistingAt(LabelNode* cbLabel, BaseNode** stoppedAt = nullptr) noexcept;
//! Adds the given `block` to the block list and assign it a unique block id.
Error addBlock(RABlock* block) noexcept;
inline Error addExitBlock(RABlock* block) noexcept {
- block->addFlags(RABlock::kFlagIsFuncExit);
+ block->addFlags(RABlockFlags::kIsFuncExit);
return _exits.append(allocator(), block);
}
- ASMJIT_INLINE RAInst* newRAInst(RABlock* block, uint32_t flags, uint32_t tiedRegCount, const RARegMask& clobberedRegs) noexcept {
+ ASMJIT_FORCE_INLINE RAInst* newRAInst(RABlock* block, RATiedFlags flags, uint32_t tiedRegCount, const RARegMask& clobberedRegs) noexcept {
void* p = zone()->alloc(RAInst::sizeOf(tiedRegCount));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
return new(p) RAInst(block, flags, tiedRegCount, clobberedRegs);
}
- ASMJIT_INLINE Error assignRAInst(BaseNode* node, RABlock* block, RAInstBuilder& ib) noexcept {
+ ASMJIT_FORCE_INLINE Error assignRAInst(BaseNode* node, RABlock* block, RAInstBuilder& ib) noexcept {
uint32_t tiedRegCount = ib.tiedRegCount();
RAInst* raInst = newRAInst(block, ib.aggregatedFlags(), tiedRegCount, ib._clobbered);
@@ -874,7 +888,7 @@ public:
return DebugUtils::errored(kErrorOutOfMemory);
RARegIndex index;
- uint32_t flagsFilter = ~ib.forbiddenFlags();
+ RATiedFlags flagsFilter = ~ib.forbiddenFlags();
index.buildIndexes(ib._count);
raInst->_tiedIndex = index;
@@ -885,15 +899,15 @@ public:
RAWorkReg* workReg = workRegById(tiedReg->workId());
workReg->resetTiedReg();
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
if (tiedReg->hasUseId()) {
- block->addFlags(RABlock::kFlagHasFixedRegs);
+ block->addFlags(RABlockFlags::kHasFixedRegs);
raInst->_usedRegs[group] |= Support::bitMask(tiedReg->useId());
}
if (tiedReg->hasOutId()) {
- block->addFlags(RABlock::kFlagHasFixedRegs);
+ block->addFlags(RABlockFlags::kHasFixedRegs);
}
RATiedReg& dst = raInst->_tiedRegs[index[group]++];
@@ -901,7 +915,7 @@ public:
dst._flags &= flagsFilter;
if (!tiedReg->isDuplicate())
- dst._allocableRegs &= ~ib._used[group];
+ dst._useRegMask &= ~ib._used[group];
}
node->setPassData<RAInst>(raInst);
@@ -915,18 +929,15 @@ public:
//! Traverse the whole function and do the following:
//!
- //! 1. Construct CFG (represented by `RABlock`) by populating `_blocks` and
- //! `_exits`. Blocks describe the control flow of the function and contain
- //! some additional information that is used by the register allocator.
+ //! 1. Construct CFG (represented by `RABlock`) by populating `_blocks` and `_exits`. Blocks describe the control
+ //! flow of the function and contain some additional information that is used by the register allocator.
//!
- //! 2. Remove unreachable code immediately. This is not strictly necessary
- //! for BaseCompiler itself as the register allocator cannot reach such
- //! nodes, but keeping instructions that use virtual registers would fail
- //! during instruction encoding phase (Assembler).
+ //! 2. Remove unreachable code immediately. This is not strictly necessary for BaseCompiler itself as the register
+ //! allocator cannot reach such nodes, but keeping instructions that use virtual registers would fail during
+ //! instruction encoding phase (Assembler).
//!
- //! 3. `RAInst` is created for each `InstNode` or compatible. It contains
- //! information that is essential for further analysis and register
- //! allocation.
+ //! 3. `RAInst` is created for each `InstNode` or compatible. It contains information that is essential for further
+ //! analysis and register allocation.
//!
//! Use `RACFGBuilderT` template that provides the necessary boilerplate.
virtual Error buildCFG() noexcept = 0;
@@ -940,7 +951,7 @@ public:
//! \{
//! Constructs CFG views (only POV at the moment).
- Error buildViews() noexcept;
+ Error buildCFGViews() noexcept;
//! \}
@@ -948,13 +959,11 @@ public:
//! \{
// Terminology:
- // - A node `X` dominates a node `Z` if any path from the entry point to
- // `Z` has to go through `X`.
- // - A node `Z` post-dominates a node `X` if any path from `X` to the end
- // of the graph has to go through `Z`.
+ // - A node `X` dominates a node `Z` if any path from the entry point to `Z` has to go through `X`.
+ // - A node `Z` post-dominates a node `X` if any path from `X` to the end of the graph has to go through `Z`.
//! Constructs a dominator-tree from CFG.
- Error buildDominators() noexcept;
+ Error buildCFGDominators() noexcept;
bool _strictlyDominates(const RABlock* a, const RABlock* b) const noexcept;
const RABlock* _nearestCommonDominator(const RABlock* a, const RABlock* b) const noexcept;
@@ -974,17 +983,15 @@ public:
//! \name CFG - Utilities
//! \{
- Error removeUnreachableBlocks() noexcept;
+ Error removeUnreachableCode() noexcept;
- //! Returns `node` or some node after that is ideal for beginning a new block.
- //! This function is mostly used after a conditional or unconditional jump to
- //! select the successor node. In some cases the next node could be a label,
+ //! Returns `node` or some node after that is ideal for beginning a new block. This function is mostly used after
+ //! a conditional or unconditional jump to select the successor node. In some cases the next node could be a label,
//! which means it could have assigned some block already.
BaseNode* findSuccessorStartingAt(BaseNode* node) noexcept;
- //! Returns `true` of the `node` can flow to `target` without reaching code
- //! nor data. It's used to eliminate jumps to labels that are next right to
- //! them.
+ //! Returns `true` of the `node` can flow to `target` without reaching code nor data. It's used to eliminate jumps
+ //! to labels that are next right to them.
bool isNextTo(BaseNode* node, BaseNode* target) noexcept;
//! \}
@@ -994,25 +1001,25 @@ public:
//! Returns a native size of the general-purpose register of the target architecture.
inline uint32_t registerSize() const noexcept { return _sp.size(); }
- inline uint32_t availableRegCount(uint32_t group) const noexcept { return _availableRegCount[group]; }
+ inline uint32_t availableRegCount(RegGroup group) const noexcept { return _availableRegCount[group]; }
inline RAWorkReg* workRegById(uint32_t workId) const noexcept { return _workRegs[workId]; }
inline RAWorkRegs& workRegs() noexcept { return _workRegs; }
- inline RAWorkRegs& workRegs(uint32_t group) noexcept { return _workRegsOfGroup[group]; }
+ inline RAWorkRegs& workRegs(RegGroup group) noexcept { return _workRegsOfGroup[group]; }
inline const RAWorkRegs& workRegs() const noexcept { return _workRegs; }
- inline const RAWorkRegs& workRegs(uint32_t group) const noexcept { return _workRegsOfGroup[group]; }
+ inline const RAWorkRegs& workRegs(RegGroup group) const noexcept { return _workRegsOfGroup[group]; }
inline uint32_t workRegCount() const noexcept { return _workRegs.size(); }
- inline uint32_t workRegCount(uint32_t group) const noexcept { return _workRegsOfGroup[group].size(); }
+ inline uint32_t workRegCount(RegGroup group) const noexcept { return _workRegsOfGroup[group].size(); }
inline void _buildPhysIndex() noexcept {
_physRegIndex.buildIndexes(_physRegCount);
- _physRegTotal = uint32_t(_physRegIndex[BaseReg::kGroupVirt - 1]) +
- uint32_t(_physRegCount[BaseReg::kGroupVirt - 1]) ;
+ _physRegTotal = uint32_t(_physRegIndex[RegGroup::kMaxVirt]) +
+ uint32_t(_physRegCount[RegGroup::kMaxVirt]) ;
}
- inline uint32_t physRegIndex(uint32_t group) const noexcept { return _physRegIndex[group]; }
+ inline uint32_t physRegIndex(RegGroup group) const noexcept { return _physRegIndex[group]; }
inline uint32_t physRegTotal() const noexcept { return _physRegTotal; }
Error _asWorkReg(VirtReg* vReg, RAWorkReg** out) noexcept;
@@ -1024,7 +1031,7 @@ public:
return *out ? kErrorOk : _asWorkReg(vReg, out);
}
- inline Error virtIndexAsWorkReg(uint32_t vIndex, RAWorkReg** out) noexcept {
+ ASMJIT_FORCE_INLINE Error virtIndexAsWorkReg(uint32_t vIndex, RAWorkReg** out) noexcept {
const ZoneVector<VirtReg*>& virtRegs = cc()->virtRegs();
if (ASMJIT_UNLIKELY(vIndex >= virtRegs.size()))
return DebugUtils::errored(kErrorInvalidVirtId);
@@ -1045,7 +1052,10 @@ public:
inline BaseMem workRegAsMem(RAWorkReg* workReg) noexcept {
getOrCreateStackSlot(workReg);
- return BaseMem(BaseMem::Decomposed { _sp.type(), workReg->virtId(), BaseReg::kTypeNone, 0, 0, 0, BaseMem::kSignatureMemRegHomeFlag });
+ return BaseMem(OperandSignature::fromOpType(OperandType::kMem) |
+ OperandSignature::fromMemBaseType(_sp.type()) |
+ OperandSignature::fromBits(OperandSignature::kMemRegHomeFlag),
+ workReg->virtId(), 0, 0);
}
WorkToPhysMap* newWorkToPhysMap() noexcept;
@@ -1085,7 +1095,7 @@ public:
//! Initializes data structures used for global live spans.
Error initGlobalLiveSpans() noexcept;
- Error binPack(uint32_t group) noexcept;
+ Error binPack(RegGroup group) noexcept;
//! \}
@@ -1159,8 +1169,8 @@ public:
inline ZoneAllocator* RABlock::allocator() const noexcept { return _ra->allocator(); }
-inline uint32_t RABlock::entryScratchGpRegs() const noexcept {
- uint32_t regs = _entryScratchGpRegs;
+inline RegMask RABlock::entryScratchGpRegs() const noexcept {
+ RegMask regs = _entryScratchGpRegs;
if (hasSharedAssignmentId())
regs = _ra->_sharedAssignments[_sharedAssignmentId].entryScratchGpRegs();
return regs;
diff --git a/src/asmjit/core/rastack.cpp b/src/asmjit/core/rastack.cpp
index b886279..2b7ed59 100644
--- a/src/asmjit/core/rastack.cpp
+++ b/src/asmjit/core/rastack.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_COMPILER
@@ -29,9 +11,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::RAStackAllocator - Slots]
-// ============================================================================
+// RAStackAllocator - Slots
+// ========================
RAStackSlot* RAStackAllocator::newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags) noexcept {
if (ASMJIT_UNLIKELY(_slots.willGrow(allocator(), 1) != kErrorOk))
@@ -55,9 +36,8 @@ RAStackSlot* RAStackAllocator::newSlot(uint32_t baseRegId, uint32_t size, uint32
return slot;
}
-// ============================================================================
-// [asmjit::RAStackAllocator - Utilities]
-// ============================================================================
+// RAStackAllocator - Utilities
+// ============================
struct RAStackGap {
inline RAStackGap() noexcept
@@ -82,10 +62,9 @@ Error RAStackAllocator::calculateStackFrame() noexcept {
// STEP 1:
//
- // Update usage based on the size of the slot. We boost smaller slots in a way
- // that 32-bit register has higher priority than a 128-bit register, however,
- // if one 128-bit register is used 4 times more than some other 32-bit register
- // it will overweight it.
+ // Update usage based on the size of the slot. We boost smaller slots in a way that 32-bit register has higher
+ // priority than a 128-bit register, however, if one 128-bit register is used 4 times more than some other 32-bit
+ // register it will overweight it.
for (RAStackSlot* slot : _slots) {
uint32_t alignment = slot->alignment();
ASMJIT_ASSERT(alignment > 0);
@@ -98,8 +77,8 @@ Error RAStackAllocator::calculateStackFrame() noexcept {
else
weight = power;
- // If overflown, which has less chance of winning a lottery, just use max
- // possible weight. In such case it probably doesn't matter at all.
+ // If overflown, which has less chance of winning a lottery, just use max possible weight. In such case it
+ // probably doesn't matter at all.
if (weight > 0xFFFFFFFFu)
weight = 0xFFFFFFFFu;
@@ -116,12 +95,11 @@ Error RAStackAllocator::calculateStackFrame() noexcept {
// STEP 3:
//
- // Calculate offset of each slot. We start from the slot that has the highest
- // weight and advance to slots with lower weight. It could look that offsets
- // start from the first slot in our list and then simply increase, but it's
- // not always the case as we also try to fill all gaps introduced by the fact
- // that slots are sorted by weight and not by size & alignment, so when we need
- // to align some slot we distribute the gap caused by the alignment to `gaps`.
+ // Calculate offset of each slot. We start from the slot that has the highest weight and advance to slots with
+ // lower weight. It could look that offsets start from the first slot in our list and then simply increase, but
+ // it's not always the case as we also try to fill all gaps introduced by the fact that slots are sorted by
+ // weight and not by size & alignment, so when we need to align some slot we distribute the gap caused by the
+ // alignment to `gaps`.
uint32_t offset = 0;
ZoneVector<RAStackGap> gaps[kSizeCount - 1];
diff --git a/src/asmjit/core/rastack_p.h b/src/asmjit/core/rastack_p.h
index 33d4e1d..90640b4 100644
--- a/src/asmjit/core/rastack_p.h
+++ b/src/asmjit/core/rastack_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RASTACK_P_H_INCLUDED
#define ASMJIT_CORE_RASTACK_P_H_INCLUDED
@@ -35,26 +17,25 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RAStackSlot]
-// ============================================================================
-
//! Stack slot.
struct RAStackSlot {
//! Stack slot flags.
//!
//! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it?
- enum Flags : uint32_t {
+ enum Flags : uint16_t {
//! Stack slot is register home slot.
kFlagRegHome = 0x0001u,
//! Stack slot position matches argument passed via stack.
- kFlagStackArg = 0x0002u
+ kFlagStackArg = 0x0002u
};
enum ArgIndex : uint32_t {
kNoArgIndex = 0xFF
};
+ //! \name Members
+ //! \{
+
//! Base register used to address the stack.
uint8_t _baseRegId;
//! Minimum alignment required by the slot.
@@ -71,6 +52,8 @@ struct RAStackSlot {
//! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame().
int32_t _offset;
+ //! \}
+
//! \name Accessors
//! \{
@@ -101,10 +84,6 @@ struct RAStackSlot {
typedef ZoneVector<RAStackSlot*> RAStackSlots;
-// ============================================================================
-// [asmjit::RAStackAllocator]
-// ============================================================================
-
//! Stack allocator.
class RAStackAllocator {
public:
@@ -121,6 +100,9 @@ public:
kSizeCount = 7
};
+ //! \name Members
+ //! \{
+
//! Allocator used to allocate internal data.
ZoneAllocator* _allocator;
//! Count of bytes used by all slots.
@@ -132,7 +114,9 @@ public:
//! Stack slots vector.
RAStackSlots _slots;
- //! \name Construction / Destruction
+ //! \}
+
+ //! \name Construction & Destruction
//! \{
inline RAStackAllocator() noexcept
diff --git a/src/asmjit/core/string.cpp b/src/asmjit/core/string.cpp
index 8cebfcc..19d1e18 100644
--- a/src/asmjit/core/string.cpp
+++ b/src/asmjit/core/string.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/string.h"
@@ -27,18 +9,16 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::String - Globals]
-// ============================================================================
+// String - Globals
+// ================
static const char String_baseN[] = "0123456789ABCDEF";
constexpr size_t kMinAllocSize = 64;
constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold;
-// ============================================================================
-// [asmjit::String]
-// ============================================================================
+// String - Clear & Reset
+// ======================
Error String::reset() noexcept {
if (_type == kTypeLarge)
@@ -60,7 +40,10 @@ Error String::clear() noexcept {
return kErrorOk;
}
-char* String::prepare(uint32_t op, size_t size) noexcept {
+// String - Prepare
+// ================
+
+char* String::prepare(ModifyOp op, size_t size) noexcept {
char* curData;
size_t curSize;
size_t curCapacity;
@@ -76,7 +59,7 @@ char* String::prepare(uint32_t op, size_t size) noexcept {
curCapacity = kSSOCapacity;
}
- if (op == kOpAssign) {
+ if (op == ModifyOp::kAssign) {
if (size > curCapacity) {
// Prevent arithmetic overflow.
if (ASMJIT_UNLIKELY(size >= kMaxAllocSize))
@@ -150,6 +133,9 @@ char* String::prepare(uint32_t op, size_t size) noexcept {
}
}
+// String - Assign
+// ===============
+
Error String::assign(const char* data, size_t size) noexcept {
char* dst = nullptr;
@@ -210,11 +196,10 @@ Error String::assign(const char* data, size_t size) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::String - Operations]
-// ============================================================================
+// String - Operations
+// ===================
-Error String::_opString(uint32_t op, const char* str, size_t size) noexcept {
+Error String::_opString(ModifyOp op, const char* str, size_t size) noexcept {
if (size == SIZE_MAX)
size = str ? strlen(str) : size_t(0);
@@ -229,7 +214,7 @@ Error String::_opString(uint32_t op, const char* str, size_t size) noexcept {
return kErrorOk;
}
-Error String::_opChar(uint32_t op, char c) noexcept {
+Error String::_opChar(ModifyOp op, char c) noexcept {
char* p = prepare(op, 1);
if (!p)
return DebugUtils::errored(kErrorOutOfMemory);
@@ -238,7 +223,7 @@ Error String::_opChar(uint32_t op, char c) noexcept {
return kErrorOk;
}
-Error String::_opChars(uint32_t op, char c, size_t n) noexcept {
+Error String::_opChars(ModifyOp op, char c, size_t n) noexcept {
if (!n)
return kErrorOk;
@@ -255,7 +240,7 @@ Error String::padEnd(size_t n, char c) noexcept {
return n > size ? appendChars(c, n - size) : kErrorOk;
}
-Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) noexcept {
+Error String::_opNumber(ModifyOp op, uint64_t i, uint32_t base, size_t width, StringFormatFlags flags) noexcept {
if (base == 0)
base = 10;
@@ -265,24 +250,22 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
uint64_t orig = i;
char sign = '\0';
- // --------------------------------------------------------------------------
- // [Sign]
- // --------------------------------------------------------------------------
+ // Format Sign
+ // -----------
- if ((flags & kFormatSigned) != 0 && int64_t(i) < 0) {
+ if (Support::test(flags, StringFormatFlags::kSigned) && int64_t(i) < 0) {
i = uint64_t(-int64_t(i));
sign = '-';
}
- else if ((flags & kFormatShowSign) != 0) {
+ else if (Support::test(flags, StringFormatFlags::kShowSign)) {
sign = '+';
}
- else if ((flags & kFormatShowSpace) != 0) {
+ else if (Support::test(flags, StringFormatFlags::kShowSpace)) {
sign = ' ';
}
- // --------------------------------------------------------------------------
- // [Number]
- // --------------------------------------------------------------------------
+ // Format Number
+ // -------------
switch (base) {
case 2:
@@ -320,11 +303,10 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
size_t numberSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
- // --------------------------------------------------------------------------
- // [Alternate Form]
- // --------------------------------------------------------------------------
+ // Alternate Form
+ // --------------
- if ((flags & kFormatAlternate) != 0) {
+ if (Support::test(flags, StringFormatFlags::kAlternate)) {
if (base == 8) {
if (orig != 0)
*--p = '0';
@@ -335,9 +317,8 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
}
}
- // --------------------------------------------------------------------------
- // [Width]
- // --------------------------------------------------------------------------
+ // String Width
+ // ------------
if (sign != 0)
*--p = sign;
@@ -350,9 +331,8 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
else
width -= numberSize;
- // --------------------------------------------------------------------------
- // Write]
- // --------------------------------------------------------------------------
+ // Finalize
+ // --------
size_t prefixSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberSize;
char* data = prepare(op, prefixSize + width + numberSize);
@@ -370,7 +350,7 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
return kErrorOk;
}
-Error String::_opHex(uint32_t op, const void* data, size_t size, char separator) noexcept {
+Error String::_opHex(ModifyOp op, const void* data, size_t size, char separator) noexcept {
char* dst;
const uint8_t* src = static_cast<const uint8_t*>(data);
@@ -414,7 +394,7 @@ Error String::_opHex(uint32_t op, const void* data, size_t size, char separator)
return kErrorOk;
}
-Error String::_opFormat(uint32_t op, const char* fmt, ...) noexcept {
+Error String::_opFormat(ModifyOp op, const char* fmt, ...) noexcept {
Error err;
va_list ap;
@@ -425,8 +405,8 @@ Error String::_opFormat(uint32_t op, const char* fmt, ...) noexcept {
return err;
}
-Error String::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept {
- size_t startAt = (op == kOpAssign) ? size_t(0) : size();
+Error String::_opVFormat(ModifyOp op, const char* fmt, va_list ap) noexcept {
+ size_t startAt = (op == ModifyOp::kAssign) ? size_t(0) : size();
size_t remainingCapacity = capacity() - startAt;
char buf[1024];
@@ -504,9 +484,8 @@ bool String::eq(const char* other, size_t size) const noexcept {
}
}
-// ============================================================================
-// [asmjit::Support - Unit]
-// ============================================================================
+// String - Tests
+// ==============
#if defined(ASMJIT_TEST)
UNIT(core_string) {
@@ -566,7 +545,7 @@ UNIT(core_string) {
EXPECT(s.appendUInt(1234) == kErrorOk);
EXPECT(s.eq("1234") == true);
- EXPECT(s.assignUInt(0xFFFF, 16, 0, String::kFormatAlternate) == kErrorOk);
+ EXPECT(s.assignUInt(0xFFFF, 16, 0, StringFormatFlags::kAlternate) == kErrorOk);
EXPECT(s.eq("0xFFFF"));
StringTmp<64> sTmp;
diff --git a/src/asmjit/core/string.h b/src/asmjit/core/string.h
index b58725e..d309b82 100644
--- a/src/asmjit/core/string.h
+++ b/src/asmjit/core/string.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_STRING_H_INCLUDED
#define ASMJIT_CORE_STRING_H_INCLUDED
@@ -32,20 +14,41 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_utilities
//! \{
-// ============================================================================
-// [asmjit::FixedString]
-// ============================================================================
+//! Format flags used by \ref String API.
+enum class StringFormatFlags : uint32_t {
+ //! No flags.
+ kNone = 0x00000000u,
+ //! Show sign.
+ kShowSign = 0x00000001u,
+ //! Show space.
+ kShowSpace = 0x00000002u,
+ //! Alternate form (use 0x when formatting HEX number).
+ kAlternate = 0x00000004u,
+ //! The input is signed.
+ kSigned = 0x80000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(StringFormatFlags)
-//! A fixed string - only useful for strings that would never exceed `N - 1`
-//! characters; always null-terminated.
+//! Fixed string - only useful for strings that would never exceed `N - 1` characters; always null-terminated.
template<size_t N>
union FixedString {
+ //! \name Constants
+ //! \{
+
+ // This cannot be constexpr as GCC 4.8 refuses constexpr members of unions.
enum : uint32_t {
- kNumU32 = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t))
+ kNumUInt32Words = uint32_t((N + sizeof(uint32_t) - 1) / sizeof(uint32_t))
};
- char str[kNumU32 * sizeof(uint32_t)];
- uint32_t u32[kNumU32];
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ char str[kNumUInt32Words * sizeof(uint32_t)];
+ uint32_t u32[kNumUInt32Words];
+
+ //! \}
//! \name Utilities
//! \{
@@ -56,46 +59,31 @@ union FixedString {
//! \}
};
-// ============================================================================
-// [asmjit::String]
-// ============================================================================
//! A simple non-reference counted string that uses small string optimization (SSO).
//!
//! This string has 3 allocation possibilities:
//!
-//! 1. Small - embedded buffer is used for up to `kSSOCapacity` characters.
-//! This should handle most small strings and thus avoid dynamic
-//! memory allocation for most use-cases.
+//! 1. Small - embedded buffer is used for up to `kSSOCapacity` characters. This should handle most small
+//! strings and thus avoid dynamic memory allocation for most use-cases.
//!
-//! 2. Large - string that doesn't fit into an embedded buffer (or string
-//! that was truncated from a larger buffer) and is owned by
-//! AsmJit. When you destroy the string AsmJit would automatically
+//! 2. Large - string that doesn't fit into an embedded buffer (or string that was truncated from a larger
+//! buffer) and is owned by AsmJit. When you destroy the string AsmJit would automatically
//! release the large buffer.
//!
-//! 3. External - like Large (2), however, the large buffer is not owned by
-//! AsmJit and won't be released when the string is destroyed
-//! or reallocated. This is mostly useful for working with
-//! larger temporary strings allocated on stack or with immutable
-//! strings.
+//! 3. External - like Large (2), however, the large buffer is not owned by AsmJit and won't be released when
+//! the string is destroyed or reallocated. This is mostly useful for working with larger temporary
+//! strings allocated on stack or with immutable strings.
class String {
public:
ASMJIT_NONCOPYABLE(String)
//! String operation.
- enum Op : uint32_t {
+ enum class ModifyOp : uint32_t {
//! Assignment - a new content replaces the current one.
- kOpAssign = 0,
+ kAssign = 0,
//! Append - a new content is appended to the string.
- kOpAppend = 1
- };
-
- //! String format flags.
- enum FormatFlags : uint32_t {
- kFormatShowSign = 0x00000001u,
- kFormatShowSpace = 0x00000002u,
- kFormatAlternate = 0x00000004u,
- kFormatSigned = 0x80000000u
+ kAppend = 1
};
//! \cond INTERNAL
@@ -106,8 +94,10 @@ public:
//! String type.
enum Type : uint8_t {
- kTypeLarge = 0x1Fu, //!< Large string (owned by String).
- kTypeExternal = 0x20u //!< External string (zone allocated or not owned by String).
+ //! Large string (owned by String).
+ kTypeLarge = 0x1Fu,
+ //! External string (zone allocated or not owned by String).
+ kTypeExternal = 0x20u
};
union Raw {
@@ -213,15 +203,15 @@ public:
//! Clears the content of the string.
ASMJIT_API Error clear() noexcept;
- ASMJIT_API char* prepare(uint32_t op, size_t size) noexcept;
+ ASMJIT_API char* prepare(ModifyOp op, size_t size) noexcept;
- ASMJIT_API Error _opString(uint32_t op, const char* str, size_t size = SIZE_MAX) noexcept;
- ASMJIT_API Error _opChar(uint32_t op, char c) noexcept;
- ASMJIT_API Error _opChars(uint32_t op, char c, size_t n) noexcept;
- ASMJIT_API Error _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept;
- ASMJIT_API Error _opHex(uint32_t op, const void* data, size_t size, char separator = '\0') noexcept;
- ASMJIT_API Error _opFormat(uint32_t op, const char* fmt, ...) noexcept;
- ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept;
+ ASMJIT_API Error _opString(ModifyOp op, const char* str, size_t size = SIZE_MAX) noexcept;
+ ASMJIT_API Error _opChar(ModifyOp op, char c) noexcept;
+ ASMJIT_API Error _opChars(ModifyOp op, char c, size_t n) noexcept;
+ ASMJIT_API Error _opNumber(ModifyOp op, uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept;
+ ASMJIT_API Error _opHex(ModifyOp op, const void* data, size_t size, char separator = '\0') noexcept;
+ ASMJIT_API Error _opFormat(ModifyOp op, const char* fmt, ...) noexcept;
+ ASMJIT_API Error _opVFormat(ModifyOp op, const char* fmt, va_list ap) noexcept;
//! Replaces the current of the string with `data` of the given `size`.
//!
@@ -235,45 +225,45 @@ public:
//! Replaces the current of the string by a single `c` character.
inline Error assign(char c) noexcept {
- return _opChar(kOpAssign, c);
+ return _opChar(ModifyOp::kAssign, c);
}
//! Replaces the current of the string by a `c` character, repeated `n` times.
inline Error assignChars(char c, size_t n) noexcept {
- return _opChars(kOpAssign, c, n);
+ return _opChars(ModifyOp::kAssign, c, n);
}
//! Replaces the current of the string by a formatted integer `i` (signed).
- inline Error assignInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
- return _opNumber(kOpAssign, uint64_t(i), base, width, flags | kFormatSigned);
+ inline Error assignInt(int64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ return _opNumber(ModifyOp::kAssign, uint64_t(i), base, width, flags | StringFormatFlags::kSigned);
}
//! Replaces the current of the string by a formatted integer `i` (unsigned).
- inline Error assignUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
- return _opNumber(kOpAssign, i, base, width, flags);
+ inline Error assignUInt(uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ return _opNumber(ModifyOp::kAssign, i, base, width, flags);
}
//! Replaces the current of the string by the given `data` converted to a HEX string.
inline Error assignHex(const void* data, size_t size, char separator = '\0') noexcept {
- return _opHex(kOpAssign, data, size, separator);
+ return _opHex(ModifyOp::kAssign, data, size, separator);
}
//! Replaces the current of the string by a formatted string `fmt`.
template<typename... Args>
inline Error assignFormat(const char* fmt, Args&&... args) noexcept {
- return _opFormat(kOpAssign, fmt, std::forward<Args>(args)...);
+ return _opFormat(ModifyOp::kAssign, fmt, std::forward<Args>(args)...);
}
//! Replaces the current of the string by a formatted string `fmt` (va_list version).
inline Error assignVFormat(const char* fmt, va_list ap) noexcept {
- return _opVFormat(kOpAssign, fmt, ap);
+ return _opVFormat(ModifyOp::kAssign, fmt, ap);
}
//! Appends `str` having the given size `size` to the string.
//!
//! Null terminated strings can set `size` to `SIZE_MAX`.
inline Error append(const char* str, size_t size = SIZE_MAX) noexcept {
- return _opString(kOpAppend, str, size);
+ return _opString(ModifyOp::kAppend, str, size);
}
//! Appends `other` string to this string.
@@ -283,38 +273,38 @@ public:
//! Appends a single `c` character.
inline Error append(char c) noexcept {
- return _opChar(kOpAppend, c);
+ return _opChar(ModifyOp::kAppend, c);
}
//! Appends `c` character repeated `n` times.
inline Error appendChars(char c, size_t n) noexcept {
- return _opChars(kOpAppend, c, n);
+ return _opChars(ModifyOp::kAppend, c, n);
}
//! Appends a formatted integer `i` (signed).
- inline Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
- return _opNumber(kOpAppend, uint64_t(i), base, width, flags | kFormatSigned);
+ inline Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ return _opNumber(ModifyOp::kAppend, uint64_t(i), base, width, flags | StringFormatFlags::kSigned);
}
//! Appends a formatted integer `i` (unsigned).
- inline Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
- return _opNumber(kOpAppend, i, base, width, flags);
+ inline Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, StringFormatFlags flags = StringFormatFlags::kNone) noexcept {
+ return _opNumber(ModifyOp::kAppend, i, base, width, flags);
}
//! Appends the given `data` converted to a HEX string.
inline Error appendHex(const void* data, size_t size, char separator = '\0') noexcept {
- return _opHex(kOpAppend, data, size, separator);
+ return _opHex(ModifyOp::kAppend, data, size, separator);
}
//! Appends a formatted string `fmt` with `args`.
template<typename... Args>
inline Error appendFormat(const char* fmt, Args&&... args) noexcept {
- return _opFormat(kOpAppend, fmt, std::forward<Args>(args)...);
+ return _opFormat(ModifyOp::kAppend, fmt, std::forward<Args>(args)...);
}
//! Appends a formatted string `fmt` (va_list version).
inline Error appendVFormat(const char* fmt, va_list ap) noexcept {
- return _opVFormat(kOpAppend, fmt, ap);
+ return _opVFormat(ModifyOp::kAppend, fmt, ap);
}
ASMJIT_API Error padEnd(size_t n, char c = ' ') noexcept;
@@ -332,8 +322,8 @@ public:
//! Resets string to embedded and makes it empty (zero length, zero first char)
//!
- //! \note This is always called internally after an external buffer was released
- //! as it zeroes all bytes used by String's embedded storage.
+ //! \note This is always called internally after an external buffer was released as it zeroes all bytes
+ //! used by String's embedded storage.
inline void _resetInternal() noexcept {
for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_raw.uptr); i++)
_raw.uptr[i] = 0;
@@ -347,26 +337,8 @@ public:
}
//! \}
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use assign() instead of assignString()")
- inline Error assignString(const char* data, size_t size = SIZE_MAX) noexcept { return assign(data, size); }
-
- ASMJIT_DEPRECATED("Use assign() instead of assignChar()")
- inline Error assignChar(char c) noexcept { return assign(c); }
-
- ASMJIT_DEPRECATED("Use append() instead of appendString()")
- inline Error appendString(const char* data, size_t size = SIZE_MAX) noexcept { return append(data, size); }
-
- ASMJIT_DEPRECATED("Use append() instead of appendChar()")
- inline Error appendChar(char c) noexcept { return append(c); }
-#endif // !ASMJIT_NO_DEPRECATED
};
-// ============================================================================
-// [asmjit::StringTmp]
-// ============================================================================
-
//! Temporary string builder, has statically allocated `N` bytes.
template<size_t N>
class StringTmp : public String {
diff --git a/src/asmjit/core/support.cpp b/src/asmjit/core/support.cpp
index a99477d..34253fd 100644
--- a/src/asmjit/core/support.cpp
+++ b/src/asmjit/core/support.cpp
@@ -1,34 +1,15 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Support - Unit]
-// ============================================================================
+// Support - Tests
+// ===============
#if defined(ASMJIT_TEST)
template<typename T>
@@ -85,10 +66,14 @@ static void testBitUtils() noexcept {
for (i = 0; i < 63; i++) EXPECT(Support::blsi(uint64_t(3) << i) == uint64_t(1) << i);
INFO("Support::ctz()");
+ for (i = 0; i < 32; i++) EXPECT(Support::Internal::clzFallback(uint32_t(1) << i) == 31 - i);
+ for (i = 0; i < 64; i++) EXPECT(Support::Internal::clzFallback(uint64_t(1) << i) == 63 - i);
+ for (i = 0; i < 32; i++) EXPECT(Support::Internal::ctzFallback(uint32_t(1) << i) == i);
+ for (i = 0; i < 64; i++) EXPECT(Support::Internal::ctzFallback(uint64_t(1) << i) == i);
+ for (i = 0; i < 32; i++) EXPECT(Support::clz(uint32_t(1) << i) == 31 - i);
+ for (i = 0; i < 64; i++) EXPECT(Support::clz(uint64_t(1) << i) == 63 - i);
for (i = 0; i < 32; i++) EXPECT(Support::ctz(uint32_t(1) << i) == i);
for (i = 0; i < 64; i++) EXPECT(Support::ctz(uint64_t(1) << i) == i);
- for (i = 0; i < 32; i++) EXPECT(Support::constCtz(uint32_t(1) << i) == i);
- for (i = 0; i < 64; i++) EXPECT(Support::constCtz(uint64_t(1) << i) == i);
INFO("Support::bitMask()");
EXPECT(Support::bitMask(0, 1, 7) == 0x83u);
diff --git a/src/asmjit/core/support.h b/src/asmjit/core/support.h
index f98ffaa..ebf0354 100644
--- a/src/asmjit/core/support.h
+++ b/src/asmjit/core/support.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_SUPPORT_H_INCLUDED
#define ASMJIT_CORE_SUPPORT_H_INCLUDED
@@ -40,9 +22,8 @@ ASMJIT_BEGIN_NAMESPACE
//! not be used outside of AsmJit and related projects like AsmTK.
namespace Support {
-// ============================================================================
-// [asmjit::Support - Architecture Features & Constraints]
-// ============================================================================
+// Support - Architecture Features & Constraints
+// =============================================
//! \cond INTERNAL
static constexpr bool kUnalignedAccess16 = ASMJIT_ARCH_X86 != 0;
@@ -50,9 +31,14 @@ static constexpr bool kUnalignedAccess32 = ASMJIT_ARCH_X86 != 0;
static constexpr bool kUnalignedAccess64 = ASMJIT_ARCH_X86 != 0;
//! \endcond
-// ============================================================================
-// [asmjit::Support - Internal]
-// ============================================================================
+// Support - Basic Traits
+// ======================
+
+#if ASMJIT_ARCH_X86
+typedef uint8_t FastUInt8;
+#else
+typedef uint32_t FastUInt8;
+#endif
//! \cond INTERNAL
namespace Internal {
@@ -90,27 +76,9 @@ namespace Internal {
}
//! \endcond
-// ============================================================================
-// [asmjit::Support - Basic Traits]
-// ============================================================================
-
template<typename T>
static constexpr bool isUnsigned() noexcept { return std::is_unsigned<T>::value; }
-// ============================================================================
-// [asmjit::Support - FastUInt8]
-// ============================================================================
-
-#if ASMJIT_ARCH_X86
-typedef uint8_t FastUInt8;
-#else
-typedef unsigned int FastUInt8;
-#endif
-
-// ============================================================================
-// [asmjit::Support - asInt / asUInt / asNormalized]
-// ============================================================================
-
//! Casts an integer `x` to either `int32_t` or `int64_t` depending on `T`.
template<typename T>
static constexpr typename Internal::Int32Or64<T, 0>::Type asInt(const T& x) noexcept {
@@ -135,15 +103,33 @@ static constexpr typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type asS
return (typename Internal::StdInt<sizeof(T), isUnsigned<T>()>::Type)x;
}
-// ============================================================================
-// [asmjit::Support - BitCast]
-// ============================================================================
+//! A helper class that can be used to iterate over enum values.
+template<typename T, T from = (T)0, T to = T::kMaxValue>
+struct EnumValues {
+ typedef typename std::underlying_type<T>::type ValueType;
+
+ struct Iterator {
+ ValueType value;
+
+ inline T operator*() const { return (T)value; }
+ inline void operator++() { ++value; }
+
+ inline bool operator==(const Iterator& other) const noexcept { return value == other.value; }
+ inline bool operator!=(const Iterator& other) const noexcept { return value != other.value; }
+ };
+
+ inline Iterator begin() const noexcept { return Iterator{ValueType(from)}; }
+ inline Iterator end() const noexcept { return Iterator{ValueType(to) + 1}; }
+};
+
+// Support - BitCast
+// =================
//! \cond
namespace Internal {
template<typename DstT, typename SrcT>
union BitCastUnion {
- ASMJIT_INLINE BitCastUnion(SrcT src) noexcept : src(src) {}
+ inline BitCastUnion(SrcT src) noexcept : src(src) {}
SrcT src;
DstT dst;
};
@@ -156,9 +142,8 @@ namespace Internal {
template<typename Dst, typename Src>
static inline Dst bitCast(const Src& x) noexcept { return Internal::BitCastUnion<Dst, Src>(x).dst; }
-// ============================================================================
-// [asmjit::Support - BitOps]
-// ============================================================================
+// Support - BitOps
+// ================
//! Storage used to store a pack of bits (should by compatible with a machine word).
typedef Internal::StdInt<sizeof(uintptr_t), 1>::Type BitWord;
@@ -226,16 +211,16 @@ static constexpr T lsbMask(const CountT& n) noexcept {
template<typename T, typename IndexT>
static constexpr bool bitTest(T x, IndexT n) noexcept {
typedef typename std::make_unsigned<T>::type U;
- return (U(x) & (U(1) << n)) != 0;
+ return (U(x) & (U(1) << asUInt(n))) != 0;
}
//! Returns a bit-mask that has `x` bit set.
-template<typename T>
-static constexpr uint32_t bitMask(T x) noexcept { return (1u << x); }
+template<typename Index>
+static constexpr uint32_t bitMask(const Index& x) noexcept { return (1u << asUInt(x)); }
//! Returns a bit-mask that has `x` bit set (multiple arguments).
-template<typename T, typename... Args>
-static constexpr uint32_t bitMask(T x, Args... args) noexcept { return bitMask(x) | bitMask(args...); }
+template<typename Index, typename... Args>
+static constexpr uint32_t bitMask(const Index& x, Args... args) noexcept { return bitMask(x) | bitMask(args...); }
//! Converts a boolean value `b` to zero or full mask (all bits set).
template<typename DstT, typename SrcT>
@@ -244,6 +229,10 @@ static constexpr DstT bitMaskFromBool(SrcT b) noexcept {
return DstT(U(0) - U(b));
}
+//! Tests whether `a & b` is non-zero.
+template<typename A, typename B>
+static inline constexpr bool test(A a, B b) noexcept { return (asUInt(a) & asUInt(b)) != 0; }
+
//! \cond
namespace Internal {
// Fills all trailing bits right from the first most significant bit set.
@@ -264,9 +253,8 @@ static constexpr T fillTrailingBits(const T& x) noexcept {
return T(Internal::fillTrailingBitsImpl(U(x)));
}
-// ============================================================================
-// [asmjit::Support - CTZ]
-// ============================================================================
+// Support - Count Leading/Trailing Zeros
+// ======================================
//! \cond
namespace Internal {
@@ -315,11 +303,8 @@ constexpr uint32_t ctzFallback(const T& x) noexcept {
return BitScanCalc<T, bitSizeOf<T>() / 2u>::ctz(BitScanData<T>{x, 1}).n;
}
-template<typename T> constexpr uint32_t constClz(const T& x) noexcept { return clzFallback(asUInt(x)); }
-template<typename T> constexpr uint32_t constCtz(const T& x) noexcept { return ctzFallback(asUInt(x)); }
-
-template<typename T> inline uint32_t clzImpl(const T& x) noexcept { return constClz(x); }
-template<typename T> inline uint32_t ctzImpl(const T& x) noexcept { return constCtz(x); }
+template<typename T> inline uint32_t clzImpl(const T& x) noexcept { return clzFallback(asUInt(x)); }
+template<typename T> inline uint32_t ctzImpl(const T& x) noexcept { return ctzFallback(asUInt(x)); }
#if !defined(ASMJIT_NO_INTRINSICS)
# if defined(__GNUC__)
@@ -347,23 +332,83 @@ template<> inline uint32_t ctzImpl(const uint64_t& x) noexcept { unsigned long i
template<typename T>
static inline uint32_t clz(T x) noexcept { return Internal::clzImpl(asUInt(x)); }
-//! Count leading zeros in `x` (constant expression).
-template<typename T>
-static constexpr inline uint32_t constClz(T x) noexcept { return Internal::constClz(asUInt(x)); }
-
//! Count trailing zeros in `x` (returns a position of a first bit set in `x`).
//!
//! \note The input MUST NOT be zero, otherwise the result is undefined.
template<typename T>
static inline uint32_t ctz(T x) noexcept { return Internal::ctzImpl(asUInt(x)); }
-//! Count trailing zeros in `x` (constant expression).
-template<typename T>
-static constexpr inline uint32_t constCtz(T x) noexcept { return Internal::constCtz(asUInt(x)); }
+template<uint64_t kInput>
+struct ConstCTZ {
+ static constexpr uint32_t value =
+ (kInput & (uint64_t(1) << 0)) ? 0 :
+ (kInput & (uint64_t(1) << 1)) ? 1 :
+ (kInput & (uint64_t(1) << 2)) ? 2 :
+ (kInput & (uint64_t(1) << 3)) ? 3 :
+ (kInput & (uint64_t(1) << 4)) ? 4 :
+ (kInput & (uint64_t(1) << 5)) ? 5 :
+ (kInput & (uint64_t(1) << 6)) ? 6 :
+ (kInput & (uint64_t(1) << 7)) ? 7 :
+ (kInput & (uint64_t(1) << 8)) ? 8 :
+ (kInput & (uint64_t(1) << 9)) ? 9 :
+ (kInput & (uint64_t(1) << 10)) ? 10 :
+ (kInput & (uint64_t(1) << 11)) ? 11 :
+ (kInput & (uint64_t(1) << 12)) ? 12 :
+ (kInput & (uint64_t(1) << 13)) ? 13 :
+ (kInput & (uint64_t(1) << 14)) ? 14 :
+ (kInput & (uint64_t(1) << 15)) ? 15 :
+ (kInput & (uint64_t(1) << 16)) ? 16 :
+ (kInput & (uint64_t(1) << 17)) ? 17 :
+ (kInput & (uint64_t(1) << 18)) ? 18 :
+ (kInput & (uint64_t(1) << 19)) ? 19 :
+ (kInput & (uint64_t(1) << 20)) ? 20 :
+ (kInput & (uint64_t(1) << 21)) ? 21 :
+ (kInput & (uint64_t(1) << 22)) ? 22 :
+ (kInput & (uint64_t(1) << 23)) ? 23 :
+ (kInput & (uint64_t(1) << 24)) ? 24 :
+ (kInput & (uint64_t(1) << 25)) ? 25 :
+ (kInput & (uint64_t(1) << 26)) ? 26 :
+ (kInput & (uint64_t(1) << 27)) ? 27 :
+ (kInput & (uint64_t(1) << 28)) ? 28 :
+ (kInput & (uint64_t(1) << 29)) ? 29 :
+ (kInput & (uint64_t(1) << 30)) ? 30 :
+ (kInput & (uint64_t(1) << 31)) ? 31 :
+ (kInput & (uint64_t(1) << 32)) ? 32 :
+ (kInput & (uint64_t(1) << 33)) ? 33 :
+ (kInput & (uint64_t(1) << 34)) ? 34 :
+ (kInput & (uint64_t(1) << 35)) ? 35 :
+ (kInput & (uint64_t(1) << 36)) ? 36 :
+ (kInput & (uint64_t(1) << 37)) ? 37 :
+ (kInput & (uint64_t(1) << 38)) ? 38 :
+ (kInput & (uint64_t(1) << 39)) ? 39 :
+ (kInput & (uint64_t(1) << 40)) ? 40 :
+ (kInput & (uint64_t(1) << 41)) ? 41 :
+ (kInput & (uint64_t(1) << 42)) ? 42 :
+ (kInput & (uint64_t(1) << 43)) ? 43 :
+ (kInput & (uint64_t(1) << 44)) ? 44 :
+ (kInput & (uint64_t(1) << 45)) ? 45 :
+ (kInput & (uint64_t(1) << 46)) ? 46 :
+ (kInput & (uint64_t(1) << 47)) ? 47 :
+ (kInput & (uint64_t(1) << 48)) ? 48 :
+ (kInput & (uint64_t(1) << 49)) ? 49 :
+ (kInput & (uint64_t(1) << 50)) ? 50 :
+ (kInput & (uint64_t(1) << 51)) ? 51 :
+ (kInput & (uint64_t(1) << 52)) ? 52 :
+ (kInput & (uint64_t(1) << 53)) ? 53 :
+ (kInput & (uint64_t(1) << 54)) ? 54 :
+ (kInput & (uint64_t(1) << 55)) ? 55 :
+ (kInput & (uint64_t(1) << 56)) ? 56 :
+ (kInput & (uint64_t(1) << 57)) ? 57 :
+ (kInput & (uint64_t(1) << 58)) ? 58 :
+ (kInput & (uint64_t(1) << 59)) ? 59 :
+ (kInput & (uint64_t(1) << 60)) ? 60 :
+ (kInput & (uint64_t(1) << 61)) ? 61 :
+ (kInput & (uint64_t(1) << 62)) ? 62 :
+ (kInput & (uint64_t(1) << 63)) ? 63 : 64;
+};
-// ============================================================================
-// [asmjit::Support - PopCnt]
-// ============================================================================
+// Support - PopCnt
+// ================
// Based on the following resource:
// http://graphics.stanford.edu/~seander/bithacks.html
@@ -422,9 +467,8 @@ static inline uint32_t popcnt(T x) noexcept { return Internal::popcntImpl(asUInt
template<typename T>
static inline uint32_t constPopcnt(T x) noexcept { return Internal::constPopcntImpl(asUInt(x)); }
-// ============================================================================
-// [asmjit::Support - Min/Max]
-// ============================================================================
+// Support - Min/Max
+// =================
// NOTE: These are constexpr `min()` and `max()` implementations that are not
// exactly the same as `std::min()` and `std::max()`. The return value is not
@@ -442,9 +486,8 @@ static constexpr T max(const T& a, const T& b) noexcept { return a < b ? b : a;
template<typename T, typename... Args>
static constexpr T max(const T& a, const T& b, Args&&... args) noexcept { return max(max(a, b), std::forward<Args>(args)...); }
-// ============================================================================
-// [asmjit::Support - Immediate Helpers]
-// ============================================================================
+// Support - Immediate Helpers
+// ===========================
namespace Internal {
template<typename T, bool IsFloat>
@@ -466,14 +509,13 @@ static inline int64_t immediateFromT(const T& x) noexcept { return Internal::Imm
template<typename T>
static inline T immediateToT(int64_t x) noexcept { return Internal::ImmConv<T, std::is_floating_point<T>::value>::toT(x); }
-// ============================================================================
-// [asmjit::Support - Overflow Arithmetic]
-// ============================================================================
+// Support - Overflow Arithmetic
+// =============================
//! \cond
namespace Internal {
template<typename T>
- ASMJIT_INLINE T addOverflowFallback(T x, T y, FastUInt8* of) noexcept {
+ inline T addOverflowFallback(T x, T y, FastUInt8* of) noexcept {
typedef typename std::make_unsigned<T>::type U;
U result = U(x) + U(y);
@@ -482,7 +524,7 @@ namespace Internal {
}
template<typename T>
- ASMJIT_INLINE T subOverflowFallback(T x, T y, FastUInt8* of) noexcept {
+ inline T subOverflowFallback(T x, T y, FastUInt8* of) noexcept {
typedef typename std::make_unsigned<T>::type U;
U result = U(x) - U(y);
@@ -491,7 +533,7 @@ namespace Internal {
}
template<typename T>
- ASMJIT_INLINE T mulOverflowFallback(T x, T y, FastUInt8* of) noexcept {
+ inline T mulOverflowFallback(T x, T y, FastUInt8* of) noexcept {
typedef typename Internal::StdInt<sizeof(T) * 2, isUnsigned<T>()>::Type I;
typedef typename std::make_unsigned<I>::type U;
@@ -509,32 +551,32 @@ namespace Internal {
}
template<>
- ASMJIT_INLINE int64_t mulOverflowFallback(int64_t x, int64_t y, FastUInt8* of) noexcept {
+ inline int64_t mulOverflowFallback(int64_t x, int64_t y, FastUInt8* of) noexcept {
int64_t result = int64_t(uint64_t(x) * uint64_t(y));
*of = FastUInt8(*of | FastUInt8(x && (result / x != y)));
return result;
}
template<>
- ASMJIT_INLINE uint64_t mulOverflowFallback(uint64_t x, uint64_t y, FastUInt8* of) noexcept {
+ inline uint64_t mulOverflowFallback(uint64_t x, uint64_t y, FastUInt8* of) noexcept {
uint64_t result = x * y;
*of = FastUInt8(*of | FastUInt8(y != 0 && allOnes<uint64_t>() / y < x));
return result;
}
// These can be specialized.
- template<typename T> ASMJIT_INLINE T addOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return addOverflowFallback(x, y, of); }
- template<typename T> ASMJIT_INLINE T subOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return subOverflowFallback(x, y, of); }
- template<typename T> ASMJIT_INLINE T mulOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return mulOverflowFallback(x, y, of); }
+ template<typename T> inline T addOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return addOverflowFallback(x, y, of); }
+ template<typename T> inline T subOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return subOverflowFallback(x, y, of); }
+ template<typename T> inline T mulOverflowImpl(const T& x, const T& y, FastUInt8* of) noexcept { return mulOverflowFallback(x, y, of); }
#if defined(__GNUC__) && !defined(ASMJIT_NO_INTRINSICS)
#if defined(__clang__) || __GNUC__ >= 5
- #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, RESULT_T, BUILTIN) \
- template<> \
- ASMJIT_INLINE T FUNC(const T& x, const T& y, FastUInt8* of) noexcept { \
- RESULT_T result; \
- *of = FastUInt8(*of | (BUILTIN((RESULT_T)x, (RESULT_T)y, &result))); \
- return T(result); \
+ #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, RESULT_T, BUILTIN) \
+ template<> \
+ inline T FUNC(const T& x, const T& y, FastUInt8* of) noexcept { \
+ RESULT_T result; \
+ *of = FastUInt8(*of | (BUILTIN((RESULT_T)x, (RESULT_T)y, &result))); \
+ return T(result); \
}
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, int32_t , int , __builtin_sadd_overflow )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , __builtin_uadd_overflow )
@@ -554,12 +596,12 @@ namespace Internal {
// There is a bug in MSVC that makes these specializations unusable, maybe in the future...
#if defined(_MSC_VER) && 0
- #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
- template<> \
- ASMJIT_INLINE T FUNC(T x, T y, FastUInt8* of) noexcept { \
- ALT_T result; \
- *of = FastUInt8(*of | BUILTIN(0, (ALT_T)x, (ALT_T)y, &result)); \
- return T(result); \
+ #define ASMJIT_ARITH_OVERFLOW_SPECIALIZE(FUNC, T, ALT_T, BUILTIN) \
+ template<> \
+ inline T FUNC(T x, T y, FastUInt8* of) noexcept { \
+ ALT_T result; \
+ *of = FastUInt8(*of | BUILTIN(0, (ALT_T)x, (ALT_T)y, &result)); \
+ return T(result); \
}
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(addOverflowImpl, uint32_t, unsigned int , _addcarry_u32 )
ASMJIT_ARITH_OVERFLOW_SPECIALIZE(subOverflowImpl, uint32_t, unsigned int , _subborrow_u32)
@@ -573,17 +615,16 @@ namespace Internal {
//! \endcond
template<typename T>
-static ASMJIT_INLINE T addOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::addOverflowImpl(asStdInt(x), asStdInt(y), of)); }
+static inline T addOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::addOverflowImpl(asStdInt(x), asStdInt(y), of)); }
template<typename T>
-static ASMJIT_INLINE T subOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::subOverflowImpl(asStdInt(x), asStdInt(y), of)); }
+static inline T subOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::subOverflowImpl(asStdInt(x), asStdInt(y), of)); }
template<typename T>
-static ASMJIT_INLINE T mulOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::mulOverflowImpl(asStdInt(x), asStdInt(y), of)); }
+static inline T mulOverflow(const T& x, const T& y, FastUInt8* of) noexcept { return T(Internal::mulOverflowImpl(asStdInt(x), asStdInt(y), of)); }
-// ============================================================================
-// [asmjit::Support - Alignment]
-// ============================================================================
+// Support - Alignment
+// ===================
template<typename X, typename Y>
static constexpr bool isAligned(X base, Y alignment) noexcept {
@@ -624,9 +665,8 @@ static constexpr X alignDown(X x, Y alignment) noexcept {
return (X)( (U)x & ~((U)(alignment) - 1u) );
}
-// ============================================================================
-// [asmjit::Support - NumGranularized]
-// ============================================================================
+// Support - NumGranularized
+// =========================
//! Calculates the number of elements that would be required if `base` is
//! granularized by `granularity`. This function can be used to calculate
@@ -637,9 +677,8 @@ static constexpr X numGranularized(X base, Y granularity) noexcept {
return X((U(base) + U(granularity) - 1) / U(granularity));
}
-// ============================================================================
-// [asmjit::Support - IsBetween]
-// ============================================================================
+// Support - IsBetween
+// ===================
//! Checks whether `x` is greater than or equal to `a` and lesser than or equal to `b`.
template<typename T>
@@ -647,9 +686,8 @@ static constexpr bool isBetween(const T& x, const T& a, const T& b) noexcept {
return x >= a && x <= b;
}
-// ============================================================================
-// [asmjit::Support - IsInt / IsUInt]
-// ============================================================================
+// Support - IsInt & IsUInt
+// ========================
//! Checks whether the given integer `x` can be casted to a 4-bit signed integer.
template<typename T>
@@ -779,17 +817,15 @@ static bool inline isEncodableOffset64(int64_t offset, uint32_t nBits) noexcept
return Support::sar(Support::shl(offset, nRev), nRev) == offset;
}
-// ============================================================================
-// [asmjit::Support - ByteSwap]
-// ============================================================================
+// Support - ByteSwap
+// ==================
static constexpr uint32_t byteswap32(uint32_t x) noexcept {
return (x << 24) | (x >> 24) | ((x << 8) & 0x00FF0000u) | ((x >> 8) & 0x0000FF00);
}
-// ============================================================================
-// [asmjit::Support - BytePack / Unpack]
-// ============================================================================
+// Support - BytePack & Unpack
+// ===========================
//! Pack four 8-bit integer into a 32-bit integer as it is an array of `{b0,b1,b2,b3}`.
static constexpr uint32_t bytepack32_4x8(uint32_t a, uint32_t b, uint32_t c, uint32_t d) noexcept {
@@ -802,17 +838,15 @@ static constexpr uint32_t unpackU32At0(T x) noexcept { return ASMJIT_ARCH_LE ? u
template<typename T>
static constexpr uint32_t unpackU32At1(T x) noexcept { return ASMJIT_ARCH_BE ? uint32_t(uint64_t(x) & 0xFFFFFFFFu) : uint32_t(uint64_t(x) >> 32); }
-// ============================================================================
-// [asmjit::Support - Position of byte (in bit-shift)]
-// ============================================================================
+// Support - Position of byte (in bit-shift)
+// =========================================
static inline uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
return ASMJIT_ARCH_LE ? index * 8 : (uint32_t(sizeof(uint32_t)) - 1u - index) * 8;
}
-// ============================================================================
-// [asmjit::Support - String Utilities]
-// ============================================================================
+// Support - String Utilities
+// ==========================
template<typename T>
static constexpr T asciiToLower(T c) noexcept { return T(c ^ T(T(c >= T('A') && c <= T('Z')) << 5)); }
@@ -820,7 +854,7 @@ static constexpr T asciiToLower(T c) noexcept { return T(c ^ T(T(c >= T('A') &&
template<typename T>
static constexpr T asciiToUpper(T c) noexcept { return T(c ^ T(T(c >= T('a') && c <= T('z')) << 5)); }
-static ASMJIT_INLINE size_t strLen(const char* s, size_t maxSize) noexcept {
+static ASMJIT_FORCE_INLINE size_t strLen(const char* s, size_t maxSize) noexcept {
size_t i = 0;
while (i < maxSize && s[i] != '\0')
i++;
@@ -839,7 +873,7 @@ static inline uint32_t hashString(const char* data, size_t size) noexcept {
return hashCode;
}
-static ASMJIT_INLINE const char* findPackedString(const char* p, uint32_t id) noexcept {
+static ASMJIT_FORCE_INLINE const char* findPackedString(const char* p, uint32_t id) noexcept {
uint32_t i = 0;
while (i < id) {
while (p[0])
@@ -855,7 +889,7 @@ static ASMJIT_INLINE const char* findPackedString(const char* p, uint32_t id) no
//! `a` is a null terminated instruction name from arch-specific `nameData[]`
//! table. `b` is a possibly non-null terminated instruction name passed to
//! `InstAPI::stringToInstId()`.
-static ASMJIT_INLINE int cmpInstName(const char* a, const char* b, size_t size) noexcept {
+static ASMJIT_FORCE_INLINE int cmpInstName(const char* a, const char* b, size_t size) noexcept {
for (size_t i = 0; i < size; i++) {
int c = int(uint8_t(a[i])) - int(uint8_t(b[i]));
if (c != 0) return c;
@@ -863,14 +897,13 @@ static ASMJIT_INLINE int cmpInstName(const char* a, const char* b, size_t size)
return int(uint8_t(a[size]));
}
-// ============================================================================
-// [asmjit::Support - Read / Write]
-// ============================================================================
+// Support - Memory Read & Write
+// =============================
static inline uint32_t readU8(const void* p) noexcept { return uint32_t(static_cast<const uint8_t*>(p)[0]); }
static inline int32_t readI8(const void* p) noexcept { return int32_t(static_cast<const int8_t*>(p)[0]); }
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline uint32_t readU16x(const void* p) noexcept {
if (BO == ByteOrder::kNative && (kUnalignedAccess16 || Alignment >= 2)) {
typedef typename Internal::AlignedInt<uint16_t, Alignment>::T U16AlignedToN;
@@ -883,7 +916,7 @@ static inline uint32_t readU16x(const void* p) noexcept {
}
}
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline int32_t readI16x(const void* p) noexcept {
if (BO == ByteOrder::kNative && (kUnalignedAccess16 || Alignment >= 2)) {
typedef typename Internal::AlignedInt<uint16_t, Alignment>::T U16AlignedToN;
@@ -896,7 +929,7 @@ static inline int32_t readI16x(const void* p) noexcept {
}
}
-template<uint32_t BO = ByteOrder::kNative>
+template<ByteOrder BO = ByteOrder::kNative>
static inline uint32_t readU24u(const void* p) noexcept {
uint32_t b0 = readU8(static_cast<const uint8_t*>(p) + (BO == ByteOrder::kLE ? 2 : 0));
uint32_t b1 = readU8(static_cast<const uint8_t*>(p) + (BO == ByteOrder::kLE ? 1 : 1));
@@ -904,7 +937,7 @@ static inline uint32_t readU24u(const void* p) noexcept {
return shl(b0, 16) | shl(b1, 8) | b2;
}
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline uint32_t readU32x(const void* p) noexcept {
if (kUnalignedAccess32 || Alignment >= 4) {
typedef typename Internal::AlignedInt<uint32_t, Alignment>::T U32AlignedToN;
@@ -918,7 +951,7 @@ static inline uint32_t readU32x(const void* p) noexcept {
}
}
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline uint64_t readU64x(const void* p) noexcept {
if (BO == ByteOrder::kNative && (kUnalignedAccess64 || Alignment >= 8)) {
typedef typename Internal::AlignedInt<uint64_t, Alignment>::T U64AlignedToN;
@@ -931,10 +964,10 @@ static inline uint64_t readU64x(const void* p) noexcept {
}
}
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline int32_t readI32x(const void* p) noexcept { return int32_t(readU32x<BO, Alignment>(p)); }
-template<uint32_t BO, size_t Alignment>
+template<ByteOrder BO, size_t Alignment>
static inline int64_t readI64x(const void* p) noexcept { return int64_t(readU64x<BO, Alignment>(p)); }
template<size_t Alignment> static inline int32_t readI16xLE(const void* p) noexcept { return readI16x<ByteOrder::kLE, Alignment>(p); }
@@ -1001,7 +1034,7 @@ static inline uint64_t readU64uBE(const void* p) noexcept { return readU64xBE<1>
static inline void writeU8(void* p, uint32_t x) noexcept { static_cast<uint8_t*>(p)[0] = uint8_t(x & 0xFFu); }
static inline void writeI8(void* p, int32_t x) noexcept { static_cast<uint8_t*>(p)[0] = uint8_t(x & 0xFF); }
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1>
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
static inline void writeU16x(void* p, uint32_t x) noexcept {
if (BO == ByteOrder::kNative && (kUnalignedAccess16 || Alignment >= 2)) {
typedef typename Internal::AlignedInt<uint16_t, Alignment>::T U16AlignedToN;
@@ -1013,14 +1046,14 @@ static inline void writeU16x(void* p, uint32_t x) noexcept {
}
}
-template<uint32_t BO = ByteOrder::kNative>
+template<ByteOrder BO = ByteOrder::kNative>
static inline void writeU24u(void* p, uint32_t v) noexcept {
static_cast<uint8_t*>(p)[0] = uint8_t((v >> (BO == ByteOrder::kLE ? 0 : 16)) & 0xFFu);
static_cast<uint8_t*>(p)[1] = uint8_t((v >> (BO == ByteOrder::kLE ? 8 : 8)) & 0xFFu);
static_cast<uint8_t*>(p)[2] = uint8_t((v >> (BO == ByteOrder::kLE ? 16 : 0)) & 0xFFu);
}
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1>
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
static inline void writeU32x(void* p, uint32_t x) noexcept {
if (kUnalignedAccess32 || Alignment >= 4) {
typedef typename Internal::AlignedInt<uint32_t, Alignment>::T U32AlignedToN;
@@ -1032,7 +1065,7 @@ static inline void writeU32x(void* p, uint32_t x) noexcept {
}
}
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1>
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1>
static inline void writeU64x(void* p, uint64_t x) noexcept {
if (BO == ByteOrder::kNative && (kUnalignedAccess64 || Alignment >= 8)) {
typedef typename Internal::AlignedInt<uint64_t, Alignment>::T U64AlignedToN;
@@ -1044,9 +1077,9 @@ static inline void writeU64x(void* p, uint64_t x) noexcept {
}
}
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI16x(void* p, int32_t x) noexcept { writeU16x<BO, Alignment>(p, uint32_t(x)); }
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI32x(void* p, int32_t x) noexcept { writeU32x<BO, Alignment>(p, uint32_t(x)); }
-template<uint32_t BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI64x(void* p, int64_t x) noexcept { writeU64x<BO, Alignment>(p, uint64_t(x)); }
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI16x(void* p, int32_t x) noexcept { writeU16x<BO, Alignment>(p, uint32_t(x)); }
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI32x(void* p, int32_t x) noexcept { writeU32x<BO, Alignment>(p, uint32_t(x)); }
+template<ByteOrder BO = ByteOrder::kNative, size_t Alignment = 1> static inline void writeI64x(void* p, int64_t x) noexcept { writeU64x<BO, Alignment>(p, uint64_t(x)); }
template<size_t Alignment = 1> static inline void writeI16xLE(void* p, int32_t x) noexcept { writeI16x<ByteOrder::kLE, Alignment>(p, x); }
template<size_t Alignment = 1> static inline void writeI16xBE(void* p, int32_t x) noexcept { writeI16x<ByteOrder::kBE, Alignment>(p, x); }
@@ -1111,9 +1144,8 @@ static inline void writeI64uBE(void* p, int64_t x) noexcept { writeI64xBE<1>(p,
static inline void writeU64aBE(void* p, uint64_t x) noexcept { writeU64xBE<8>(p, x); }
static inline void writeU64uBE(void* p, uint64_t x) noexcept { writeU64xBE<1>(p, x); }
-// ============================================================================
-// [asmjit::Support - Operators]
-// ============================================================================
+// Support - Operators
+// ===================
//! \cond INTERNAL
struct Set { template<typename T> static inline T op(T x, T y) noexcept { DebugUtils::unused(x); return y; } };
@@ -1129,9 +1161,8 @@ struct Min { template<typename T> static inline T op(T x, T y) noexcept { ret
struct Max { template<typename T> static inline T op(T x, T y) noexcept { return max<T>(x, y); } };
//! \endcond
-// ============================================================================
-// [asmjit::Support - BitWordIterator]
-// ============================================================================
+// Support - BitWordIterator
+// =========================
//! Iterates over each bit in a number which is set to 1.
//!
@@ -1149,13 +1180,13 @@ struct Max { template<typename T> static inline T op(T x, T y) noexcept { ret
template<typename T>
class BitWordIterator {
public:
- inline explicit BitWordIterator(T bitWord) noexcept
+ ASMJIT_FORCE_INLINE explicit BitWordIterator(T bitWord) noexcept
: _bitWord(bitWord) {}
- inline void init(T bitWord) noexcept { _bitWord = bitWord; }
- inline bool hasNext() const noexcept { return _bitWord != 0; }
+ ASMJIT_FORCE_INLINE void init(T bitWord) noexcept { _bitWord = bitWord; }
+ ASMJIT_FORCE_INLINE bool hasNext() const noexcept { return _bitWord != 0; }
- inline uint32_t next() noexcept {
+ ASMJIT_FORCE_INLINE uint32_t next() noexcept {
ASMJIT_ASSERT(_bitWord != 0);
uint32_t index = ctz(_bitWord);
_bitWord ^= T(1u) << index;
@@ -1165,20 +1196,19 @@ public:
T _bitWord;
};
-// ============================================================================
-// [asmjit::Support - BitWordFlipIterator]
-// ============================================================================
+// Support - BitWordFlipIterator
+// =============================
template<typename T>
class BitWordFlipIterator {
public:
- inline explicit BitWordFlipIterator(T bitWord) noexcept
+ ASMJIT_FORCE_INLINE explicit BitWordFlipIterator(T bitWord) noexcept
: _bitWord(bitWord) {}
- inline void init(T bitWord) noexcept { _bitWord = bitWord; }
- inline bool hasNext() const noexcept { return _bitWord != 0; }
+ ASMJIT_FORCE_INLINE void init(T bitWord) noexcept { _bitWord = bitWord; }
+ ASMJIT_FORCE_INLINE bool hasNext() const noexcept { return _bitWord != 0; }
- inline uint32_t nextAndFlip() noexcept {
+ ASMJIT_FORCE_INLINE uint32_t nextAndFlip() noexcept {
ASMJIT_ASSERT(_bitWord != 0);
uint32_t index = ctz(_bitWord);
_bitWord ^= T(1u) << index;
@@ -1189,9 +1219,8 @@ public:
T _xorMask;
};
-// ============================================================================
-// [asmjit::Support - BitVectorOps]
-// ============================================================================
+// Support - BitVectorOps
+// ======================
//! \cond
namespace Internal {
@@ -1295,9 +1324,8 @@ static inline size_t bitVectorIndexOf(T* buf, size_t start, bool value) noexcept
}
}
-// ============================================================================
-// [asmjit::Support - BitVectorIterator]
-// ============================================================================
+// Support - BitVectorIterator
+// ===========================
template<typename T>
class BitVectorIterator {
@@ -1307,13 +1335,13 @@ public:
size_t _end;
T _current;
- ASMJIT_INLINE BitVectorIterator(const BitVectorIterator& other) noexcept = default;
+ ASMJIT_FORCE_INLINE BitVectorIterator(const BitVectorIterator& other) noexcept = default;
- ASMJIT_INLINE BitVectorIterator(const T* data, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_FORCE_INLINE BitVectorIterator(const T* data, size_t numBitWords, size_t start = 0) noexcept {
init(data, numBitWords, start);
}
- ASMJIT_INLINE void init(const T* data, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_FORCE_INLINE void init(const T* data, size_t numBitWords, size_t start = 0) noexcept {
const T* ptr = data + (start / bitSizeOf<T>());
size_t idx = alignDown(start, bitSizeOf<T>());
size_t end = numBitWords * bitSizeOf<T>();
@@ -1331,11 +1359,11 @@ public:
_current = bitWord;
}
- ASMJIT_INLINE bool hasNext() const noexcept {
+ ASMJIT_FORCE_INLINE bool hasNext() const noexcept {
return _current != T(0);
}
- ASMJIT_INLINE size_t next() noexcept {
+ ASMJIT_FORCE_INLINE size_t next() noexcept {
T bitWord = _current;
ASMJIT_ASSERT(bitWord != T(0));
@@ -1350,20 +1378,21 @@ public:
return n;
}
- ASMJIT_INLINE size_t peekNext() const noexcept {
+ ASMJIT_FORCE_INLINE size_t peekNext() const noexcept {
ASMJIT_ASSERT(_current != T(0));
return _idx + ctz(_current);
}
};
-// ============================================================================
-// [asmjit::Support - BitVectorOpIterator]
-// ============================================================================
+// Support - BitVectorOpIterator
+// =============================
template<typename T, class OperatorT>
class BitVectorOpIterator {
public:
- static constexpr uint32_t kTSizeInBits = bitSizeOf<T>();
+ enum : uint32_t {
+ kTSizeInBits = bitSizeOf<T>()
+ };
const T* _aPtr;
const T* _bPtr;
@@ -1371,11 +1400,11 @@ public:
size_t _end;
T _current;
- ASMJIT_INLINE BitVectorOpIterator(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_FORCE_INLINE BitVectorOpIterator(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
init(aData, bData, numBitWords, start);
}
- ASMJIT_INLINE void init(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
+ ASMJIT_FORCE_INLINE void init(const T* aData, const T* bData, size_t numBitWords, size_t start = 0) noexcept {
const T* aPtr = aData + (start / bitSizeOf<T>());
const T* bPtr = bData + (start / bitSizeOf<T>());
size_t idx = alignDown(start, bitSizeOf<T>());
@@ -1395,11 +1424,11 @@ public:
_current = bitWord;
}
- ASMJIT_INLINE bool hasNext() noexcept {
+ ASMJIT_FORCE_INLINE bool hasNext() noexcept {
return _current != T(0);
}
- ASMJIT_INLINE size_t next() noexcept {
+ ASMJIT_FORCE_INLINE size_t next() noexcept {
T bitWord = _current;
ASMJIT_ASSERT(bitWord != T(0));
@@ -1415,29 +1444,29 @@ public:
}
};
-// ============================================================================
-// [asmjit::Support - Sorting]
-// ============================================================================
+// Support - Sorting
+// =================
//! Sort order.
-enum SortOrder : uint32_t {
- kSortAscending = 0, //!< Ascending.
- kSortDescending = 1 //!< Descending.
+enum class SortOrder : uint32_t {
+ //!< Ascending order.
+ kAscending = 0,
+ //!< Descending order.
+ kDescending = 1
};
//! A helper class that provides comparison of any user-defined type that
//! implements `<` and `>` operators (primitive types are supported as well).
-template<uint32_t Order = kSortAscending>
+template<SortOrder kOrder = SortOrder::kAscending>
struct Compare {
template<typename A, typename B>
inline int operator()(const A& a, const B& b) const noexcept {
- return Order == kSortAscending ? int(a > b) - int(a < b)
- : int(a < b) - int(a > b);
+ return kOrder == SortOrder::kAscending ? int(a > b) - int(a < b) : int(a < b) - int(a > b);
}
};
//! Insertion sort.
-template<typename T, typename CompareT = Compare<kSortAscending>>
+template<typename T, typename CompareT = Compare<SortOrder::kAscending>>
static inline void iSort(T* base, size_t size, const CompareT& cmp = CompareT()) noexcept {
for (T* pm = base + 1; pm < base + size; pm++)
for (T* pl = pm; pl > base && cmp(pl[-1], pl[0]) > 0; pl--)
@@ -1449,8 +1478,10 @@ namespace Internal {
//! Quick-sort implementation.
template<typename T, class CompareT>
struct QSortImpl {
- static constexpr size_t kStackSize = 64 * 2;
- static constexpr size_t kISortThreshold = 7;
+ enum : size_t {
+ kStackSize = 64 * 2,
+ kISortThreshold = 7
+ };
// Based on "PDCLib - Public Domain C Library" and rewritten to C++.
static void sort(T* base, size_t size, const CompareT& cmp) noexcept {
@@ -1515,31 +1546,162 @@ namespace Internal {
//! Quick sort implementation.
//!
-//! The main reason to provide a custom qsort implementation is that we needed
-//! something that will never throw `bad_alloc` exception. This implementation
-//! doesn't use dynamic memory allocation.
-template<typename T, class CompareT = Compare<kSortAscending>>
+//! The main reason to provide a custom qsort implementation is that we needed something that will
+//! never throw `bad_alloc` exception. This implementation doesn't use dynamic memory allocation.
+template<typename T, class CompareT = Compare<SortOrder::kAscending>>
static inline void qSort(T* base, size_t size, const CompareT& cmp = CompareT()) noexcept {
Internal::QSortImpl<T, CompareT>::sort(base, size, cmp);
}
-// ============================================================================
-// [asmjit::Support::Temporary]
-// ============================================================================
+// Support - Array
+// ===============
+
+//! Array type, similar to std::array<T, N>, with the possibility to use enums in operator[].
+//!
+//! \note The array has C semantics - the elements in the array are not initialized.
+template<typename T, size_t N>
+struct Array {
+ //! \name Members
+ //! \{
+
+ //! The underlying array data, use \ref data() to access it.
+ T _data[N];
+
+ //! \}
+
+ //! \cond
+ // std compatibility.
+ typedef T value_type;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ typedef pointer iterator;
+ typedef const_pointer const_iterator;
+ //! \endcond
+
+ //! \name Overloaded Operators
+ //! \{
+
+ template<typename Index>
+ inline T& operator[](const Index& index) noexcept {
+ typedef typename Internal::StdInt<sizeof(Index), 1>::Type U;
+ ASMJIT_ASSERT(U(index) < N);
+ return _data[U(index)];
+ }
+
+ template<typename Index>
+ inline const T& operator[](const Index& index) const noexcept {
+ typedef typename Internal::StdInt<sizeof(Index), 1>::Type U;
+ ASMJIT_ASSERT(U(index) < N);
+ return _data[U(index)];
+ }
+
+ inline bool operator==(const Array& other) const noexcept {
+ for (size_t i = 0; i < N; i++)
+ if (_data[i] != other._data[i])
+ return false;
+ return true;
+ }
+
+ inline bool operator!=(const Array& other) const noexcept {
+ return !operator==(other);
+ }
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ inline bool empty() const noexcept { return false; }
+ inline size_t size() const noexcept { return N; }
+
+ inline T* data() noexcept { return _data; }
+ inline const T* data() const noexcept { return _data; }
+
+ inline T& front() noexcept { return _data[0]; }
+ inline const T& front() const noexcept { return _data[0]; }
+
+ inline T& back() noexcept { return _data[N - 1]; }
+ inline const T& back() const noexcept { return _data[N - 1]; }
+
+ inline T* begin() noexcept { return _data; }
+ inline T* end() noexcept { return _data + N; }
+
+ inline const T* begin() const noexcept { return _data; }
+ inline const T* end() const noexcept { return _data + N; }
+
+ inline const T* cbegin() const noexcept { return _data; }
+ inline const T* cend() const noexcept { return _data + N; }
+
+ //! \}
+
+ //! \name Utilities
+ //! \{
+
+ inline void swap(Array& other) noexcept {
+ for (size_t i = 0; i < N; i++)
+ std::swap(_data[i], other._data[i]);
+ }
+
+ inline void fill(const T& value) noexcept {
+ for (size_t i = 0; i < N; i++)
+ _data[i] = value;
+ }
+
+ inline void copyFrom(const Array& other) noexcept {
+ for (size_t i = 0; i < N; i++)
+ _data[i] = other._data[i];
+ }
+
+ template<typename Operator>
+ inline void combine(const Array& other) noexcept {
+ for (size_t i = 0; i < N; i++)
+ _data[i] = Operator::op(_data[i], other._data[i]);
+ }
+
+ template<typename Operator>
+ inline T aggregate(T initialValue = T()) const noexcept {
+ T value = initialValue;
+ for (size_t i = 0; i < N; i++)
+ value = Operator::op(value, _data[i]);
+ return value;
+ }
+
+ template<typename Fn>
+ inline void forEach(Fn&& fn) noexcept {
+ for (size_t i = 0; i < N; i++)
+ fn(_data[i]);
+ }
+ //! \}
+};
+
+// Support::Temporary
+// ==================
//! Used to pass a temporary buffer to:
//!
//! - Containers that use user-passed buffer as an initial storage (still can grow).
//! - Zone allocator that would use the temporary buffer as a first block.
struct Temporary {
+ //! \name Members
+ //! \{
+
void* _data;
size_t _size;
+ //! \}
+
//! \name Construction & Destruction
//! \{
- constexpr Temporary(const Temporary& other) noexcept = default;
- constexpr Temporary(void* data, size_t size) noexcept
+ inline constexpr Temporary(const Temporary& other) noexcept = default;
+ inline constexpr Temporary(void* data, size_t size) noexcept
: _data(data),
_size(size) {}
@@ -1557,9 +1719,9 @@ struct Temporary {
//! Returns the data storage.
template<typename T = void>
- constexpr T* data() const noexcept { return static_cast<T*>(_data); }
+ inline constexpr T* data() const noexcept { return static_cast<T*>(_data); }
//! Returns the data storage size in bytes.
- constexpr size_t size() const noexcept { return _size; }
+ inline constexpr size_t size() const noexcept { return _size; }
//! \}
};
diff --git a/src/asmjit/core/target.cpp b/src/asmjit/core/target.cpp
index 9ce94f3..fef025d 100644
--- a/src/asmjit/core/target.cpp
+++ b/src/asmjit/core/target.cpp
@@ -1,37 +1,14 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/target.h"
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Target - Construction / Destruction]
-// ============================================================================
-
-Target::Target() noexcept
- : _environment() {}
+Target::Target() noexcept : _environment() {}
Target::~Target() noexcept {}
ASMJIT_END_NAMESPACE
diff --git a/src/asmjit/core/target.h b/src/asmjit/core/target.h
index f2045c0..23b0c62 100644
--- a/src/asmjit/core/target.h
+++ b/src/asmjit/core/target.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_TARGET_H_INCLUDED
#define ASMJIT_CORE_TARGET_H_INCLUDED
@@ -32,98 +14,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::CodeInfo]
-// ============================================================================
-
-#ifndef ASMJIT_NO_DEPRECATED
-//! Basic information about a code (or target). It describes its architecture,
-//! code generation mode (or optimization level), and base address.
-class ASMJIT_DEPRECATED_STRUCT("Use Environment instead of CodeInfo") CodeInfo {
-public:
- //!< Environment information.
- Environment _environment;
- //! Base address.
- uint64_t _baseAddress;
-
- //! \name Construction & Destruction
- //! \{
-
- inline CodeInfo() noexcept
- : _environment(),
- _baseAddress(Globals::kNoBaseAddress) {}
-
- inline explicit CodeInfo(uint32_t arch, uint32_t subArch = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
- : _environment(arch, subArch),
- _baseAddress(baseAddress) {}
-
- inline explicit CodeInfo(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
- : _environment(environment),
- _baseAddress(baseAddress) {}
-
-
- inline CodeInfo(const CodeInfo& other) noexcept { init(other); }
-
- inline bool isInitialized() const noexcept {
- return _environment.arch() != Environment::kArchUnknown;
- }
-
- inline void init(const CodeInfo& other) noexcept {
- *this = other;
- }
-
- inline void init(uint32_t arch, uint32_t subArch = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept {
- _environment.init(arch, subArch);
- _baseAddress = baseAddress;
- }
-
- inline void reset() noexcept {
- _environment.reset();
- _baseAddress = Globals::kNoBaseAddress;
- }
-
- //! \}
-
- //! \name Overloaded Operators
- //! \{
-
- inline CodeInfo& operator=(const CodeInfo& other) noexcept = default;
-
- inline bool operator==(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) == 0; }
- inline bool operator!=(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) != 0; }
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- //! Returns the target environment information, see \ref Environment.
- inline const Environment& environment() const noexcept { return _environment; }
-
- //! Returns the target architecture, see \ref Environment::Arch.
- inline uint32_t arch() const noexcept { return _environment.arch(); }
- //! Returns the target sub-architecture, see \ref Environment::SubArch.
- inline uint32_t subArch() const noexcept { return _environment.subArch(); }
- //! Returns the native size of the target's architecture GP register.
- inline uint32_t gpSize() const noexcept { return _environment.registerSize(); }
-
- //! Tests whether this CodeInfo has a base address set.
- inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
- //! Returns the base address or \ref Globals::kNoBaseAddress if it's not set.
- inline uint64_t baseAddress() const noexcept { return _baseAddress; }
- //! Sets base address to `p`.
- inline void setBaseAddress(uint64_t p) noexcept { _baseAddress = p; }
- //! Resets base address (implicitly sets it to \ref Globals::kNoBaseAddress).
- inline void resetBaseAddress() noexcept { _baseAddress = Globals::kNoBaseAddress; }
-
- //! \}
-};
-#endif // !ASMJIT_NO_DEPRECATED
-
-// ============================================================================
-// [asmjit::Target]
-// ============================================================================
-
//! Target is an abstract class that describes a machine code target.
class ASMJIT_VIRTAPI Target {
public:
@@ -146,24 +36,12 @@ public:
//! \name Accessors
//! \{
- //! Returns CodeInfo of this target.
- //!
- //! CodeInfo can be used to setup a CodeHolder in case you plan to generate a
- //! code compatible and executable by this Runtime.
+ //! Returns target's environment.
inline const Environment& environment() const noexcept { return _environment; }
-
- //! Returns the target architecture, see \ref Environment::Arch.
- inline uint32_t arch() const noexcept { return _environment.arch(); }
- //! Returns the target sub-architecture, see \ref Environment::SubArch.
- inline uint32_t subArch() const noexcept { return _environment.subArch(); }
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use environment() instead")
- inline CodeInfo codeInfo() const noexcept { return CodeInfo(_environment); }
-
- ASMJIT_DEPRECATED("Use environment().format() instead")
- inline uint32_t targetType() const noexcept { return _environment.format(); }
-#endif // !ASMJIT_NO_DEPRECATED
+ //! Returns the target architecture.
+ inline Arch arch() const noexcept { return _environment.arch(); }
+ //! Returns the target sub-architecture.
+ inline SubArch subArch() const noexcept { return _environment.subArch(); }
//! \}
};
diff --git a/src/asmjit/core/type.cpp b/src/asmjit/core/type.cpp
index a2bebf4..536fb88 100644
--- a/src/asmjit/core/type.cpp
+++ b/src/asmjit/core/type.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/misc_p.h"
@@ -27,58 +9,58 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Type]
-// ============================================================================
-
-namespace Type {
+namespace TypeUtils {
-template<uint32_t TYPE_ID>
-struct BaseOfTypeId {
- static constexpr uint32_t kTypeId =
- isBase (TYPE_ID) ? TYPE_ID :
- isMask8 (TYPE_ID) ? kIdU8 :
- isMask16(TYPE_ID) ? kIdU16 :
- isMask32(TYPE_ID) ? kIdU32 :
- isMask64(TYPE_ID) ? kIdU64 :
- isMmx32 (TYPE_ID) ? kIdI32 :
- isMmx64 (TYPE_ID) ? kIdI64 :
- isVec32 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec32Start :
- isVec64 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec64Start :
- isVec128(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec128Start :
- isVec256(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec256Start :
- isVec512(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec512Start : 0;
+template<uint32_t Index>
+struct ScalarOfTypeId {
+ enum : uint32_t {
+ kTypeId = uint32_t(
+ isScalar(TypeId(Index)) ? TypeId(Index) :
+ isMask8 (TypeId(Index)) ? TypeId::kUInt8 :
+ isMask16(TypeId(Index)) ? TypeId::kUInt16 :
+ isMask32(TypeId(Index)) ? TypeId::kUInt32 :
+ isMask64(TypeId(Index)) ? TypeId::kUInt64 :
+ isMmx32 (TypeId(Index)) ? TypeId::kUInt32 :
+ isMmx64 (TypeId(Index)) ? TypeId::kUInt64 :
+ isVec32 (TypeId(Index)) ? TypeId((Index - uint32_t(TypeId::_kVec32Start ) + uint32_t(TypeId::kInt8)) & 0xFF) :
+ isVec64 (TypeId(Index)) ? TypeId((Index - uint32_t(TypeId::_kVec64Start ) + uint32_t(TypeId::kInt8)) & 0xFF) :
+ isVec128(TypeId(Index)) ? TypeId((Index - uint32_t(TypeId::_kVec128Start) + uint32_t(TypeId::kInt8)) & 0xFF) :
+ isVec256(TypeId(Index)) ? TypeId((Index - uint32_t(TypeId::_kVec256Start) + uint32_t(TypeId::kInt8)) & 0xFF) :
+ isVec512(TypeId(Index)) ? TypeId((Index - uint32_t(TypeId::_kVec512Start) + uint32_t(TypeId::kInt8)) & 0xFF) : TypeId::kVoid)
+ };
};
-template<uint32_t TYPE_ID>
+template<uint32_t Index>
struct SizeOfTypeId {
- static constexpr uint32_t kTypeSize =
- isInt8 (TYPE_ID) ? 1 :
- isUInt8 (TYPE_ID) ? 1 :
- isInt16 (TYPE_ID) ? 2 :
- isUInt16 (TYPE_ID) ? 2 :
- isInt32 (TYPE_ID) ? 4 :
- isUInt32 (TYPE_ID) ? 4 :
- isInt64 (TYPE_ID) ? 8 :
- isUInt64 (TYPE_ID) ? 8 :
- isFloat32(TYPE_ID) ? 4 :
- isFloat64(TYPE_ID) ? 8 :
- isFloat80(TYPE_ID) ? 10 :
- isMask8 (TYPE_ID) ? 1 :
- isMask16 (TYPE_ID) ? 2 :
- isMask32 (TYPE_ID) ? 4 :
- isMask64 (TYPE_ID) ? 8 :
- isMmx32 (TYPE_ID) ? 4 :
- isMmx64 (TYPE_ID) ? 8 :
- isVec32 (TYPE_ID) ? 4 :
- isVec64 (TYPE_ID) ? 8 :
- isVec128 (TYPE_ID) ? 16 :
- isVec256 (TYPE_ID) ? 32 :
- isVec512 (TYPE_ID) ? 64 : 0;
+ enum : uint32_t {
+ kTypeSize =
+ isInt8 (TypeId(Index)) ? 1 :
+ isUInt8 (TypeId(Index)) ? 1 :
+ isInt16 (TypeId(Index)) ? 2 :
+ isUInt16 (TypeId(Index)) ? 2 :
+ isInt32 (TypeId(Index)) ? 4 :
+ isUInt32 (TypeId(Index)) ? 4 :
+ isInt64 (TypeId(Index)) ? 8 :
+ isUInt64 (TypeId(Index)) ? 8 :
+ isFloat32(TypeId(Index)) ? 4 :
+ isFloat64(TypeId(Index)) ? 8 :
+ isFloat80(TypeId(Index)) ? 10 :
+ isMask8 (TypeId(Index)) ? 1 :
+ isMask16 (TypeId(Index)) ? 2 :
+ isMask32 (TypeId(Index)) ? 4 :
+ isMask64 (TypeId(Index)) ? 8 :
+ isMmx32 (TypeId(Index)) ? 4 :
+ isMmx64 (TypeId(Index)) ? 8 :
+ isVec32 (TypeId(Index)) ? 4 :
+ isVec64 (TypeId(Index)) ? 8 :
+ isVec128 (TypeId(Index)) ? 16 :
+ isVec256 (TypeId(Index)) ? 32 :
+ isVec512 (TypeId(Index)) ? 64 : 0
+ };
};
const TypeData _typeData = {
- #define VALUE(x) BaseOfTypeId<x>::kTypeId
+ #define VALUE(x) TypeId(ScalarOfTypeId<x>::kTypeId)
{ ASMJIT_LOOKUP_TABLE_256(VALUE, 0) },
#undef VALUE
@@ -87,6 +69,6 @@ const TypeData _typeData = {
#undef VALUE
};
-} // {Type}
+} // {TypeUtils}
ASMJIT_END_NAMESPACE
diff --git a/src/asmjit/core/type.h b/src/asmjit/core/type.h
index ef03ecb..3754959 100644
--- a/src/asmjit/core/type.h
+++ b/src/asmjit/core/type.h
@@ -1,210 +1,237 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_TYPE_H_INCLUDED
#define ASMJIT_CORE_TYPE_H_INCLUDED
#include "../core/globals.h"
+#include "../core/support.h"
ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
-// ============================================================================
-// [asmjit::Type]
-// ============================================================================
-
-//! Provides a minimalist type-system that is used by Asmjit library.
-namespace Type {
-
-//! TypeId.
+//! Type identifier provides a minimalist type system used across AsmJit library.
//!
-//! This is an additional information that can be used to describe a value-type
-//! of physical or virtual register. it's used mostly by BaseCompiler to describe
-//! register representation (the group of data stored in the register and the
-//! width used) and it's also used by APIs that allow to describe and work with
-//! function signatures.
-enum Id : uint32_t {
- kIdVoid = 0, //!< Void type.
-
- _kIdBaseStart = 32,
- _kIdBaseEnd = 44,
-
- _kIdIntStart = 32,
- _kIdIntEnd = 41,
-
- kIdIntPtr = 32, //!< Abstract signed integer type that has a native size.
- kIdUIntPtr = 33, //!< Abstract unsigned integer type that has a native size.
-
- kIdI8 = 34, //!< 8-bit signed integer type.
- kIdU8 = 35, //!< 8-bit unsigned integer type.
- kIdI16 = 36, //!< 16-bit signed integer type.
- kIdU16 = 37, //!< 16-bit unsigned integer type.
- kIdI32 = 38, //!< 32-bit signed integer type.
- kIdU32 = 39, //!< 32-bit unsigned integer type.
- kIdI64 = 40, //!< 64-bit signed integer type.
- kIdU64 = 41, //!< 64-bit unsigned integer type.
-
- _kIdFloatStart = 42,
- _kIdFloatEnd = 44,
-
- kIdF32 = 42, //!< 32-bit floating point type.
- kIdF64 = 43, //!< 64-bit floating point type.
- kIdF80 = 44, //!< 80-bit floating point type.
-
- _kIdMaskStart = 45,
- _kIdMaskEnd = 48,
-
- kIdMask8 = 45, //!< 8-bit opmask register (K).
- kIdMask16 = 46, //!< 16-bit opmask register (K).
- kIdMask32 = 47, //!< 32-bit opmask register (K).
- kIdMask64 = 48, //!< 64-bit opmask register (K).
-
- _kIdMmxStart = 49,
- _kIdMmxEnd = 50,
-
- kIdMmx32 = 49, //!< 64-bit MMX register only used for 32 bits.
- kIdMmx64 = 50, //!< 64-bit MMX register.
-
- _kIdVec32Start = 51,
- _kIdVec32End = 60,
-
- kIdI8x4 = 51,
- kIdU8x4 = 52,
- kIdI16x2 = 53,
- kIdU16x2 = 54,
- kIdI32x1 = 55,
- kIdU32x1 = 56,
- kIdF32x1 = 59,
-
- _kIdVec64Start = 61,
- _kIdVec64End = 70,
-
- kIdI8x8 = 61,
- kIdU8x8 = 62,
- kIdI16x4 = 63,
- kIdU16x4 = 64,
- kIdI32x2 = 65,
- kIdU32x2 = 66,
- kIdI64x1 = 67,
- kIdU64x1 = 68,
- kIdF32x2 = 69,
- kIdF64x1 = 70,
-
- _kIdVec128Start = 71,
- _kIdVec128End = 80,
-
- kIdI8x16 = 71,
- kIdU8x16 = 72,
- kIdI16x8 = 73,
- kIdU16x8 = 74,
- kIdI32x4 = 75,
- kIdU32x4 = 76,
- kIdI64x2 = 77,
- kIdU64x2 = 78,
- kIdF32x4 = 79,
- kIdF64x2 = 80,
-
- _kIdVec256Start = 81,
- _kIdVec256End = 90,
-
- kIdI8x32 = 81,
- kIdU8x32 = 82,
- kIdI16x16 = 83,
- kIdU16x16 = 84,
- kIdI32x8 = 85,
- kIdU32x8 = 86,
- kIdI64x4 = 87,
- kIdU64x4 = 88,
- kIdF32x8 = 89,
- kIdF64x4 = 90,
-
- _kIdVec512Start = 91,
- _kIdVec512End = 100,
-
- kIdI8x64 = 91,
- kIdU8x64 = 92,
- kIdI16x32 = 93,
- kIdU16x32 = 94,
- kIdI32x16 = 95,
- kIdU32x16 = 96,
- kIdI64x8 = 97,
- kIdU64x8 = 98,
- kIdF32x16 = 99,
- kIdF64x8 = 100,
-
- kIdCount = 101,
- kIdMax = 255
+//! This is an additional information that can be used to describe a value-type of physical or virtual register. It's
+//! used mostly by BaseCompiler to describe register representation (the group of data stored in the register and the
+//! width used) and it's also used by APIs that allow to describe and work with function signatures.
+enum class TypeId : uint8_t {
+ //! Void type.
+ kVoid = 0,
+
+ _kBaseStart = 32,
+ _kBaseEnd = 44,
+
+ _kIntStart = 32,
+ _kIntEnd = 41,
+
+ //! Abstract signed integer type that has a native size.
+ kIntPtr = 32,
+ //! Abstract unsigned integer type that has a native size.
+ kUIntPtr = 33,
+
+ //! 8-bit signed integer type.
+ kInt8 = 34,
+ //! 8-bit unsigned integer type.
+ kUInt8 = 35,
+ //! 16-bit signed integer type.
+ kInt16 = 36,
+ //! 16-bit unsigned integer type.
+ kUInt16 = 37,
+ //! 32-bit signed integer type.
+ kInt32 = 38,
+ //! 32-bit unsigned integer type.
+ kUInt32 = 39,
+ //! 64-bit signed integer type.
+ kInt64 = 40,
+ //! 64-bit unsigned integer type.
+ kUInt64 = 41,
+
+ _kFloatStart = 42,
+ _kFloatEnd = 44,
+
+ //! 32-bit floating point type.
+ kFloat32 = 42,
+ //! 64-bit floating point type.
+ kFloat64 = 43,
+ //! 80-bit floating point type.
+ kFloat80 = 44,
+
+ _kMaskStart = 45,
+ _kMaskEnd = 48,
+
+ //! 8-bit opmask register (K).
+ kMask8 = 45,
+ //! 16-bit opmask register (K).
+ kMask16 = 46,
+ //! 32-bit opmask register (K).
+ kMask32 = 47,
+ //! 64-bit opmask register (K).
+ kMask64 = 48,
+
+ _kMmxStart = 49,
+ _kMmxEnd = 50,
+
+ //! 64-bit MMX register only used for 32 bits.
+ kMmx32 = 49,
+ //! 64-bit MMX register.
+ kMmx64 = 50,
+
+ _kVec32Start = 51,
+ _kVec32End = 60,
+
+ kInt8x4 = 51,
+ kUInt8x4 = 52,
+ kInt16x2 = 53,
+ kUInt16x2 = 54,
+ kInt32x1 = 55,
+ kUInt32x1 = 56,
+ kFloat32x1 = 59,
+
+ _kVec64Start = 61,
+ _kVec64End = 70,
+
+ kInt8x8 = 61,
+ kUInt8x8 = 62,
+ kInt16x4 = 63,
+ kUInt16x4 = 64,
+ kInt32x2 = 65,
+ kUInt32x2 = 66,
+ kInt64x1 = 67,
+ kUInt64x1 = 68,
+ kFloat32x2 = 69,
+ kFloat64x1 = 70,
+
+ _kVec128Start = 71,
+ _kVec128End = 80,
+
+ kInt8x16 = 71,
+ kUInt8x16 = 72,
+ kInt16x8 = 73,
+ kUInt16x8 = 74,
+ kInt32x4 = 75,
+ kUInt32x4 = 76,
+ kInt64x2 = 77,
+ kUInt64x2 = 78,
+ kFloat32x4 = 79,
+ kFloat64x2 = 80,
+
+ _kVec256Start = 81,
+ _kVec256End = 90,
+
+ kInt8x32 = 81,
+ kUInt8x32 = 82,
+ kInt16x16 = 83,
+ kUInt16x16 = 84,
+ kInt32x8 = 85,
+ kUInt32x8 = 86,
+ kInt64x4 = 87,
+ kUInt64x4 = 88,
+ kFloat32x8 = 89,
+ kFloat64x4 = 90,
+
+ _kVec512Start = 91,
+ _kVec512End = 100,
+
+ kInt8x64 = 91,
+ kUInt8x64 = 92,
+ kInt16x32 = 93,
+ kUInt16x32 = 94,
+ kInt32x16 = 95,
+ kUInt32x16 = 96,
+ kInt64x8 = 97,
+ kUInt64x8 = 98,
+ kFloat32x16 = 99,
+ kFloat64x8 = 100,
+
+ kLastAssigned = kFloat64x8,
+
+ kMaxValue = 255
};
+ASMJIT_DEFINE_ENUM_COMPARE(TypeId)
+
+//! Type identifier utilities.
+namespace TypeUtils {
struct TypeData {
- uint8_t baseOf[kIdMax + 1];
- uint8_t sizeOf[kIdMax + 1];
+ TypeId scalarOf[uint32_t(TypeId::kMaxValue) + 1];
+ uint8_t sizeOf[uint32_t(TypeId::kMaxValue) + 1];
};
ASMJIT_VARAPI const TypeData _typeData;
-static constexpr bool isVoid(uint32_t typeId) noexcept { return typeId == 0; }
-static constexpr bool isValid(uint32_t typeId) noexcept { return typeId >= _kIdIntStart && typeId <= _kIdVec512End; }
-static constexpr bool isBase(uint32_t typeId) noexcept { return typeId >= _kIdBaseStart && typeId <= _kIdBaseEnd; }
-static constexpr bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIdIntPtr && typeId <= kIdUIntPtr; }
-
-static constexpr bool isInt(uint32_t typeId) noexcept { return typeId >= _kIdIntStart && typeId <= _kIdIntEnd; }
-static constexpr bool isInt8(uint32_t typeId) noexcept { return typeId == kIdI8; }
-static constexpr bool isUInt8(uint32_t typeId) noexcept { return typeId == kIdU8; }
-static constexpr bool isInt16(uint32_t typeId) noexcept { return typeId == kIdI16; }
-static constexpr bool isUInt16(uint32_t typeId) noexcept { return typeId == kIdU16; }
-static constexpr bool isInt32(uint32_t typeId) noexcept { return typeId == kIdI32; }
-static constexpr bool isUInt32(uint32_t typeId) noexcept { return typeId == kIdU32; }
-static constexpr bool isInt64(uint32_t typeId) noexcept { return typeId == kIdI64; }
-static constexpr bool isUInt64(uint32_t typeId) noexcept { return typeId == kIdU64; }
-
-static constexpr bool isGp8(uint32_t typeId) noexcept { return typeId >= kIdI8 && typeId <= kIdU8; }
-static constexpr bool isGp16(uint32_t typeId) noexcept { return typeId >= kIdI16 && typeId <= kIdU16; }
-static constexpr bool isGp32(uint32_t typeId) noexcept { return typeId >= kIdI32 && typeId <= kIdU32; }
-static constexpr bool isGp64(uint32_t typeId) noexcept { return typeId >= kIdI64 && typeId <= kIdU64; }
-
-static constexpr bool isFloat(uint32_t typeId) noexcept { return typeId >= _kIdFloatStart && typeId <= _kIdFloatEnd; }
-static constexpr bool isFloat32(uint32_t typeId) noexcept { return typeId == kIdF32; }
-static constexpr bool isFloat64(uint32_t typeId) noexcept { return typeId == kIdF64; }
-static constexpr bool isFloat80(uint32_t typeId) noexcept { return typeId == kIdF80; }
-
-static constexpr bool isMask(uint32_t typeId) noexcept { return typeId >= _kIdMaskStart && typeId <= _kIdMaskEnd; }
-static constexpr bool isMask8(uint32_t typeId) noexcept { return typeId == kIdMask8; }
-static constexpr bool isMask16(uint32_t typeId) noexcept { return typeId == kIdMask16; }
-static constexpr bool isMask32(uint32_t typeId) noexcept { return typeId == kIdMask32; }
-static constexpr bool isMask64(uint32_t typeId) noexcept { return typeId == kIdMask64; }
-
-static constexpr bool isMmx(uint32_t typeId) noexcept { return typeId >= _kIdMmxStart && typeId <= _kIdMmxEnd; }
-static constexpr bool isMmx32(uint32_t typeId) noexcept { return typeId == kIdMmx32; }
-static constexpr bool isMmx64(uint32_t typeId) noexcept { return typeId == kIdMmx64; }
-
-static constexpr bool isVec(uint32_t typeId) noexcept { return typeId >= _kIdVec32Start && typeId <= _kIdVec512End; }
-static constexpr bool isVec32(uint32_t typeId) noexcept { return typeId >= _kIdVec32Start && typeId <= _kIdVec32End; }
-static constexpr bool isVec64(uint32_t typeId) noexcept { return typeId >= _kIdVec64Start && typeId <= _kIdVec64End; }
-static constexpr bool isVec128(uint32_t typeId) noexcept { return typeId >= _kIdVec128Start && typeId <= _kIdVec128End; }
-static constexpr bool isVec256(uint32_t typeId) noexcept { return typeId >= _kIdVec256Start && typeId <= _kIdVec256End; }
-static constexpr bool isVec512(uint32_t typeId) noexcept { return typeId >= _kIdVec512Start && typeId <= _kIdVec512End; }
+//! Returns the scalar type of `typeId`.
+static inline TypeId scalarOf(TypeId typeId) noexcept { return _typeData.scalarOf[uint32_t(typeId)]; }
+
+//! Returns the size [in bytes] of `typeId`.
+static inline uint32_t sizeOf(TypeId typeId) noexcept { return _typeData.sizeOf[uint32_t(typeId)]; }
+
+//! Tests whether a given type `typeId` is between `a` and `b`.
+static inline constexpr bool isBetween(TypeId typeId, TypeId a, TypeId b) noexcept {
+ return Support::isBetween(uint32_t(typeId), uint32_t(a), uint32_t(b));
+}
+
+//! Tests whether a given type `typeId` is \ref TypeId::kVoid.
+static inline constexpr bool isVoid(TypeId typeId) noexcept { return typeId == TypeId::kVoid; }
+//! Tests whether a given type `typeId` is a valid non-void type.
+static inline constexpr bool isValid(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kIntStart, TypeId::_kVec512End); }
+//! Tests whether a given type `typeId` is scalar (has no vector part).
+static inline constexpr bool isScalar(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kBaseStart, TypeId::_kBaseEnd); }
+//! Tests whether a given type `typeId` is abstract, which means that its size depends on register size.
+static inline constexpr bool isAbstract(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kIntPtr, TypeId::kUIntPtr); }
+
+//! Tests whether a given type is a scalar integer (signed or unsigned) of any size.
+static inline constexpr bool isInt(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kIntStart, TypeId::_kIntEnd); }
+//! Tests whether a given type is a scalar 8-bit integer (signed).
+static inline constexpr bool isInt8(TypeId typeId) noexcept { return typeId == TypeId::kInt8; }
+//! Tests whether a given type is a scalar 8-bit integer (unsigned).
+static inline constexpr bool isUInt8(TypeId typeId) noexcept { return typeId == TypeId::kUInt8; }
+//! Tests whether a given type is a scalar 16-bit integer (signed).
+static inline constexpr bool isInt16(TypeId typeId) noexcept { return typeId == TypeId::kInt16; }
+//! Tests whether a given type is a scalar 16-bit integer (unsigned).
+static inline constexpr bool isUInt16(TypeId typeId) noexcept { return typeId == TypeId::kUInt16; }
+//! Tests whether a given type is a scalar 32-bit integer (signed).
+static inline constexpr bool isInt32(TypeId typeId) noexcept { return typeId == TypeId::kInt32; }
+//! Tests whether a given type is a scalar 32-bit integer (unsigned).
+static inline constexpr bool isUInt32(TypeId typeId) noexcept { return typeId == TypeId::kUInt32; }
+//! Tests whether a given type is a scalar 64-bit integer (signed).
+static inline constexpr bool isInt64(TypeId typeId) noexcept { return typeId == TypeId::kInt64; }
+//! Tests whether a given type is a scalar 64-bit integer (unsigned).
+static inline constexpr bool isUInt64(TypeId typeId) noexcept { return typeId == TypeId::kUInt64; }
+
+static inline constexpr bool isGp8(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt8, TypeId::kUInt8); }
+static inline constexpr bool isGp16(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt16, TypeId::kUInt16); }
+static inline constexpr bool isGp32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt32, TypeId::kUInt32); }
+static inline constexpr bool isGp64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::kInt64, TypeId::kUInt64); }
+
+//! Tests whether a given type is a scalar floating point of any size.
+static inline constexpr bool isFloat(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kFloatStart, TypeId::_kFloatEnd); }
+//! Tests whether a given type is a scalar 32-bit float.
+static inline constexpr bool isFloat32(TypeId typeId) noexcept { return typeId == TypeId::kFloat32; }
+//! Tests whether a given type is a scalar 64-bit float.
+static inline constexpr bool isFloat64(TypeId typeId) noexcept { return typeId == TypeId::kFloat64; }
+//! Tests whether a given type is a scalar 80-bit float.
+static inline constexpr bool isFloat80(TypeId typeId) noexcept { return typeId == TypeId::kFloat80; }
+
+static inline constexpr bool isMask(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMaskStart, TypeId::_kMaskEnd); }
+static inline constexpr bool isMask8(TypeId typeId) noexcept { return typeId == TypeId::kMask8; }
+static inline constexpr bool isMask16(TypeId typeId) noexcept { return typeId == TypeId::kMask16; }
+static inline constexpr bool isMask32(TypeId typeId) noexcept { return typeId == TypeId::kMask32; }
+static inline constexpr bool isMask64(TypeId typeId) noexcept { return typeId == TypeId::kMask64; }
+
+static inline constexpr bool isMmx(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kMmxStart, TypeId::_kMmxEnd); }
+static inline constexpr bool isMmx32(TypeId typeId) noexcept { return typeId == TypeId::kMmx32; }
+static inline constexpr bool isMmx64(TypeId typeId) noexcept { return typeId == TypeId::kMmx64; }
+
+static inline constexpr bool isVec(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec512End); }
+static inline constexpr bool isVec32(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec32Start, TypeId::_kVec32End); }
+static inline constexpr bool isVec64(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec64Start, TypeId::_kVec64End); }
+static inline constexpr bool isVec128(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec128Start, TypeId::_kVec128End); }
+static inline constexpr bool isVec256(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec256Start, TypeId::_kVec256End); }
+static inline constexpr bool isVec512(TypeId typeId) noexcept { return isBetween(typeId, TypeId::_kVec512Start, TypeId::_kVec512End); }
//! \cond
enum TypeCategory : uint32_t {
@@ -215,157 +242,174 @@ enum TypeCategory : uint32_t {
kTypeCategoryFunction = 4
};
-template<typename T, uint32_t Category>
-struct IdOfT_ByCategory {}; // Fails if not specialized.
+template<typename T, TypeCategory kCategory>
+struct TypeIdOfT_ByCategory {}; // Fails if not specialized.
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryIntegral> {
+struct TypeIdOfT_ByCategory<T, kTypeCategoryIntegral> {
enum : uint32_t {
- kTypeId = (sizeof(T) == 1 && std::is_signed<T>::value) ? kIdI8 :
- (sizeof(T) == 1 && !std::is_signed<T>::value) ? kIdU8 :
- (sizeof(T) == 2 && std::is_signed<T>::value) ? kIdI16 :
- (sizeof(T) == 2 && !std::is_signed<T>::value) ? kIdU16 :
- (sizeof(T) == 4 && std::is_signed<T>::value) ? kIdI32 :
- (sizeof(T) == 4 && !std::is_signed<T>::value) ? kIdU32 :
- (sizeof(T) == 8 && std::is_signed<T>::value) ? kIdI64 :
- (sizeof(T) == 8 && !std::is_signed<T>::value) ? kIdU64 : kIdVoid
+ kTypeId = uint32_t(
+ (sizeof(T) == 1 && std::is_signed<T>::value) ? TypeId::kInt8 :
+ (sizeof(T) == 1 && !std::is_signed<T>::value) ? TypeId::kUInt8 :
+ (sizeof(T) == 2 && std::is_signed<T>::value) ? TypeId::kInt16 :
+ (sizeof(T) == 2 && !std::is_signed<T>::value) ? TypeId::kUInt16 :
+ (sizeof(T) == 4 && std::is_signed<T>::value) ? TypeId::kInt32 :
+ (sizeof(T) == 4 && !std::is_signed<T>::value) ? TypeId::kUInt32 :
+ (sizeof(T) == 8 && std::is_signed<T>::value) ? TypeId::kInt64 :
+ (sizeof(T) == 8 && !std::is_signed<T>::value) ? TypeId::kUInt64 : TypeId::kVoid)
};
};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryFloatingPoint> {
+struct TypeIdOfT_ByCategory<T, kTypeCategoryFloatingPoint> {
enum : uint32_t {
- kTypeId = (sizeof(T) == 4 ) ? kIdF32 :
- (sizeof(T) == 8 ) ? kIdF64 :
- (sizeof(T) >= 10) ? kIdF80 : kIdVoid
+ kTypeId = uint32_t(
+ (sizeof(T) == 4 ) ? TypeId::kFloat32 :
+ (sizeof(T) == 8 ) ? TypeId::kFloat64 :
+ (sizeof(T) >= 10) ? TypeId::kFloat80 : TypeId::kVoid)
};
};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryEnum>
- : public IdOfT_ByCategory<typename std::underlying_type<T>::type, kTypeCategoryIntegral> {};
+struct TypeIdOfT_ByCategory<T, kTypeCategoryEnum>
+ : public TypeIdOfT_ByCategory<typename std::underlying_type<T>::type, kTypeCategoryIntegral> {};
template<typename T>
-struct IdOfT_ByCategory<T, kTypeCategoryFunction> {
- enum: uint32_t { kTypeId = kIdUIntPtr };
+struct TypeIdOfT_ByCategory<T, kTypeCategoryFunction> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
};
//! \endcond
-//! IdOfT<> template allows to get a TypeId from a C++ type `T`.
-template<typename T>
-struct IdOfT
+//! TypeIdOfT<> template allows to get a TypeId from a C++ type `T`.
#ifdef _DOXYGEN
+template<typename T>
+struct TypeIdOfT {
//! TypeId of C++ type `T`.
- static constexpr uint32_t kTypeId = _TypeIdDeducedAtCompileTime_;
+ static constexpr TypeId kTypeId = _TypeIdDeducedAtCompileTime_;
+};
#else
- : public IdOfT_ByCategory<T,
+template<typename T>
+struct TypeIdOfT
+ : public TypeIdOfT_ByCategory<T,
std::is_enum<T>::value ? kTypeCategoryEnum :
std::is_integral<T>::value ? kTypeCategoryIntegral :
std::is_floating_point<T>::value ? kTypeCategoryFloatingPoint :
- std::is_function<T>::value ? kTypeCategoryFunction : kTypeCategoryUnknown>
+ std::is_function<T>::value ? kTypeCategoryFunction : kTypeCategoryUnknown> {};
#endif
-{};
//! \cond
template<typename T>
-struct IdOfT<T*> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+struct TypeIdOfT<T*> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
+};
template<typename T>
-struct IdOfT<T&> { enum : uint32_t { kTypeId = kIdUIntPtr }; };
+struct TypeIdOfT<T&> {
+ enum : uint32_t {
+ kTypeId = uint32_t(TypeId::kUIntPtr)
+ };
+};
//! \endcond
-static inline uint32_t baseOf(uint32_t typeId) noexcept {
- ASMJIT_ASSERT(typeId <= kIdMax);
- return _typeData.baseOf[typeId];
-}
-
-static inline uint32_t sizeOf(uint32_t typeId) noexcept {
- ASMJIT_ASSERT(typeId <= kIdMax);
- return _typeData.sizeOf[typeId];
-}
+//! Returns a corresponding \ref TypeId of `T` type.
+template<typename T>
+static inline constexpr TypeId typeIdOfT() noexcept { return TypeId(TypeIdOfT<T>::kTypeId); }
-//! Returns offset needed to convert a `kIntPtr` and `kUIntPtr` TypeId
-//! into a type that matches `registerSize` (general-purpose register size).
-//! If you find such TypeId it's then only about adding the offset to it.
+//! Returns offset needed to convert a `kIntPtr` and `kUIntPtr` TypeId into a type that matches `registerSize`
+//! (general-purpose register size). If you find such TypeId it's then only about adding the offset to it.
//!
//! For example:
//!
//! ```
-//! uint32_t registerSize = '4' or '8';
-//! uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize);
+//! uint32_t registerSize = /* 4 or 8 */;
+//! uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize);
//!
-//! uint32_t typeId = 'some type-id';
+//! TypeId typeId = 'some type-id';
//!
//! // Normalize some typeId into a non-abstract typeId.
-//! if (Type::isAbstract(typeId)) typeId += deabstractDelta;
+//! if (TypeUtils::isAbstract(typeId)) typeId += deabstractDelta;
//!
-//! // The same, but by using Type::deabstract() function.
-//! typeId = Type::deabstract(typeId, deabstractDelta);
+//! // The same, but by using TypeUtils::deabstract() function.
+//! typeId = TypeUtils::deabstract(typeId, deabstractDelta);
//! ```
-static constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
- return registerSize >= 8 ? kIdI64 - kIdIntPtr : kIdI32 - kIdIntPtr;
+static inline constexpr uint32_t deabstractDeltaOfSize(uint32_t registerSize) noexcept {
+ return registerSize >= 8 ? uint32_t(TypeId::kInt64) - uint32_t(TypeId::kIntPtr)
+ : uint32_t(TypeId::kInt32) - uint32_t(TypeId::kIntPtr);
+}
+
+//! Deabstracts a given `typeId` into a native type by using `deabstractDelta`, which was previously
+//! calculated by calling \ref deabstractDeltaOfSize() with a target native register size.
+static inline constexpr TypeId deabstract(TypeId typeId, uint32_t deabstractDelta) noexcept {
+ return isAbstract(typeId) ? TypeId(uint32_t(typeId) + deabstractDelta) : typeId;
}
-static constexpr uint32_t deabstract(uint32_t typeId, uint32_t deabstractDelta) noexcept {
- return isAbstract(typeId) ? typeId + deabstractDelta : typeId;
+static inline constexpr TypeId scalarToVector(TypeId scalarTypeId, TypeId vecStartId) noexcept {
+ return TypeId(uint32_t(vecStartId) + uint32_t(scalarTypeId) - uint32_t(TypeId::kInt8));
}
+} // {TypeUtils}
+
+//! Provides type identifiers that can be used in templates instead of native types.
+namespace Type {
+
//! bool as C++ type-name.
struct Bool {};
//! int8_t as C++ type-name.
-struct I8 {};
+struct Int8 {};
//! uint8_t as C++ type-name.
-struct U8 {};
+struct UInt8 {};
//! int16_t as C++ type-name.
-struct I16 {};
+struct Int16 {};
//! uint16_t as C++ type-name.
-struct U16 {};
+struct UInt16 {};
//! int32_t as C++ type-name.
-struct I32 {};
+struct Int32 {};
//! uint32_t as C++ type-name.
-struct U32 {};
+struct UInt32 {};
//! int64_t as C++ type-name.
-struct I64 {};
+struct Int64 {};
//! uint64_t as C++ type-name.
-struct U64 {};
+struct UInt64 {};
//! intptr_t as C++ type-name.
-struct IPtr {};
+struct IntPtr {};
//! uintptr_t as C++ type-name.
-struct UPtr {};
+struct UIntPtr {};
//! float as C++ type-name.
-struct F32 {};
+struct Float32 {};
//! double as C++ type-name.
-struct F64 {};
+struct Float64 {};
} // {Type}
-// ============================================================================
-// [ASMJIT_DEFINE_TYPE_ID]
-// ============================================================================
-
//! \cond
-#define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
-namespace Type { \
- template<> \
- struct IdOfT<T> { \
- enum : uint32_t { kTypeId = TYPE_ID }; \
- }; \
+#define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
+namespace TypeUtils { \
+ template<> \
+ struct TypeIdOfT<T> { \
+ enum : uint32_t { \
+ kTypeId = uint32_t(TYPE_ID) \
+ }; \
+ }; \
}
-ASMJIT_DEFINE_TYPE_ID(void, kIdVoid);
-ASMJIT_DEFINE_TYPE_ID(Bool, kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I8 , kIdI8);
-ASMJIT_DEFINE_TYPE_ID(U8 , kIdU8);
-ASMJIT_DEFINE_TYPE_ID(I16 , kIdI16);
-ASMJIT_DEFINE_TYPE_ID(U16 , kIdU16);
-ASMJIT_DEFINE_TYPE_ID(I32 , kIdI32);
-ASMJIT_DEFINE_TYPE_ID(U32 , kIdU32);
-ASMJIT_DEFINE_TYPE_ID(I64 , kIdI64);
-ASMJIT_DEFINE_TYPE_ID(U64 , kIdU64);
-ASMJIT_DEFINE_TYPE_ID(IPtr, kIdIntPtr);
-ASMJIT_DEFINE_TYPE_ID(UPtr, kIdUIntPtr);
-ASMJIT_DEFINE_TYPE_ID(F32 , kIdF32);
-ASMJIT_DEFINE_TYPE_ID(F64 , kIdF64);
+ASMJIT_DEFINE_TYPE_ID(void , TypeId::kVoid);
+ASMJIT_DEFINE_TYPE_ID(Type::Bool , TypeId::kUInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::Int8 , TypeId::kInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt8 , TypeId::kUInt8);
+ASMJIT_DEFINE_TYPE_ID(Type::Int16 , TypeId::kInt16);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt16 , TypeId::kUInt16);
+ASMJIT_DEFINE_TYPE_ID(Type::Int32 , TypeId::kInt32);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt32 , TypeId::kUInt32);
+ASMJIT_DEFINE_TYPE_ID(Type::Int64 , TypeId::kInt64);
+ASMJIT_DEFINE_TYPE_ID(Type::UInt64 , TypeId::kUInt64);
+ASMJIT_DEFINE_TYPE_ID(Type::IntPtr , TypeId::kIntPtr);
+ASMJIT_DEFINE_TYPE_ID(Type::UIntPtr, TypeId::kUIntPtr);
+ASMJIT_DEFINE_TYPE_ID(Type::Float32, TypeId::kFloat32);
+ASMJIT_DEFINE_TYPE_ID(Type::Float64, TypeId::kFloat64);
//! \endcond
//! \}
diff --git a/src/asmjit/core/virtmem.cpp b/src/asmjit/core/virtmem.cpp
index 4ac00e6..8259f9c 100644
--- a/src/asmjit/core/virtmem.cpp
+++ b/src/asmjit/core/virtmem.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_JIT
@@ -44,9 +26,11 @@
// Apple recently introduced MAP_JIT flag, which we want to use.
#if defined(__APPLE__)
+ #include <pthread.h>
#include <TargetConditionals.h>
#if TARGET_OS_OSX
#include <sys/utsname.h>
+ #include <libkern/OSCacheControl.h> // sys_icache_invalidate().
#endif
// Older SDK doesn't define `MAP_JIT`.
#ifndef MAP_JIT
@@ -54,7 +38,7 @@
#endif
#endif
- // BSD/OSX: `MAP_ANONYMOUS` is not defined, `MAP_ANON` is.
+ // BSD/MAC: `MAP_ANONYMOUS` is not defined, `MAP_ANON` is.
#if !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
@@ -75,22 +59,25 @@
#define ASMJIT_VM_SHM_AVAILABLE 1
#endif
-ASMJIT_BEGIN_NAMESPACE
+#if defined(__APPLE__) && ASMJIT_ARCH_ARM >= 64
+ #define ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP
+#endif
+
+ASMJIT_BEGIN_SUB_NAMESPACE(VirtMem)
-// ============================================================================
-// [asmjit::VirtMem - Utilities]
-// ============================================================================
+// Virtual Memory Utilities
+// ========================
-static const uint32_t VirtMem_dualMappingFilter[2] = {
- VirtMem::kAccessWrite | VirtMem::kMMapMaxAccessWrite,
- VirtMem::kAccessExecute | VirtMem::kMMapMaxAccessExecute
+static const MemoryFlags dualMappingFilter[2] = {
+ MemoryFlags::kAccessWrite | MemoryFlags::kMMapMaxAccessWrite,
+ MemoryFlags::kAccessExecute | MemoryFlags::kMMapMaxAccessExecute
};
-// ============================================================================
-// [asmjit::VirtMem - Virtual Memory [Windows]]
-// ============================================================================
+// Virtual Memory [Windows]
+// ========================
#if defined(_WIN32)
+
struct ScopedHandle {
inline ScopedHandle() noexcept
: value(nullptr) {}
@@ -103,7 +90,7 @@ struct ScopedHandle {
HANDLE value;
};
-static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
+static void getVMInfo(Info& vmInfo) noexcept {
SYSTEM_INFO systemInfo;
::GetSystemInfo(&systemInfo);
@@ -111,15 +98,15 @@ static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
vmInfo.pageGranularity = systemInfo.dwAllocationGranularity;
}
-// Returns windows-specific protectFlags from \ref VirtMem::Flags.
-static DWORD VirtMem_winProtectFlagsFromFlags(uint32_t flags) noexcept {
+// Returns windows-specific protectFlags from \ref MemoryFlags.
+static DWORD protectFlagsFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
DWORD protectFlags;
// READ|WRITE|EXECUTE.
- if (flags & VirtMem::kAccessExecute)
- protectFlags = (flags & VirtMem::kAccessWrite) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
- else if (flags & VirtMem::kAccessRW)
- protectFlags = (flags & VirtMem::kAccessWrite) ? PAGE_READWRITE : PAGE_READONLY;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute))
+ protectFlags = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+ else if (Support::test(memoryFlags, MemoryFlags::kAccessRW))
+ protectFlags = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? PAGE_READWRITE : PAGE_READONLY;
else
protectFlags = PAGE_NOACCESS;
@@ -127,19 +114,23 @@ static DWORD VirtMem_winProtectFlagsFromFlags(uint32_t flags) noexcept {
return protectFlags;
}
-static DWORD VirtMem_winDesiredAccessFromFlags(uint32_t flags) noexcept {
- DWORD access = (flags & VirtMem::kAccessWrite) ? FILE_MAP_WRITE : FILE_MAP_READ;
- if (flags & VirtMem::kAccessExecute)
+static DWORD desiredAccessFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
+ DWORD access = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? FILE_MAP_WRITE : FILE_MAP_READ;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute))
access |= FILE_MAP_EXECUTE;
return access;
}
-Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
+static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
+ return HardenedRuntimeFlags::kNone;
+}
+
+Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
*p = nullptr;
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
- DWORD protectFlags = VirtMem_winProtectFlagsFromFlags(flags);
+ DWORD protectFlags = protectFlagsFromMemoryFlags(memoryFlags);
void* result = ::VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, protectFlags);
if (!result)
@@ -149,15 +140,15 @@ Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
return kErrorOk;
}
-Error VirtMem::release(void* p, size_t size) noexcept {
+Error release(void* p, size_t size) noexcept {
DebugUtils::unused(size);
if (ASMJIT_UNLIKELY(!::VirtualFree(p, 0, MEM_RELEASE)))
return DebugUtils::errored(kErrorInvalidArgument);
return kErrorOk;
}
-Error VirtMem::protect(void* p, size_t size, uint32_t flags) noexcept {
- DWORD protectFlags = VirtMem_winProtectFlagsFromFlags(flags);
+Error protect(void* p, size_t size, MemoryFlags memoryFlags) noexcept {
+ DWORD protectFlags = protectFlagsFromMemoryFlags(memoryFlags);
DWORD oldFlags;
if (::VirtualProtect(p, size, protectFlags, &oldFlags))
@@ -166,8 +157,8 @@ Error VirtMem::protect(void* p, size_t size, uint32_t flags) noexcept {
return DebugUtils::errored(kErrorInvalidArgument);
}
-Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept {
- dm->ro = nullptr;
+Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
+ dm->rx = nullptr;
dm->rw = nullptr;
if (size == 0)
@@ -187,8 +178,8 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
- uint32_t accessFlags = flags & ~VirtMem_dualMappingFilter[i];
- DWORD desiredAccess = VirtMem_winDesiredAccessFromFlags(accessFlags);
+ MemoryFlags accessFlags = memoryFlags & ~dualMappingFilter[i];
+ DWORD desiredAccess = desiredAccessFromMemoryFlags(accessFlags);
ptr[i] = ::MapViewOfFile(handle.value, desiredAccess, 0, 0, size);
if (ptr[i] == nullptr) {
@@ -198,37 +189,36 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
}
}
- dm->ro = ptr[0];
+ dm->rx = ptr[0];
dm->rw = ptr[1];
return kErrorOk;
}
-Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
+Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
DebugUtils::unused(size);
bool failed = false;
- if (!::UnmapViewOfFile(dm->ro))
+ if (!::UnmapViewOfFile(dm->rx))
failed = true;
- if (dm->ro != dm->rw && !UnmapViewOfFile(dm->rw))
+ if (dm->rx != dm->rw && !UnmapViewOfFile(dm->rw))
failed = true;
if (failed)
return DebugUtils::errored(kErrorInvalidArgument);
- dm->ro = nullptr;
+ dm->rx = nullptr;
dm->rw = nullptr;
return kErrorOk;
}
#endif
-// ============================================================================
-// [asmjit::VirtMem - Virtual Memory [Posix]]
-// ============================================================================
+// Virtual Memory [Posix]
+// ======================
#if !defined(_WIN32)
-static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
+static void getVMInfo(Info& vmInfo) noexcept {
uint32_t pageSize = uint32_t(::getpagesize());
vmInfo.pageSize = pageSize;
@@ -236,14 +226,14 @@ static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
}
#if !defined(SHM_ANON)
-static const char* VirtMem_getTmpDir() noexcept {
+static const char* getTmpDir() noexcept {
const char* tmpDir = getenv("TMPDIR");
return tmpDir ? tmpDir : "/tmp";
}
#endif
// Translates libc errors specific to VirtualMemory mapping to `asmjit::Error`.
-static Error VirtMem_asmjitErrorFromErrno(int e) noexcept {
+static Error asmjitErrorFromErrno(int e) noexcept {
switch (e) {
case EACCES:
case EAGAIN:
@@ -265,16 +255,14 @@ static Error VirtMem_asmjitErrorFromErrno(int e) noexcept {
}
}
-// Some operating systems don't allow /dev/shm to be executable. On Linux this
-// happens when /dev/shm is mounted with 'noexec', which is enforced by systemd.
-// Other operating systems like MacOS also restrict executable permissions regarding
-// /dev/shm, so we use a runtime detection before attempting to allocate executable
-// memory. Sometimes we don't need the detection as we know it would always result
-// in `kShmStrategyTmpDir`.
-enum ShmStrategy : uint32_t {
- kShmStrategyUnknown = 0,
- kShmStrategyDevShm = 1,
- kShmStrategyTmpDir = 2
+// Some operating systems don't allow /dev/shm to be executable. On Linux this happens when /dev/shm is mounted with
+// 'noexec', which is enforced by systemd. Other operating systems like MacOS also restrict executable permissions
+// regarding /dev/shm, so we use a runtime detection before attempting to allocate executable memory. Sometimes we
+// don't need the detection as we know it would always result in `ShmStrategy::kTmpDir`.
+enum class ShmStrategy : uint32_t {
+ kUnknown = 0,
+ kDevShm = 1,
+ kTmpDir = 2
};
class AnonymousMemory {
@@ -289,17 +277,17 @@ public:
FileType _fileType;
StringTmp<128> _tmpName;
- ASMJIT_INLINE AnonymousMemory() noexcept
+ inline AnonymousMemory() noexcept
: _fd(-1),
_fileType(kFileTypeNone),
_tmpName() {}
- ASMJIT_INLINE ~AnonymousMemory() noexcept {
+ inline ~AnonymousMemory() noexcept {
unlink();
close();
}
- ASMJIT_INLINE int fd() const noexcept { return _fd; }
+ inline int fd() const noexcept { return _fd; }
Error open(bool preferTmpOverDevShm) noexcept {
#if defined(__linux__) && defined(__NR_memfd_create)
@@ -319,7 +307,7 @@ public:
if (e == ENOSYS)
memfd_create_not_supported = 1;
else
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
#endif
@@ -331,13 +319,12 @@ public:
if (ASMJIT_LIKELY(_fd >= 0))
return kErrorOk;
else
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(errno));
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
#else
- // POSIX API. We have to generate somehow a unique name. This is nothing
- // cryptographic, just using a bit from the stack address to always have
- // a different base for different threads (as threads have their own stack)
- // and retries for avoiding collisions. We use `shm_open()` with flags that
- // require creation of the file so we never open an existing shared memory.
+ // POSIX API. We have to generate somehow a unique name. This is nothing cryptographic, just using a bit from
+ // the stack address to always have a different base for different threads (as threads have their own stack)
+ // and retries for avoiding collisions. We use `shm_open()` with flags that require creation of the file so we
+ // never open an existing shared memory.
static std::atomic<uint32_t> internalCounter;
const char* kShmFormat = "/shm-id-%016llX";
@@ -351,7 +338,7 @@ public:
bool useTmp = !ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm;
if (useTmp) {
- _tmpName.assign(VirtMem_getTmpDir());
+ _tmpName.assign(getTmpDir());
_tmpName.appendFormat(kShmFormat, (unsigned long long)bits);
_fd = ::open(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, 0);
if (ASMJIT_LIKELY(_fd >= 0)) {
@@ -372,7 +359,7 @@ public:
int e = errno;
if (e != EEXIST)
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
return DebugUtils::errored(kErrorFailedToOpenAnonymousMemory);
@@ -406,17 +393,30 @@ public:
Error allocate(size_t size) noexcept {
// TODO: Improve this by using `posix_fallocate()` when available.
if (ftruncate(_fd, off_t(size)) != 0)
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(errno));
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
return kErrorOk;
}
};
+// Returns `mmap()` protection flags from \ref MemoryFlags.
+static int mmProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
+ int protection = 0;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessRead)) protection |= PROT_READ;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessWrite)) protection |= PROT_READ | PROT_WRITE;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute)) protection |= PROT_READ | PROT_EXEC;
+ return protection;
+}
+
#if defined(__APPLE__)
-// Detects whether the current process is hardened, which means that pages that
-// have WRITE and EXECUTABLE flags cannot be allocated without MAP_JIT flag.
-static ASMJIT_INLINE bool VirtMem_isHardened() noexcept {
- static volatile uint32_t globalHardenedFlag;
+// Detects whether the current process is hardened, which means that pages that have WRITE and EXECUTABLE flags cannot
+// be allocated without MAP_JIT flag.
+static inline bool hasHardenedRuntimeMacOS() noexcept {
+#if TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
+ // MacOS on AArch64 has always hardened runtime enabled.
+ return true;
+#else
+ static std::atomic<uint32_t> globalHardenedFlag;
enum HardenedFlag : uint32_t {
kHardenedFlagUnknown = 0,
@@ -424,37 +424,40 @@ static ASMJIT_INLINE bool VirtMem_isHardened() noexcept {
kHardenedFlagEnabled = 2
};
- uint32_t flag = globalHardenedFlag;
+ uint32_t flag = globalHardenedFlag.load();
if (flag == kHardenedFlagUnknown) {
- VirtMem::Info memInfo;
- VirtMem_getInfo(memInfo);
+ size_t pageSize = ::getpagesize();
- void* ptr = mmap(nullptr, memInfo.pageSize, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ void* ptr = mmap(nullptr, pageSize, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (ptr == MAP_FAILED) {
flag = kHardenedFlagEnabled;
}
else {
flag = kHardenedFlagDisabled;
- munmap(ptr, memInfo.pageSize);
+ munmap(ptr, pageSize);
}
- globalHardenedFlag = flag;
+ globalHardenedFlag.store(flag);
}
return flag == kHardenedFlagEnabled;
+#endif
}
-// MAP_JIT flag required to run unsigned JIT code is only supported by kernel
-// version 10.14+ (Mojave) and IOS.
-static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
-#if TARGET_OS_OSX
- static volatile int globalVersion;
+static inline bool hasMapJitSupportMacOS() noexcept {
+#if TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
+ // MacOS for 64-bit AArch architecture always uses hardened runtime. Some documentation can be found here:
+ // - https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon
+ return true;
+#elif TARGET_OS_OSX
+ // MAP_JIT flag required to run unsigned JIT code is only supported by kernel version 10.14+ (Mojave) and IOS.
+ static std::atomic<uint32_t> globalVersion;
- int ver = globalVersion;
+ int ver = globalVersion.load();
if (!ver) {
- struct utsname osname;
+ struct utsname osname {};
uname(&osname);
ver = atoi(osname.release);
- globalVersion = ver;
+ globalVersion.store(ver);
}
return ver >= 18;
#else
@@ -462,53 +465,63 @@ static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
return true;
#endif
}
+#endif // __APPLE__
+
+// Detects whether the current process is hardened, which means that pages that have WRITE and EXECUTABLE flags
+// cannot be normally allocated. On MacOS such allocation requires MAP_JIT flag.
+static inline bool hasHardenedRuntime() noexcept {
+#if defined(__APPLE__)
+ return hasHardenedRuntimeMacOS();
+#else
+ return false;
#endif
+}
-// Returns `mmap()` protection flags from \ref VirtMem::Flags.
-static int VirtMem_mmProtFromFlags(uint32_t flags) noexcept {
- int protection = 0;
- if (flags & VirtMem::kAccessRead) protection |= PROT_READ;
- if (flags & VirtMem::kAccessWrite) protection |= PROT_READ | PROT_WRITE;
- if (flags & VirtMem::kAccessExecute) protection |= PROT_READ | PROT_EXEC;
- return protection;
+// Detects whether MAP_JIT is available.
+static inline bool hasMapJitSupport() noexcept {
+#if defined(__APPLE__)
+ return hasMapJitSupportMacOS();
+#else
+ return false;
+#endif
}
// Returns either MAP_JIT or 0 based on `flags` and the host operating system.
-static ASMJIT_INLINE int VirtMem_mmMapJitFromFlags(uint32_t flags) noexcept {
+static inline int mmMapJitFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
#if defined(__APPLE__)
- // Always use MAP_JIT flag if user asked for it (could be used for testing
- // on non-hardened processes) and detect whether it must be used when the
- // process is actually hardened (in that case it doesn't make sense to rely
- // on user `flags`).
- bool useMapJit = (flags & VirtMem::kMMapEnableMapJit) != 0 || VirtMem_isHardened();
+ // Always use MAP_JIT flag if user asked for it (could be used for testing on non-hardened processes) and detect
+ // whether it must be used when the process is actually hardened (in that case it doesn't make sense to rely on
+ // user `memoryFlags`).
+ bool useMapJit = Support::test(memoryFlags, MemoryFlags::kMMapEnableMapJit) || hasHardenedRuntime();
if (useMapJit)
- return VirtMem_hasMapJitSupport() ? int(MAP_JIT) : 0;
+ return hasMapJitSupport() ? int(MAP_JIT) : 0;
else
return 0;
#else
- DebugUtils::unused(flags);
+ DebugUtils::unused(memoryFlags);
return 0;
#endif
}
// Returns BSD-specific `PROT_MAX()` flags.
-static ASMJIT_INLINE int VirtMem_mmMaxProtFromFlags(uint32_t flags) noexcept {
+static inline int mmMaxProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
#if defined(PROT_MAX)
- static constexpr uint32_t kMaxProtShift = Support::constCtz(VirtMem::kMMapMaxAccessRead);
- if (flags & (VirtMem::kMMapMaxAccessReadWrite | VirtMem::kMMapMaxAccessExecute))
- return PROT_MAX(VirtMem_mmProtFromFlags(flags >> kMaxProtShift));
+ static constexpr uint32_t kMaxProtShift = Support::ConstCTZ<uint32_t(MemoryFlags::kMMapMaxAccessRead)>::value;
+
+ if (Support::test(memoryFlags, MemoryFlags::kMMapMaxAccessReadWrite | MemoryFlags::kMMapMaxAccessExecute))
+ return PROT_MAX(mmProtFromMemoryFlags((MemoryFlags)(uint32_t(memoryFlags) >> kMaxProtShift)));
else
return 0;
#else
- DebugUtils::unused(flags);
+ DebugUtils::unused(memoryFlags);
return 0;
#endif
}
#if ASMJIT_VM_SHM_DETECT
-static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept {
+static Error detectShmStrategy(ShmStrategy* strategyOut) noexcept {
AnonymousMemory anonMem;
- VirtMem::Info vmInfo = VirtMem::info();
+ Info vmInfo = info();
ASMJIT_PROPAGATE(anonMem.open(false));
ASMJIT_PROPAGATE(anonMem.allocate(vmInfo.pageSize));
@@ -517,46 +530,57 @@ static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept {
if (ptr == MAP_FAILED) {
int e = errno;
if (e == EINVAL) {
- *strategyOut = kShmStrategyTmpDir;
+ *strategyOut = ShmStrategy::kTmpDir;
return kErrorOk;
}
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
else {
munmap(ptr, vmInfo.pageSize);
- *strategyOut = kShmStrategyDevShm;
+ *strategyOut = ShmStrategy::kDevShm;
return kErrorOk;
}
}
#endif
-static Error VirtMem_getShmStrategy(uint32_t* strategyOut) noexcept {
+static Error getShmStrategy(ShmStrategy* strategyOut) noexcept {
#if ASMJIT_VM_SHM_DETECT
- // Initially don't assume anything. It has to be tested whether
- // '/dev/shm' was mounted with 'noexec' flag or not.
- static volatile uint32_t globalShmStrategy = kShmStrategyUnknown;
-
- uint32_t strategy = globalShmStrategy;
- if (strategy == kShmStrategyUnknown) {
- ASMJIT_PROPAGATE(VirtMem_detectShmStrategy(&strategy));
- globalShmStrategy = strategy;
+ // Initially don't assume anything. It has to be tested whether '/dev/shm' was mounted with 'noexec' flag or not.
+ static std::atomic<uint32_t> globalShmStrategy;
+
+ ShmStrategy strategy = static_cast<ShmStrategy>(globalShmStrategy.load());
+ if (strategy == ShmStrategy::kUnknown) {
+ ASMJIT_PROPAGATE(detectShmStrategy(&strategy));
+ globalShmStrategy.store(static_cast<uint32_t>(strategy));
}
*strategyOut = strategy;
return kErrorOk;
#else
- *strategyOut = kShmStrategyTmpDir;
+ *strategyOut = ShmStrategy::kTmpDir;
return kErrorOk;
#endif
}
-Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
+static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
+ HardenedRuntimeFlags hrFlags = HardenedRuntimeFlags::kNone;
+
+ if (hasHardenedRuntime())
+ hrFlags |= HardenedRuntimeFlags::kEnabled;
+
+ if (hasMapJitSupport())
+ hrFlags |= HardenedRuntimeFlags::kMapJit;
+
+ return hrFlags;
+}
+
+Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
*p = nullptr;
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
- int protection = VirtMem_mmProtFromFlags(flags) | VirtMem_mmMaxProtFromFlags(flags);
- int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | VirtMem_mmMapJitFromFlags(flags);
+ int protection = mmProtFromMemoryFlags(memoryFlags) | mmMaxProtFromMemoryFlags(memoryFlags);
+ int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | mmMapJitFromMemoryFlags(memoryFlags);
void* ptr = mmap(nullptr, size, protection, mmFlags, -1, 0);
if (ptr == MAP_FAILED)
@@ -566,7 +590,7 @@ Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
return kErrorOk;
}
-Error VirtMem::release(void* p, size_t size) noexcept {
+Error release(void* p, size_t size) noexcept {
if (ASMJIT_UNLIKELY(munmap(p, size) != 0))
return DebugUtils::errored(kErrorInvalidArgument);
@@ -574,26 +598,26 @@ Error VirtMem::release(void* p, size_t size) noexcept {
}
-Error VirtMem::protect(void* p, size_t size, uint32_t flags) noexcept {
- int protection = VirtMem_mmProtFromFlags(flags);
+Error protect(void* p, size_t size, MemoryFlags memoryFlags) noexcept {
+ int protection = mmProtFromMemoryFlags(memoryFlags);
if (mprotect(p, size, protection) == 0)
return kErrorOk;
return DebugUtils::errored(kErrorInvalidArgument);
}
-Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept {
- dm->ro = nullptr;
+Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
+ dm->rx = nullptr;
dm->rw = nullptr;
if (off_t(size) <= 0)
return DebugUtils::errored(size == 0 ? kErrorInvalidArgument : kErrorTooLarge);
- bool preferTmpOverDevShm = (flags & kMappingPreferTmp) != 0;
+ bool preferTmpOverDevShm = Support::test(memoryFlags, MemoryFlags::kMappingPreferTmp);
if (!preferTmpOverDevShm) {
- uint32_t strategy;
- ASMJIT_PROPAGATE(VirtMem_getShmStrategy(&strategy));
- preferTmpOverDevShm = (strategy == kShmStrategyTmpDir);
+ ShmStrategy strategy;
+ ASMJIT_PROPAGATE(getShmStrategy(&strategy));
+ preferTmpOverDevShm = (strategy == ShmStrategy::kTmpDir);
}
AnonymousMemory anonMem;
@@ -602,8 +626,8 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
- uint32_t accessFlags = flags & ~VirtMem_dualMappingFilter[i];
- int protection = VirtMem_mmProtFromFlags(accessFlags) | VirtMem_mmMaxProtFromFlags(accessFlags);
+ MemoryFlags accessFlags = memoryFlags & ~dualMappingFilter[i];
+ int protection = mmProtFromMemoryFlags(accessFlags) | mmMaxProtFromMemoryFlags(accessFlags);
ptr[i] = mmap(nullptr, size, protection, MAP_SHARED, anonMem.fd(), 0);
if (ptr[i] == MAP_FAILED) {
@@ -611,40 +635,61 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
int e = errno;
if (i == 1)
munmap(ptr[0], size);
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
}
- dm->ro = ptr[0];
+ dm->rx = ptr[0];
dm->rw = ptr[1];
return kErrorOk;
}
-Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
- Error err = release(dm->ro, size);
- if (dm->ro != dm->rw)
+Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
+ Error err = release(dm->rx, size);
+ if (dm->rx != dm->rw)
err |= release(dm->rw, size);
if (err)
return DebugUtils::errored(kErrorInvalidArgument);
- dm->ro = nullptr;
+ dm->rx = nullptr;
dm->rw = nullptr;
return kErrorOk;
}
#endif
-// ============================================================================
-// [asmjit::VirtMem - Virtual Memory [Memory Info]]
-// ============================================================================
+// Virtual Memory - Flush Instruction Cache
+// ========================================
+
+void flushInstructionCache(void* p, size_t size) noexcept {
+#if ASMJIT_ARCH_X86
+ // X86/X86_64 architecture doesn't require to do anything to flush instruction cache.
+ DebugUtils::unused(p, size);
+#elif defined(__APPLE__)
+ sys_icache_invalidate(p, size);
+#elif defined(_WIN32)
+ // Windows has a built-in support in `kernel32.dll`.
+ FlushInstructionCache(GetCurrentProcess(), p, size);
+#elif defined(__GNUC__)
+ char* start = static_cast<char*>(p);
+ char* end = start + size;
+ __builtin___clear_cache(start, end);
+#else
+ #pragma message("asmjit::VirtMem::flushInstructionCache() doesn't have implementation for the target OS and compiler")
+ DebugUtils::unused(p, size);
+#endif
+}
+
+// Virtual Memory - Memory Info
+// ============================
-VirtMem::Info VirtMem::info() noexcept {
- static VirtMem::Info vmInfo;
+Info info() noexcept {
static std::atomic<uint32_t> vmInfoInitialized;
+ static Info vmInfo;
if (!vmInfoInitialized.load()) {
- VirtMem::Info localMemInfo;
- VirtMem_getInfo(localMemInfo);
+ Info localMemInfo;
+ getVMInfo(localMemInfo);
vmInfo = localMemInfo;
vmInfoInitialized.store(1u);
@@ -653,6 +698,24 @@ VirtMem::Info VirtMem::info() noexcept {
return vmInfo;
}
-ASMJIT_END_NAMESPACE
+// Virtual Memory - Hardened Runtime Info
+// ======================================
+
+HardenedRuntimeInfo hardenedRuntimeInfo() noexcept {
+ return HardenedRuntimeInfo { getHardenedRuntimeFlags() };
+}
+
+// Virtual Memory - Project JIT Memory
+// ===================================
+
+void protectJitMemory(ProtectJitAccess access) noexcept {
+#if defined(ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP)
+ pthread_jit_write_protect_np(static_cast<uint32_t>(access));
+#else
+ DebugUtils::unused(access);
+#endif
+}
+
+ASMJIT_END_SUB_NAMESPACE
#endif
diff --git a/src/asmjit/core/virtmem.h b/src/asmjit/core/virtmem.h
index 07a2dff..50f0945 100644
--- a/src/asmjit/core/virtmem.h
+++ b/src/asmjit/core/virtmem.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_VIRTMEM_H_INCLUDED
#define ASMJIT_CORE_VIRTMEM_H_INCLUDED
@@ -34,127 +16,222 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_virtual_memory
//! \{
-// ============================================================================
-// [asmjit::VirtMem]
-// ============================================================================
-
//! Virtual memory management.
namespace VirtMem {
+//! Flushes instruction cache in the given region.
+//!
+//! Only useful on non-x86 architectures, however, it's a good practice to call it on any platform to make your
+//! code more portable.
+ASMJIT_API void flushInstructionCache(void* p, size_t size) noexcept;
+
+//! Virtual memory information.
+struct Info {
+ //! Virtual memory page size.
+ uint32_t pageSize;
+ //! Virtual memory page granularity.
+ uint32_t pageGranularity;
+};
+
+//! Returns virtual memory information, see `VirtMem::Info` for more details.
+ASMJIT_API Info info() noexcept;
+
//! Virtual memory access and mmap-specific flags.
-enum Flags : uint32_t {
- //! No access flags.
- kAccessNone = 0x00000000u,
+enum class MemoryFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
//! Memory is readable.
kAccessRead = 0x00000001u,
+
//! Memory is writable.
kAccessWrite = 0x00000002u,
+
//! Memory is executable.
kAccessExecute = 0x00000004u,
- //! A combination of \ref kAccessRead and \ref kAccessWrite.
+ //! A combination of \ref MemoryFlags::kAccessRead and \ref MemoryFlags::kAccessWrite.
kAccessReadWrite = kAccessRead | kAccessWrite,
- //! A combination of \ref kAccessRead, \ref kAccessWrite.
+
+ //! A combination of \ref MemoryFlags::kAccessRead, \ref MemoryFlags::kAccessWrite.
kAccessRW = kAccessRead | kAccessWrite,
- //! A combination of \ref kAccessRead and \ref kAccessExecute.
+
+ //! A combination of \ref MemoryFlags::kAccessRead and \ref MemoryFlags::kAccessExecute.
kAccessRX = kAccessRead | kAccessExecute,
- //! A combination of \ref kAccessRead, \ref kAccessWrite, and \ref kAccessExecute.
+
+ //! A combination of \ref MemoryFlags::kAccessRead, \ref MemoryFlags::kAccessWrite, and
+ //! \ref MemoryFlags::kAccessExecute.
kAccessRWX = kAccessRead | kAccessWrite | kAccessExecute,
- //! Use a `MAP_JIT` flag available on Apple platforms (introduced by Mojave),
- //! which allows JIT code to be executed in MAC bundles. This flag is not turned
- //! on by default, because when a process uses `fork()` the child process
- //! has no access to the pages mapped with `MAP_JIT`, which could break code
- //! that doesn't expect this behavior.
+ //! Use a `MAP_JIT` flag available on Apple platforms (introduced by Mojave), which allows JIT code to be executed
+ //! in MAC bundles. This flag is not turned on by default, because when a process uses `fork()` the child process
+ //! has no access to the pages mapped with `MAP_JIT`, which could break code that doesn't expect this behavior.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc().
kMMapEnableMapJit = 0x00000010u,
//! Pass `PROT_MAX(PROT_READ)` to mmap() on platforms that support `PROT_MAX`.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc().
kMMapMaxAccessRead = 0x00000020u,
//! Pass `PROT_MAX(PROT_WRITE)` to mmap() on platforms that support `PROT_MAX`.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc().
kMMapMaxAccessWrite = 0x00000040u,
//! Pass `PROT_MAX(PROT_EXEC)` to mmap() on platforms that support `PROT_MAX`.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc().
kMMapMaxAccessExecute = 0x00000080u,
- //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
+ //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessWrite.
kMMapMaxAccessReadWrite = kMMapMaxAccessRead | kMMapMaxAccessWrite,
- //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessWrite.
+
+ //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessWrite.
kMMapMaxAccessRW = kMMapMaxAccessRead | kMMapMaxAccessWrite,
- //! A combination of \ref kMMapMaxAccessRead and \ref kMMapMaxAccessExecute.
+
+ //! A combination of \ref MemoryFlags::kMMapMaxAccessRead and \ref MemoryFlags::kMMapMaxAccessExecute.
kMMapMaxAccessRX = kMMapMaxAccessRead | kMMapMaxAccessExecute,
- //! A combination of \ref kMMapMaxAccessRead, \ref kMMapMaxAccessWrite, \ref kMMapMaxAccessExecute.
+
+ //! A combination of \ref MemoryFlags::kMMapMaxAccessRead, \ref MemoryFlags::kMMapMaxAccessWrite, \ref
+ //! MemoryFlags::kMMapMaxAccessExecute.
kMMapMaxAccessRWX = kMMapMaxAccessRead | kMMapMaxAccessWrite | kMMapMaxAccessExecute,
- //! Not an access flag, only used by `allocDualMapping()` to override the
- //! default allocation strategy to always use a 'tmp' directory instead of
- //! "/dev/shm" (on POSIX platforms). Please note that this flag will be
- //! ignored if the operating system allows to allocate an executable memory
- //! by a different API than `open()` or `shm_open()`. For example on Linux
- //! `memfd_create()` is preferred and on BSDs `shm_open(SHM_ANON, ...)` is
- //! used if SHM_ANON is defined.
+ //! Not an access flag, only used by `allocDualMapping()` to override the default allocation strategy to always use
+ //! a 'tmp' directory instead of "/dev/shm" (on POSIX platforms). Please note that this flag will be ignored if the
+ //! operating system allows to allocate an executable memory by a different API than `open()` or `shm_open()`. For
+ //! example on Linux `memfd_create()` is preferred and on BSDs `shm_open(SHM_ANON, ...)` is used if SHM_ANON is
+ //! defined.
+ //!
+ //! \note This flag can only be used with \ref VirtMem::alloc().
kMappingPreferTmp = 0x80000000u
};
+ASMJIT_DEFINE_ENUM_FLAGS(MemoryFlags)
-//! Virtual memory information.
-struct Info {
- //! Virtual memory page size.
- uint32_t pageSize;
- //! Virtual memory page granularity.
- uint32_t pageGranularity;
-};
-
-//! Dual memory mapping used to map an anonymous memory into two memory regions
-//! where one region is read-only, but executable, and the second region is
-//! read+write, but not executable. Please see \ref VirtMem::allocDualMapping()
-//! for more details.
-struct DualMapping {
- //! Pointer to data with 'Read' or 'Read+Execute' access.
- void* ro;
- //! Pointer to data with 'Read-Write' access, but never 'Write+Execute'.
- void* rw;
-};
-
-//! Returns virtual memory information, see `VirtMem::Info` for more details.
-ASMJIT_API Info info() noexcept;
-
-//! Allocates virtual memory by either using `mmap()` (POSIX) or `VirtualAlloc()`
-//! (Windows).
+//! Allocates virtual memory by either using `mmap()` (POSIX) or `VirtualAlloc()` (Windows).
//!
-//! \note `size` should be aligned to page size, use \ref VirtMem::info()
-//! to obtain it. Invalid size will not be corrected by the implementation
-//! and the allocation would not succeed in such case.
-ASMJIT_API Error alloc(void** p, size_t size, uint32_t flags) noexcept;
+//! \note `size` should be aligned to page size, use \ref VirtMem::info() to obtain it. Invalid size will not be
+//! corrected by the implementation and the allocation would not succeed in such case.
+ASMJIT_API Error alloc(void** p, size_t size, MemoryFlags flags) noexcept;
//! Releases virtual memory previously allocated by \ref VirtMem::alloc().
//!
-//! \note The size must be the same as used by \ref VirtMem::alloc(). If the
-//! size is not the same value the call will fail on any POSIX system, but
-//! pass on Windows, because it's implemented differently.
+//! \note The size must be the same as used by \ref VirtMem::alloc(). If the size is not the same value the call
+//! will fail on any POSIX system, but pass on Windows, because it's implemented differently.
ASMJIT_API Error release(void* p, size_t size) noexcept;
-//! A cross-platform wrapper around `mprotect()` (POSIX) and `VirtualProtect()`
-//! (Windows).
-ASMJIT_API Error protect(void* p, size_t size, uint32_t flags) noexcept;
+//! A cross-platform wrapper around `mprotect()` (POSIX) and `VirtualProtect()` (Windows).
+ASMJIT_API Error protect(void* p, size_t size, MemoryFlags flags) noexcept;
+
+//! Dual memory mapping used to map an anonymous memory into two memory regions where one region is read-only, but
+//! executable, and the second region is read+write, but not executable. See \ref VirtMem::allocDualMapping() for
+//! more details.
+struct DualMapping {
+ //! Pointer to data with 'Read+Execute' access (this memory is not writable).
+ void* rx;
+ //! Pointer to data with 'Read+Write' access (this memory is not executable).
+ void* rw;
+};
-//! Allocates virtual memory and creates two views of it where the first view
-//! has no write access. This is an addition to the API that should be used
-//! in cases in which the operating system either enforces W^X security policy
-//! or the application wants to use this policy by default to improve security
-//! and prevent an accidental (or purposed) self-modifying code.
+//! Allocates virtual memory and creates two views of it where the first view has no write access. This is an addition
+//! to the API that should be used in cases in which the operating system either enforces W^X security policy or the
+//! application wants to use this policy by default to improve security and prevent an accidental (or purposed)
+//! self-modifying code.
//!
-//! The memory returned in the `dm` are two independent mappings of the same
-//! shared memory region. You must use \ref VirtMem::releaseDualMapping() to
-//! release it when it's no longer needed. Never use `VirtMem::release()` to
-//! release the memory returned by `allocDualMapping()` as that would fail on
-//! Windows.
+//! The memory returned in the `dm` are two independent mappings of the same shared memory region. You must use
+//! \ref VirtMem::releaseDualMapping() to release it when it's no longer needed. Never use `VirtMem::release()` to
+//! release the memory returned by `allocDualMapping()` as that would fail on Windows.
//!
//! \remarks Both pointers in `dm` would be set to `nullptr` if the function fails.
-ASMJIT_API Error allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept;
+ASMJIT_API Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags flags) noexcept;
//! Releases virtual memory mapping previously allocated by \ref VirtMem::allocDualMapping().
//!
//! \remarks Both pointers in `dm` would be set to `nullptr` if the function succeeds.
ASMJIT_API Error releaseDualMapping(DualMapping* dm, size_t size) noexcept;
+//! Hardened runtime flags.
+enum class HardenedRuntimeFlags : uint32_t {
+ //! No flags.
+ kNone = 0,
+
+ //! Hardened runtime is enabled - it's not possible to have "Write & Execute" memory protection. The runtime
+ //! enforces W^X (either write or execute).
+ //!
+ //! \note If the runtime is hardened it means that an operating system specific protection is used. For example on
+ //! MacOS platform it's possible to allocate memory with MAP_JIT flag and then use `pthread_jit_write_protect_np()`
+ //! to temporarily swap access permissions for the current thread. Dual mapping is also a possibility on X86/X64
+ //! architecture.
+ kEnabled = 0x00000001u,
+
+ //! Read+Write+Execute can only be allocated with MAP_JIT flag (Apple specific).
+ kMapJit = 0x00000002u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(HardenedRuntimeFlags)
+
+//! Hardened runtime information.
+struct HardenedRuntimeInfo {
+ //! Hardened runtime flags.
+ HardenedRuntimeFlags flags;
+};
+
+//! Returns runtime features provided by the OS.
+ASMJIT_API HardenedRuntimeInfo hardenedRuntimeInfo() noexcept;
+
+//! Values that can be used with `protectJitMemory()` function.
+enum class ProtectJitAccess : uint32_t {
+ //! Protect JIT memory with Read+Write permissions.
+ kReadWrite = 0,
+ //! Protect JIT memory with Read+Execute permissions.
+ kReadExecute = 1
+};
+
+//! Protects access of memory mapped with MAP_JIT flag for the current thread.
+//!
+//! \note This feature is only available on Apple hardware (AArch64) at the moment and and uses a non-portable
+//! `pthread_jit_write_protect_np()` call when available.
+//!
+//! This function must be called before and after a memory mapped with MAP_JIT flag is modified. Example:
+//!
+//! ```
+//! void* codePtr = ...;
+//! size_t codeSize = ...;
+//!
+//! VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
+//! memcpy(codePtr, source, codeSize);
+//! VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute);
+//! VirtMem::flushInstructionCache(codePtr, codeSize);
+//! ```
+//!
+//! See \ref ProtectJitReadWriteScope, which makes it simpler than the code above.
+ASMJIT_API void protectJitMemory(ProtectJitAccess access) noexcept;
+
+//! JIT protection scope that prepares the given memory block to be written to in the current thread.
+//!
+//! It calls `VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite)` at construction time and
+//! `VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute)` combined with `flushInstructionCache()`
+//! in destructor. The purpose of this class is to make writing to JIT memory easier.
+class ProtectJitReadWriteScope {
+public:
+ void* _rxPtr;
+ size_t _size;
+
+ //! Makes the given memory block RW protected.
+ ASMJIT_FORCE_INLINE ProtectJitReadWriteScope(void* rxPtr, size_t size) noexcept
+ : _rxPtr(rxPtr),
+ _size(size) {
+ protectJitMemory(ProtectJitAccess::kReadWrite);
+ }
+
+ // Not copyable.
+ ProtectJitReadWriteScope(const ProtectJitReadWriteScope& other) = delete;
+
+ //! Makes the memory block RX protected again and flushes instruction cache.
+ ASMJIT_FORCE_INLINE ~ProtectJitReadWriteScope() noexcept {
+ protectJitMemory(ProtectJitAccess::kReadExecute);
+ flushInstructionCache(_rxPtr, _size);
+ }
+};
+
} // VirtMem
//! \}
diff --git a/src/asmjit/core/zone.cpp b/src/asmjit/core/zone.cpp
index 61f7cec..d68e110 100644
--- a/src/asmjit/core/zone.cpp
+++ b/src/asmjit/core/zone.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/support.h"
@@ -27,17 +9,15 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::Zone - Statics]
-// ============================================================================
+// Zone - Globals
+// ==============
-// Zero size block used by `Zone` that doesn't have any memory allocated.
-// Should be allocated in read-only memory and should never be modified.
+// Zero size block used by `Zone` that doesn't have any memory allocated. Should be allocated in read-only memory
+// and should never be modified.
const Zone::Block Zone::_zeroBlock = { nullptr, nullptr, 0 };
-// ============================================================================
-// [asmjit::Zone - Init / Reset]
-// ============================================================================
+// Zone - Init & Reset
+// ===================
void Zone::_init(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept {
ASMJIT_ASSERT(blockSize >= kMinBlockSize);
@@ -66,28 +46,27 @@ void Zone::_init(size_t blockSize, size_t blockAlignment, const Support::Tempora
}
}
-void Zone::reset(uint32_t resetPolicy) noexcept {
+void Zone::reset(ResetPolicy resetPolicy) noexcept {
Block* cur = _block;
// Can't be altered.
if (cur == &_zeroBlock)
return;
- if (resetPolicy == Globals::kResetHard) {
+ if (resetPolicy == ResetPolicy::kHard) {
Block* initial = const_cast<Zone::Block*>(&_zeroBlock);
_ptr = initial->data();
_end = initial->data();
_block = initial;
- // Since cur can be in the middle of the double-linked list, we have to
- // traverse both directions (`prev` and `next`) separately to visit all.
+ // Since cur can be in the middle of the double-linked list, we have to traverse both directions (`prev` and
+ // `next`) separately to visit all.
Block* next = cur->next;
do {
Block* prev = cur->prev;
- // If this is the first block and this ZoneTmp is temporary then the
- // first block is statically allocated. We cannot free it and it makes
- // sense to keep it even when this is hard reset.
+ // If this is the first block and this ZoneTmp is temporary then the first block is statically allocated.
+ // We cannot free it and it makes sense to keep it even when this is hard reset.
if (prev == nullptr && _isTemporary) {
cur->prev = nullptr;
cur->next = nullptr;
@@ -113,9 +92,8 @@ void Zone::reset(uint32_t resetPolicy) noexcept {
}
}
-// ============================================================================
-// [asmjit::Zone - Alloc]
-// ============================================================================
+// Zone - Alloc
+// ============
void* Zone::_alloc(size_t size, size_t alignment) noexcept {
Block* curBlock = _block;
@@ -124,10 +102,9 @@ void* Zone::_alloc(size_t size, size_t alignment) noexcept {
size_t rawBlockAlignment = blockAlignment();
size_t minimumAlignment = Support::max<size_t>(alignment, rawBlockAlignment);
- // If the `Zone` has been cleared 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 in that case.
+ // If the `Zone` has been cleared 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 in that case.
if (next) {
uint8_t* ptr = Support::alignUp(next->data(), minimumAlignment);
uint8_t* end = Support::alignDown(next->data() + next->size, rawBlockAlignment);
@@ -147,18 +124,16 @@ void* Zone::_alloc(size_t size, size_t alignment) noexcept {
if (ASMJIT_UNLIKELY(newSize > SIZE_MAX - kBlockSize - blockAlignmentOverhead))
return nullptr;
- // Allocate new block - we add alignment overhead to `newSize`, which becomes the
- // new block size, and we also add `kBlockOverhead` to the allocator as it includes
- // members of `Zone::Block` structure.
+ // Allocate new block - we add alignment overhead to `newSize`, which becomes the new block size, and we also add
+ // `kBlockOverhead` to the allocator as it includes members of `Zone::Block` structure.
newSize += blockAlignmentOverhead;
Block* newBlock = static_cast<Block*>(::malloc(newSize + kBlockSize));
if (ASMJIT_UNLIKELY(!newBlock))
return nullptr;
- // Align the pointer to `minimumAlignment` and adjust the size of this block
- // accordingly. It's the same as using `minimumAlignment - Support::alignUpDiff()`,
- // just written differently.
+ // Align the pointer to `minimumAlignment` and adjust the size of this block accordingly. It's the same as using
+ // `minimumAlignment - Support::alignUpDiff()`, just written differently.
{
newBlock->prev = nullptr;
newBlock->next = nullptr;
@@ -168,9 +143,8 @@ void* Zone::_alloc(size_t size, size_t alignment) noexcept {
newBlock->prev = curBlock;
curBlock->next = newBlock;
- // Does only happen if there is a next block, but the requested memory
- // can't fit into it. In this case a new buffer is allocated and inserted
- // between the current block and the next one.
+ // Does only happen if there is a next block, but the requested memory can't fit into it. In this case a new
+ // buffer is allocated and inserted between the current block and the next one.
if (next) {
newBlock->next = next;
next->prev = newBlock;
@@ -226,9 +200,8 @@ char* Zone::sformat(const char* fmt, ...) noexcept {
return static_cast<char*>(dup(buf, size));
}
-// ============================================================================
-// [asmjit::ZoneAllocator - Helpers]
-// ============================================================================
+// ZoneAllocator - Utilities
+// =========================
#if defined(ASMJIT_BUILD_DEBUG)
static bool ZoneAllocator_hasDynamicBlock(ZoneAllocator* self, ZoneAllocator::DynamicBlock* block) noexcept {
@@ -242,9 +215,8 @@ static bool ZoneAllocator_hasDynamicBlock(ZoneAllocator* self, ZoneAllocator::Dy
}
#endif
-// ============================================================================
-// [asmjit::ZoneAllocator - Init / Reset]
-// ============================================================================
+// ZoneAllocator - Init & Reset
+// ============================
void ZoneAllocator::reset(Zone* zone) noexcept {
// Free dynamic blocks.
@@ -260,9 +232,8 @@ void ZoneAllocator::reset(Zone* zone) noexcept {
_zone = zone;
}
-// ============================================================================
-// [asmjit::ZoneAllocator - Alloc / Release]
-// ============================================================================
+// asmjit::ZoneAllocator - Alloc & Release
+// =======================================
void* ZoneAllocator::_alloc(size_t size, size_t& allocatedSize) noexcept {
ASMJIT_ASSERT(isInitialized());
diff --git a/src/asmjit/core/zone.h b/src/asmjit/core/zone.h
index 8947519..eaea252 100644
--- a/src/asmjit/core/zone.h
+++ b/src/asmjit/core/zone.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONE_H_INCLUDED
#define ASMJIT_CORE_ZONE_H_INCLUDED
@@ -31,20 +13,14 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::Zone]
-// ============================================================================
-
//! Zone memory.
//!
-//! Zone is an incremental memory allocator that allocates memory by simply
-//! incrementing a pointer. It allocates blocks of memory by using C's `malloc()`,
-//! but divides these blocks into smaller segments requested by calling
+//! Zone is an incremental memory allocator that allocates memory by simply incrementing a pointer. It allocates
+//! blocks of memory by using C's `malloc()`, but divides these blocks into smaller segments requested by calling
//! `Zone::alloc()` and friends.
//!
-//! Zone has no function to release the allocated memory. It has to be released
-//! all at once by calling `reset()`. If you need a more friendly allocator that
-//! also supports `release()`, consider using `Zone` with `ZoneAllocator`.
+//! Zone has no function to release the allocated memory. It has to be released all at once by calling `reset()`.
+//! If you need a more friendly allocator that also supports `release()`, consider using `Zone` with `ZoneAllocator`.
class Zone {
public:
ASMJIT_NONCOPYABLE(Zone)
@@ -103,28 +79,31 @@ public:
//! Creates a new Zone.
//!
- //! The `blockSize` parameter describes the default size of the block. If the
- //! `size` parameter passed to `alloc()` is greater than the default size
- //! `Zone` will allocate and use a larger block, but it will not change the
+ //! The `blockSize` parameter describes the default size of the block. If the `size` parameter passed to `alloc()`
+ //! is greater than the default size `Zone` will allocate and use a larger block, but it will not change the
//! default `blockSize`.
//!
- //! It's not required, but it's good practice to set `blockSize` to a
- //! reasonable value that depends on the usage of `Zone`. Greater block sizes
- //! are generally safer and perform better than unreasonably low block sizes.
- ASMJIT_INLINE explicit Zone(size_t blockSize, size_t blockAlignment = 1) noexcept {
+ //! It's not required, but it's good practice to set `blockSize` to a reasonable value that depends on the usage
+ //! of `Zone`. Greater block sizes are generally safer and perform better than unreasonably low block sizes.
+ inline explicit Zone(size_t blockSize, size_t blockAlignment = 1) noexcept {
_init(blockSize, blockAlignment, nullptr);
}
- ASMJIT_INLINE Zone(size_t blockSize, size_t blockAlignment, const Support::Temporary& temporary) noexcept {
+ //! Creates a new Zone with a first block pointing to a `temporary` memory.
+ inline Zone(size_t blockSize, size_t blockAlignment, const Support::Temporary& temporary) noexcept {
_init(blockSize, blockAlignment, &temporary);
}
+ //! \overload
+ inline Zone(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept {
+ _init(blockSize, blockAlignment, temporary);
+ }
+
//! Moves an existing `Zone`.
//!
- //! \note You cannot move an existing `ZoneTmp` as it uses embedded storage.
- //! Attempting to move `ZoneTmp` would result in assertion failure in debug
- //! mode and undefined behavior in release mode.
- ASMJIT_INLINE Zone(Zone&& other) noexcept
+ //! \note You cannot move an existing `ZoneTmp` as it uses embedded storage. Attempting to move `ZoneTmp` would
+ //! result in assertion failure in debug mode and undefined behavior in release mode.
+ inline Zone(Zone&& other) noexcept
: _ptr(other._ptr),
_end(other._end),
_block(other._block),
@@ -137,16 +116,16 @@ public:
//! Destroys the `Zone` instance.
//!
- //! This will destroy the `Zone` instance and release all blocks of memory
- //! allocated by it. It performs implicit `reset(Globals::kResetHard)`.
- ASMJIT_INLINE ~Zone() noexcept { reset(Globals::kResetHard); }
+ //! This will destroy the `Zone` instance and release all blocks of memory allocated by it. It performs implicit
+ //! `reset(ResetPolicy::kHard)`.
+ inline ~Zone() noexcept { reset(ResetPolicy::kHard); }
ASMJIT_API void _init(size_t blockSize, size_t blockAlignment, const Support::Temporary* temporary) noexcept;
//! Resets the `Zone` invalidating all blocks allocated.
//!
//! See `Globals::ResetPolicy` for more details.
- ASMJIT_API void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept;
+ ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
//! \}
@@ -154,29 +133,28 @@ public:
//! \{
//! Tests whether this `Zone` is actually a `ZoneTmp` that uses temporary memory.
- ASMJIT_INLINE bool isTemporary() const noexcept { return _isTemporary != 0; }
+ inline bool isTemporary() const noexcept { return _isTemporary != 0; }
//! Returns the default block size.
- ASMJIT_INLINE size_t blockSize() const noexcept { return _blockSize; }
+ inline size_t blockSize() const noexcept { return _blockSize; }
//! Returns the default block alignment.
- ASMJIT_INLINE size_t blockAlignment() const noexcept { return size_t(1) << _blockAlignmentShift; }
+ inline size_t blockAlignment() const noexcept { return size_t(1) << _blockAlignmentShift; }
//! Returns remaining size of the current block.
- ASMJIT_INLINE size_t remainingSize() const noexcept { return (size_t)(_end - _ptr); }
+ inline size_t remainingSize() const noexcept { return (size_t)(_end - _ptr); }
//! Returns the current zone cursor (dangerous).
//!
- //! This is a function that can be used to get exclusive access to the current
- //! block's memory buffer.
+ //! This is a function that can be used to get exclusive access to the current block's memory buffer.
template<typename T = uint8_t>
- ASMJIT_INLINE T* ptr() noexcept { return reinterpret_cast<T*>(_ptr); }
+ inline T* ptr() noexcept { return reinterpret_cast<T*>(_ptr); }
//! Returns the end of the current zone block, only useful if you use `ptr()`.
template<typename T = uint8_t>
- ASMJIT_INLINE T* end() noexcept { return reinterpret_cast<T*>(_end); }
+ inline T* end() noexcept { return reinterpret_cast<T*>(_end); }
//! Sets the current zone pointer to `ptr` (must be within the current block).
template<typename T>
- ASMJIT_INLINE void setPtr(T* ptr) noexcept {
+ inline void setPtr(T* ptr) noexcept {
uint8_t* p = reinterpret_cast<uint8_t*>(ptr);
ASMJIT_ASSERT(p >= _ptr && p <= _end);
_ptr = p;
@@ -184,7 +162,7 @@ public:
//! Sets the end zone pointer to `end` (must be within the current block).
template<typename T>
- ASMJIT_INLINE void setEnd(T* end) noexcept {
+ inline void setEnd(T* end) noexcept {
uint8_t* p = reinterpret_cast<uint8_t*>(end);
ASMJIT_ASSERT(p >= _ptr && p <= _end);
_end = p;
@@ -195,7 +173,7 @@ public:
//! \name Utilities
//! \{
- ASMJIT_INLINE void swap(Zone& other) noexcept {
+ inline void swap(Zone& other) noexcept {
// This could lead to a disaster.
ASMJIT_ASSERT(!this->isTemporary());
ASMJIT_ASSERT(!other.isTemporary());
@@ -207,30 +185,29 @@ public:
}
//! Aligns the current pointer to `alignment`.
- ASMJIT_INLINE void align(size_t alignment) noexcept {
+ inline void align(size_t alignment) noexcept {
_ptr = Support::min(Support::alignUp(_ptr, alignment), _end);
}
//! Ensures the remaining size is at least equal or greater than `size`.
//!
- //! \note This function doesn't respect any alignment. If you need to ensure
- //! there is enough room for an aligned allocation you need to call `align()`
- //! before calling `ensure()`.
- ASMJIT_INLINE Error ensure(size_t size) noexcept {
+ //! \note This function doesn't respect any alignment. If you need to ensure there is enough room for an aligned
+ //! allocation you need to call `align()` before calling `ensure()`.
+ inline Error ensure(size_t size) noexcept {
if (size <= remainingSize())
return kErrorOk;
else
return _alloc(0, 1) ? kErrorOk : DebugUtils::errored(kErrorOutOfMemory);
}
- ASMJIT_INLINE void _assignBlock(Block* block) noexcept {
+ inline void _assignBlock(Block* block) noexcept {
size_t alignment = blockAlignment();
_ptr = Support::alignUp(block->data(), alignment);
_end = Support::alignDown(block->data() + block->size, alignment);
_block = block;
}
- ASMJIT_INLINE void _assignZeroBlock() noexcept {
+ inline void _assignZeroBlock() noexcept {
Block* block = const_cast<Block*>(&_zeroBlock);
_ptr = block->data();
_end = block->data();
@@ -244,9 +221,8 @@ public:
//! Allocates the requested memory specified by `size`.
//!
- //! Pointer returned is valid until the `Zone` instance is destroyed or reset
- //! by calling `reset()`. If you plan to make an instance of C++ from the
- //! given pointer use placement `new` and `delete` operators:
+ //! Pointer returned is valid until the `Zone` instance is destroyed or reset 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;
@@ -274,7 +250,7 @@ public:
//! // Reset or destroy `Zone`.
//! zone.reset();
//! ```
- ASMJIT_INLINE void* alloc(size_t size) noexcept {
+ inline void* alloc(size_t size) noexcept {
if (ASMJIT_UNLIKELY(size > remainingSize()))
return _alloc(size, 1);
@@ -284,7 +260,7 @@ public:
}
//! Allocates the requested memory specified by `size` and `alignment`.
- ASMJIT_INLINE void* alloc(size_t size, size_t alignment) noexcept {
+ inline void* alloc(size_t size, size_t alignment) noexcept {
ASMJIT_ASSERT(Support::isPowerOf2(alignment));
uint8_t* ptr = Support::alignUp(_ptr, alignment);
@@ -298,7 +274,7 @@ public:
//! Allocates the requested memory specified by `size` without doing any checks.
//!
//! Can only be called if `remainingSize()` returns size at least equal to `size`.
- ASMJIT_INLINE void* allocNoCheck(size_t size) noexcept {
+ inline void* allocNoCheck(size_t size) noexcept {
ASMJIT_ASSERT(remainingSize() >= size);
uint8_t* ptr = _ptr;
@@ -309,7 +285,7 @@ public:
//! Allocates the requested memory specified by `size` and `alignment` without doing any checks.
//!
//! Performs the same operation as `Zone::allocNoCheck(size)` with `alignment` applied.
- ASMJIT_INLINE void* allocNoCheck(size_t size, size_t alignment) noexcept {
+ inline void* allocNoCheck(size_t size, size_t alignment) noexcept {
ASMJIT_ASSERT(Support::isPowerOf2(alignment));
uint8_t* ptr = Support::alignUp(_ptr, alignment);
@@ -324,25 +300,25 @@ public:
//! Like `alloc()`, but the return pointer is casted to `T*`.
template<typename T>
- ASMJIT_INLINE T* allocT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
+ inline T* allocT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
return static_cast<T*>(alloc(size, alignment));
}
//! Like `allocNoCheck()`, but the return pointer is casted to `T*`.
template<typename T>
- ASMJIT_INLINE T* allocNoCheckT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
+ inline T* allocNoCheckT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
return static_cast<T*>(allocNoCheck(size, alignment));
}
//! Like `allocZeroed()`, but the return pointer is casted to `T*`.
template<typename T>
- ASMJIT_INLINE T* allocZeroedT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
+ inline T* allocZeroedT(size_t size = sizeof(T), size_t alignment = alignof(T)) noexcept {
return static_cast<T*>(allocZeroed(size, alignment));
}
//! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
template<typename T>
- ASMJIT_INLINE T* newT() noexcept {
+ inline T* newT() noexcept {
void* p = alloc(sizeof(T), alignof(T));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
@@ -351,7 +327,7 @@ public:
//! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
template<typename T, typename... Args>
- ASMJIT_INLINE T* newT(Args&&... args) noexcept {
+ inline T* newT(Args&&... args) noexcept {
void* p = alloc(sizeof(T), alignof(T));
if (ASMJIT_UNLIKELY(!p))
return nullptr;
@@ -368,7 +344,7 @@ public:
ASMJIT_API void* dup(const void* data, size_t size, bool nullTerminate = false) noexcept;
//! Helper to duplicate data.
- ASMJIT_INLINE void* dupAligned(const void* data, size_t size, size_t alignment, bool nullTerminate = false) noexcept {
+ inline void* dupAligned(const void* data, size_t size, size_t alignment, bool nullTerminate = false) noexcept {
align(alignment);
return dup(data, size, nullTerminate);
}
@@ -379,15 +355,10 @@ public:
//! \}
};
-// ============================================================================
-// [b2d::ZoneTmp]
-// ============================================================================
-
//! \ref Zone with `N` bytes of a static storage, used for the initial block.
//!
-//! Temporary zones are used in cases where it's known that some memory will be
-//! required, but in many cases it won't exceed N bytes, so the whole operation
-//! can be performed without a dynamic memory allocation.
+//! Temporary zones are used in cases where it's known that some memory will be required, but in many cases it won't
+//! exceed N bytes, so the whole operation can be performed without a dynamic memory allocation.
template<size_t N>
class ZoneTmp : public Zone {
public:
@@ -399,35 +370,29 @@ public:
} _storage;
//! Creates a temporary zone. Dynamic block size is specified by `blockSize`.
- ASMJIT_INLINE explicit ZoneTmp(size_t blockSize, size_t blockAlignment = 1) noexcept
+ inline explicit ZoneTmp(size_t blockSize, size_t blockAlignment = 1) noexcept
: Zone(blockSize, blockAlignment, Support::Temporary(_storage.data, N)) {}
};
-// ============================================================================
-// [asmjit::ZoneAllocator]
-// ============================================================================
-
-//! Zone-based memory allocator that uses an existing `Zone` and provides a
-//! `release()` functionality on top of it. It uses `Zone` only for chunks
-//! that can be pooled, and uses libc `malloc()` for chunks that are large.
+//! Zone-based memory allocator that uses an existing `Zone` and provides a `release()` functionality on top of it.
+//! It uses `Zone` only for chunks that can be pooled, and uses libc `malloc()` for chunks that are large.
//!
-//! The advantage of ZoneAllocator is that it can allocate small chunks of memory
-//! really fast, and these chunks, when released, will be reused by consecutive
-//! calls to `alloc()`. Also, since ZoneAllocator uses `Zone`, you can turn any
-//! `Zone` into a `ZoneAllocator`, and use it in your `Pass` when necessary.
+//! The advantage of ZoneAllocator is that it can allocate small chunks of memory really fast, and these chunks,
+//! when released, will be reused by consecutive calls to `alloc()`. Also, since ZoneAllocator uses `Zone`, you can
+//! turn any `Zone` into a `ZoneAllocator`, and use it in your `Pass` when necessary.
//!
-//! ZoneAllocator is used by AsmJit containers to make containers having only
-//! few elements fast (and lightweight) and to allow them to grow and use
-//! dynamic blocks when require more storage.
+//! ZoneAllocator is used by AsmJit containers to make containers having only few elements fast (and lightweight)
+//! and to allow them to grow and use dynamic blocks when require more storage.
class ZoneAllocator {
public:
ASMJIT_NONCOPYABLE(ZoneAllocator)
//! \cond INTERNAL
- enum {
- // In short, we pool chunks of these sizes:
- // [32, 64, 96, 128, 192, 256, 320, 384, 448, 512]
+ // In short, we pool chunks of these sizes:
+ // [32, 64, 96, 128, 192, 256, 320, 384, 448, 512]
+
+ enum : uint32_t {
//! How many bytes per a low granularity pool (has to be at least 16).
kLoGranularity = 32,
//! Number of slots of a low granularity pool.
@@ -452,9 +417,8 @@ public:
Slot* next;
};
- //! A block of memory that has been allocated dynamically and is not part of
- //! block-list used by the allocator. This is used to keep track of all these
- //! blocks so they can be freed by `reset()` if not freed explicitly.
+ //! A block of memory that has been allocated dynamically and is not part of block-list used by the allocator.
+ //! This is used to keep track of all these blocks so they can be freed by `reset()` if not freed explicitly.
struct DynamicBlock {
DynamicBlock* prev;
DynamicBlock* next;
@@ -462,6 +426,9 @@ public:
//! \endcond
+ //! \name Members
+ //! \{
+
//! Zone used to allocate memory that fits into slots.
Zone* _zone;
//! Indexed slots containing released memory.
@@ -469,6 +436,8 @@ public:
//! Dynamic blocks for larger allocations (no slots).
DynamicBlock* _dynamicBlocks;
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -496,9 +465,9 @@ public:
//! It's the same as calling `reset(zone)`.
inline void init(Zone* zone) noexcept { reset(zone); }
- //! Resets this `ZoneAllocator` and also forget about the current `Zone` which
- //! is attached (if any). Reset optionally attaches a new `zone` passed, or
- //! keeps the `ZoneAllocator` in an uninitialized state, if `zone` is null.
+ //! Resets this `ZoneAllocator` and also forget about the current `Zone` which is attached (if any). Reset
+ //! optionally attaches a new `zone` passed, or keeps the `ZoneAllocator` in an uninitialized state, if
+ //! `zone` is null.
ASMJIT_API void reset(Zone* zone = nullptr) noexcept;
//! \}
@@ -506,8 +475,7 @@ public:
//! \name Accessors
//! \{
- //! Returns the assigned `Zone` of this allocator or null if this `ZoneAllocator`
- //! is not initialized.
+ //! Returns the assigned `Zone` of this allocator or null if this `ZoneAllocator` is not initialized.
inline Zone* zone() const noexcept { return _zone; }
//! \}
@@ -516,10 +484,10 @@ public:
//! \name Internals
//! \{
- //! Returns the slot index to be used for `size`. Returns `true` if a valid slot
- //! has been written to `slot` and `allocatedSize` has been filled with slot
- //! exact size (`allocatedSize` can be equal or slightly greater than `size`).
- static ASMJIT_INLINE bool _getSlotIndex(size_t size, uint32_t& slot) noexcept {
+ //! Returns the slot index to be used for `size`. Returns `true` if a valid slot has been written to `slot` and
+ //! `allocatedSize` has been filled with slot exact size (`allocatedSize` can be equal or slightly greater than
+ //! `size`).
+ static inline bool _getSlotIndex(size_t size, uint32_t& slot) noexcept {
ASMJIT_ASSERT(size > 0);
if (size > kHiMaxSize)
return false;
@@ -533,7 +501,7 @@ public:
}
//! \overload
- static ASMJIT_INLINE bool _getSlotIndex(size_t size, uint32_t& slot, size_t& allocatedSize) noexcept {
+ static inline bool _getSlotIndex(size_t size, uint32_t& slot, size_t& allocatedSize) noexcept {
ASMJIT_ASSERT(size > 0);
if (size > kHiMaxSize)
return false;
@@ -571,9 +539,8 @@ public:
return _alloc(size, allocatedSize);
}
- //! Like `alloc(size)`, but provides a second argument `allocatedSize` that
- //! provides a way to know how big the block returned actually is. This is
- //! useful for containers to prevent growing too early.
+ //! Like `alloc(size)`, but provides a second argument `allocatedSize` that provides a way to know how big
+ //! the block returned actually is. This is useful for containers to prevent growing too early.
inline void* alloc(size_t size, size_t& allocatedSize) noexcept {
ASMJIT_ASSERT(isInitialized());
return _alloc(size, allocatedSize);
@@ -621,9 +588,8 @@ public:
return new(p) T(std::forward<Args>(args)...);
}
- //! Releases the memory previously allocated by `alloc()`. The `size` argument
- //! has to be the same as used to call `alloc()` or `allocatedSize` returned
- //! by `alloc()`.
+ //! Releases the memory previously allocated by `alloc()`. The `size` argument has to be the same as used to call
+ //! `alloc()` or `allocatedSize` returned by `alloc()`.
inline void release(void* p, size_t size) noexcept {
ASMJIT_ASSERT(isInitialized());
ASMJIT_ASSERT(p != nullptr);
diff --git a/src/asmjit/core/zonehash.cpp b/src/asmjit/core/zonehash.cpp
index fb48d85..3778fbe 100644
--- a/src/asmjit/core/zonehash.cpp
+++ b/src/asmjit/core/zonehash.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/support.h"
@@ -28,9 +10,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ZoneHashBase - Helpers]
-// ============================================================================
+// ZoneHashBase - Prime Numbers
+// ============================
#define ASMJIT_POPULATE_PRIMES(ENTRY) \
ENTRY(2 , 0x80000000, 32), /* [N * 0x80000000 >> 32] (rcp=2147483648) */ \
@@ -183,9 +164,8 @@ static const uint8_t ZoneHash_primeShift[] = {
#undef E
};
-// ============================================================================
-// [asmjit::ZoneHashBase - Rehash]
-// ============================================================================
+// ZoneHashBase - Rehash
+// =====================
void ZoneHashBase::_rehash(ZoneAllocator* allocator, uint32_t primeIndex) noexcept {
ASMJIT_ASSERT(primeIndex < ASMJIT_ARRAY_SIZE(ZoneHash_primeArray));
@@ -225,9 +205,8 @@ void ZoneHashBase::_rehash(ZoneAllocator* allocator, uint32_t primeIndex) noexce
allocator->release(oldData, oldCount * sizeof(ZoneHashNode*));
}
-// ============================================================================
-// [asmjit::ZoneHashBase - Ops]
-// ============================================================================
+// ZoneHashBase - Operations
+// =========================
ZoneHashNode* ZoneHashBase::_insert(ZoneAllocator* allocator, ZoneHashNode* node) noexcept {
uint32_t hashMod = _calcMod(node->_hashCode);
@@ -266,9 +245,8 @@ ZoneHashNode* ZoneHashBase::_remove(ZoneAllocator* allocator, ZoneHashNode* node
return nullptr;
}
-// ============================================================================
-// [asmjit::ZoneHash - Unit]
-// ============================================================================
+// ZoneHashBase - Tests
+// ====================
#if defined(ASMJIT_TEST)
struct MyHashNode : public ZoneHashNode {
diff --git a/src/asmjit/core/zonehash.h b/src/asmjit/core/zonehash.h
index dbad427..f332290 100644
--- a/src/asmjit/core/zonehash.h
+++ b/src/asmjit/core/zonehash.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONEHASH_H_INCLUDED
#define ASMJIT_CORE_ZONEHASH_H_INCLUDED
@@ -31,14 +13,9 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneHashNode]
-// ============================================================================
-
//! Node used by \ref ZoneHash template.
//!
-//! You must provide function `bool eq(const Key& key)` in order to make
-//! `ZoneHash::get()` working.
+//! You must provide function `bool eq(const Key& key)` in order to make `ZoneHash::get()` working.
class ZoneHashNode {
public:
ASMJIT_NONCOPYABLE(ZoneHashNode)
@@ -56,10 +33,6 @@ public:
uint32_t _customData;
};
-// ============================================================================
-// [asmjit::ZoneHashBase]
-// ============================================================================
-
//! Base class used by \ref ZoneHash template
class ZoneHashBase {
public:
@@ -162,16 +135,11 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::ZoneHash]
-// ============================================================================
-
//! Low-level hash table specialized for storing string keys and POD values.
//!
-//! This hash table allows duplicates to be inserted (the API is so low
-//! level that it's up to you if you allow it or not, as you should first
-//! `get()` the node and then modify it or insert a new node by using `insert()`,
-//! depending on the intention).
+//! This hash table allows duplicates to be inserted (the API is so low level that it's up to you if you allow it or
+//! not, as you should first `get()` the node and then modify it or insert a new node by using `insert()`, depending
+//! on the intention).
template<typename NodeT>
class ZoneHash : public ZoneHashBase {
public:
diff --git a/src/asmjit/core/zonelist.cpp b/src/asmjit/core/zonelist.cpp
index 3496aa8..d4b311d 100644
--- a/src/asmjit/core/zonelist.cpp
+++ b/src/asmjit/core/zonelist.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/zone.h"
@@ -27,9 +9,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ZoneList - Unit]
-// ============================================================================
+// ZoneList - Tests
+// ================
#if defined(ASMJIT_TEST)
class MyListNode : public ZoneListNode<MyListNode> {};
diff --git a/src/asmjit/core/zonelist.h b/src/asmjit/core/zonelist.h
index d7fb1dd..c5e0013 100644
--- a/src/asmjit/core/zonelist.h
+++ b/src/asmjit/core/zonelist.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONELIST_H_INCLUDED
#define ASMJIT_CORE_ZONELIST_H_INCLUDED
@@ -31,17 +13,28 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneListNode]
-// ============================================================================
-
//! Node used by \ref ZoneList template.
template<typename NodeT>
class ZoneListNode {
public:
ASMJIT_NONCOPYABLE(ZoneListNode)
- NodeT* _listNodes[Globals::kLinkCount];
+ //! \name Constants
+ //! \{
+
+ enum : size_t {
+ kNodeIndexPrev = 0,
+ kNodeIndexNext = 1
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ NodeT* _listNodes[2];
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -57,26 +50,37 @@ public:
//! \name Accessors
//! \{
- inline bool hasPrev() const noexcept { return _listNodes[Globals::kLinkPrev] != nullptr; }
- inline bool hasNext() const noexcept { return _listNodes[Globals::kLinkNext] != nullptr; }
+ inline bool hasPrev() const noexcept { return _listNodes[kNodeIndexPrev] != nullptr; }
+ inline bool hasNext() const noexcept { return _listNodes[kNodeIndexNext] != nullptr; }
- inline NodeT* prev() const noexcept { return _listNodes[Globals::kLinkPrev]; }
- inline NodeT* next() const noexcept { return _listNodes[Globals::kLinkNext]; }
+ inline NodeT* prev() const noexcept { return _listNodes[kNodeIndexPrev]; }
+ inline NodeT* next() const noexcept { return _listNodes[kNodeIndexNext]; }
//! \}
};
-// ============================================================================
-// [asmjit::ZoneList<T>]
-// ============================================================================
-
//! Zone allocated list container that uses nodes of `NodeT` type.
template <typename NodeT>
class ZoneList {
public:
ASMJIT_NONCOPYABLE(ZoneList)
- NodeT* _nodes[Globals::kLinkCount];
+ //! \name Constants
+ //! \{
+
+ enum : size_t {
+ kNodeIndexFirst = 0,
+ kNodeIndexLast = 1
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ NodeT* _nodes[2];
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -98,8 +102,8 @@ public:
//! \{
inline bool empty() const noexcept { return _nodes[0] == nullptr; }
- inline NodeT* first() const noexcept { return _nodes[Globals::kLinkFirst]; }
- inline NodeT* last() const noexcept { return _nodes[Globals::kLinkLast]; }
+ inline NodeT* first() const noexcept { return _nodes[kNodeIndexFirst]; }
+ inline NodeT* last() const noexcept { return _nodes[kNodeIndexLast]; }
//! \}
@@ -140,11 +144,11 @@ public:
node->_listNodes[ dir] = next;
}
- inline void append(NodeT* node) noexcept { _addNode(node, Globals::kLinkLast); }
- inline void prepend(NodeT* node) noexcept { _addNode(node, Globals::kLinkFirst); }
+ inline void append(NodeT* node) noexcept { _addNode(node, kNodeIndexLast); }
+ inline void prepend(NodeT* node) noexcept { _addNode(node, kNodeIndexFirst); }
- inline void insertAfter(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkNext); }
- inline void insertBefore(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkPrev); }
+ inline void insertAfter(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, NodeT::kNodeIndexNext); }
+ inline void insertBefore(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, NodeT::kNodeIndexPrev); }
inline NodeT* unlink(NodeT* node) noexcept {
NodeT* prev = node->prev();
diff --git a/src/asmjit/core/zonestack.cpp b/src/asmjit/core/zonestack.cpp
index 52841b5..77e6f20 100644
--- a/src/asmjit/core/zonestack.cpp
+++ b/src/asmjit/core/zonestack.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/zone.h"
@@ -27,15 +9,14 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ZoneStackBase - Init / Reset]
-// ============================================================================
+// ZoneStackBase - Init & Reset
+// ============================
Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcept {
ZoneAllocator* oldAllocator = _allocator;
if (oldAllocator) {
- Block* block = _block[Globals::kLinkFirst];
+ Block* block = _block[kBlockIndexFirst];
while (block) {
Block* next = block->next();
oldAllocator->release(block, kBlockSize);
@@ -43,8 +24,8 @@ Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcep
}
_allocator = nullptr;
- _block[Globals::kLinkLeft] = nullptr;
- _block[Globals::kLinkRight] = nullptr;
+ _block[kBlockIndexFirst] = nullptr;
+ _block[kBlockIndexLast] = nullptr;
}
if (allocator) {
@@ -52,22 +33,21 @@ Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcep
if (ASMJIT_UNLIKELY(!block))
return DebugUtils::errored(kErrorOutOfMemory);
- block->_link[Globals::kLinkLeft] = nullptr;
- block->_link[Globals::kLinkRight] = nullptr;
+ block->_link[kBlockIndexPrev] = nullptr;
+ block->_link[kBlockIndexNext] = nullptr;
block->_start = (uint8_t*)block + middleIndex;
block->_end = (uint8_t*)block + middleIndex;
_allocator = allocator;
- _block[Globals::kLinkLeft] = block;
- _block[Globals::kLinkRight] = block;
+ _block[kBlockIndexFirst] = block;
+ _block[kBlockIndexLast] = block;
}
return kErrorOk;
}
-// ============================================================================
-// [asmjit::ZoneStackBase - Ops]
-// ============================================================================
+// ZoneStackBase - Operations
+// ==========================
Error ZoneStackBase::_prepareBlock(uint32_t side, size_t initialIndex) noexcept {
ASMJIT_ASSERT(isInitialized());
@@ -109,9 +89,8 @@ void ZoneStackBase::_cleanupBlock(uint32_t side, size_t middleIndex) noexcept {
}
}
-// ============================================================================
-// [asmjit::ZoneStack - Unit]
-// ============================================================================
+// ZoneStack - Tests
+// =================
#if defined(ASMJIT_TEST)
template<typename T>
diff --git a/src/asmjit/core/zonestack.h b/src/asmjit/core/zonestack.h
index e2aaa6f..aea7b68 100644
--- a/src/asmjit/core/zonestack.h
+++ b/src/asmjit/core/zonestack.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONESTACK_H_INCLUDED
#define ASMJIT_CORE_ZONESTACK_H_INCLUDED
@@ -31,24 +13,43 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneStackBase]
-// ============================================================================
-
//! Base class used by \ref ZoneStack.
class ZoneStackBase {
public:
ASMJIT_NONCOPYABLE(ZoneStackBase)
- static constexpr uint32_t kBlockSize = ZoneAllocator::kHiMaxSize;
+ //! \name Constants
+ //! \{
+
+ enum : size_t {
+ kBlockIndexPrev = 0,
+ kBlockIndexNext = 1,
+
+ kBlockIndexFirst = 0,
+ kBlockIndexLast = 1,
+
+ kBlockSize = ZoneAllocator::kHiMaxSize
+ };
+
+ //! \}
+
+ //! \name Types
+ //! \{
struct Block {
+ //! Next and previous blocks.
+ Block* _link[2];
+ //! Pointer to the start of the array.
+ void* _start;
+ //! Pointer to the end of the array.
+ void* _end;
+
inline bool empty() const noexcept { return _start == _end; }
- inline Block* prev() const noexcept { return _link[Globals::kLinkLeft]; }
- inline Block* next() const noexcept { return _link[Globals::kLinkRight]; }
+ inline Block* prev() const noexcept { return _link[kBlockIndexPrev]; }
+ inline Block* next() const noexcept { return _link[kBlockIndexNext]; }
- inline void setPrev(Block* block) noexcept { _link[Globals::kLinkLeft] = block; }
- inline void setNext(Block* block) noexcept { _link[Globals::kLinkRight] = block; }
+ inline void setPrev(Block* block) noexcept { _link[kBlockIndexPrev] = block; }
+ inline void setNext(Block* block) noexcept { _link[kBlockIndexNext] = block; }
template<typename T>
inline T* start() const noexcept { return static_cast<T*>(_start); }
@@ -74,18 +75,21 @@ public:
return (uintptr_t)_end <= ((uintptr_t)this + kEndBlockIndex - sizeof(T));
}
-
- Block* _link[Globals::kLinkCount]; //!< Next and previous blocks.
- void* _start; //!< Pointer to the start of the array.
- void* _end; //!< Pointer to the end of the array.
};
+ //! \}
+
+ //! \name Members
+ //! \{
+
//! Allocator used to allocate data.
ZoneAllocator* _allocator;
//! First and last blocks.
- Block* _block[Globals::kLinkCount];
+ Block* _block[2];
- //! \name Construction / Destruction
+ //! \}
+
+ //! \name Construction & Destruction
//! \{
inline ZoneStackBase() noexcept {
@@ -125,16 +129,15 @@ public:
//! \endcond
};
-// ============================================================================
-// [asmjit::ZoneStack<T>]
-// ============================================================================
-
//! Zone allocated stack container.
template<typename T>
class ZoneStack : public ZoneStackBase {
public:
ASMJIT_NONCOPYABLE(ZoneStack)
+ //! \name Constants
+ //! \{
+
enum : uint32_t {
kNumBlockItems = uint32_t((kBlockSize - sizeof(Block)) / sizeof(T)),
kStartBlockIndex = uint32_t(sizeof(Block)),
@@ -142,7 +145,9 @@ public:
kEndBlockIndex = uint32_t(kStartBlockIndex + (kNumBlockItems ) * sizeof(T))
};
- //! \name Construction / Destruction
+ //! \}
+
+ //! \name Construction & Destruction
//! \{
inline ZoneStack() noexcept {}
@@ -155,13 +160,13 @@ public:
//! \name Utilities
//! \{
- ASMJIT_INLINE Error prepend(T item) noexcept {
+ inline Error prepend(T item) noexcept {
ASMJIT_ASSERT(isInitialized());
- Block* block = _block[Globals::kLinkFirst];
+ Block* block = _block[kBlockIndexFirst];
if (!block->canPrepend<T>()) {
- ASMJIT_PROPAGATE(_prepareBlock(Globals::kLinkFirst, kEndBlockIndex));
- block = _block[Globals::kLinkFirst];
+ ASMJIT_PROPAGATE(_prepareBlock(kBlockIndexFirst, kEndBlockIndex));
+ block = _block[kBlockIndexFirst];
}
T* ptr = block->start<T>() - 1;
@@ -171,13 +176,13 @@ public:
return kErrorOk;
}
- ASMJIT_INLINE Error append(T item) noexcept {
+ inline Error append(T item) noexcept {
ASMJIT_ASSERT(isInitialized());
- Block* block = _block[Globals::kLinkLast];
+ Block* block = _block[kBlockIndexLast];
if (!block->canAppend<T>()) {
- ASMJIT_PROPAGATE(_prepareBlock(Globals::kLinkLast, kStartBlockIndex));
- block = _block[Globals::kLinkLast];
+ ASMJIT_PROPAGATE(_prepareBlock(kBlockIndexLast, kStartBlockIndex));
+ block = _block[kBlockIndexLast];
}
T* ptr = block->end<T>();
@@ -188,11 +193,11 @@ public:
return kErrorOk;
}
- ASMJIT_INLINE T popFirst() noexcept {
+ inline T popFirst() noexcept {
ASMJIT_ASSERT(isInitialized());
ASMJIT_ASSERT(!empty());
- Block* block = _block[Globals::kLinkFirst];
+ Block* block = _block[kBlockIndexFirst];
ASMJIT_ASSERT(!block->empty());
T* ptr = block->start<T>();
@@ -200,16 +205,16 @@ public:
block->setStart(ptr);
if (block->empty())
- _cleanupBlock(Globals::kLinkFirst, kMidBlockIndex);
+ _cleanupBlock(kBlockIndexFirst, kMidBlockIndex);
return item;
}
- ASMJIT_INLINE T pop() noexcept {
+ inline T pop() noexcept {
ASMJIT_ASSERT(isInitialized());
ASMJIT_ASSERT(!empty());
- Block* block = _block[Globals::kLinkLast];
+ Block* block = _block[kBlockIndexLast];
ASMJIT_ASSERT(!block->empty());
T* ptr = block->end<T>();
@@ -219,7 +224,7 @@ public:
block->setEnd(ptr);
if (block->empty())
- _cleanupBlock(Globals::kLinkLast, kMidBlockIndex);
+ _cleanupBlock(kBlockIndexLast, kMidBlockIndex);
return item;
}
diff --git a/src/asmjit/core/zonestring.h b/src/asmjit/core/zonestring.h
index cb25b29..01f5bd8 100644
--- a/src/asmjit/core/zonestring.h
+++ b/src/asmjit/core/zonestring.h
@@ -1,28 +1,10 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
-#ifndef ASMJIT_CORE_SMALLSTRING_H_INCLUDED
-#define ASMJIT_CORE_SMALLSTRING_H_INCLUDED
+#ifndef ASMJIT_CORE_ZONESTRING_H_INCLUDED
+#define ASMJIT_CORE_ZONESTRING_H_INCLUDED
#include "../core/globals.h"
#include "../core/zone.h"
@@ -32,10 +14,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneStringBase]
-// ============================================================================
-
//! A helper class used by \ref ZoneString implementation.
struct ZoneStringBase {
union {
@@ -74,28 +52,34 @@ struct ZoneStringBase {
}
};
-// ============================================================================
-// [asmjit::ZoneString<N>]
-// ============================================================================
-
//! A string template that can be zone allocated.
//!
-//! Helps with creating strings that can be either statically allocated if they
-//! are small, or externally allocated in case their size exceeds the limit.
-//! The `N` represents the size of the whole `ZoneString` structure, based on
+//! Helps with creating strings that can be either statically allocated if they are small, or externally allocated
+//! in case their size exceeds the limit. The `N` represents the size of the whole `ZoneString` structure, based on
//! that size the maximum size of the internal buffer is determined.
template<size_t N>
class ZoneString {
public:
- static constexpr uint32_t kWholeSize =
- (N > sizeof(ZoneStringBase)) ? uint32_t(N) : uint32_t(sizeof(ZoneStringBase));
- static constexpr uint32_t kMaxEmbeddedSize = kWholeSize - 5;
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ kWholeSize = (N > sizeof(ZoneStringBase)) ? uint32_t(N) : uint32_t(sizeof(ZoneStringBase)),
+ kMaxEmbeddedSize = kWholeSize - 5
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
union {
ZoneStringBase _base;
char _wholeData[kWholeSize];
};
+ //! \}
+
//! \name Construction & Destruction
//! \{
@@ -120,9 +104,8 @@ public:
//! Copies a new `data` of the given `size` to the string.
//!
- //! If the `size` exceeds the internal buffer the given `zone` will be
- //! used to duplicate the data, otherwise the internal buffer will be
- //! used as a storage.
+ //! If the `size` exceeds the internal buffer the given `zone` will be used to duplicate the data, otherwise
+ //! the internal buffer will be used as a storage.
inline Error setData(Zone* zone, const char* data, size_t size) noexcept {
return _base.setData(zone, kMaxEmbeddedSize, data, size);
}
@@ -134,4 +117,4 @@ public:
ASMJIT_END_NAMESPACE
-#endif // ASMJIT_CORE_SMALLSTRING_H_INCLUDED
+#endif // ASMJIT_CORE_ZONESTRING_H_INCLUDED
diff --git a/src/asmjit/core/zonetree.cpp b/src/asmjit/core/zonetree.cpp
index a16f092..8c42af8 100644
--- a/src/asmjit/core/zonetree.cpp
+++ b/src/asmjit/core/zonetree.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/support.h"
@@ -28,9 +10,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ZoneTree - Unit]
-// ============================================================================
+// ZoneTreeBase - Tests
+// ====================
#if defined(ASMJIT_TEST)
template<typename NodeT>
diff --git a/src/asmjit/core/zonetree.h b/src/asmjit/core/zonetree.h
index 1877919..41c4e0e 100644
--- a/src/asmjit/core/zonetree.h
+++ b/src/asmjit/core/zonetree.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONETREE_H_INCLUDED
#define ASMJIT_CORE_ZONETREE_H_INCLUDED
@@ -31,10 +13,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneTreeNode]
-// ============================================================================
-
//! RB-Tree node.
//!
//! The color is stored in a least significant bit of the `left` node.
@@ -44,12 +22,22 @@ class ZoneTreeNode {
public:
ASMJIT_NONCOPYABLE(ZoneTreeNode)
+ //! \name Constants
+ //! \{
+
enum : uintptr_t {
kRedMask = 0x1,
kPtrMask = ~kRedMask
};
- uintptr_t _rbNodeData[Globals::kLinkCount];
+ //! \}
+
+ //! \name Members
+ //! \{
+
+ uintptr_t _rbNodeData[2];
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -123,10 +111,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::ZoneTree]
-// ============================================================================
-
//! RB-Tree.
template<typename NodeT>
class ZoneTree {
@@ -164,7 +148,7 @@ public:
std::swap(_root, other._root);
}
- template<typename CompareT = Support::Compare<Support::kSortAscending>>
+ template<typename CompareT = Support::Compare<Support::SortOrder::kAscending>>
void insert(NodeT* node, const CompareT& cmp = CompareT()) noexcept {
// Node to insert must not contain garbage.
ASMJIT_ASSERT(!node->hasLeft());
@@ -176,18 +160,18 @@ public:
return;
}
- ZoneTreeNode head; // False root node,
- head._setRight(_root); // having root on the right.
+ ZoneTreeNode head; // False root node,
+ head._setRight(_root); // having root on the right.
- ZoneTreeNode* g = nullptr; // Grandparent.
- ZoneTreeNode* p = nullptr; // Parent.
- ZoneTreeNode* t = &head; // Iterator.
- ZoneTreeNode* q = _root; // Query.
+ ZoneTreeNode* g = nullptr; // Grandparent.
+ ZoneTreeNode* p = nullptr; // Parent.
+ ZoneTreeNode* t = &head; // Iterator.
+ ZoneTreeNode* q = _root; // Query.
- size_t dir = 0; // Direction for accessing child nodes.
- size_t last = 0; // Not needed to initialize, but makes some tools happy.
+ size_t dir = 0; // Direction for accessing child nodes.
+ size_t last = 0; // Not needed to initialize, but makes some tools happy.
- node->_makeRed(); // New nodes are always red and violations fixed appropriately.
+ node->_makeRed(); // New nodes are always red and violations fixed appropriately.
// Search down the tree.
for (;;) {
@@ -229,7 +213,7 @@ public:
}
//! Remove node from RBTree.
- template<typename CompareT = Support::Compare<Support::kSortAscending>>
+ template<typename CompareT = Support::Compare<Support::SortOrder::kAscending>>
void remove(ZoneTreeNode* node, const CompareT& cmp = CompareT()) noexcept {
ZoneTreeNode head; // False root node,
head._setRight(_root); // having root on the right.
@@ -304,10 +288,9 @@ public:
p->_setChild(p->_getRight() == q,
q->_getChild(q->_getLeft() == nullptr));
- // NOTE: The original algorithm used a trick to just copy 'key/value' to
- // `f` and mark `q` for deletion. But this is unacceptable here as we
- // really want to destroy the passed `node`. So, we have to make sure that
- // we have really removed `f` and not `q`.
+ // NOTE: The original algorithm used a trick to just copy 'key/value' to `f` and mark `q` for deletion. But this
+ // is unacceptable here as we really want to destroy the passed `node`. So, we have to make sure that we have
+ // really removed `f` and not `q`.
if (f != q) {
ASMJIT_ASSERT(f != &head);
ASMJIT_ASSERT(f != gf);
@@ -337,8 +320,8 @@ public:
if (_root) _root->_makeBlack();
}
- template<typename KeyT, typename CompareT = Support::Compare<Support::kSortAscending>>
- ASMJIT_INLINE NodeT* get(const KeyT& key, const CompareT& cmp = CompareT()) const noexcept {
+ template<typename KeyT, typename CompareT = Support::Compare<Support::SortOrder::kAscending>>
+ inline NodeT* get(const KeyT& key, const CompareT& cmp = CompareT()) const noexcept {
ZoneTreeNode* node = _root;
while (node) {
auto result = cmp(*static_cast<const NodeT*>(node), key);
@@ -359,7 +342,7 @@ public:
static inline bool _isValidRed(ZoneTreeNode* node) noexcept { return ZoneTreeNode::_isValidRed(node); }
//! Single rotation.
- static ASMJIT_INLINE ZoneTreeNode* _singleRotate(ZoneTreeNode* root, size_t dir) noexcept {
+ static inline ZoneTreeNode* _singleRotate(ZoneTreeNode* root, size_t dir) noexcept {
ZoneTreeNode* save = root->_getChild(!dir);
root->_setChild(!dir, save->_getChild(dir));
save->_setChild( dir, root);
@@ -369,7 +352,7 @@ public:
}
//! Double rotation.
- static ASMJIT_INLINE ZoneTreeNode* _doubleRotate(ZoneTreeNode* root, size_t dir) noexcept {
+ static inline ZoneTreeNode* _doubleRotate(ZoneTreeNode* root, size_t dir) noexcept {
root->_setChild(!dir, _singleRotate(root->_getChild(!dir), !dir));
return _singleRotate(root, dir);
}
diff --git a/src/asmjit/core/zonevector.cpp b/src/asmjit/core/zonevector.cpp
index 160ac59..dfec5d5 100644
--- a/src/asmjit/core/zonevector.cpp
+++ b/src/asmjit/core/zonevector.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#include "../core/support.h"
@@ -28,9 +10,8 @@
ASMJIT_BEGIN_NAMESPACE
-// ============================================================================
-// [asmjit::ZoneVectorBase - Helpers]
-// ============================================================================
+// ZoneVectorBase - Helpers
+// ========================
Error ZoneVectorBase::_grow(ZoneAllocator* allocator, uint32_t sizeOfT, uint32_t n) noexcept {
uint32_t threshold = Globals::kGrowThreshold / sizeOfT;
@@ -112,9 +93,8 @@ Error ZoneVectorBase::_resize(ZoneAllocator* allocator, uint32_t sizeOfT, uint32
return kErrorOk;
}
-// ============================================================================
-// [asmjit::ZoneBitVector - Ops]
-// ============================================================================
+// ZoneBitVector - Operations
+// ==========================
Error ZoneBitVector::copyFrom(ZoneAllocator* allocator, const ZoneBitVector& other) noexcept {
BitWord* data = _data;
@@ -280,9 +260,8 @@ Error ZoneBitVector::_append(ZoneAllocator* allocator, bool value) noexcept {
return _resize(allocator, newSize, idealCapacity, value);
}
-// ============================================================================
-// [asmjit::ZoneVector / ZoneBitVector - Unit]
-// ============================================================================
+// ZoneVector / ZoneBitVector - Tests
+// ==================================
#if defined(ASMJIT_TEST)
template<typename T>
diff --git a/src/asmjit/core/zonevector.h b/src/asmjit/core/zonevector.h
index 1340bf8..447c08c 100644
--- a/src/asmjit/core/zonevector.h
+++ b/src/asmjit/core/zonevector.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_ZONEVECTOR_H_INCLUDED
#define ASMJIT_CORE_ZONEVECTOR_H_INCLUDED
@@ -32,10 +14,6 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_zone
//! \{
-// ============================================================================
-// [asmjit::ZoneVectorBase]
-// ============================================================================
-
//! Base class used by \ref ZoneVector template.
class ZoneVectorBase {
public:
@@ -129,10 +107,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::ZoneVector<T>]
-// ============================================================================
-
//! Template used to store and manage array of Zone allocated data.
//!
//! This template has these advantages over other std::vector<>:
@@ -213,10 +187,10 @@ public:
//! \{
//! Swaps this vector with `other`.
- inline void swap(ZoneVector<T>& other) noexcept { _swap(other); }
+ ASMJIT_FORCE_INLINE void swap(ZoneVector<T>& other) noexcept { _swap(other); }
//! Prepends `item` to the vector.
- inline Error prepend(ZoneAllocator* allocator, const T& item) noexcept {
+ ASMJIT_FORCE_INLINE Error prepend(ZoneAllocator* allocator, const T& item) noexcept {
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
@@ -228,7 +202,7 @@ public:
}
//! Inserts an `item` at the specified `index`.
- inline Error insert(ZoneAllocator* allocator, size_t index, const T& item) noexcept {
+ ASMJIT_FORCE_INLINE Error insert(ZoneAllocator* allocator, size_t index, const T& item) noexcept {
ASMJIT_ASSERT(index <= _size);
if (ASMJIT_UNLIKELY(_size == _capacity))
@@ -243,7 +217,7 @@ public:
}
//! Appends `item` to the vector.
- inline Error append(ZoneAllocator* allocator, const T& item) noexcept {
+ ASMJIT_FORCE_INLINE Error append(ZoneAllocator* allocator, const T& item) noexcept {
if (ASMJIT_UNLIKELY(_size == _capacity))
ASMJIT_PROPAGATE(grow(allocator, 1));
@@ -254,7 +228,7 @@ public:
}
//! Appends `other` vector at the end of this vector.
- inline Error concat(ZoneAllocator* allocator, const ZoneVector<T>& other) noexcept {
+ ASMJIT_FORCE_INLINE Error concat(ZoneAllocator* allocator, const ZoneVector<T>& other) noexcept {
uint32_t size = other._size;
if (_capacity - _size < size)
ASMJIT_PROPAGATE(grow(allocator, size));
@@ -269,10 +243,9 @@ public:
//! Prepends `item` to the vector (unsafe case).
//!
- //! Can only be used together with `willGrow()`. If `willGrow(N)` returns
- //! `kErrorOk` then N elements can be added to the vector without checking
- //! if there is a place for them. Used mostly internally.
- inline void prependUnsafe(const T& item) noexcept {
+ //! Can only be used together with `willGrow()`. If `willGrow(N)` returns `kErrorOk` then N elements
+ //! can be added to the vector without checking if there is a place for them. Used mostly internally.
+ ASMJIT_FORCE_INLINE void prependUnsafe(const T& item) noexcept {
ASMJIT_ASSERT(_size < _capacity);
T* data = static_cast<T*>(_data);
@@ -285,10 +258,9 @@ public:
//! Append s`item` to the vector (unsafe case).
//!
- //! Can only be used together with `willGrow()`. If `willGrow(N)` returns
- //! `kErrorOk` then N elements can be added to the vector without checking
- //! if there is a place for them. Used mostly internally.
- inline void appendUnsafe(const T& item) noexcept {
+ //! Can only be used together with `willGrow()`. If `willGrow(N)` returns `kErrorOk` then N elements
+ //! can be added to the vector without checking if there is a place for them. Used mostly internally.
+ ASMJIT_FORCE_INLINE void appendUnsafe(const T& item) noexcept {
ASMJIT_ASSERT(_size < _capacity);
memcpy(static_cast<T*>(_data) + _size, &item, sizeof(T));
@@ -296,7 +268,7 @@ public:
}
//! Inserts an `item` at the specified `index` (unsafe case).
- inline void insertUnsafe(size_t index, const T& item) noexcept {
+ ASMJIT_FORCE_INLINE void insertUnsafe(size_t index, const T& item) noexcept {
ASMJIT_ASSERT(_size < _capacity);
ASMJIT_ASSERT(index <= _size);
@@ -306,7 +278,7 @@ public:
_size++;
}
//! Concatenates all items of `other` at the end of the vector.
- inline void concatUnsafe(const ZoneVector<T>& other) noexcept {
+ ASMJIT_FORCE_INLINE void concatUnsafe(const ZoneVector<T>& other) noexcept {
uint32_t size = other._size;
ASMJIT_ASSERT(_capacity - _size >= size);
@@ -317,7 +289,7 @@ public:
}
//! Returns index of the given `val` or `Globals::kNotFound` if it doesn't exist.
- inline uint32_t indexOf(const T& val) const noexcept {
+ ASMJIT_FORCE_INLINE uint32_t indexOf(const T& val) const noexcept {
const T* data = static_cast<const T*>(_data);
uint32_t size = _size;
@@ -351,7 +323,7 @@ public:
return data()[index];
}
- template<typename CompareT = Support::Compare<Support::kSortAscending>>
+ template<typename CompareT = Support::Compare<Support::SortOrder::kAscending>>
inline void sort(const CompareT& cmp = CompareT()) noexcept {
Support::qSort<T, CompareT>(data(), size(), cmp);
}
@@ -370,18 +342,16 @@ public:
//! Returns a reference to the first element of the vector.
//!
- //! \note The vector must have at least one element. Attempting to use
- //! `first()` on empty vector will trigger an assertion failure in debug
- //! builds.
+ //! \note The vector must have at least one element. Attempting to use `first()` on empty vector will trigger
+ //! an assertion failure in debug builds.
inline T& first() noexcept { return operator[](0); }
//! \overload
inline const T& first() const noexcept { return operator[](0); }
//! Returns a reference to the last element of the vector.
//!
- //! \note The vector must have at least one element. Attempting to use
- //! `last()` on empty vector will trigger an assertion failure in debug
- //! builds.
+ //! \note The vector must have at least one element. Attempting to use `last()` on empty vector will trigger
+ //! an assertion failure in debug builds.
inline T& last() noexcept { return operator[](_size - 1); }
//! \overload
inline const T& last() const noexcept { return operator[](_size - 1); }
@@ -403,9 +373,8 @@ public:
//! Resizes the vector to hold `n` elements.
//!
- //! If `n` is greater than the current size then the additional elements'
- //! content will be initialized to zero. If `n` is less than the current
- //! size then the vector will be truncated to exactly `n` elements.
+ //! If `n` is greater than the current size then the additional elements' content will be initialized to zero.
+ //! If `n` is less than the current size then the vector will be truncated to exactly `n` elements.
inline Error resize(ZoneAllocator* allocator, uint32_t n) noexcept {
return ZoneVectorBase::_resize(allocator, sizeof(T), n);
}
@@ -422,15 +391,24 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::ZoneBitVector]
-// ============================================================================
-
//! Zone-allocated bit vector.
class ZoneBitVector {
public:
typedef Support::BitWord BitWord;
- static constexpr uint32_t kBitWordSizeInBits = Support::kBitWordSizeInBits;
+
+ ASMJIT_NONCOPYABLE(ZoneBitVector)
+
+ //! \name Constants
+ //! \{
+
+ enum : uint32_t {
+ kBitWordSizeInBits = Support::kBitWordSizeInBits
+ };
+
+ //! \}
+
+ //! \name Members
+ //! \{
//! Bits.
BitWord* _data = nullptr;
@@ -439,7 +417,7 @@ public:
//! Capacity of the bit-vector (in bits).
uint32_t _capacity = 0;
- ASMJIT_NONCOPYABLE(ZoneBitVector)
+ //! \}
//! \cond INTERNAL
//! \name Internal
@@ -548,7 +526,7 @@ public:
Support::bitVectorFlipBit(_data, index);
}
- ASMJIT_INLINE Error append(ZoneAllocator* allocator, bool value) noexcept {
+ ASMJIT_FORCE_INLINE Error append(ZoneAllocator* allocator, bool value) noexcept {
uint32_t index = _size;
if (ASMJIT_UNLIKELY(index >= _capacity))
return _append(allocator, value);
@@ -567,35 +545,34 @@ public:
ASMJIT_API Error copyFrom(ZoneAllocator* allocator, const ZoneBitVector& other) noexcept;
- inline void clearAll() noexcept {
+ ASMJIT_FORCE_INLINE void clearAll() noexcept {
_zeroBits(_data, _wordsPerBits(_size));
}
- inline void fillAll() noexcept {
+ ASMJIT_FORCE_INLINE void fillAll() noexcept {
_fillBits(_data, _wordsPerBits(_size));
_clearUnusedBits();
}
- inline void clearBits(uint32_t start, uint32_t count) noexcept {
+ ASMJIT_FORCE_INLINE void clearBits(uint32_t start, uint32_t count) noexcept {
ASMJIT_ASSERT(start <= _size);
ASMJIT_ASSERT(_size - start >= count);
Support::bitVectorClear(_data, start, count);
}
- inline void fillBits(uint32_t start, uint32_t count) noexcept {
+ ASMJIT_FORCE_INLINE void fillBits(uint32_t start, uint32_t count) noexcept {
ASMJIT_ASSERT(start <= _size);
ASMJIT_ASSERT(_size - start >= count);
Support::bitVectorFill(_data, start, count);
}
- //! Performs a logical bitwise AND between bits specified in this array and bits
- //! in `other`. If `other` has less bits than `this` then all remaining bits are
- //! set to zero.
+ //! Performs a logical bitwise AND between bits specified in this array and bits in `other`. If `other` has less
+ //! bits than `this` then all remaining bits are set to zero.
//!
//! \note The size of the BitVector is unaffected by this operation.
- inline void and_(const ZoneBitVector& other) noexcept {
+ ASMJIT_FORCE_INLINE void and_(const ZoneBitVector& other) noexcept {
BitWord* dst = _data;
const BitWord* src = other._data;
@@ -615,12 +592,11 @@ public:
}
}
- //! Performs a logical bitwise AND between bits specified in this array and
- //! negated bits in `other`. If `other` has less bits than `this` then all
- //! remaining bits are kept intact.
+ //! Performs a logical bitwise AND between bits specified in this array and negated bits in `other`. If `other`
+ //! has less bits than `this` then all remaining bits are kept intact.
//!
//! \note The size of the BitVector is unaffected by this operation.
- inline void andNot(const ZoneBitVector& other) noexcept {
+ ASMJIT_FORCE_INLINE void andNot(const ZoneBitVector& other) noexcept {
BitWord* dst = _data;
const BitWord* src = other._data;
@@ -629,12 +605,11 @@ public:
dst[i] = dst[i] & ~src[i];
}
- //! Performs a logical bitwise OP between bits specified in this array and bits
- //! in `other`. If `other` has less bits than `this` then all remaining bits
- //! are kept intact.
+ //! Performs a logical bitwise OP between bits specified in this array and bits in `other`. If `other` has less
+ //! bits than `this` then all remaining bits are kept intact.
//!
//! \note The size of the BitVector is unaffected by this operation.
- inline void or_(const ZoneBitVector& other) noexcept {
+ ASMJIT_FORCE_INLINE void or_(const ZoneBitVector& other) noexcept {
BitWord* dst = _data;
const BitWord* src = other._data;
@@ -644,15 +619,16 @@ public:
_clearUnusedBits();
}
- inline void _clearUnusedBits() noexcept {
+ ASMJIT_FORCE_INLINE void _clearUnusedBits() noexcept {
uint32_t idx = _size / kBitWordSizeInBits;
uint32_t bit = _size % kBitWordSizeInBits;
- if (!bit) return;
+ if (!bit)
+ return;
_data[idx] &= (BitWord(1) << bit) - 1u;
}
- inline bool eq(const ZoneBitVector& other) const noexcept {
+ ASMJIT_FORCE_INLINE bool eq(const ZoneBitVector& other) const noexcept {
if (_size != other._size)
return false;
@@ -691,14 +667,14 @@ public:
class ForEachBitSet : public Support::BitVectorIterator<BitWord> {
public:
- ASMJIT_INLINE explicit ForEachBitSet(const ZoneBitVector& bitVector) noexcept
+ inline explicit ForEachBitSet(const ZoneBitVector& bitVector) noexcept
: Support::BitVectorIterator<BitWord>(bitVector.data(), bitVector.sizeInBitWords()) {}
};
template<class Operator>
class ForEachBitOp : public Support::BitVectorOpIterator<BitWord, Operator> {
public:
- ASMJIT_INLINE ForEachBitOp(const ZoneBitVector& a, const ZoneBitVector& b) noexcept
+ inline ForEachBitOp(const ZoneBitVector& a, const ZoneBitVector& b) noexcept
: Support::BitVectorOpIterator<BitWord, Operator>(a.data(), b.data(), a.sizeInBitWords()) {
ASMJIT_ASSERT(a.size() == b.size());
}
diff --git a/src/asmjit/x86.h b/src/asmjit/x86.h
index 2c49518..84bc84b 100644
--- a/src/asmjit/x86.h
+++ b/src/asmjit/x86.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_H_INCLUDED
#define ASMJIT_X86_H_INCLUDED
@@ -40,15 +22,14 @@
//! ### Supported Instructions
//!
//! - Emitters:
-//! - \ref x86::EmitterExplicitT - Provides all instructions that use
-//! explicit operands, provides also utility functions. The member
-//! functions provided are part of all X86 emitters.
-//! - \ref x86::EmitterImplicitT - Provides all instructions that use
-//! implicit operands, these cannot be used with \ref x86::Compiler.
+//! - \ref x86::EmitterExplicitT - Provides all instructions that use explicit operands, provides also utility
+//! functions. The member functions provided are part of all X86 emitters.
+//! - \ref x86::EmitterImplicitT - Provides all instructions that use implicit operands, these cannot be used
+//! with \ref x86::Compiler.
//!
//! - Instruction representation:
-//! - \ref x86::Inst::Id - instruction identifiers.
-//! - \ref x86::Inst::Options - instruction options.
+//! - \ref x86::Inst::Id - Provides instruction identifiers for both X86/X86_64 architectures.
+//! - \ref InstOptions - Provides generic and X86/X86_64 specific options.
//!
//! ### Register Operands
//!
@@ -74,34 +55,28 @@
//!
//! ### Memory Operands
//!
-//! - \ref x86::Mem - X86/X64 memory operand that provides support for all
-//! X86 and X64 addressing features including absolute addresses, index
-//! scales, and segment override prefixes.
-//!
-//! ### Other
-//!
-//! - \ref x86::Features - X86/X64 CPU features on top of \ref BaseFeatures.
+//! - \ref x86::Mem - X86/X64 memory operand that provides support for all X86 and X64 addressing features
+//! including absolute addresses, index scales, and segment override prefixes.
//!
//! ### Status and Control Words
//!
-//! - \ref asmjit::x86::FpuWord::Status - FPU status word.
-//! - \ref asmjit::x86::FpuWord::Control - FPU control word.
-//!
-//! ### Predicates
-//!
-//! - \ref x86::Predicate - namespace that provides X86/X64 predicates.
-//! - \ref x86::Predicate::Cmp - `CMP[PD|PS|SD|SS]` predicate (SSE+).
-//! - \ref x86::Predicate::PCmpStr - `[V]PCMP[I|E]STR[I|M]` predicate (SSE4.1+).
-//! - \ref x86::Predicate::Round - `ROUND[PD|PS|SD|SS]` predicate (SSE+).
-//! - \ref x86::Predicate::VCmp - `VCMP[PD|PS|SD|SS]` predicate (AVX+).
-//! - \ref x86::Predicate::VFixupImm - `VFIXUPIMM[PD|PS|SD|SS]` predicate (AVX512+).
-//! - \ref x86::Predicate::VFPClass - `VFPCLASS[PD|PS|SD|SS]` predicate (AVX512+).
-//! - \ref x86::Predicate::VGetMant - `VGETMANT[PD|PS|SD|SS]` predicate (AVX512+).
-//! - \ref x86::Predicate::VPCmp - `VPCMP[U][B|W|D|Q]` predicate (AVX512+).
-//! - \ref x86::Predicate::VPCom - `VPCOM[U][B|W|D|Q]` predicate (XOP).
-//! - \ref x86::Predicate::VRange - `VRANGE[PD|PS|SD|SS]` predicate (AVX512+).
-//! - \ref x86::Predicate::VReduce - `REDUCE[PD|PS|SD|SS]` predicate (AVX512+).
-//! - \ref x86::TLog - namespace that provides `VPTERNLOG[D|Q]` predicate / operations.
+//! - \ref x86::FpuStatusWord - FPU status word bits / decomposition.
+//! - \ref x86::FpuControlWord - FPU control word bits / decomposition.
+//!
+//! ### Predicates (immediate values)
+//!
+//! - \ref x86::CmpImm - `CMP[PD|PS|SD|SS]` predicate (SSE+).
+//! - \ref x86::PCmpStrImm - `[V]PCMP[I|E]STR[I|M]` predicate (SSE4.1+, AVX+).
+//! - \ref x86::RoundImm - `[V]ROUND[PD|PS|SD|SS]` predicate (SSE+, AVX+).
+//! - \ref x86::VCmpImm - `VCMP[PD|PS|SD|SS]` predicate (AVX+).
+//! - \ref x86::VFixupImm - `VFIXUPIMM[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::VFPClassImm - `VFPCLASS[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::VGetMantImm - `VGETMANT[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::VPCmpImm - `VPCMP[U][B|W|D|Q]` predicate (AVX512+).
+//! - \ref x86::VPComImm - `VPCOM[U][B|W|D|Q]` predicate (XOP).
+//! - \ref x86::VRangeImm - `VRANGE[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::VReduceImm - `REDUCE[PD|PS|SD|SS]` predicate (AVX512+).
+//! - \ref x86::TLogImm - `VPTERNLOG[D|Q]` predicate and operations (AVX512+).
#include "core.h"
@@ -110,7 +85,6 @@
#include "x86/x86builder.h"
#include "x86/x86compiler.h"
#include "x86/x86emitter.h"
-#include "x86/x86features.h"
#include "x86/x86globals.h"
#include "x86/x86instdb.h"
#include "x86/x86operand.h"
diff --git a/src/asmjit/x86/x86archtraits_p.h b/src/asmjit/x86/x86archtraits_p.h
index 66a6f50..7c43651 100644
--- a/src/asmjit/x86/x86archtraits_p.h
+++ b/src/asmjit/x86/x86archtraits_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86ARCHTRAITS_P_H_INCLUDED
#define ASMJIT_X86_X86ARCHTRAITS_P_H_INCLUDED
@@ -34,10 +16,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::x86ArchTraits
-// ============================================================================
-
+//! X86 architecture traits (internal).
static const constexpr ArchTraits x86ArchTraits = {
// SP/FP/LR/PC.
Gp::kIdSp, Gp::kIdBp, 0xFF, 0xFF,
@@ -52,51 +31,53 @@ static const constexpr ArchTraits x86ArchTraits = {
0x7FFFFFFFu, 0x7FFFFFFFu,
// ISA features [Gp, Vec, Other0, Other1].
- { ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop, 0, 0, 0 },
-
- // RegInfo.
- #define V(index) { x86::RegTraits<index>::kSignature }
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ {{
+ InstHints::kRegSwap | InstHints::kPushPop,
+ InstHints::kNoHints,
+ InstHints::kNoHints,
+ InstHints::kNoHints
+ }},
+
+ // Register signatures.
+ #define V(index) OperandSignature(x86::RegTraits<RegType(index)>::kSignature)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// RegTypeToTypeId.
- #define V(index) x86::RegTraits<index>::kTypeId
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ #define V(index) TypeId(x86::RegTraits<RegType(index)>::kTypeId)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// TypeIdToRegType.
- #define V(index) (index + Type::_kIdBaseStart == Type::kIdI8 ? Reg::kTypeGpbLo : \
- index + Type::_kIdBaseStart == Type::kIdU8 ? Reg::kTypeGpbLo : \
- index + Type::_kIdBaseStart == Type::kIdI16 ? Reg::kTypeGpw : \
- index + Type::_kIdBaseStart == Type::kIdU16 ? Reg::kTypeGpw : \
- index + Type::_kIdBaseStart == Type::kIdI32 ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdU32 ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdIntPtr ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdUIntPtr ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdF32 ? Reg::kTypeXmm : \
- index + Type::_kIdBaseStart == Type::kIdF64 ? Reg::kTypeXmm : \
- index + Type::_kIdBaseStart == Type::kIdMask8 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask16 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask32 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask64 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMmx32 ? Reg::kTypeMm : \
- index + Type::_kIdBaseStart == Type::kIdMmx64 ? Reg::kTypeMm : Reg::kTypeNone)
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ #define V(index) (index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt8) ? RegType::kX86_GpbLo : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt8) ? RegType::kX86_GpbLo : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt16) ? RegType::kX86_Gpw : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt16) ? RegType::kX86_Gpw : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt32) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt32) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kIntPtr) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUIntPtr) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat32) ? RegType::kX86_Xmm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat64) ? RegType::kX86_Xmm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask8) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask16) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask32) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask64) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMmx32) ? RegType::kX86_Mm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMmx64) ? RegType::kX86_Mm : RegType::kNone)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
{
- ISAWordNameId::kDB,
- ISAWordNameId::kDW,
- ISAWordNameId::kDD,
- ISAWordNameId::kDQ
+ ArchTypeNameId::kDB,
+ ArchTypeNameId::kDW,
+ ArchTypeNameId::kDD,
+ ArchTypeNameId::kDQ
}
};
-// ============================================================================
-// [asmjit::x86::x64ArchTraits
-// ============================================================================
-
+//! X64 architecture traits (internal).
static const constexpr ArchTraits x64ArchTraits = {
// SP/FP/LR/PC.
Gp::kIdSp, Gp::kIdBp, 0xFF, 0xFF,
@@ -111,46 +92,51 @@ static const constexpr ArchTraits x64ArchTraits = {
0x7FFFFFFFu, 0x7FFFFFFFu,
// ISA features [Gp, Vec, Other0, Other1].
- { ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop, 0, 0, 0 },
-
- // RegInfo.
- #define V(index) { x86::RegTraits<index>::kSignature }
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ {{
+ InstHints::kRegSwap | InstHints::kPushPop,
+ InstHints::kNoHints,
+ InstHints::kNoHints,
+ InstHints::kNoHints
+ }},
+
+ // Register signatures.
+ #define V(index) OperandSignature(x86::RegTraits<RegType(index)>::kSignature)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// RegTypeToTypeId.
- #define V(index) x86::RegTraits<index>::kTypeId
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ #define V(index) TypeId(x86::RegTraits<RegType(index)>::kTypeId)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// TypeIdToRegType.
- #define V(index) (index + Type::_kIdBaseStart == Type::kIdI8 ? Reg::kTypeGpbLo : \
- index + Type::_kIdBaseStart == Type::kIdU8 ? Reg::kTypeGpbLo : \
- index + Type::_kIdBaseStart == Type::kIdI16 ? Reg::kTypeGpw : \
- index + Type::_kIdBaseStart == Type::kIdU16 ? Reg::kTypeGpw : \
- index + Type::_kIdBaseStart == Type::kIdI32 ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdU32 ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdI64 ? Reg::kTypeGpq : \
- index + Type::_kIdBaseStart == Type::kIdU64 ? Reg::kTypeGpq : \
- index + Type::_kIdBaseStart == Type::kIdIntPtr ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdUIntPtr ? Reg::kTypeGpd : \
- index + Type::_kIdBaseStart == Type::kIdF32 ? Reg::kTypeXmm : \
- index + Type::_kIdBaseStart == Type::kIdF64 ? Reg::kTypeXmm : \
- index + Type::_kIdBaseStart == Type::kIdMask8 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask16 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask32 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMask64 ? Reg::kTypeKReg : \
- index + Type::_kIdBaseStart == Type::kIdMmx32 ? Reg::kTypeMm : \
- index + Type::_kIdBaseStart == Type::kIdMmx64 ? Reg::kTypeMm : Reg::kTypeNone)
- { ASMJIT_LOOKUP_TABLE_32(V, 0) },
+ #define V(index) (index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt8) ? RegType::kX86_GpbLo : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt8) ? RegType::kX86_GpbLo : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt16) ? RegType::kX86_Gpw : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt16) ? RegType::kX86_Gpw : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt32) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt32) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kInt64) ? RegType::kX86_Gpq : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUInt64) ? RegType::kX86_Gpq : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kIntPtr) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kUIntPtr) ? RegType::kX86_Gpd : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat32) ? RegType::kX86_Xmm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kFloat64) ? RegType::kX86_Xmm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask8) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask16) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask32) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMask64) ? RegType::kX86_KReg : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMmx32) ? RegType::kX86_Mm : \
+ index + uint32_t(TypeId::_kBaseStart) == uint32_t(TypeId::kMmx64) ? RegType::kX86_Mm : RegType::kNone)
+ {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
#undef V
// Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
{
- ISAWordNameId::kDB,
- ISAWordNameId::kDW,
- ISAWordNameId::kDD,
- ISAWordNameId::kDQ
+ ArchTypeNameId::kDB,
+ ArchTypeNameId::kDW,
+ ArchTypeNameId::kDD,
+ ArchTypeNameId::kDQ
}
};
diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp
index a568dab..4da28f1 100644
--- a/src/asmjit/x86/x86assembler.cpp
+++ b/src/asmjit/x86/x86assembler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
@@ -39,15 +21,10 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [TypeDefs]
-// ============================================================================
-
typedef Support::FastUInt8 FastUInt8;
-// ============================================================================
-// [Constants]
-// ============================================================================
+// x86::Assembler - Constants
+// ==========================
//! X86 bytes used to encode important prefixes.
enum X86Byte : uint32_t {
@@ -78,13 +55,13 @@ enum X86Byte : uint32_t {
//! 4-byte EVEX prefix:
//! - `[0]` - `0x62`.
- //! - `[1]` - Payload0 or `P[ 7: 0]` - `[R X B R' 0 0 m m]`.
+ //! - `[1]` - Payload0 or `P[ 7: 0]` - `[R X B R' 0 m m m]`.
//! - `[2]` - Payload1 or `P[15: 8]` - `[W v v v v 1 p p]`.
//! - `[3]` - Payload2 or `P[23:16]` - `[z L' L b V' a a a]`.
//!
//! Payload:
- //! - `P[ 1: 0]` - OPCODE: EVEX.mmmmm, only lowest 2 bits [1:0] used.
- //! - `P[ 3: 2]` - ______: Must be 0.
+ //! - `P[ 2: 0]` - OPCODE: EVEX.mmmmm, only lowest 3 bits [2:0] used.
+ //! - `P[ 3]` - ______: Must be 0.
//! - `P[ 4]` - REG-ID: EVEX.R' - 5th bit of 'RRRRR'.
//! - `P[ 5]` - REG-ID: EVEX.B - 4th bit of 'BBBBB'.
//! - `P[ 6]` - REG-ID: EVEX.X - 5th bit of 'BBBBB' or 4th bit of 'XXXX' (with SIB).
@@ -166,15 +143,13 @@ static const uint32_t x86OpcodePopSReg[8] = {
Opcode::k000F00 | 0xA9 // Pop GS.
};
-// ============================================================================
-// [asmjit::X86MemInfo | X86VEXPrefix | X86LLByRegType | X86CDisp8Table]
+// x86::Assembler - X86MemInfo | X86VEXPrefix | X86LLByRegType | X86CDisp8Table
// ============================================================================
//! Memory operand's info bits.
//!
-//! A lookup table that contains various information based on the BASE and INDEX
-//! information of a memory operand. This is much better and safer than playing
-//! with IFs in the code and can check for errors must faster and better.
+//! A lookup table that contains various information based on the BASE and INDEX information of a memory operand. This
+//! is much better and safer than playing with IFs in the code and can check for errors must faster and better.
enum X86MemInfo_Enum {
kX86MemInfo_0 = 0x00,
@@ -191,52 +166,48 @@ enum X86MemInfo_Enum {
template<uint32_t X>
struct X86MemInfo_T {
- enum {
+ enum : uint32_t {
B = (X ) & 0x1F,
I = (X >> 5) & 0x1F,
- kBase = (B >= Reg::kTypeGpw && B <= Reg::kTypeGpq ) ? kX86MemInfo_BaseGp :
- (B == Reg::kTypeRip ) ? kX86MemInfo_BaseRip :
- (B == Label::kLabelTag ) ? kX86MemInfo_BaseLabel : 0,
-
- kIndex = (I >= Reg::kTypeGpw && I <= Reg::kTypeGpq ) ? kX86MemInfo_Index :
- (I >= Reg::kTypeXmm && I <= Reg::kTypeZmm ) ? kX86MemInfo_Index : 0,
-
- k67H = (B == Reg::kTypeGpw && I == Reg::kTypeNone) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeGpd && I == Reg::kTypeNone) ? kX86MemInfo_67H_X64 :
- (B == Reg::kTypeNone && I == Reg::kTypeGpw ) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeNone && I == Reg::kTypeGpd ) ? kX86MemInfo_67H_X64 :
- (B == Reg::kTypeGpw && I == Reg::kTypeGpw ) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeGpd && I == Reg::kTypeGpd ) ? kX86MemInfo_67H_X64 :
- (B == Reg::kTypeGpw && I == Reg::kTypeXmm ) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeGpd && I == Reg::kTypeXmm ) ? kX86MemInfo_67H_X64 :
- (B == Reg::kTypeGpw && I == Reg::kTypeYmm ) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeGpd && I == Reg::kTypeYmm ) ? kX86MemInfo_67H_X64 :
- (B == Reg::kTypeGpw && I == Reg::kTypeZmm ) ? kX86MemInfo_67H_X86 :
- (B == Reg::kTypeGpd && I == Reg::kTypeZmm ) ? kX86MemInfo_67H_X64 :
- (B == Label::kLabelTag && I == Reg::kTypeGpw ) ? kX86MemInfo_67H_X86 :
- (B == Label::kLabelTag && I == Reg::kTypeGpd ) ? kX86MemInfo_67H_X64 : 0,
+ kBase = (B >= uint32_t(RegType::kX86_Gpw) && B <= uint32_t(RegType::kX86_Gpq)) ? kX86MemInfo_BaseGp :
+ (B == uint32_t(RegType::kX86_Rip) ) ? kX86MemInfo_BaseRip :
+ (B == uint32_t(RegType::kLabelTag) ) ? kX86MemInfo_BaseLabel : 0,
+
+ kIndex = (I >= uint32_t(RegType::kX86_Gpw) && I <= uint32_t(RegType::kX86_Gpq)) ? kX86MemInfo_Index :
+ (I >= uint32_t(RegType::kX86_Xmm) && I <= uint32_t(RegType::kX86_Zmm)) ? kX86MemInfo_Index : 0,
+
+ k67H = (B == uint32_t(RegType::kX86_Gpw) && I == uint32_t(RegType::kNone) ) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kX86_Gpd) && I == uint32_t(RegType::kNone) ) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kNone) && I == uint32_t(RegType::kX86_Gpw)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kNone) && I == uint32_t(RegType::kX86_Gpd)) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kX86_Gpw) && I == uint32_t(RegType::kX86_Gpw)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kX86_Gpd) && I == uint32_t(RegType::kX86_Gpd)) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kX86_Gpw) && I == uint32_t(RegType::kX86_Xmm)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kX86_Gpd) && I == uint32_t(RegType::kX86_Xmm)) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kX86_Gpw) && I == uint32_t(RegType::kX86_Ymm)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kX86_Gpd) && I == uint32_t(RegType::kX86_Ymm)) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kX86_Gpw) && I == uint32_t(RegType::kX86_Zmm)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kX86_Gpd) && I == uint32_t(RegType::kX86_Zmm)) ? kX86MemInfo_67H_X64 :
+ (B == uint32_t(RegType::kLabelTag) && I == uint32_t(RegType::kX86_Gpw)) ? kX86MemInfo_67H_X86 :
+ (B == uint32_t(RegType::kLabelTag) && I == uint32_t(RegType::kX86_Gpd)) ? kX86MemInfo_67H_X64 : 0,
kValue = kBase | kIndex | k67H | 0x04 | 0x08
};
};
// The result stored in the LUT is a combination of
-// - 67H - Address override prefix - depends on BASE+INDEX register types and
-// the target architecture.
-// - REX - A possible combination of REX.[B|X|R|W] bits in REX prefix where
-// REX.B and REX.X are possibly masked out, but REX.R and REX.W are
-// kept as is.
+// - 67H - Address override prefix - depends on BASE+INDEX register types and the target architecture.
+// - REX - A possible combination of REX.[B|X|R|W] bits in REX prefix where REX.B and REX.X are possibly
+// masked out, but REX.R and REX.W are kept as is.
#define VALUE(x) X86MemInfo_T<x>::kValue
static const uint8_t x86MemInfo[] = { ASMJIT_LOOKUP_TABLE_1024(VALUE, 0) };
#undef VALUE
-// VEX3 or XOP xor bits applied to the opcode before emitted. The index to this
-// table is 'mmmmm' value, which contains all we need. This is only used by a
-// 3 BYTE VEX and XOP prefixes, 2 BYTE VEX prefix is handled differently. The
-// idea is to minimize the difference between VEX3 vs XOP when encoding VEX
-// or XOP instruction. This should minimize the code required to emit such
-// instructions and should also make it faster as we don't need any branch to
+// VEX3 or XOP xor bits applied to the opcode before emitted. The index to this table is 'mmmmm' value, which
+// contains all we need. This is only used by a 3 BYTE VEX and XOP prefixes, 2 BYTE VEX prefix is handled differently.
+// The idea is to minimize the difference between VEX3 vs XOP when encoding VEX or XOP instruction. This should
+// minimize the code required to emit such instructions and should also make it faster as we don't need any branch to
// decide between VEX3 vs XOP.
// ____ ___
// [_OPCODE_|WvvvvLpp|RXBmmmmm|VEX3_XOP]
@@ -244,26 +215,23 @@ static const uint8_t x86MemInfo[] = { ASMJIT_LOOKUP_TABLE_1024(VALUE, 0) };
static const uint32_t x86VEXPrefix[] = { ASMJIT_LOOKUP_TABLE_16(VALUE, 0) };
#undef VALUE
-// Table that contains LL opcode field addressed by a register size / 16. It's
-// used to propagate L.256 or L.512 when YMM or ZMM registers are used,
-// respectively.
+// Table that contains LL opcode field addressed by a register size / 16. It's used to propagate L.256 or L.512 when
+// YMM or ZMM registers are used, respectively.
#define VALUE(x) (x & (64 >> 4)) ? Opcode::kLL_2 : \
(x & (32 >> 4)) ? Opcode::kLL_1 : Opcode::kLL_0
static const uint32_t x86LLBySizeDiv16[] = { ASMJIT_LOOKUP_TABLE_16(VALUE, 0) };
#undef VALUE
-// Table that contains LL opcode field addressed by a register size / 16. It's
-// used to propagate L.256 or L.512 when YMM or ZMM registers are used,
-// respectively.
-#define VALUE(x) x == Reg::kTypeZmm ? Opcode::kLL_2 : \
- x == Reg::kTypeYmm ? Opcode::kLL_1 : Opcode::kLL_0
+// Table that contains LL opcode field addressed by a register size / 16. It's used to propagate L.256 or L.512 when
+// YMM or ZMM registers are used, respectively.
+#define VALUE(x) x == uint32_t(RegType::kX86_Zmm) ? Opcode::kLL_2 : \
+ x == uint32_t(RegType::kX86_Ymm) ? Opcode::kLL_1 : Opcode::kLL_0
static const uint32_t x86LLByRegType[] = { ASMJIT_LOOKUP_TABLE_16(VALUE, 0) };
#undef VALUE
-// Table that contains a scale (shift left) based on 'TTWLL' field and
-// the instruction's tuple-type (TT) field. The scale is then applied to
-// the BASE-N stored in each opcode to calculate the final compressed
-// displacement used by all EVEX encoded instructions.
+// Table that contains a scale (shift left) based on 'TTWLL' field and the instruction's tuple-type (TT) field. The
+// scale is then applied to the BASE-N stored in each opcode to calculate the final compressed displacement used by
+// all EVEX encoded instructions.
template<uint32_t X>
struct X86CDisp8SHL_T {
enum {
@@ -314,33 +282,32 @@ struct X86Mod16BaseIndexTable_T {
static const uint8_t x86Mod16BaseIndexTable[] = { ASMJIT_LOOKUP_TABLE_64(VALUE, 0) };
#undef VALUE
-// ============================================================================
-// [asmjit::x86::Assembler - Helpers]
-// ============================================================================
+// x86::Assembler - Helpers
+// ========================
-static ASMJIT_INLINE bool x86IsJmpOrCall(uint32_t instId) noexcept {
+static ASMJIT_FORCE_INLINE bool x86IsJmpOrCall(InstId instId) noexcept {
return instId == Inst::kIdJmp || instId == Inst::kIdCall;
}
-static ASMJIT_INLINE bool x86IsImplicitMem(const Operand_& op, uint32_t base) noexcept {
+static ASMJIT_FORCE_INLINE bool x86IsImplicitMem(const Operand_& op, uint32_t base) noexcept {
return op.isMem() && op.as<Mem>().baseId() == base && !op.as<Mem>().hasOffset();
}
//! Combine `regId` and `vvvvvId` into a single value (used by AVX and AVX-512).
-static ASMJIT_INLINE uint32_t x86PackRegAndVvvvv(uint32_t regId, uint32_t vvvvvId) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t x86PackRegAndVvvvv(uint32_t regId, uint32_t vvvvvId) noexcept {
return regId + (vvvvvId << kVexVVVVVShift);
}
-static ASMJIT_INLINE uint32_t x86OpcodeLByVMem(const Operand_& op) noexcept {
- return x86LLByRegType[op.as<Mem>().indexType()];
+static ASMJIT_FORCE_INLINE uint32_t x86OpcodeLByVMem(const Operand_& op) noexcept {
+ return x86LLByRegType[size_t(op.as<Mem>().indexType())];
}
-static ASMJIT_INLINE uint32_t x86OpcodeLBySize(uint32_t size) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t x86OpcodeLBySize(uint32_t size) noexcept {
return x86LLBySizeDiv16[size / 16];
}
//! Encode MOD byte.
-static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcept {
ASMJIT_ASSERT(m <= 3);
ASMJIT_ASSERT(o <= 7);
ASMJIT_ASSERT(rm <= 7);
@@ -348,14 +315,14 @@ static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm)
}
//! Encode SIB byte.
-static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) noexcept {
ASMJIT_ASSERT(s <= 3);
ASMJIT_ASSERT(i <= 7);
ASMJIT_ASSERT(b <= 7);
return (s << 6) + (i << 3) + b;
}
-static ASMJIT_INLINE bool x86IsRexInvalid(uint32_t rex) noexcept {
+static ASMJIT_FORCE_INLINE bool x86IsRexInvalid(uint32_t rex) noexcept {
// Validates the following possibilities:
// REX == 0x00 -> OKAY (X86_32 / X86_64).
// REX == 0x40-0x4F -> OKAY (X86_64).
@@ -364,29 +331,33 @@ static ASMJIT_INLINE bool x86IsRexInvalid(uint32_t rex) noexcept {
return rex > kX86ByteInvalidRex;
}
+static ASMJIT_FORCE_INLINE uint32_t x86GetForceEvex3MaskInLastBit(InstOptions options) noexcept {
+ constexpr uint32_t kVex3Bit = Support::ConstCTZ<uint32_t(InstOptions::kX86_Vex3)>::value;
+ return uint32_t(options & InstOptions::kX86_Vex3) << (31 - kVex3Bit);
+}
+
template<typename T>
-static constexpr T x86SignExtendI32(T imm) noexcept { return T(int64_t(int32_t(imm & T(0xFFFFFFFF)))); }
+static ASMJIT_FORCE_INLINE constexpr T x86SignExtendI32(T imm) noexcept { return T(int64_t(int32_t(imm & T(0xFFFFFFFF)))); }
-static ASMJIT_INLINE uint32_t x86AltOpcodeOf(const InstDB::InstInfo* info) noexcept {
+static ASMJIT_FORCE_INLINE uint32_t x86AltOpcodeOf(const InstDB::InstInfo* info) noexcept {
return InstDB::_altOpcodeTable[info->_altOpcodeIndex];
}
-// ============================================================================
-// [asmjit::X86BufferWriter]
-// ============================================================================
+// x86::Assembler - X86BufferWriter
+// ================================
class X86BufferWriter : public CodeWriter {
public:
- ASMJIT_INLINE explicit X86BufferWriter(Assembler* a) noexcept
+ ASMJIT_FORCE_INLINE explicit X86BufferWriter(Assembler* a) noexcept
: CodeWriter(a) {}
- ASMJIT_INLINE void emitPP(uint32_t opcode) noexcept {
+ ASMJIT_FORCE_INLINE void emitPP(uint32_t opcode) noexcept {
uint32_t ppIndex = (opcode >> Opcode::kPP_Shift) &
(Opcode::kPP_FPUMask >> Opcode::kPP_Shift) ;
emit8If(x86OpcodePP[ppIndex], ppIndex != 0);
}
- ASMJIT_INLINE void emitMMAndOpcode(uint32_t opcode) noexcept {
+ ASMJIT_FORCE_INLINE void emitMMAndOpcode(uint32_t opcode) noexcept {
uint32_t mmIndex = (opcode & Opcode::kMM_Mask) >> Opcode::kMM_Shift;
const X86OpcodeMM& mmCode = x86OpcodeMM[mmIndex];
@@ -395,7 +366,7 @@ public:
emit8(opcode);
}
- ASMJIT_INLINE void emitSegmentOverride(uint32_t segmentId) noexcept {
+ ASMJIT_FORCE_INLINE void emitSegmentOverride(uint32_t segmentId) noexcept {
ASMJIT_ASSERT(segmentId < ASMJIT_ARRAY_SIZE(x86SegmentPrefix));
FastUInt8 prefix = x86SegmentPrefix[segmentId];
@@ -403,11 +374,11 @@ public:
}
template<typename CondT>
- ASMJIT_INLINE void emitAddressOverride(CondT condition) noexcept {
+ ASMJIT_FORCE_INLINE void emitAddressOverride(CondT condition) noexcept {
emit8If(0x67, condition);
}
- ASMJIT_INLINE void emitImmByteOrDWord(uint64_t immValue, FastUInt8 immSize) noexcept {
+ ASMJIT_FORCE_INLINE void emitImmByteOrDWord(uint64_t immValue, FastUInt8 immSize) noexcept {
if (!immSize)
return;
@@ -431,7 +402,7 @@ public:
emit8(imm & 0xFFu);
}
- ASMJIT_INLINE void emitImmediate(uint64_t immValue, FastUInt8 immSize) noexcept {
+ ASMJIT_FORCE_INLINE void emitImmediate(uint64_t immValue, FastUInt8 immSize) noexcept {
#if ASMJIT_ARCH_BITS >= 64
uint64_t imm = immValue;
if (immSize >= 4) {
@@ -474,45 +445,57 @@ public:
// If the operand is AH|BH|CH|DH
// - patch its index from 0..3 to 4..7 as encoded by X86.
// - Disallow REX prefix.
-#define FIXUP_GPB(REG_OP, REG_ID) \
- do { \
- if (!static_cast<const Gp&>(REG_OP).isGpbHi()) { \
- options |= (REG_ID >= 4) ? uint32_t(Inst::kOptionRex) \
- : uint32_t(0); \
- } \
- else { \
- options |= Inst::_kOptionInvalidRex; \
- REG_ID += 4; \
- } \
+#define FIXUP_GPB(REG_OP, REG_ID) \
+ do { \
+ if (!static_cast<const Gp&>(REG_OP).isGpbHi()) { \
+ options |= (REG_ID) >= 4 ? InstOptions::kX86_Rex \
+ : InstOptions::kNone; \
+ } \
+ else { \
+ options |= InstOptions::kX86_InvalidRex; \
+ REG_ID += 4; \
+ } \
} while (0)
-#define ENC_OPS1(OP0) ((Operand::kOp##OP0))
-#define ENC_OPS2(OP0, OP1) ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3))
-#define ENC_OPS3(OP0, OP1, OP2) ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6))
-#define ENC_OPS4(OP0, OP1, OP2, OP3) ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6) + ((Operand::kOp##OP3) << 9))
+#define ENC_OPS1(OP0) \
+ (uint32_t(OperandType::k##OP0))
-// ============================================================================
-// [asmjit::x86::Assembler - Movabs Heuristics]
-// ============================================================================
+#define ENC_OPS2(OP0, OP1) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3))
-static ASMJIT_INLINE uint32_t x86GetMovAbsInstSize64Bit(uint32_t regSize, uint32_t options, const Mem& rmRel) noexcept {
+#define ENC_OPS3(OP0, OP1, OP2) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3) + \
+ (uint32_t(OperandType::k##OP2) << 6))
+
+#define ENC_OPS4(OP0, OP1, OP2, OP3) \
+ (uint32_t(OperandType::k##OP0) + \
+ (uint32_t(OperandType::k##OP1) << 3) + \
+ (uint32_t(OperandType::k##OP2) << 6) + \
+ (uint32_t(OperandType::k##OP3) << 9))
+
+// x86::Assembler - Movabs Heuristics
+// ==================================
+
+static ASMJIT_FORCE_INLINE uint32_t x86GetMovAbsInstSize64Bit(uint32_t regSize, InstOptions options, const Mem& rmRel) noexcept {
uint32_t segmentPrefixSize = rmRel.segmentId() != 0;
uint32_t _66hPrefixSize = regSize == 2;
- uint32_t rexPrefixSize = (regSize == 8) || ((options & Inst::kOptionRex) != 0);
+ uint32_t rexPrefixSize = regSize == 8 || Support::test(options, InstOptions::kX86_Rex);
uint32_t opCodeByteSize = 1;
uint32_t immediateSize = 8;
return segmentPrefixSize + _66hPrefixSize + rexPrefixSize + opCodeByteSize + immediateSize;
}
-static ASMJIT_INLINE bool x86ShouldUseMovabs(Assembler* self, X86BufferWriter& writer, uint32_t regSize, uint32_t options, const Mem& rmRel) noexcept {
+static ASMJIT_FORCE_INLINE bool x86ShouldUseMovabs(Assembler* self, X86BufferWriter& writer, uint32_t regSize, InstOptions options, const Mem& rmRel) noexcept {
if (self->is32Bit()) {
// There is no relative addressing, just decide whether to use MOV encoded with MOD R/M or absolute.
- return !(options & Inst::kOptionModMR);
+ return !Support::test(options, InstOptions::kX86_ModMR | InstOptions::kX86_ModMR);
}
else {
// If the addressing type is REL or MOD R/M was specified then absolute mov won't be used.
- if (rmRel.addrType() == Mem::kAddrTypeRel || (options & Inst::kOptionModMR) != 0)
+ if (rmRel.addrType() == Mem::AddrType::kRel || Support::test(options, InstOptions::kX86_ModMR))
return false;
int64_t addrValue = rmRel.offset();
@@ -520,7 +503,7 @@ static ASMJIT_INLINE bool x86ShouldUseMovabs(Assembler* self, X86BufferWriter& w
// If the address type is default, it means to basically check whether relative addressing is possible. However,
// this is only possible when the base address is known - relative encoding uses RIP+N it has to be calculated.
- if (rmRel.addrType() == Mem::kAddrTypeDefault && baseAddress != Globals::kNoBaseAddress && !rmRel.hasSegment()) {
+ if (rmRel.addrType() == Mem::AddrType::kDefault && baseAddress != Globals::kNoBaseAddress && !rmRel.hasSegment()) {
uint32_t instructionSize = x86GetMovAbsInstSize64Bit(regSize, options, rmRel);
uint64_t virtualOffset = uint64_t(writer.offsetFrom(self->_bufferData));
uint64_t rip64 = baseAddress + self->_section->offset() + virtualOffset + instructionSize;
@@ -538,9 +521,8 @@ static ASMJIT_INLINE bool x86ShouldUseMovabs(Assembler* self, X86BufferWriter& w
}
}
-// ============================================================================
-// [asmjit::x86::Assembler - Construction / Destruction]
-// ============================================================================
+// x86::Assembler - Construction & Destruction
+// ===========================================
Assembler::Assembler(CodeHolder* code) noexcept : BaseAssembler() {
if (code)
@@ -548,27 +530,26 @@ Assembler::Assembler(CodeHolder* code) noexcept : BaseAssembler() {
}
Assembler::~Assembler() noexcept {}
-// ============================================================================
-// [asmjit::x86::Assembler - Emit (Low-Level)]
-// ============================================================================
+// x86::Assembler - Emit (Low-Level)
+// =================================
-ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
+ASMJIT_FAVOR_SPEED Error Assembler::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
constexpr uint32_t kVSHR_W = Opcode::kW_Shift - 23;
constexpr uint32_t kVSHR_PP = Opcode::kPP_Shift - 16;
constexpr uint32_t kVSHR_PP_EW = Opcode::kPP_Shift - 16;
- constexpr uint32_t kRequiresSpecialHandling =
- uint32_t(Inst::kOptionReserved) | // Logging/Validation/Error.
- uint32_t(Inst::kOptionRep ) | // REP/REPE prefix.
- uint32_t(Inst::kOptionRepne ) | // REPNE prefix.
- uint32_t(Inst::kOptionLock ) | // LOCK prefix.
- uint32_t(Inst::kOptionXAcquire) | // XACQUIRE prefix.
- uint32_t(Inst::kOptionXRelease) ; // XRELEASE prefix.
+ constexpr InstOptions kRequiresSpecialHandling =
+ InstOptions::kReserved | // Logging/Validation/Error.
+ InstOptions::kX86_Rep | // REP/REPE prefix.
+ InstOptions::kX86_Repne | // REPNE prefix.
+ InstOptions::kX86_Lock | // LOCK prefix.
+ InstOptions::kX86_XAcquire | // XACQUIRE prefix.
+ InstOptions::kX86_XRelease ; // XRELEASE prefix.
Error err;
Opcode opcode; // Instruction opcode.
- uint32_t options; // Instruction options.
+ InstOptions options; // Instruction options.
uint32_t isign3; // A combined signature of first 3 operands.
const Operand_* rmRel; // Memory operand or operand that holds Label|Imm.
@@ -595,17 +576,16 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
const InstDB::CommonInfo* commonInfo = &instInfo->commonInfo();
// Signature of the first 3 operands.
- isign3 = o0.opType() + (o1.opType() << 3) + (o2.opType() << 6);
+ isign3 = (uint32_t(o0.opType()) ) +
+ (uint32_t(o1.opType()) << 3) +
+ (uint32_t(o2.opType()) << 6);
- // Combine all instruction options and also check whether the instruction
- // is valid. All options that require special handling (including invalid
- // instruction) are handled by the next branch.
- options = uint32_t(instId == 0);
- options |= uint32_t((size_t)(_bufferEnd - writer.cursor()) < 16);
- options |= uint32_t(instOptions() | forcedInstOptions());
+ // Combine all instruction options and also check whether the instruction is valid. All options
+ // that require special handling (including invalid instruction) are handled by the next branch.
+ options = InstOptions((instId == 0) | ((size_t)(_bufferEnd - writer.cursor()) < 16)) | instOptions() | forcedInstOptions();
// Handle failure and rare cases first.
- if (ASMJIT_UNLIKELY(options & kRequiresSpecialHandling)) {
+ if (ASMJIT_UNLIKELY(Support::test(options, kRequiresSpecialHandling))) {
if (ASMJIT_UNLIKELY(!_code))
return reportError(DebugUtils::errored(kErrorNotInitialized));
@@ -620,7 +600,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
#ifndef ASMJIT_NO_VALIDATION
// Strict validation.
- if (hasValidationOption(kValidationOptionAssembler)) {
+ if (hasDiagnosticOption(DiagnosticOptions::kValidateAssembler)) {
Operand_ opArray[Globals::kMaxOpCount];
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
@@ -630,37 +610,37 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
}
#endif
- uint32_t iFlags = instInfo->flags();
+ InstDB::InstFlags iFlags = instInfo->flags();
// LOCK, XACQUIRE, and XRELEASE prefixes.
- if (options & Inst::kOptionLock) {
- bool xAcqRel = (options & (Inst::kOptionXAcquire | Inst::kOptionXRelease)) != 0;
+ if (Support::test(options, InstOptions::kX86_Lock)) {
+ bool xAcqRel = Support::test(options, InstOptions::kX86_XAcquire | InstOptions::kX86_XRelease);
- if (ASMJIT_UNLIKELY(!(iFlags & (InstDB::kFlagLock)) && !xAcqRel))
+ if (ASMJIT_UNLIKELY(!Support::test(iFlags, InstDB::InstFlags::kLock) && !xAcqRel))
goto InvalidLockPrefix;
if (xAcqRel) {
- if (ASMJIT_UNLIKELY((options & Inst::kOptionXAcquire) && !(iFlags & InstDB::kFlagXAcquire)))
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_XAcquire) && !Support::test(iFlags, InstDB::InstFlags::kXAcquire)))
goto InvalidXAcquirePrefix;
- if (ASMJIT_UNLIKELY((options & Inst::kOptionXRelease) && !(iFlags & InstDB::kFlagXRelease)))
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_XRelease) && !Support::test(iFlags, InstDB::InstFlags::kXRelease)))
goto InvalidXReleasePrefix;
- writer.emit8((options & Inst::kOptionXAcquire) ? 0xF2 : 0xF3);
+ writer.emit8(Support::test(options, InstOptions::kX86_XAcquire) ? 0xF2 : 0xF3);
}
writer.emit8(0xF0);
}
// REP and REPNE prefixes.
- if (options & (Inst::kOptionRep | Inst::kOptionRepne)) {
- if (ASMJIT_UNLIKELY(!(iFlags & InstDB::kFlagRep)))
+ if (Support::test(options, InstOptions::kX86_Rep | InstOptions::kX86_Repne)) {
+ if (ASMJIT_UNLIKELY(!Support::test(iFlags, InstDB::InstFlags::kRep)))
goto InvalidRepPrefix;
- if (_extraReg.isReg() && ASMJIT_UNLIKELY(_extraReg.group() != Reg::kGroupGp || _extraReg.id() != Gp::kIdCx))
+ if (ASMJIT_UNLIKELY(_extraReg.isReg() && (_extraReg.group() != RegGroup::kGp || _extraReg.id() != Gp::kIdCx)))
goto InvalidRepPrefix;
- writer.emit8((options & Inst::kOptionRepne) ? 0xF2 : 0xF3);
+ writer.emit8(Support::test(options, InstOptions::kX86_Repne) ? 0xF2 : 0xF3);
}
}
@@ -670,24 +650,20 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
rbReg = 0;
opcode |= instInfo->_mainOpcodeValue;
- // --------------------------------------------------------------------------
- // [Encoding Scope]
- // --------------------------------------------------------------------------
+ // Encoding Scope
+ // --------------
- // How it works? Each case here represents a unique encoding of a group of
- // instructions, which is handled separately. The handlers check instruction
- // signature, possibly register types, etc, and process this information by
- // writing some bits to opcode, opReg/rbReg, immValue/immSize, etc, and then
- // at the end of the sequence it uses goto to jump into a lower level handler,
- // that actually encodes the instruction.
+ // How it works? Each case here represents a unique encoding of a group of instructions, which is handled
+ // separately. The handlers check instruction signature, possibly register types, etc, and process this
+ // information by writing some bits to opcode, opReg/rbReg, immValue/immSize, etc, and then at the end of
+ // the sequence it uses goto to jump into a lower level handler, that actually encodes the instruction.
switch (instInfo->_encoding) {
case InstDB::kEncodingNone:
goto EmitDone;
- // ------------------------------------------------------------------------
- // [X86]
- // ------------------------------------------------------------------------
+ // Base Instructions
+ // -----------------
case InstDB::kEncodingX86Op:
goto EmitX86Op;
@@ -710,7 +686,7 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
if (ASMJIT_UNLIKELY(!o0.isReg()))
goto InvalidInstruction;
- rmInfo = x86MemInfo[o0.as<Reg>().type()];
+ rmInfo = x86MemInfo[size_t(o0.as<Reg>().type())];
writer.emitAddressOverride((rmInfo & _addressOverrideMask()) != 0);
goto EmitX86Op;
@@ -1005,7 +981,7 @@ CaseX86M_GPB_MulDiv:
}
// MOD/MR: The default encoding used if not instructed otherwise..
- if (!(options & Inst::kOptionModRM))
+ if (!Support::test(options, InstOptions::kX86_ModRM))
goto EmitX86R;
// MOD/RM: Alternative encoding selected via instruction options.
@@ -1073,7 +1049,7 @@ CaseX86M_GPB_MulDiv:
else
goto InvalidImmediate;
}
- else if (canTransformTo32Bit && hasEncodingOption(kEncodingOptionOptimizeForSize)) {
+ else if (canTransformTo32Bit && hasEncodingOption(EncodingOptions::kOptimizeForSize)) {
size = 4;
}
@@ -1081,12 +1057,12 @@ CaseX86M_GPB_MulDiv:
}
immSize = FastUInt8(Support::min<uint32_t>(size, 4));
- if (Support::isInt8(immValue) && !(options & Inst::kOptionLongForm))
+ if (Support::isInt8(immValue) && !Support::test(options, InstOptions::kLongForm))
immSize = 1;
}
// Short form - AL, AX, EAX, RAX.
- if (rbReg == 0 && (size == 1 || immSize != 1) && !(options & Inst::kOptionLongForm)) {
+ if (rbReg == 0 && (size == 1 || immSize != 1) && !Support::test(options, InstOptions::kLongForm)) {
opcode &= Opcode::kPP_66 | Opcode::kW;
opcode |= ((opReg << 3) | (0x04 + (size != 1)));
immSize = FastUInt8(Support::min<uint32_t>(size, 4));
@@ -1110,7 +1086,7 @@ CaseX86M_GPB_MulDiv:
if (memSize == 4)
immValue = x86SignExtendI32<int64_t>(immValue);
- if (Support::isInt8(immValue) && !(options & Inst::kOptionLongForm))
+ if (Support::isInt8(immValue) && !Support::test(options, InstOptions::kLongForm))
immSize = 1;
opcode += memSize != 1 ? (immSize != 1 ? 1 : 3) : 0;
@@ -1179,9 +1155,8 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS1(Mem))
goto EmitX86M;
- // Call with 32-bit displacement use 0xE8 opcode. Call with 8-bit
- // displacement is not encodable so the alternative opcode field
- // in X86DB must be zero.
+ // Call with 32-bit displacement use 0xE8 opcode. Call with 8-bit displacement is not encodable so the
+ // alternative opcode field in X86DB must be zero.
opcode = 0xE8;
opReg = 0;
goto EmitJmpCall;
@@ -1295,7 +1270,7 @@ CaseX86M_GPB_MulDiv:
immValue = o2.as<Imm>().value();
immSize = 1;
- if (!Support::isInt8(immValue) || (options & Inst::kOptionLongForm)) {
+ if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
immSize = o0.size() == 2 ? 2 : 4;
}
@@ -1317,7 +1292,7 @@ CaseX86M_GPB_MulDiv:
if (o0.size() == 4)
immValue = x86SignExtendI32<int64_t>(immValue);
- if (!Support::isInt8(immValue) || (options & Inst::kOptionLongForm)) {
+ if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
immSize = o0.size() == 2 ? 2 : 4;
}
@@ -1369,7 +1344,7 @@ CaseX86M_GPB_MulDiv:
if (o0.size() == 4)
immValue = x86SignExtendI32<int64_t>(immValue);
- if (!Support::isInt8(immValue) || (options & Inst::kOptionLongForm)) {
+ if (!Support::isInt8(immValue) || Support::test(options, InstOptions::kLongForm)) {
opcode -= 2;
immSize = o0.size() == 2 ? 2 : 4;
}
@@ -1460,8 +1435,8 @@ CaseX86M_GPB_MulDiv:
break;
case InstDB::kEncodingX86Jcc:
- if ((options & (Inst::kOptionTaken | Inst::kOptionNotTaken)) && hasEncodingOption(kEncodingOptionPredictedJumps)) {
- uint8_t prefix = (options & Inst::kOptionTaken) ? uint8_t(0x3E) : uint8_t(0x2E);
+ if (Support::test(options, InstOptions::kTaken | InstOptions::kNotTaken) && hasEncodingOption(EncodingOptions::kPredictedJumps)) {
+ uint8_t prefix = Support::test(options, InstOptions::kTaken) ? uint8_t(0x3E) : uint8_t(0x2E);
writer.emit8(prefix);
}
@@ -1493,8 +1468,8 @@ CaseX86M_GPB_MulDiv:
if (isign3 == ENC_OPS1(Mem))
goto EmitX86M;
- // Jump encoded with 32-bit displacement use 0xE9 opcode. Jump encoded
- // with 8-bit displacement's opcode is stored as an alternative opcode.
+ // Jump encoded with 32-bit displacement use 0xE9 opcode. Jump encoded with 8-bit displacement's opcode is
+ // stored as an alternative opcode.
opcode = 0xE9;
opReg = 0;
goto EmitJmpCall;
@@ -1548,11 +1523,9 @@ CaseX86M_GPB_MulDiv:
case InstDB::kEncodingX86Mov:
// Reg <- Reg
if (isign3 == ENC_OPS2(Reg, Reg)) {
- // Asmjit uses segment registers indexed from 1 to 6, leaving zero as
- // "no segment register used". We have to fix this (decrement the index
- // of the register) when emitting MOV instructions which move to/from
- // a segment register. The segment register is always `opReg`, because
- // the MOV instruction uses either RM or MR encoding.
+ // Asmjit uses segment registers indexed from 1 to 6, leaving zero as "no segment register used". We have to
+ // fix this (decrement the index of the register) when emitting MOV instructions which move to/from a segment
+ // register. The segment register is always `opReg`, because the MOV instruction uses either RM or MR encoding.
// GP <- ??
if (Reg::isGp(o0)) {
@@ -1562,21 +1535,15 @@ CaseX86M_GPB_MulDiv:
// GP <- GP
if (Reg::isGp(o1)) {
uint32_t opSize = o0.size();
- if (opSize != o1.size()) {
- // TODO: [X86 Assembler] This is a non-standard extension, which should be removed.
- // We allow 'mov r64, r32' as it's basically zero-extend.
- if (opSize == 8 && o1.size() == 4)
- opSize = 4; // Zero extend, don't promote to 64-bit.
- else
- goto InvalidInstruction;
- }
+ if (opSize != o1.size())
+ goto InvalidInstruction;
if (opSize == 1) {
FIXUP_GPB(o0, rbReg);
FIXUP_GPB(o1, opReg);
opcode = 0x88;
- if (!(options & Inst::kOptionModRM))
+ if (!Support::test(options, InstOptions::kX86_ModRM))
goto EmitX86R;
opcode += 2;
@@ -1587,7 +1554,7 @@ CaseX86M_GPB_MulDiv:
opcode = 0x89;
opcode.addPrefixBySize(opSize);
- if (!(options & Inst::kOptionModRM))
+ if (!Support::test(options, InstOptions::kX86_ModRM))
goto EmitX86R;
opcode += 2;
@@ -1742,8 +1709,8 @@ CaseX86M_GPB_MulDiv:
immValue = o1.as<Imm>().value();
// Optimize the instruction size by using a 32-bit immediate if possible.
- if (immSize == 8 && !(options & Inst::kOptionLongForm)) {
- if (Support::isUInt32(immValue) && hasEncodingOption(kEncodingOptionOptimizeForSize)) {
+ if (immSize == 8 && !Support::test(options, InstOptions::kLongForm)) {
+ if (Support::isUInt32(immValue) && hasEncodingOption(EncodingOptions::kOptimizeForSize)) {
// Zero-extend by using a 32-bit GPD destination instead of a 64-bit GPQ.
immSize = 4;
}
@@ -1796,7 +1763,7 @@ CaseX86M_GPB_MulDiv:
if (ASMJIT_UNLIKELY(rmRel->as<Mem>().hasBaseOrIndex()))
goto InvalidAddress;
- if (ASMJIT_UNLIKELY(rmRel->as<Mem>().addrType() == Mem::kAddrTypeRel))
+ if (ASMJIT_UNLIKELY(rmRel->as<Mem>().addrType() == Mem::AddrType::kRel))
goto InvalidAddress;
immValue = rmRel->as<Mem>().offset();
@@ -1944,7 +1911,7 @@ CaseX86M_GPB_MulDiv:
immValue = o0.as<Imm>().value();
immSize = 4;
- if (Support::isInt8(immValue) && !(options & Inst::kOptionLongForm))
+ if (Support::isInt8(immValue) && !Support::test(options, InstOptions::kLongForm))
immSize = 1;
opcode = immSize == 1 ? 0x6A : 0x68;
@@ -1964,9 +1931,8 @@ CaseX86M_GPB_MulDiv:
}
else {
CaseX86PushPop_Gp:
- // We allow 2 byte, 4 byte, and 8 byte register sizes, although PUSH
- // and POP only allow 2 bytes or native size. On 64-bit we simply
- // PUSH/POP 64-bit register even if 32-bit register was given.
+ // We allow 2 byte, 4 byte, and 8 byte register sizes, although PUSH and POP only allow 2 bytes or
+ // native size. On 64-bit we simply PUSH/POP 64-bit register even if 32-bit register was given.
if (ASMJIT_UNLIKELY(o0.size() < 2))
goto InvalidInstruction;
@@ -1999,7 +1965,7 @@ CaseX86PushPop_Gp:
if (isign3 == ENC_OPS1(Imm)) {
immValue = o0.as<Imm>().value();
- if (immValue == 0 && !(options & Inst::kOptionLongForm)) {
+ if (immValue == 0 && !Support::test(options, InstOptions::kLongForm)) {
// 'ret' without immediate, change C2 to C3.
opcode.add(1);
goto EmitX86Op;
@@ -2031,7 +1997,7 @@ CaseX86PushPop_Gp:
immValue = o1.as<Imm>().value() & 0xFF;
immSize = 0;
- if (immValue == 1 && !(options & Inst::kOptionLongForm))
+ if (immValue == 1 && !Support::test(options, InstOptions::kLongForm))
goto EmitX86R;
opcode -= 0x10;
@@ -2058,7 +2024,7 @@ CaseX86PushPop_Gp:
immValue = o1.as<Imm>().value() & 0xFF;
immSize = 0;
- if (immValue == 1 && !(options & Inst::kOptionLongForm))
+ if (immValue == 1 && !Support::test(options, InstOptions::kLongForm))
goto EmitX86M;
opcode -= 0x10;
@@ -2226,7 +2192,7 @@ CaseX86PushPop_Gp:
}
// Short form - AL, AX, EAX, RAX.
- if (rbReg == 0 && !(options & Inst::kOptionLongForm)) {
+ if (rbReg == 0 && !Support::test(options, InstOptions::kLongForm)) {
opcode &= Opcode::kPP_66 | Opcode::kW;
opcode |= 0xA8 + (o0.size() != 1);
goto EmitX86Op;
@@ -2290,7 +2256,7 @@ CaseX86PushPop_Gp:
// Encode 'xchg eax, eax' by by using a generic path.
}
}
- else if (!(options & Inst::kOptionLongForm)) {
+ else if (!Support::test(options, InstOptions::kLongForm)) {
// The special encoding encodes only one register, which is non-zero.
opReg += rbReg;
@@ -2328,7 +2294,7 @@ CaseX86PushPop_Gp:
rbReg = o1.id();
// ModRM encoding:
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitX86R;
// ModMR encoding:
@@ -2352,9 +2318,8 @@ CaseX86PushPop_Gp:
}
break;
- // ------------------------------------------------------------------------
- // [FPU]
- // ------------------------------------------------------------------------
+ // FPU Instructions
+ // ----------------
case InstDB::kEncodingFpuOp:
goto EmitFpuOp;
@@ -2414,16 +2379,16 @@ CaseFpuArith_Mem:
if (isign3 == ENC_OPS1(Mem)) {
rmRel = &o0;
- if (o0.size() == 4 && commonInfo->hasFlag(InstDB::kFlagFpuM32)) {
+ if (o0.size() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
goto EmitX86M;
}
- if (o0.size() == 8 && commonInfo->hasFlag(InstDB::kFlagFpuM64)) {
+ if (o0.size() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
opcode += 4;
goto EmitX86M;
}
- if (o0.size() == 10 && commonInfo->hasFlag(InstDB::kFlagFpuM80)) {
+ if (o0.size() == 10 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM80)) {
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractModO();
goto EmitX86M;
@@ -2443,16 +2408,16 @@ CaseFpuArith_Mem:
opcode &= ~uint32_t(Opcode::kCDSHL_Mask);
rmRel = &o0;
- if (o0.size() == 2 && commonInfo->hasFlag(InstDB::kFlagFpuM16)) {
+ if (o0.size() == 2 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM16)) {
opcode += 4;
goto EmitX86M;
}
- if (o0.size() == 4 && commonInfo->hasFlag(InstDB::kFlagFpuM32)) {
+ if (o0.size() == 4 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM32)) {
goto EmitX86M;
}
- if (o0.size() == 8 && commonInfo->hasFlag(InstDB::kFlagFpuM64)) {
+ if (o0.size() == 8 && commonInfo->hasFlag(InstDB::InstFlags::kFpuM64)) {
opcode = x86AltOpcodeOf(instInfo) & ~uint32_t(Opcode::kCDSHL_Mask);
opReg = opcode.extractModO();
goto EmitX86M;
@@ -2492,9 +2457,8 @@ CaseFpuArith_Mem:
}
break;
- // ------------------------------------------------------------------------
- // [Ext]
- // ------------------------------------------------------------------------
+ // Ext Instructions (Legacy Extensions)
+ // ------------------------------------
case InstDB::kEncodingExtPextrw:
if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
@@ -2552,7 +2516,7 @@ CaseFpuArith_Mem:
opReg = o0.id();
rbReg = o1.id();
- if (!(options & Inst::kOptionModMR) || !instInfo->_altOpcodeIndex)
+ if (!Support::test(options, InstOptions::kX86_ModMR) || !instInfo->_altOpcodeIndex)
goto EmitX86R;
opcode = x86AltOpcodeOf(instInfo);
@@ -2648,7 +2612,7 @@ CaseExtMovd:
if (Reg::isMm(o0) && Reg::isMm(o1)) {
opcode = Opcode::k000F00 | 0x6F;
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitX86R;
opcode += 0x10;
@@ -2660,7 +2624,7 @@ CaseExtMovd:
if (Reg::isXmm(o0) && Reg::isXmm(o1)) {
opcode = Opcode::kF30F00 | 0x7E;
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitX86R;
opcode = Opcode::k660F00 | 0xD6;
@@ -2858,9 +2822,8 @@ CaseExtRm:
}
break;
- // ------------------------------------------------------------------------
- // [Extrq / Insertq (SSE4A)]
- // ------------------------------------------------------------------------
+ // Extrq & Insertq (SSE4A)
+ // -----------------------
case InstDB::kEncodingExtExtrq:
opReg = o0.id();
@@ -2884,7 +2847,7 @@ CaseExtRm:
case InstDB::kEncodingExtInsertq: {
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
opReg = o0.id();
rbReg = o1.id();
@@ -2904,9 +2867,8 @@ CaseExtRm:
break;
}
- // ------------------------------------------------------------------------
- // [3dNow]
- // ------------------------------------------------------------------------
+ // 3DNOW Instructions
+ // ------------------
case InstDB::kEncodingExt3dNow:
// Every 3dNow instruction starts with 0x0F0F and the actual opcode is
@@ -2928,12 +2890,11 @@ CaseExtRm:
}
break;
- // ------------------------------------------------------------------------
- // [VEX/EVEX]
- // ------------------------------------------------------------------------
+ // VEX/EVEX Instructions
+ // ---------------------
case InstDB::kEncodingVexOp:
- goto EmitVexEvexOp;
+ goto EmitVexOp;
case InstDB::kEncodingVexOpMod:
rbReg = 0;
@@ -2957,7 +2918,7 @@ CaseExtRm:
}
// Form 'k, k'.
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitVexEvexR;
opcode.add(1);
@@ -3239,7 +3200,7 @@ CaseVexRvm_R:
case InstDB::kEncodingVexRvmr: {
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
immValue = o3.id() << 4;
immSize = 1;
@@ -3274,7 +3235,7 @@ CaseVexRvm_R:
VexRvmi:
{
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
immValue = o3.as<Imm>().value();
immSize = 1;
@@ -3335,7 +3296,7 @@ VexRvmi:
case InstDB::kEncodingVexRmvi: {
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
immValue = o3.as<Imm>().value();
immSize = 1;
@@ -3441,7 +3402,7 @@ VexRvmi:
opReg = x86PackRegAndVvvvv(o0.id(), o2.id());
rbReg = o1.id();
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitVexEvexR;
opcode.addW();
@@ -3506,7 +3467,7 @@ VexRvmi:
opReg = x86PackRegAndVvvvv(o0.id(), o2.id());
rbReg = o1.id();
- if (!(options & Inst::kOptionModMR))
+ if (!Support::test(options, InstOptions::kX86_ModMR))
goto EmitVexEvexR;
opcode.addW();
@@ -3703,7 +3664,7 @@ CaseVexVmi_AfterImm:
case InstDB::kEncodingVexRvrmRvmr: {
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
opReg = x86PackRegAndVvvvv(o0.id(), o1.id());
@@ -3742,7 +3703,7 @@ CaseVexVmi_AfterImm:
if (ASMJIT_UNLIKELY(!o4.isImm()))
goto InvalidInstruction;
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
opcode |= x86OpcodeLBySize(o0.size() | o1.size() | o2.size() | o3.size());
immValue = o4.as<Imm>().valueAs<uint8_t>() & 0x0F;
@@ -3794,9 +3755,8 @@ CaseVexVmi_AfterImm:
}
break;
- // ------------------------------------------------------------------------
- // [FMA4]
- // ------------------------------------------------------------------------
+ // FMA4 Instructions
+ // -----------------
case InstDB::kEncodingFma4_Lx:
// It's fine to just check the first operand, second is just for sanity.
@@ -3805,12 +3765,12 @@ CaseVexVmi_AfterImm:
case InstDB::kEncodingFma4: {
const Operand_& o3 = opExt[EmitterUtils::kOp3];
- const uint32_t isign4 = isign3 + (o3.opType() << 9);
+ const uint32_t isign4 = isign3 + (uint32_t(o3.opType()) << 9);
if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
opReg = x86PackRegAndVvvvv(o0.id(), o1.id());
- if (!(options & Inst::kOptionModMR)) {
+ if (!Support::test(options, InstOptions::kX86_ModMR)) {
// MOD/RM - Encoding preferred by LLVM.
opcode.addW();
rbReg = o3.id();
@@ -3850,9 +3810,8 @@ CaseVexVmi_AfterImm:
break;
}
- // ------------------------------------------------------------------------
- // [AMX]
- // ------------------------------------------------------------------------
+ // AMX Instructions
+ // ----------------
case InstDB::kEncodingAmxCfg:
if (isign3 == ENC_OPS1(Mem)) {
@@ -3896,9 +3855,8 @@ CaseVexVmi_AfterImm:
goto InvalidInstruction;
- // --------------------------------------------------------------------------
- // [Emit - X86]
- // --------------------------------------------------------------------------
+ // Emit - X86 Opcode
+ // -----------------
EmitX86OpMovAbs:
immSize = FastUInt8(registerSize());
@@ -3922,9 +3880,8 @@ EmitX86Op:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - X86 - Opcode + Reg]
- // --------------------------------------------------------------------------
+ // Emit - X86 - Opcode + Reg
+ // -------------------------
EmitX86OpReg:
// Emit mandatory instruction prefix.
@@ -3947,9 +3904,8 @@ EmitX86OpReg:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - X86 - Opcode with implicit <mem> operand]
- // --------------------------------------------------------------------------
+ // Emit - X86 - Opcode with Implicit <mem> Operand
+ // -----------------------------------------------
EmitX86OpImplicitMem:
rmInfo = x86MemInfo[rmRel->as<Mem>().baseAndIndexTypes()];
@@ -3979,9 +3935,8 @@ EmitX86OpImplicitMem:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - X86 - Opcode /r - register]
- // --------------------------------------------------------------------------
+ // Emit - X86 - Opcode /r - Register
+ // ---------------------------------
EmitX86R:
// Mandatory instruction prefix.
@@ -4012,9 +3967,8 @@ EmitX86R:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - X86 - Opcode /r - memory base]
- // --------------------------------------------------------------------------
+ // Emit - X86 - Opcode /r - Memory Base
+ // ------------------------------------
EmitX86RFromM:
rmInfo = x86MemInfo[rmRel->as<Mem>().baseAndIndexTypes()];
@@ -4053,14 +4007,13 @@ EmitX86RFromM:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - X86 - Opcode /r - memory operand]
- // --------------------------------------------------------------------------
+ // Emit - X86 - Opcode /r - memory Operand
+ // ---------------------------------------
EmitX86M:
// `rmRel` operand must be memory.
ASMJIT_ASSERT(rmRel != nullptr);
- ASMJIT_ASSERT(rmRel->opType() == Operand::kOpMem);
+ ASMJIT_ASSERT(rmRel->opType() == OperandType::kMem);
ASMJIT_ASSERT((opcode & Opcode::kCDSHL_Mask) == 0);
// Emit override prefixes.
@@ -4099,9 +4052,8 @@ EmitX86M:
// ... Fall through ...
- // --------------------------------------------------------------------------
- // [Emit - MOD/SIB]
- // --------------------------------------------------------------------------
+ // Emit - MOD/SIB
+ // --------------
EmitModSib:
if (!(rmInfo & (kX86MemInfo_Index | kX86MemInfo_67H_X86))) {
@@ -4158,12 +4110,12 @@ EmitModSib:
}
// ==========|> [ABSOLUTE | DISP32].
else if (!(rmInfo & (kX86MemInfo_BaseLabel | kX86MemInfo_BaseRip))) {
- uint32_t addrType = rmRel->as<Mem>().addrType();
+ Mem::AddrType addrType = rmRel->as<Mem>().addrType();
relOffset = rmRel->as<Mem>().offsetLo32();
if (is32Bit()) {
// Explicit relative addressing doesn't work in 32-bit mode.
- if (ASMJIT_UNLIKELY(addrType == Mem::kAddrTypeRel))
+ if (ASMJIT_UNLIKELY(addrType == Mem::AddrType::kRel))
goto InvalidAddress;
writer.emit8(x86EncodeMod(0, opReg, 5));
@@ -4174,14 +4126,13 @@ EmitModSib:
bool isOffsetU32 = rmRel->as<Mem>().offsetHi32() == 0;
uint64_t baseAddress = code()->baseAddress();
- // If relative addressing was not explicitly set then we can try to guess.
- // By guessing we check some properties of the memory operand and try to
- // base the decision on the segment prefix and the address type.
- if (addrType == Mem::kAddrTypeDefault) {
+ // If relative addressing was not explicitly set then we can try to guess. By guessing we check some
+ // properties of the memory operand and try to base the decision on the segment prefix and the address type.
+ if (addrType == Mem::AddrType::kDefault) {
if (baseAddress == Globals::kNoBaseAddress) {
// Prefer absolute addressing mode if the offset is 32-bit.
- addrType = isOffsetI32 || isOffsetU32 ? Mem::kAddrTypeAbs
- : Mem::kAddrTypeRel;
+ addrType = isOffsetI32 || isOffsetU32 ? Mem::AddrType::kAbs
+ : Mem::AddrType::kRel;
}
else {
// Prefer absolute addressing mode if FS|GS segment override is present.
@@ -4189,18 +4140,18 @@ EmitModSib:
// Prefer absolute addressing mode if this is LEA with 32-bit immediate.
bool isLea32 = (instId == Inst::kIdLea) && (isOffsetI32 || isOffsetU32);
- addrType = hasFsGs || isLea32 ? Mem::kAddrTypeAbs
- : Mem::kAddrTypeRel;
+ addrType = hasFsGs || isLea32 ? Mem::AddrType::kAbs
+ : Mem::AddrType::kRel;
}
}
- if (addrType == Mem::kAddrTypeRel) {
+ if (addrType == Mem::AddrType::kRel) {
uint32_t kModRel32Size = 5;
uint64_t virtualOffset = uint64_t(writer.offsetFrom(_bufferData)) + immSize + kModRel32Size;
if (baseAddress == Globals::kNoBaseAddress || _section->id() != 0) {
// Create a new RelocEntry as we cannot calculate the offset right now.
- err = _code->newRelocEntry(&re, RelocEntry::kTypeAbsToRel);
+ err = _code->newRelocEntry(&re, RelocType::kAbsToRel);
if (ASMJIT_UNLIKELY(err))
goto Failed;
@@ -4235,22 +4186,19 @@ EmitModSib:
}
}
- // Handle unsigned 32-bit address that doesn't work with sign extension.
- // Consider the following instructions:
+ // Handle unsigned 32-bit address that doesn't work with sign extension. Consider the following instructions:
//
// 1. lea rax, [-1] - Sign extended to 0xFFFFFFFFFFFFFFFF
// 2. lea rax, [0xFFFFFFFF] - Zero extended to 0x00000000FFFFFFFF
// 3. add rax, [-1] - Sign extended to 0xFFFFFFFFFFFFFFFF
// 4. add rax, [0xFFFFFFFF] - Zero extended to 0x00000000FFFFFFFF
//
- // Sign extension is naturally performed by the CPU so we don't have to
- // bother, however, zero extension requires address-size override prefix,
- // which we probably don't have at this moment. So to make the address
+ // Sign extension is naturally performed by the CPU so we don't have to bother, however, zero extension
+ // requires address-size override prefix, which we probably don't have at this moment. So to make the address
// valid we need to insert it at `memOpAOMark` if it's not already there.
//
- // If this is 'lea' instruction then it's possible to remove REX.W part
- // from REX prefix (if it's there), which would be one-byte shorter than
- // inserting address-size override.
+ // If this is 'lea' instruction then it's possible to remove REX.W part from REX prefix (if it's there), which
+ // would be one-byte shorter than inserting address-size override.
//
// NOTE: If we don't do this then these instructions are unencodable.
if (!isOffsetI32) {
@@ -4261,16 +4209,15 @@ EmitModSib:
// We only patch the existing code if we don't have address-size override.
if (*memOpAOMark != 0x67) {
if (instId == Inst::kIdLea) {
- // LEA: Remove REX.W, if present. This is easy as we know that 'lea'
- // doesn't use any PP prefix so if REX prefix was emitted it would be
- // at `memOpAOMark`.
+ // LEA: Remove REX.W, if present. This is easy as we know that 'lea' doesn't use any PP prefix so if REX
+ // prefix was emitted it would be at `memOpAOMark`.
uint32_t rex = *memOpAOMark;
if (rex & kX86ByteRex) {
rex &= (~kX86ByteRexW) & 0xFF;
*memOpAOMark = uint8_t(rex);
// We can remove the REX prefix completely if it was not forced.
- if (rex == kX86ByteRex && !(options & Inst::kOptionRex))
+ if (rex == kX86ByteRex && !Support::test(options, InstOptions::kX86_Rex))
writer.remove8(memOpAOMark);
}
}
@@ -4303,7 +4250,7 @@ EmitModSib_LabelRip_X86:
if (ASMJIT_UNLIKELY(!label))
goto InvalidLabel;
- err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs);
+ err = _code->newRelocEntry(&re, RelocType::kRelToAbs);
if (ASMJIT_UNLIKELY(err))
goto Failed;
@@ -4328,7 +4275,7 @@ EmitModSib_LabelRip_X86:
}
else {
// [RIP->ABS].
- err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs);
+ err = _code->newRelocEntry(&re, RelocType::kRelToAbs);
if (ASMJIT_UNLIKELY(err))
goto Failed;
@@ -4370,8 +4317,8 @@ EmitModSib_LabelRip_X86:
}
}
else if (!(rmInfo & kX86MemInfo_67H_X86)) {
- // ESP|RSP can't be used as INDEX in pure SIB mode, however, VSIB mode
- // allows XMM4|YMM4|ZMM4 (that's why the check is before the label).
+ // ESP|RSP can't be used as INDEX in pure SIB mode, however, VSIB mode allows XMM4|YMM4|ZMM4 (that's why the
+ // check is before the label).
if (ASMJIT_UNLIKELY(rxReg == Gp::kIdSp))
goto InvalidAddressIndex;
@@ -4435,10 +4382,9 @@ EmitModVSib:
// 16-bit address mode (32-bit mode with 67 override prefix).
relOffset = (int32_t(rmRel->as<Mem>().offsetLo32()) << 16) >> 16;
- // NOTE: 16-bit addresses don't use SIB byte and their encoding differs. We
- // use a table-based approach to calculate the proper MOD byte as it's easier.
- // Also, not all BASE [+ INDEX] combinations are supported in 16-bit mode, so
- // this may fail.
+ // NOTE: 16-bit addresses don't use SIB byte and their encoding differs. We use a table-based approach to
+ // calculate the proper MOD byte as it's easier. Also, not all BASE [+ INDEX] combinations are supported
+ // in 16-bit mode, so this may fail.
const uint32_t kBaseGpIdx = (kX86MemInfo_BaseGp | kX86MemInfo_Index);
if (rmInfo & kBaseGpIdx) {
@@ -4490,9 +4436,8 @@ EmitModVSib:
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - FPU]
- // --------------------------------------------------------------------------
+ // Emit - FPU
+ // ----------
EmitFpuOp:
// Mandatory instruction prefix.
@@ -4503,31 +4448,29 @@ EmitFpuOp:
writer.emit8(opcode.v);
goto EmitDone;
- // --------------------------------------------------------------------------
- // [Emit - VEX|EVEX]
- // --------------------------------------------------------------------------
+ // Emit - VEX Opcode
+ // -----------------
-EmitVexEvexOp:
+EmitVexOp:
{
// These don't use immediate.
ASMJIT_ASSERT(immSize == 0);
- // Only 'vzeroall' and 'vzeroupper' instructions use this encoding, they
- // don't define 'W' to be '1' so we can just check the 'mmmmm' field. Both
- // functions can encode by using VEX2 prefix so VEX3 is basically only used
+ // Only 'vzeroall' and 'vzeroupper' instructions use this encoding, they don't define 'W' to be '1' so we can
+ // just check the 'mmmmm' field. Both functions can encode by using VEX2 prefix so VEX3 is basically only used
// when specified as instruction option.
ASMJIT_ASSERT((opcode & Opcode::kW) == 0);
- uint32_t x = ((opcode & Opcode::kMM_Mask ) >> (Opcode::kMM_Shift )) |
- ((opcode & Opcode::kLL_Mask ) >> (Opcode::kLL_Shift - 10)) |
- ((opcode & Opcode::kPP_VEXMask ) >> (Opcode::kPP_Shift - 8)) |
- ((options & Inst::kOptionVex3 ) >> (Opcode::kMM_Shift )) ;
- if (x & 0x04u) {
- x = (x & (0x4 ^ 0xFFFF)) << 8; // [00000000|00000Lpp|0000m0mm|00000000].
- x ^= (kX86ByteVex3) | // [........|00000Lpp|0000m0mm|__VEX3__].
- (0x07u << 13) | // [........|00000Lpp|1110m0mm|__VEX3__].
- (0x0Fu << 19) | // [........|01111Lpp|1110m0mm|__VEX3__].
- (opcode << 24) ; // [_OPCODE_|01111Lpp|1110m0mm|__VEX3__].
+ uint32_t x = (uint32_t(opcode & Opcode::kMM_Mask ) >> (Opcode::kMM_Shift )) |
+ (uint32_t(opcode & Opcode::kLL_Mask ) >> (Opcode::kLL_Shift - 10)) |
+ (uint32_t(opcode & Opcode::kPP_VEXMask ) >> (Opcode::kPP_Shift - 8)) ;
+
+ if (Support::test(options, InstOptions::kX86_Vex3)) {
+ x = (x & 0xFFFF) << 8; // [00000000|00000Lpp|000mmmmm|00000000].
+ x ^= (kX86ByteVex3) | // [........|00000Lpp|000mmmmm|__VEX3__].
+ (0x07u << 13) | // [........|00000Lpp|111mmmmm|__VEX3__].
+ (0x0Fu << 19) | // [........|01111Lpp|111mmmmm|__VEX3__].
+ (opcode << 24) ; // [_OPCODE_|01111Lpp|111mmmmm|__VEX3__].
writer.emit32uLE(x);
goto EmitDone;
@@ -4541,83 +4484,83 @@ EmitVexEvexOp:
}
}
- // --------------------------------------------------------------------------
- // [Emit - VEX|EVEX - /r (Register)]
- // --------------------------------------------------------------------------
+ // Emit - VEX|EVEX - /r - Register
+ // -------------------------------
EmitVexEvexR:
{
// Construct `x` - a complete EVEX|VEX prefix.
- uint32_t x = ((opReg << 4) & 0xF980u) | // [........|........|Vvvvv..R|R.......].
- ((rbReg << 2) & 0x0060u) | // [........|........|........|.BB.....].
- (opcode.extractLLMM(options)) | // [........|.LL.....|Vvvvv..R|RBBmmmmm].
- (_extraReg.id() << 16); // [........|.LL..aaa|Vvvvv..R|RBBmmmmm].
+ uint32_t x = ((opReg << 4) & 0xF980u) | // [........|........|Vvvvv..R|R.......].
+ ((rbReg << 2) & 0x0060u) | // [........|........|........|.BB.....].
+ (opcode.extractLLMMMMM(options)) | // [........|.LL.....|Vvvvv..R|RBBmmmmm].
+ (_extraReg.id() << 16); // [........|.LL..aaa|Vvvvv..R|RBBmmmmm].
opReg &= 0x7;
// Handle AVX512 options by a single branch.
- const uint32_t kAvx512Options = Inst::kOptionZMask | Inst::kOptionER | Inst::kOptionSAE;
- if (options & kAvx512Options) {
- uint32_t kBcstMask = 0x1 << 20;
- uint32_t kLLMask10 = 0x2 << 21;
- uint32_t kLLMask11 = 0x3 << 21;
+ const InstOptions kAvx512Options = InstOptions::kX86_ZMask | InstOptions::kX86_ER | InstOptions::kX86_SAE;
+ if (Support::test(options, kAvx512Options)) {
+ static constexpr uint32_t kBcstMask = 0x1 << 20;
+ static constexpr uint32_t kLLMask10 = 0x2 << 21;
+ static constexpr uint32_t kLLMask11 = 0x3 << 21;
- // Designed to be easily encodable so the position must be exact.
- // The {rz-sae} is encoded as {11}, so it should match the mask.
- ASMJIT_ASSERT(Inst::kOptionRZ_SAE == kLLMask11);
+ // Designed to be easily encodable so the position must be exact. The {rz-sae} is encoded as {11},
+ // so it should match the mask.
+ static_assert(uint32_t(InstOptions::kX86_RZ_SAE) == kLLMask11,
+ "This code requires InstOptions::X86_RZ_SAE to match kLLMask11 to work properly");
- x |= options & Inst::kOptionZMask; // [........|zLLb.aaa|Vvvvv..R|RBBmmmmm].
+ x |= uint32_t(options & InstOptions::kX86_ZMask); // [........|zLLb.aaa|Vvvvv..R|RBBmmmmm].
// Support embedded-rounding {er} and suppress-all-exceptions {sae}.
- if (options & (Inst::kOptionER | Inst::kOptionSAE)) {
- // Embedded rounding is only encodable if the instruction is either
- // scalar or it's a 512-bit operation as the {er} rounding predicate
- // collides with LL part of the instruction.
+ if (Support::test(options, InstOptions::kX86_ER | InstOptions::kX86_SAE)) {
+ // Embedded rounding is only encodable if the instruction is either scalar or it's a 512-bit
+ // operation as the {er} rounding predicate collides with LL part of the instruction.
if ((x & kLLMask11) != kLLMask10) {
- // Ok, so LL is not 10, thus the instruction must be scalar.
- // Scalar instructions don't support broadcast so if this
- // instruction supports it {er} nor {sae} would be encodable.
+ // Ok, so LL is not 10, thus the instruction must be scalar. Scalar instructions don't
+ // support broadcast so if this instruction supports it {er} nor {sae} would be encodable.
if (ASMJIT_UNLIKELY(commonInfo->hasAvx512B()))
goto InvalidEROrSAE;
}
- if (options & Inst::kOptionER) {
+ if (Support::test(options, InstOptions::kX86_ER)) {
if (ASMJIT_UNLIKELY(!commonInfo->hasAvx512ER()))
goto InvalidEROrSAE;
- x &=~kLLMask11; // [........|.00..aaa|Vvvvv..R|RBBmmmmm].
- x |= kBcstMask | (options & kLLMask11); // [........|.LLb.aaa|Vvvvv..R|RBBmmmmm].
+ x &=~kLLMask11; // [........|.00..aaa|Vvvvv..R|RBBmmmmm].
+ x |= kBcstMask | (uint32_t(options) & kLLMask11); // [........|.LLb.aaa|Vvvvv..R|RBBmmmmm].
}
else {
if (ASMJIT_UNLIKELY(!commonInfo->hasAvx512SAE()))
goto InvalidEROrSAE;
- x |= kBcstMask; // [........|.LLb.aaa|Vvvvv..R|RBBmmmmm].
+ x &=~kLLMask11; // [........|.00..aaa|Vvvvv..R|RBBmmmmm].
+ x |= kBcstMask; // [........|.00b.aaa|Vvvvv..R|RBBmmmmm].
}
}
}
- // If these bits are used then EVEX prefix is required.
- constexpr uint32_t kEvexBits = 0x00D78150u; // [........|xx.x.xxx|x......x|.x.x....].
+ // These bits would force EVEX prefix.
+ constexpr uint32_t kEvexForce = 0x00000010u; // [........|........|........|...x....].
+ constexpr uint32_t kEvexBits = 0x00D78150u; // [........|xx.x.xxx|x......x|.x.x....].
// Force EVEX prefix even in case the instruction has VEX encoding, because EVEX encoding is preferred. At the
- // moment this is only required for AVX_VNNI instructions, which were added after AVX512_VNNI instructions. If
- // such instruction doesn't specify prefix, EVEX (AVX512_VNNI) would be used by default,
+ // moment this is only required by AVX_VNNI instructions, which were added after AVX512_VNNI instructions. If
+ // such instruction doesn't specify prefix, EVEX (AVX512_VNNI) is selected by default.
if (commonInfo->preferEvex()) {
- if ((x & kEvexBits) == 0 && (options & (Inst::kOptionVex | Inst::kOptionVex3)) == 0) {
- x |= (Opcode::kMM_ForceEvex) >> Opcode::kMM_Shift;
+ if ((x & kEvexBits) == 0 && !Support::test(options, InstOptions::kX86_Vex | InstOptions::kX86_Vex3)) {
+ x |= kEvexForce;
}
}
- // Check if EVEX is required by checking bits in `x` : [........|xx.x.xxx|x......x|.x.x....].
+ // Check if EVEX is required by checking bits in `x` : [........|xx.x.xxx|x......x|.x.x....].
if (x & kEvexBits) {
- uint32_t y = ((x << 4) & 0x00080000u) | // [........|...bV...|........|........].
- ((x >> 4) & 0x00000010u) ; // [........|...bV...|........|...R....].
- x = (x & 0x00FF78E3u) | y; // [........|zLLbVaaa|0vvvv000|RBBR00mm].
- x = x << 8; // [zLLbVaaa|0vvvv000|RBBR00mm|00000000].
- x |= (opcode >> kVSHR_W ) & 0x00800000u; // [zLLbVaaa|Wvvvv000|RBBR00mm|00000000].
- x |= (opcode >> kVSHR_PP_EW) & 0x00830000u; // [zLLbVaaa|Wvvvv0pp|RBBR00mm|00000000] (added PP and EVEX.W).
- // _ ____ ____
- x ^= 0x087CF000u | kX86ByteEvex; // [zLLbVaaa|Wvvvv1pp|RBBR00mm|01100010].
+ uint32_t y = ((x << 4) & 0x00080000u) | // [........|...bV...|........|........].
+ ((x >> 4) & 0x00000010u) ; // [........|...bV...|........|...R....].
+ x = (x & 0x00FF78EFu) | y; // [........|zLLbVaaa|0vvvv000|RBBRmmmm].
+ x = x << 8; // [zLLbVaaa|0vvvv000|RBBRmmmm|00000000].
+ x |= (opcode >> kVSHR_W ) & 0x00800000u; // [zLLbVaaa|Wvvvv000|RBBRmmmm|00000000].
+ x |= (opcode >> kVSHR_PP_EW) & 0x00830000u; // [zLLbVaaa|Wvvvv0pp|RBBRmmmm|00000000] (added PP and EVEX.W).
+ // _ ____ ____
+ x ^= 0x087CF000u | kX86ByteEvex; // [zLLbVaaa|Wvvvv1pp|RBBRmmmm|01100010].
writer.emit32uLE(x);
writer.emit8(opcode.v);
@@ -4628,19 +4571,20 @@ EmitVexEvexR:
goto EmitDone;
}
- // Not EVEX, prepare `x` for VEX2 or VEX3: x = [........|00L00000|0vvvv000|R0B0mmmm].
- x |= ((opcode >> (kVSHR_W + 8)) & 0x8000u) | // [00000000|00L00000|Wvvvv000|R0B0mmmm].
- ((opcode >> (kVSHR_PP + 8)) & 0x0300u) | // [00000000|00L00000|0vvvv0pp|R0B0mmmm].
- ((x >> 11 ) & 0x0400u) ; // [00000000|00L00000|WvvvvLpp|R0B0mmmm].
+ // Not EVEX, prepare `x` for VEX2 or VEX3: x = [........|00L00000|0vvvv000|R0Bmmmmm].
+ x |= ((opcode >> (kVSHR_W + 8)) & 0x8000u) | // [00000000|00L00000|Wvvvv000|R0Bmmmmm].
+ ((opcode >> (kVSHR_PP + 8)) & 0x0300u) | // [00000000|00L00000|0vvvv0pp|R0Bmmmmm].
+ ((x >> 11 ) & 0x0400u) ; // [00000000|00L00000|WvvvvLpp|R0Bmmmmm].
+ x |= x86GetForceEvex3MaskInLastBit(options); // [x0000000|00L00000|WvvvvLpp|R0Bmmmmm].
- // Check if VEX3 is required / forced: [........|........|x.......|..x..x..].
- if (x & 0x0008024u) {
+ // Check if VEX3 is required / forced: [x.......|........|x.......|..xxxxx.].
+ if (x & 0x8000803Eu) {
uint32_t xorMsk = x86VEXPrefix[x & 0xF] | (opcode << 24);
- // Clear 'FORCE-VEX3' bit and all high bits.
- x = (x & (0x4 ^ 0xFFFF)) << 8; // [00000000|WvvvvLpp|R0B0m0mm|00000000].
- // ____ _ _
- x ^= xorMsk; // [_OPCODE_|WvvvvLpp|R1Bmmmmm|VEX3|XOP].
+ // Clear all high bits.
+ x = (x & 0xFFFF) << 8; // [00000000|WvvvvLpp|R0Bmmmmm|00000000].
+ // ____ _ _
+ x ^= xorMsk; // [_OPCODE_|WvvvvLpp|R1Bmmmmm|VEX3|XOP].
writer.emit32uLE(x);
rbReg &= 0x7;
@@ -4664,13 +4608,12 @@ EmitVexEvexR:
}
}
- // --------------------------------------------------------------------------
- // [Emit - VEX|EVEX - /r (Memory)]
- // --------------------------------------------------------------------------
+ // Emit - VEX|EVEX - /r - Memory
+ // -----------------------------
EmitVexEvexM:
ASMJIT_ASSERT(rmRel != nullptr);
- ASMJIT_ASSERT(rmRel->opType() == Operand::kOpMem);
+ ASMJIT_ASSERT(rmRel->opType() == OperandType::kMem);
rmInfo = x86MemInfo[rmRel->as<Mem>().baseAndIndexTypes()];
writer.emitSegmentOverride(rmRel->as<Mem>().segmentId());
@@ -4685,61 +4628,83 @@ EmitVexEvexM:
uint32_t broadcastBit = uint32_t(rmRel->as<Mem>().hasBroadcast());
// Construct `x` - a complete EVEX|VEX prefix.
- uint32_t x = ((opReg << 4) & 0x0000F980u) | // [........|........|Vvvvv..R|R.......].
- ((rxReg << 3) & 0x00000040u) | // [........|........|........|.X......].
- ((rxReg << 15) & 0x00080000u) | // [........|....X...|........|........].
- ((rbReg << 2) & 0x00000020u) | // [........|........|........|..B.....].
- opcode.extractLLMM(options) | // [........|.LL.X...|Vvvvv..R|RXBmmmmm].
- (_extraReg.id() << 16) | // [........|.LL.Xaaa|Vvvvv..R|RXBmmmmm].
- (broadcastBit << 20) ; // [........|.LLbXaaa|Vvvvv..R|RXBmmmmm].
+ uint32_t x = ((opReg << 4) & 0x0000F980u) | // [........|........|Vvvvv..R|R.......].
+ ((rxReg << 3) & 0x00000040u) | // [........|........|........|.X......].
+ ((rxReg << 15) & 0x00080000u) | // [........|....X...|........|........].
+ ((rbReg << 2) & 0x00000020u) | // [........|........|........|..B.....].
+ opcode.extractLLMMMMM(options) | // [........|.LL.X...|Vvvvv..R|RXBmmmmm].
+ (_extraReg.id() << 16) | // [........|.LL.Xaaa|Vvvvv..R|RXBmmmmm].
+ (broadcastBit << 20) ; // [........|.LLbXaaa|Vvvvv..R|RXBmmmmm].
opReg &= 0x07u;
- // Mark invalid VEX (force EVEX) case: // [@.......|.LLbXaaa|Vvvvv..R|RXBmmmmm].
- x |= (~commonInfo->flags() & InstDB::kFlagVex) << (31 - Support::constCtz(InstDB::kFlagVex));
+ // Mark invalid VEX (force EVEX) case: // [@.......|.LLbXaaa|Vvvvv..R|RXBmmmmm].
+ x |= uint32_t(~commonInfo->flags() & InstDB::InstFlags::kVex) << (31 - Support::ConstCTZ<uint32_t(InstDB::InstFlags::kVex)>::value);
// Handle AVX512 options by a single branch.
- const uint32_t kAvx512Options = Inst::kOptionZMask |
- Inst::kOptionER |
- Inst::kOptionSAE ;
- if (options & kAvx512Options) {
+ const InstOptions kAvx512Options = InstOptions::kX86_ZMask |
+ InstOptions::kX86_ER |
+ InstOptions::kX86_SAE ;
+ if (Support::test(options, kAvx512Options)) {
// {er} and {sae} are both invalid if memory operand is used.
- if (ASMJIT_UNLIKELY(options & (Inst::kOptionER | Inst::kOptionSAE)))
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_ER | InstOptions::kX86_SAE)))
goto InvalidEROrSAE;
- x |= options & (Inst::kOptionZMask); // [@.......|zLLbXaaa|Vvvvv..R|RXBmmmmm].
+ x |= uint32_t(options & InstOptions::kX86_ZMask); // [@.......|zLLbXaaa|Vvvvv..R|RXBmmmmm].
}
// If these bits are used then EVEX prefix is required.
- constexpr uint32_t kEvexBits = 0x80DF8110u; // [@.......|xx.xxxxx|x......x|...x....].
+ constexpr uint32_t kEvexForce = 0x00000010u; // [........|........|........|...x....].
+ constexpr uint32_t kEvexBits = 0x80DF8110u; // [@.......|xx.xxxxx|x......x|...x....].
// Force EVEX prefix even in case the instruction has VEX encoding, because EVEX encoding is preferred. At the
// moment this is only required for AVX_VNNI instructions, which were added after AVX512_VNNI instructions. If
// such instruction doesn't specify prefix, EVEX (AVX512_VNNI) would be used by default,
if (commonInfo->preferEvex()) {
- if ((x & kEvexBits) == 0 && (options & (Inst::kOptionVex | Inst::kOptionVex3)) == 0) {
- x |= (Opcode::kMM_ForceEvex) >> Opcode::kMM_Shift;
+ if ((x & kEvexBits) == 0 && !Support::test(options, InstOptions::kX86_Vex | InstOptions::kX86_Vex3)) {
+ x |= kEvexForce;
}
}
- // Check if EVEX is required by checking bits in `x` : [@.......|xx.xxxxx|x......x|...x....].
+ // Check if EVEX is required by checking bits in `x` : [@.......|xx.xxxxx|x......x|...x....].
if (x & kEvexBits) {
- uint32_t y = ((x << 4) & 0x00080000u) | // [@.......|....V...|........|........].
- ((x >> 4) & 0x00000010u) ; // [@.......|....V...|........|...R....].
- x = (x & 0x00FF78E3u) | y; // [........|zLLbVaaa|0vvvv000|RXBR00mm].
- x = x << 8; // [zLLbVaaa|0vvvv000|RBBR00mm|00000000].
- x |= (opcode >> kVSHR_W ) & 0x00800000u; // [zLLbVaaa|Wvvvv000|RBBR00mm|00000000].
- x |= (opcode >> kVSHR_PP_EW) & 0x00830000u; // [zLLbVaaa|Wvvvv0pp|RBBR00mm|00000000] (added PP and EVEX.W).
- // _ ____ ____
- x ^= 0x087CF000u | kX86ByteEvex; // [zLLbVaaa|Wvvvv1pp|RBBR00mm|01100010].
-
- writer.emit32uLE(x);
- writer.emit8(opcode.v);
+ uint32_t y = ((x << 4) & 0x00080000u) | // [@.......|....V...|........|........].
+ ((x >> 4) & 0x00000010u) ; // [@.......|....V...|........|...R....].
+ x = (x & 0x00FF78EFu) | y; // [........|zLLbVaaa|0vvvv000|RXBRmmmm].
+ x = x << 8; // [zLLbVaaa|0vvvv000|RBBRmmmm|00000000].
+ x |= (opcode >> kVSHR_W ) & 0x00800000u; // [zLLbVaaa|Wvvvv000|RBBRmmmm|00000000].
+ x |= (opcode >> kVSHR_PP_EW) & 0x00830000u; // [zLLbVaaa|Wvvvv0pp|RBBRmmmm|00000000] (added PP and EVEX.W).
+ // _ ____ ____
+ x ^= 0x087CF000u | kX86ByteEvex; // [zLLbVaaa|Wvvvv1pp|RBBRmmmm|01100010].
if (x & 0x10000000u) {
- // Broadcast, change the compressed displacement scale to either x4 (SHL 2) or x8 (SHL 3)
- // depending on instruction's W. If 'W' is 1 'SHL' must be 3, otherwise it must be 2.
+ // Broadcast support.
+ //
+ // 1. Verify our LL field is correct as broadcast changes the "size" of the source operand. For example if
+ // a broadcasted operand is qword_ptr[X] {1to8} the source size becomes 64 and not 8 as the memory operand
+ // would report.
+ //
+ // 2. Change the compressed displacement scale to either x2 (SHL1), x4 (SHL 2), or x8 (SHL 3) depending on
+ // the broadcast unit/element size.
+ uint32_t broadcastUnitSize = commonInfo->broadcastSize();
+ uint32_t broadcastVectorSize = broadcastUnitSize << uint32_t(rmRel->as<Mem>().getBroadcast());
+
+ if (ASMJIT_UNLIKELY(broadcastUnitSize == 0))
+ goto InvalidBroadcast;
+
+ // LL was already shifted 8 bits right.
+ constexpr uint32_t kLLShift = 21 + 8;
+
+ uint32_t currentLL = x & (0x3u << kLLShift);
+ uint32_t broadcastLL = (Support::max<uint32_t>(Support::ctz(broadcastVectorSize), 4) - 4) << kLLShift;
+
+ if (broadcastLL > (2u << kLLShift))
+ goto InvalidBroadcast;
+
+ uint32_t newLL = Support::max(currentLL, broadcastLL);
+ x = (x & ~(uint32_t(0x3) << kLLShift)) | newLL;
+
opcode &=~uint32_t(Opcode::kCDSHL_Mask);
- opcode |= ((x & 0x00800000u) ? 3u : 2u) << Opcode::kCDSHL_Shift;
+ opcode |= Support::ctz(broadcastUnitSize) << Opcode::kCDSHL_Shift;
}
else {
// Add the compressed displacement 'SHF' to the opcode based on 'TTWLL'.
@@ -4749,24 +4714,28 @@ EmitVexEvexM:
((x >> 29) & 0x3);
opcode += x86CDisp8SHL[TTWLL];
}
+
+ writer.emit32uLE(x);
+ writer.emit8(opcode.v);
}
else {
- // Not EVEX, prepare `x` for VEX2 or VEX3: x = [........|00L00000|0vvvv000|RXB0mmmm].
- x |= ((opcode >> (kVSHR_W + 8)) & 0x8000u) | // [00000000|00L00000|Wvvvv000|RXB0mmmm].
- ((opcode >> (kVSHR_PP + 8)) & 0x0300u) | // [00000000|00L00000|Wvvvv0pp|RXB0mmmm].
- ((x >> 11 ) & 0x0400u) ; // [00000000|00L00000|WvvvvLpp|RXB0mmmm].
+ // Not EVEX, prepare `x` for VEX2 or VEX3: x = [........|00L00000|0vvvv000|RXBmmmmm].
+ x |= ((opcode >> (kVSHR_W + 8)) & 0x8000u) | // [00000000|00L00000|Wvvvv000|RXBmmmmm].
+ ((opcode >> (kVSHR_PP + 8)) & 0x0300u) | // [00000000|00L00000|Wvvvv0pp|RXBmmmmm].
+ ((x >> 11 ) & 0x0400u) ; // [00000000|00L00000|WvvvvLpp|RXBmmmmm].
+ x |= x86GetForceEvex3MaskInLastBit(options); // [x0000000|00L00000|WvvvvLpp|RXBmmmmm].
// Clear a possible CDisp specified by EVEX.
opcode &= ~Opcode::kCDSHL_Mask;
- // Check if VEX3 is required / forced: [........|........|x.......|.xx..x..].
- if (x & 0x0008064u) {
+ // Check if VEX3 is required / forced: [x.......|........|x.......|.xxxxxx.].
+ if (x & 0x8000807Eu) {
uint32_t xorMsk = x86VEXPrefix[x & 0xF] | (opcode << 24);
- // Clear 'FORCE-VEX3' bit and all high bits.
- x = (x & (0x4 ^ 0xFFFF)) << 8; // [00000000|WvvvvLpp|RXB0m0mm|00000000].
- // ____ ___
- x ^= xorMsk; // [_OPCODE_|WvvvvLpp|RXBmmmmm|VEX3_XOP].
+ // Clear all high bits.
+ x = (x & 0xFFFF) << 8; // [00000000|WvvvvLpp|RXBmmmmm|00000000].
+ // ____ ___
+ x ^= xorMsk; // [_OPCODE_|WvvvvLpp|RXBmmmmm|VEX3_XOP].
writer.emit32uLE(x);
}
else {
@@ -4782,7 +4751,7 @@ EmitVexEvexM:
}
// MOD|SIB address.
- if (!commonInfo->hasFlag(InstDB::kFlagVsib))
+ if (!commonInfo->hasFlag(InstDB::InstFlags::kVsib))
goto EmitModSib;
// MOD|VSIB address without INDEX is invalid.
@@ -4790,9 +4759,8 @@ EmitVexEvexM:
goto EmitModVSib;
goto InvalidInstruction;
- // --------------------------------------------------------------------------
- // [Emit - Jmp/Jcc/Call]
- // --------------------------------------------------------------------------
+ // Emit - Jmp/Jcc/Call
+ // -------------------
EmitJmpCall:
{
@@ -4832,7 +4800,7 @@ EmitJmpCall:
}
else {
// Non-bound label or label bound to a different section.
- if (opCode8 && (!opcode.v || (options & Inst::kOptionShortForm))) {
+ if (opCode8 && (!opcode.v || Support::test(options, InstOptions::kShortForm))) {
writer.emit8(opCode8);
// Record DISP8 (non-bound label).
@@ -4842,7 +4810,7 @@ EmitJmpCall:
}
else {
// Refuse also 'short' prefix, if specified.
- if (ASMJIT_UNLIKELY(!opcode.v || (options & Inst::kOptionShortForm) != 0))
+ if (ASMJIT_UNLIKELY(!opcode.v || Support::test(options, InstOptions::kShortForm)))
goto InvalidDisplacement;
writer.emit8If(0x0F, (opcode & Opcode::kMM_Mask) != 0);// Emit 0F prefix.
@@ -4861,9 +4829,8 @@ EmitJmpCall:
uint64_t baseAddress = code()->baseAddress();
uint64_t jumpAddress = rmRel->as<Imm>().valueAs<uint64_t>();
- // If the base-address is known calculate a relative displacement and
- // check if it fits in 32 bits (which is always true in 32-bit mode).
- // Emit relative displacement as it was a bound label if all checks are ok.
+ // If the base-address is known calculate a relative displacement and check if it fits in 32 bits (which is
+ // always true in 32-bit mode). Emit relative displacement as it was a bound label if all checks are ok.
if (baseAddress != Globals::kNoBaseAddress) {
uint64_t rel64 = jumpAddress - (ip + baseAddress) - inst32Size;
if (Environment::is32Bit(arch()) || Support::isInt32(int64_t(rel64))) {
@@ -4871,14 +4838,14 @@ EmitJmpCall:
goto EmitJmpCallRel;
}
else {
- // Relative displacement exceeds 32-bits - relocator can only
- // insert trampoline for jmp/call, but not for jcc/jecxz.
+ // Relative displacement exceeds 32-bits - relocator can only insert trampoline for jmp/call, but not
+ // for jcc/jecxz.
if (ASMJIT_UNLIKELY(!x86IsJmpOrCall(instId)))
goto InvalidDisplacement;
}
}
- err = _code->newRelocEntry(&re, RelocEntry::kTypeAbsToRel);
+ err = _code->newRelocEntry(&re, RelocType::kAbsToRel);
if (ASMJIT_UNLIKELY(err))
goto Failed;
@@ -4887,10 +4854,9 @@ EmitJmpCall:
re->_payload = jumpAddress;
if (ASMJIT_LIKELY(opcode.v)) {
- // 64-bit: Emit REX prefix so the instruction can be patched later.
- // REX prefix does nothing if not patched, but allows to patch the
- // instruction to use MOD/M and to point to a memory where the final
- // 64-bit address is stored.
+ // 64-bit: Emit REX prefix so the instruction can be patched later. REX prefix does nothing if not patched,
+ // but allows to patch the instruction to use MOD/M and to point to a memory where the final 64-bit address
+ // is stored.
if (Environment::is64Bit(arch()) && x86IsJmpOrCall(instId)) {
if (!rex)
writer.emit8(kX86ByteRex);
@@ -4899,7 +4865,7 @@ EmitJmpCall:
if (ASMJIT_UNLIKELY(err))
goto Failed;
- re->_relocType = RelocEntry::kTypeX64AddressEntry;
+ re->_relocType = RelocType::kX64AddressEntry;
}
writer.emit8If(0x0F, (opcode & Opcode::kMM_Mask) != 0); // Emit 0F prefix.
@@ -4921,21 +4887,20 @@ EmitJmpCall:
// Not Label|Imm -> Invalid.
goto InvalidInstruction;
- // Emit jmp/call with relative displacement known at assembly-time. Decide
- // between 8-bit and 32-bit displacement encoding. Some instructions only
- // allow either 8-bit or 32-bit encoding, others allow both encodings.
+ // Emit jmp/call with relative displacement known at assembly-time. Decide between 8-bit and 32-bit displacement
+ // encoding. Some instructions only allow either 8-bit or 32-bit encoding, others allow both encodings.
EmitJmpCallRel:
- if (Support::isInt8(int32_t(rel32 + inst32Size - inst8Size)) && opCode8 && !(options & Inst::kOptionLongForm)) {
- options |= Inst::kOptionShortForm;
+ if (Support::isInt8(int32_t(rel32 + inst32Size - inst8Size)) && opCode8 && !Support::test(options, InstOptions::kLongForm)) {
+ options |= InstOptions::kShortForm;
writer.emit8(opCode8); // Emit opcode
writer.emit8(rel32 + inst32Size - inst8Size); // Emit DISP8.
goto EmitDone;
}
else {
- if (ASMJIT_UNLIKELY(!opcode.v || (options & Inst::kOptionShortForm) != 0))
+ if (ASMJIT_UNLIKELY(!opcode.v || Support::test(options, InstOptions::kShortForm)))
goto InvalidDisplacement;
- options &= ~Inst::kOptionShortForm;
+ options &= ~InstOptions::kShortForm;
writer.emit8If(0x0F, (opcode & Opcode::kMM_Mask) != 0); // Emit 0x0F prefix.
writer.emit8(opcode.v); // Emit Opcode.
writer.emit8If(x86EncodeMod(3, opReg, 0), opReg != 0); // Emit MOD.
@@ -4944,9 +4909,8 @@ EmitJmpCallRel:
}
}
- // --------------------------------------------------------------------------
- // [Emit - Relative]
- // --------------------------------------------------------------------------
+ // Emit - Relative
+ // ---------------
EmitRel:
{
@@ -4969,12 +4933,11 @@ EmitRel:
}
writer.emitImmediate(uint64_t(immValue), immSize);
- // --------------------------------------------------------------------------
- // [Done]
- // --------------------------------------------------------------------------
+ // Emit - Done
+ // -----------
EmitDone:
- if (ASMJIT_UNLIKELY(options & Inst::kOptionReserved)) {
+ if (Support::test(options, InstOptions::kReserved)) {
#ifndef ASMJIT_NO_LOGGING
if (_logger)
EmitterUtils::logInstructionEmitted(this, instId, options, o0, o1, o2, opExt, relSize, immSize, writer.cursor());
@@ -4988,9 +4951,8 @@ EmitDone:
writer.done(this);
return kErrorOk;
- // --------------------------------------------------------------------------
- // [Error Handler]
- // --------------------------------------------------------------------------
+ // Error Handler
+ // -------------
#define ERROR_HANDLER(ERR) ERR: err = DebugUtils::errored(kError##ERR); goto Failed;
ERROR_HANDLER(OutOfMemory)
@@ -5009,6 +4971,7 @@ EmitDone:
ERROR_HANDLER(InvalidPhysId)
ERROR_HANDLER(InvalidSegment)
ERROR_HANDLER(InvalidImmediate)
+ ERROR_HANDLER(InvalidBroadcast)
ERROR_HANDLER(OperandSizeMismatch)
ERROR_HANDLER(AmbiguousOperandSize)
ERROR_HANDLER(NotConsecutiveRegs)
@@ -5025,15 +4988,14 @@ Failed:
#endif
}
-// ============================================================================
-// [asmjit::x86::Assembler - Align]
-// ============================================================================
+//x86::Assembler - Align
+// =====================
-Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
+Error Assembler::align(AlignMode alignMode, uint32_t alignment) {
if (ASMJIT_UNLIKELY(!_code))
return reportError(DebugUtils::errored(kErrorNotInitialized));
- if (ASMJIT_UNLIKELY(alignMode >= kAlignCount))
+ if (ASMJIT_UNLIKELY(uint32_t(alignMode) > uint32_t(AlignMode::kMaxValue)))
return reportError(DebugUtils::errored(kErrorInvalidArgument));
if (alignment <= 1)
@@ -5049,8 +5011,8 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
uint8_t pattern = 0x00;
switch (alignMode) {
- case kAlignCode: {
- if (hasEncodingOption(kEncodingOptionOptimizedAlign)) {
+ case AlignMode::kCode: {
+ if (hasEncodingOption(EncodingOptions::kOptimizedAlign)) {
// Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 2B (NOP).
enum { kMaxNopSize = 9 };
@@ -5081,11 +5043,11 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
break;
}
- case kAlignData:
+ case AlignMode::kData:
pattern = 0xCC;
break;
- case kAlignZero:
+ case AlignMode::kZero:
// Pattern already set to zero.
break;
}
@@ -5101,7 +5063,7 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
#ifndef ASMJIT_NO_LOGGING
if (_logger) {
StringTmp<128> sb;
- sb.appendChars(' ', _logger->indentation(FormatOptions::kIndentationCode));
+ sb.appendChars(' ', _logger->indentation(FormatIndentationGroup::kCode));
sb.appendFormat("align %u\n", alignment);
_logger->log(sb);
}
@@ -5110,12 +5072,11 @@ Error Assembler::align(uint32_t alignMode, uint32_t alignment) {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::Assembler - Events]
-// ============================================================================
+// x86::Assembler - Events
+// =======================
Error Assembler::onAttach(CodeHolder* code) noexcept {
- uint32_t arch = code->arch();
+ Arch arch = code->arch();
if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
@@ -5123,12 +5084,12 @@ Error Assembler::onAttach(CodeHolder* code) noexcept {
if (Environment::is32Bit(arch)) {
// 32 bit architecture - X86.
- _forcedInstOptions |= Inst::_kOptionInvalidRex;
+ _forcedInstOptions |= InstOptions::kX86_InvalidRex;
_setAddressOverrideMask(kX86MemInfo_67H_X86);
}
else {
// 64 bit architecture - X64.
- _forcedInstOptions &= ~Inst::_kOptionInvalidRex;
+ _forcedInstOptions &= ~InstOptions::kX86_InvalidRex;
_setAddressOverrideMask(kX86MemInfo_67H_X64);
}
@@ -5136,7 +5097,7 @@ Error Assembler::onAttach(CodeHolder* code) noexcept {
}
Error Assembler::onDetach(CodeHolder* code) noexcept {
- _forcedInstOptions &= ~Inst::_kOptionInvalidRex;
+ _forcedInstOptions &= ~InstOptions::kX86_InvalidRex;
_setAddressOverrideMask(0);
return Base::onDetach(code);
diff --git a/src/asmjit/x86/x86assembler.h b/src/asmjit/x86/x86assembler.h
index 8cd1014..dbffae6 100644
--- a/src/asmjit/x86/x86assembler.h
+++ b/src/asmjit/x86/x86assembler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86ASSEMBLER_H_INCLUDED
#define ASMJIT_X86_X86ASSEMBLER_H_INCLUDED
@@ -33,21 +15,15 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::Assembler]
-// ============================================================================
-
//! X86/X64 assembler implementation.
//!
-//! x86::Assembler is a code emitter that emits machine code directly into the
-//! \ref CodeBuffer. The assembler is capable of targeting both 32-bit and 64-bit
-//! instruction sets, the instruction set can be configured through \ref CodeHolder.
+//! x86::Assembler is a code emitter that emits machine code directly into the \ref CodeBuffer. The assembler is capable
+//! of targeting both 32-bit and 64-bit instruction sets, the instruction set can be configured through \ref CodeHolder.
//!
//! ### Basics
//!
-//! The following example shows a basic use of `x86::Assembler`, how to generate
-//! a function that works in both 32-bit and 64-bit modes, and how to connect
-//! \ref JitRuntime, \ref CodeHolder, and `x86::Assembler`.
+//! The following example shows a basic use of `x86::Assembler`, how to generate a function that works in both 32-bit
+//! and 64-bit modes, and how to connect \ref JitRuntime, \ref CodeHolder, and `x86::Assembler`.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -122,32 +98,26 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! The example should be self-explanatory. It shows how to work with labels,
-//! how to use operands, and how to emit instructions that can use different
-//! registers based on runtime selection. It implements 32-bit CDECL, WIN64,
+//! The example should be self-explanatory. It shows how to work with labels, how to use operands, and how to emit
+//! instructions that can use different registers based on runtime selection. It implements 32-bit CDECL, WIN64,
//! and SysV64 caling conventions and will work on most X86/X64 environments.
//!
-//! Although functions prologs / epilogs can be implemented manually, AsmJit
-//! provides utilities that can be used to create function prologs and epilogs
-//! automatically, see \ref asmjit_function for more details.
+//! Although functions prologs / epilogs can be implemented manually, AsmJit provides utilities that can be used
+//! to create function prologs and epilogs automatically, see \ref asmjit_function for more details.
//!
//! ### Instruction Validation
//!
-//! Assembler prefers speed over strictness by default. The implementation checks
-//! the type of operands and fails if the signature of types is invalid, however,
-//! it does only basic checks regarding registers and their groups used in
-//! instructions. It's possible to pass operands that don't form any valid
-//! signature to the implementation and succeed. This is usually not a problem
-//! as Assembler provides typed API so operand types are normally checked by C++
-//! compiler at compile time, however, Assembler is fully dynamic and its \ref
-//! emit() function can be called with any instruction id, options, and operands.
-//! Moreover, it's also possible to form instructions that will be accepted by
-//! the typed API, for example by calling `mov(x86::eax, x86::al)` - the C++
-//! compiler won't see a problem as both EAX and AL are \ref Gp registers.
-//!
-//! To help with common mistakes AsmJit allows to activate instruction validation.
-//! This feature instruments the Assembler to call \ref InstAPI::validate() before
-//! it attempts to encode any instruction.
+//! Assembler prefers speed over strictness by default. The implementation checks the type of operands and fails
+//! if the signature of types is invalid, however, it does only basic checks regarding registers and their groups
+//! used in instructions. It's possible to pass operands that don't form any valid signature to the implementation
+//! and succeed. This is usually not a problem as Assembler provides typed API so operand types are normally checked
+//! by C++ compiler at compile time, however, Assembler is fully dynamic and its \ref emit() function can be called
+//! with any instruction id, options, and operands. Moreover, it's also possible to form instructions that will be
+//! accepted by the typed API, for example by calling `mov(x86::eax, x86::al)` - the C++ compiler won't see a problem
+//! as both EAX and AL are \ref Gp registers.
+//!
+//! To help with common mistakes AsmJit allows to activate instruction validation. This feature instruments
+//! the Assembler to call \ref InstAPI::validate() before it attempts to encode any instruction.
//!
//! The example below illustrates how validation can be turned on:
//!
@@ -165,7 +135,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
//!
//! // Enable strict validation.
-//! a.addValidationOptions(BaseEmitter::kValidationOptionAssembler);
+//! a.addDiagnosticOptions(DiagnosticOptions::kValidateAssembler);
//!
//! // Try to encode invalid or ill-formed instructions.
//! Error err;
@@ -188,11 +158,10 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Native Registers
//!
-//! All emitters provide functions to construct machine-size registers depending
-//! on the target. This feature is for users that want to write code targeting
-//! both 32-bit and 64-bit architectures at the same time. In AsmJit terminology
-//! such registers have prefix `z`, so for example on X86 architecture the
-//! following native registers are provided:
+//! All emitters provide functions to construct machine-size registers depending on the target. This feature is
+//! for users that want to write code targeting both 32-bit and 64-bit architectures at the same time. In AsmJit
+//! terminology such registers have prefix `z`, so for example on X86 architecture the following native registers
+//! are provided:
//!
//! - `zax` - mapped to either `eax` or `rax`
//! - `zbx` - mapped to either `ebx` or `rbx`
@@ -203,8 +172,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! - `zsi` - mapped to either `esi` or `rsi`
//! - `zdi` - mapped to either `edi` or `rdi`
//!
-//! They are accessible through \ref x86::Assembler, \ref x86::Builder, and
-//! \ref x86::Compiler. The example below illustrates how to use this feature:
+//! They are accessible through \ref x86::Assembler, \ref x86::Builder, and \ref x86::Compiler. The example below
+//! illustrates how to use this feature:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -253,11 +222,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! The example just returns `0`, but the function generated contains a standard
-//! prolog and epilog sequence and the function itself reserves 32 bytes of local
-//! stack. The advantage is clear - a single code-base can handle multiple targets
-//! easily. If you want to create a register of native size dynamically by
-//! specifying its id it's also possible:
+//! The example just returns `0`, but the function generated contains a standard prolog and epilog sequence and the
+//! function itself reserves 32 bytes of local stack. The advantage is clear - a single code-base can handle multiple
+//! targets easily. If you want to create a register of native size dynamically by specifying its id it's also possible:
//!
//! ```
//! void example(x86::Assembler& a) {
@@ -274,14 +241,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Data Embedding
//!
-//! x86::Assembler extends the standard \ref BaseAssembler with X86/X64 specific
-//! conventions that are often used by assemblers to embed data next to the code.
-//! The following functions can be used to embed data:
-//!
-//! - \ref x86::Assembler::db() - embeds byte (8 bits) (x86 naming).
-//! - \ref x86::Assembler::dw() - embeds word (16 bits) (x86 naming).
-//! - \ref x86::Assembler::dd() - embeds dword (32 bits) (x86 naming).
-//! - \ref x86::Assembler::dq() - embeds qword (64 bits) (x86 naming).
+//! x86::Assembler extends the standard \ref BaseAssembler with X86/X64 specific conventions that are often used by
+//! assemblers to embed data next to the code. The following functions can be used to embed data:
//!
//! - \ref BaseAssembler::embedInt8() - embeds int8_t (portable naming).
//! - \ref BaseAssembler::embedUInt8() - embeds uint8_t (portable naming).
@@ -294,6 +255,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! - \ref BaseAssembler::embedFloat() - embeds float (portable naming).
//! - \ref BaseAssembler::embedDouble() - embeds double (portable naming).
//!
+//! - \ref x86::Assembler::db() - embeds byte (8 bits) (x86 naming).
+//! - \ref x86::Assembler::dw() - embeds word (16 bits) (x86 naming).
+//! - \ref x86::Assembler::dd() - embeds dword (32 bits) (x86 naming).
+//! - \ref x86::Assembler::dq() - embeds qword (64 bits) (x86 naming).
+//!
//! The following example illustrates how embed works:
//!
//! ```
@@ -308,8 +274,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! Sometimes it's required to read the data that is embedded after code, for
-//! example. This can be done through \ref Label as shown below:
+//! Sometimes it's required to read the data that is embedded after code, for example. This can be done through
+//! \ref Label as shown below:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -335,17 +301,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Label Embedding
//!
-//! It's also possible to embed labels. In general AsmJit provides the following
-//! options:
+//! It's also possible to embed labels. In general AsmJit provides the following options:
//!
-//! - \ref BaseEmitter::embedLabel() - Embeds absolute address of a label.
-//! This is target dependent and would embed either 32-bit or 64-bit data
-//! that embeds absolute label address. This kind of embedding cannot be
+//! - \ref BaseEmitter::embedLabel() - Embeds absolute address of a label. This is target dependent and would
+//! embed either 32-bit or 64-bit data that embeds absolute label address. This kind of embedding cannot be
//! used in a position independent code.
//!
-//! - \ref BaseEmitter::embedLabelDelta() - Embeds a difference between two
-//! labels. The size of the difference can be specified so it's possible to
-//! embed 8-bit, 16-bit, 32-bit, and 64-bit difference, which is sufficient
+//! - \ref BaseEmitter::embedLabelDelta() - Embeds a difference between two labels. The size of the difference
+//! can be specified so it's possible to embed 8-bit, 16-bit, 32-bit, and 64-bit difference, which is sufficient
//! for most purposes.
//!
//! The following example demonstrates how to embed labels and their differences:
@@ -368,9 +331,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Using FuncFrame and FuncDetail with x86::Assembler
//!
-//! The example below demonstrates how \ref FuncFrame and \ref FuncDetail can be
-//! used together with \ref x86::Assembler to generate a function that will use
-//! platform dependent calling conventions automatically depending on the target:
+//! The example below demonstrates how \ref FuncFrame and \ref FuncDetail can be used together with \ref x86::Assembler
+//! to generate a function that will use platform dependent calling conventions automatically depending on the target:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -399,13 +361,13 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! // Create/initialize FuncDetail and FuncFrame.
//! FuncDetail func;
-//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
+//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost));
//!
//! FuncFrame frame;
//! frame.init(func);
//!
-//! // Make XMM0 and XMM1 dirty - kGroupVec describes XMM|YMM|ZMM registers.
-//! frame.setDirtyRegs(x86::Reg::kGroupVec, IntUtils::mask(0, 1));
+//! // Make XMM0 and XMM1 dirty - RegGroup::kVec describes XMM|YMM|ZMM registers.
+//! frame.setDirtyRegs(RegGroup::kVec, IntUtils::mask(0, 1));
//!
//! // Alternatively, if you don't want to use register masks you can pass BaseReg
//! // to addDirtyRegs(). The following code would add both xmm0 and xmm1.
@@ -444,50 +406,40 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Using x86::Assembler as Code-Patcher
//!
-//! This is an advanced topic that is sometimes unavoidable. AsmJit by default
-//! appends machine code it generates into a \ref CodeBuffer, however, it also
-//! allows to set the offset in \ref CodeBuffer explicitly and to overwrite its
-//! content. This technique is extremely dangerous as X86 instructions have
-//! variable length (see below), so you should in general only patch code to
-//! change instruction's immediate values or some other details not known the
-//! at a time the instruction was emitted. A typical scenario that requires
-//! code-patching is when you start emitting function and you don't know how
-//! much stack you want to reserve for it.
-//!
-//! Before we go further it's important to introduce instruction options, because
-//! they can help with code-patching (and not only patching, but that will be
-//! explained in AVX-512 section):
-//!
-//! - Many general-purpose instructions (especially arithmetic ones) on X86
-//! have multiple encodings - in AsmJit this is usually called 'short form'
-//! and 'long form'.
-//! - AsmJit always tries to use 'short form' as it makes the resulting
-//! machine-code smaller, which is always good - this decision is used
-//! by majority of assemblers out there.
-//! - AsmJit allows to override the default decision by using `short_()`
-//! and `long_()` instruction options to force short or long form,
-//! respectively. The most useful is `long_()` as it basically forces
-//! AsmJit to always emit the longest form. The `short_()` is not that
-//! useful as it's automatic (except jumps to non-bound labels). Note that
-//! the underscore after each function name avoids collision with built-in
-//! C++ types.
-//!
-//! To illustrate what short form and long form means in binary let's assume
-//! we want to emit "add esp, 16" instruction, which has two possible binary
-//! encodings:
-//!
-//! - `83C410` - This is a short form aka `short add esp, 16` - You can see
-//! opcode byte (0x8C), MOD/RM byte (0xC4) and an 8-bit immediate value
-//! representing `16`.
-//! - `81C410000000` - This is a long form aka `long add esp, 16` - You can
-//! see a different opcode byte (0x81), the same Mod/RM byte (0xC4) and a
-//! 32-bit immediate in little-endian representing `16`.
-//!
-//! It should be obvious that patching an existing instruction into an instruction
-//! having a different size may create various problems. So it's recommended to be
-//! careful and to only patch instructions into instructions having the same size.
-//! The example below demonstrates how instruction options can be used to guarantee
-//! the size of an instruction by forcing the assembler to use long-form encoding:
+//! This is an advanced topic that is sometimes unavoidable. AsmJit by default appends machine code it generates
+//! into a \ref CodeBuffer, however, it also allows to set the offset in \ref CodeBuffer explicitly and to overwrite
+//! its content. This technique is extremely dangerous as X86 instructions have variable length (see below), so you
+//! should in general only patch code to change instruction's immediate values or some other details not known the
+//! at a time the instruction was emitted. A typical scenario that requires code-patching is when you start emitting
+//! function and you don't know how much stack you want to reserve for it.
+//!
+//! Before we go further it's important to introduce instruction options, because they can help with code-patching
+//! (and not only patching, but that will be explained in AVX-512 section):
+//!
+//! - Many general-purpose instructions (especially arithmetic ones) on X86 have multiple encodings - in AsmJit
+//! this is usually called 'short form' and 'long form'.
+//!
+//! - AsmJit always tries to use 'short form' as it makes the resulting machine-code smaller, which is always
+//! good - this decision is used by majority of assemblers out there.
+//!
+//! - AsmJit allows to override the default decision by using `short_()` and `long_()` instruction options to force
+//! short or long form, respectively. The most useful is `long_()` as it basically forces AsmJit to always emit
+//! the longest form. The `short_()` is not that useful as it's automatic (except jumps to non-bound labels). Note
+//! that the underscore after each function name avoids collision with built-in C++ types.
+//!
+//! To illustrate what short form and long form means in binary let's assume we want to emit "add esp, 16" instruction,
+//! which has two possible binary encodings:
+//!
+//! - `83C410` - This is a short form aka `short add esp, 16` - You can see opcode byte (0x8C), MOD/RM byte (0xC4)
+//! and an 8-bit immediate value representing `16`.
+//!
+//! - `81C410000000` - This is a long form aka `long add esp, 16` - You can see a different opcode byte (0x81), the
+//! same Mod/RM byte (0xC4) and a 32-bit immediate in little-endian representing `16`.
+//!
+//! It should be obvious that patching an existing instruction into an instruction having a different size may create
+//! various problems. So it's recommended to be careful and to only patch instructions into instructions having the
+//! same size. The example below demonstrates how instruction options can be used to guarantee the size of an
+//! instruction by forcing the assembler to use long-form encoding:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -546,27 +498,21 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! If you run the example it will just work, because both instructions have
-//! the same size. As an experiment you can try removing `long_()` form to
-//! see what happens when wrong code is generated.
+//! If you run the example it will just work, because both instructions have the same size. As an experiment you can
+//! try removing `long_()` form to see what happens when wrong code is generated.
//!
//! ### Code Patching and REX Prefix
//!
-//! In 64-bit mode there is one more thing to worry about when patching code:
-//! REX prefix. It's a single byte prefix designed to address registers with
-//! ids from 9 to 15 and to override the default width of operation from 32
-//! to 64 bits. AsmJit, like other assemblers, only emits REX prefix when it's
-//! necessary. If the patched code only changes the immediate value as shown
-//! in the previous example then there is nothing to worry about as it doesn't
-//! change the logic behind emitting REX prefix, however, if the patched code
-//! changes register id or overrides the operation width then it's important
-//! to take care of REX prefix as well.
-//!
-//! AsmJit contains another instruction option that controls (forces) REX
-//! prefix - `rex()`. If you use it the instruction emitted will always use
-//! REX prefix even when it's encodable without it. The following list contains
-//! some instructions and their binary representations to illustrate when it's
-//! emitted:
+//! In 64-bit mode there is one more thing to worry about when patching code: REX prefix. It's a single byte prefix
+//! designed to address registers with ids from 9 to 15 and to override the default width of operation from 32 to 64
+//! bits. AsmJit, like other assemblers, only emits REX prefix when it's necessary. If the patched code only changes
+//! the immediate value as shown in the previous example then there is nothing to worry about as it doesn't change
+//! the logic behind emitting REX prefix, however, if the patched code changes register id or overrides the operation
+//! width then it's important to take care of REX prefix as well.
+//!
+//! AsmJit contains another instruction option that controls (forces) REX prefix - `rex()`. If you use it the
+//! instruction emitted will always use REX prefix even when it's encodable without it. The following list contains
+//! some instructions and their binary representations to illustrate when it's emitted:
//!
//! - `__83C410` - `add esp, 16` - 32-bit operation in 64-bit mode doesn't require REX prefix.
//! - `4083C410` - `rex add esp, 16` - 32-bit operation in 64-bit mode with forced REX prefix (0x40).
@@ -619,18 +565,15 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! It's important to understand that prefixes are part of instruction options.
-//! When a member function that involves adding a prefix is called the prefix
-//! is combined with existing instruction options, which will affect the next
+//! It's important to understand that prefixes are part of instruction options. When a member function that involves
+//! adding a prefix is called the prefix is combined with existing instruction options, which will affect the next
//! instruction generated.
//!
//! ### Generating AVX512 code.
//!
-//! x86::Assembler can generate AVX512+ code including the use of opmask
-//! registers. Opmask can be specified through \ref x86::Assembler::k()
-//! function, which stores it as an extra register, which will be used
-//! by the next instruction. AsmJit uses such concept for manipulating
-//! instruction options as well.
+//! x86::Assembler can generate AVX512+ code including the use of opmask registers. Opmask can be specified through
+//! \ref x86::Assembler::k() function, which stores it as an extra register, which will be used by the next
+//! instruction. AsmJit uses such concept for manipulating instruction options as well.
//!
//! The following AVX512 features are supported:
//!
@@ -702,9 +645,8 @@ public:
//! \name Internal
//! \{
- // NOTE: x86::Assembler uses _privateData to store 'address-override' bit that
- // is used to decide whether to emit address-override (67H) prefix based on
- // the memory BASE+INDEX registers. It's either `kX86MemInfo_67H_X86` or
+ // NOTE: x86::Assembler uses _privateData to store 'address-override' bit that is used to decide whether to emit
+ // address-override (67H) prefix based on the memory BASE+INDEX registers. It's either `kX86MemInfo_67H_X86` or
// `kX86MemInfo_67H_X64`.
inline uint32_t _addressOverrideMask() const noexcept { return _privateData; }
inline void _setAddressOverrideMask(uint32_t m) noexcept { _privateData = m; }
@@ -715,7 +657,7 @@ public:
//! \name Emit
//! \{
- ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
+ ASMJIT_API Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) override;
//! \}
//! \endcond
@@ -723,7 +665,7 @@ public:
//! \name Align
//! \{
- ASMJIT_API Error align(uint32_t alignMode, uint32_t alignment) override;
+ ASMJIT_API Error align(AlignMode alignMode, uint32_t alignment) override;
//! \}
diff --git a/src/asmjit/x86/x86builder.cpp b/src/asmjit/x86/x86builder.cpp
index b6b4ea3..a1b848d 100644
--- a/src/asmjit/x86/x86builder.cpp
+++ b/src/asmjit/x86/x86builder.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_BUILDER)
@@ -29,34 +11,22 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::Builder - Construction / Destruction]
-// ============================================================================
-
Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() {
if (code)
code->attach(this);
}
Builder::~Builder() noexcept {}
-// ============================================================================
-// [asmjit::x86::Builder - Finalize]
-// ============================================================================
-
Error Builder::finalize() {
ASMJIT_PROPAGATE(runPasses());
Assembler a(_code);
a.addEncodingOptions(encodingOptions());
- a.addValidationOptions(validationOptions());
+ a.addDiagnosticOptions(diagnosticOptions());
return serializeTo(&a);
}
-// ============================================================================
-// [asmjit::x86::Builder - Events]
-// ============================================================================
-
Error Builder::onAttach(CodeHolder* code) noexcept {
- uint32_t arch = code->arch();
+ Arch arch = code->arch();
if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
diff --git a/src/asmjit/x86/x86builder.h b/src/asmjit/x86/x86builder.h
index 256bc9e..31c9783 100644
--- a/src/asmjit/x86/x86builder.h
+++ b/src/asmjit/x86/x86builder.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86BUILDER_H_INCLUDED
#define ASMJIT_X86_X86BUILDER_H_INCLUDED
@@ -28,7 +10,6 @@
#ifndef ASMJIT_NO_BUILDER
#include "../core/builder.h"
-#include "../core/datatypes.h"
#include "../x86/x86emitter.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
@@ -36,19 +17,13 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::Builder]
-// ============================================================================
-
//! X86/X64 builder implementation.
//!
-//! The code representation used by \ref BaseBuilder is compatible with everything
-//! AsmJit provides. Each instruction is stored as \ref InstNode, which contains
-//! instruction id, options, and operands. Each instruction emitted will create
-//! a new \ref InstNode instance and add it to the current cursor in the double-linked
-//! list of nodes. Since the instruction stream used by \ref BaseBuilder can be
-//! manipulated, we can rewrite the SumInts example from \ref asmjit_assembler
-//! into the following:
+//! The code representation used by \ref BaseBuilder is compatible with everything AsmJit provides. Each instruction
+//! is stored as \ref InstNode, which contains instruction id, options, and operands. Each instruction emitted will
+//! create a new \ref InstNode instance and add it to the current cursor in the double-linked list of nodes. Since
+//! the instruction stream used by \ref BaseBuilder can be manipulated, we can rewrite the SumInts example from
+//! \ref asmjit_assembler into the following:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -72,9 +47,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! code.init(rt.environment()); // Initialize code to match the JIT environment.
//! x86::Builder cb(&code); // Create and attach x86::Builder to `code`.
//!
-//! // Decide which registers will be mapped to function arguments. Try changing
-//! // registers of `dst`, `srcA`, and `srcB` and see what happens in function's
-//! // prolog and epilog.
+//! // Decide which registers will be mapped to function arguments. Try changing registers
+//! // of `dst`, `srcA`, and `srcB` and see what happens in function's prolog and epilog.
//! x86::Gp dst = cb.zax();
//! x86::Gp srcA = cb.zcx();
//! x86::Gp srcB = cb.zdx();
@@ -84,7 +58,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! // Create and initialize `FuncDetail`.
//! FuncDetail func;
-//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
+//! func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost));
//!
//! // Remember prolog insertion point.
//! BaseNode* prologInsertionPoint = cb.cursor();
@@ -106,8 +80,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! FuncFrame frame;
//! frame.init(func);
//!
-//! // Make XMM0 and XMM1 dirty; `kGroupVec` describes XMM|YMM|ZMM registers.
-//! frame.setDirtyRegs(x86::Reg::kGroupVec, IntUtils::mask(0, 1));
+//! // Make XMM0 and XMM1 dirty; RegGroup::kVec describes XMM|YMM|ZMM registers.
+//! frame.setDirtyRegs(RegGroup::kVec, IntUtils::mask(0, 1));
//!
//! FuncArgsAssignment args(&func); // Create arguments assignment context.
//! args.assignAll(dst, srcA, srcB); // Assign our registers to arguments.
@@ -148,8 +122,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! When the example is executed it should output the following (this one using
-//! AMD64-SystemV ABI):
+//! When the example is executed it should output the following (this one using AMD64-SystemV ABI):
//!
//! ```
//! Raw Function:
@@ -170,23 +143,21 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! {5 8 4 9}
//! ```
//!
-//! The number of use-cases of \ref BaseBuilder is not limited and highly depends
-//! on your creativity and experience. The previous example can be easily improved
-//! to collect all dirty registers inside the function programmatically and to pass
-//! them to \ref FuncFrame::setDirtyRegs().
+//! The number of use-cases of \ref BaseBuilder is not limited and highly depends on your creativity and experience.
+//! The previous example can be easily improved to collect all dirty registers inside the function programmatically
+//! and to pass them to \ref FuncFrame::setDirtyRegs().
//!
//! ```
//! #include <asmjit/x86.h>
//!
//! using namespace asmjit;
//!
-//! // NOTE: This function doesn't cover all possible constructs. It ignores
-//! // instructions that write to implicit registers that are not part of the
-//! // operand list. It also counts read-only registers. Real implementation
-//! // would be a bit more complicated, but still relatively easy to implement.
+//! // NOTE: This function doesn't cover all possible constructs. It ignores instructions that write
+//! // to implicit registers that are not part of the operand list. It also counts read-only registers.
+//! // Real implementation would be a bit more complicated, but still relatively easy to implement.
//! static void collectDirtyRegs(const BaseNode* first,
//! const BaseNode* last,
-//! uint32_t regMask[BaseReg::kGroupVirt]) {
+//! Support::Array<RegMask, Globals::kNumVirtGroups>& regMask) {
//! const BaseNode* node = first;
//! while (node) {
//! if (node->actsAsInst()) {
@@ -197,7 +168,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! const Operand& op = opArray[i];
//! if (op.isReg()) {
//! const x86::Reg& reg = op.as<x86::Reg>();
-//! if (reg.group() < BaseReg::kGroupVirt) {
+//! if (reg.group() <= RegGroup::kMaxVirt) {
//! regMask[reg.group()] |= 1u << reg.id();
//! }
//! }
@@ -211,23 +182,21 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//!
//! static void setDirtyRegsOfFuncFrame(const x86::Builder& builder, FuncFrame& frame) {
-//! uint32_t regMask[BaseReg::kGroupVirt] {};
+//! Support::Array<RegMask, Globals::kNumVirtGroups> regMask {};
//! collectDirtyRegs(builder.firstNode(), builder.lastNode(), regMask);
//!
//! // X86/X64 ABIs only require to save GP/XMM registers:
-//! frame.setDirtyRegs(x86::Reg::kGroupGp , regMask[x86::Reg::kGroupGp ]);
-//! frame.setDirtyRegs(x86::Reg::kGroupVec, regMask[x86::Reg::kGroupVec]);
+//! frame.setDirtyRegs(RegGroup::kGp, regMask[RegGroup::kGp]);
+//! frame.setDirtyRegs(RegGroup::kVec, regMask[RegGroup::kVec]);
//! }
//! ```
//!
//! ### Casting Between Various Emitters
//!
-//! Even when \ref BaseAssembler and \ref BaseBuilder provide the same interface
-//! as defined by \ref BaseEmitter their platform dependent variants like \ref
-//! x86::Assembler and \ref x86::Builder cannot be interchanged or casted
-//! to each other by using a C++ `static_cast<>`. The main reason is the
-//! inheritance graph of these classes is different and cast-incompatible, as
-//! illustrated below:
+//! Even when \ref BaseAssembler and \ref BaseBuilder provide the same interface as defined by \ref BaseEmitter their
+//! platform dependent variants like \ref x86::Assembler and \ref x86::Builder cannot be interchanged or casted to each
+//! other by using a C++ `static_cast<>`. The main reason is the inheritance graph of these classes is different and
+//! cast-incompatible, as illustrated below:
//!
//! ```
//! +--------------+ +=========================+
@@ -250,15 +219,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! (abstract) (final) (mixin)
//! ```
//!
-//! The graph basically shows that it's not possible to cast between \ref
-//! x86::Assembler and \ref x86::Builder. However, since both share the
-//! base interface (\ref BaseEmitter) it's possible to cast them to a class
-//! that cannot be instantiated, but defines the same interface - the class
-//! is called \ref x86::Emitter and was introduced to make it possible to
-//! write a function that can emit to both \ref x86::Assembler and \ref
-//! x86::Builder. Note that \ref x86::Emitter cannot be created, it's abstract
-//! and has private constructors and destructors; it was only designed to be
-//! casted to and used as an interface.
+//! The graph basically shows that it's not possible to cast between \ref x86::Assembler and \ref x86::Builder.
+//! However, since both share the base interface (\ref BaseEmitter) it's possible to cast them to a class that
+//! cannot be instantiated, but defines the same interface - the class is called \ref x86::Emitter and was
+//! introduced to make it possible to write a function that can emit to both \ref x86::Assembler and \ref
+//! x86::Builder. Note that \ref x86::Emitter cannot be created, it's abstract and has private constructors and
+//! destructors; it was only designed to be casted to and used as an interface.
//!
//! Each architecture-specific emitter implements a member function called
//! `as<arch::Emitter>()`, which casts the instance to the architecture
@@ -289,19 +255,16 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! The example above shows how to create a function that can emit code to
-//! either \ref x86::Assembler or \ref x86::Builder through \ref x86::Emitter,
-//! which provides emitter-neutral functionality. \ref x86::Emitter, however,
-//! doesn't provide any emitter-specific functionality like `setCursor()`.
+//! The example above shows how to create a function that can emit code to either \ref x86::Assembler or \ref
+//! x86::Builder through \ref x86::Emitter, which provides emitter-neutral functionality. \ref x86::Emitter,
+//! however, doesn't provide any emitter-specific functionality like `setCursor()`.
//!
//! ### Code Injection and Manipulation
//!
-//! \ref BaseBuilder emitter stores its nodes in a double-linked list, which
-//! makes it easy to manipulate that list during the code generation or
-//! afterwards. Each node is always emitted next to the current cursor and the
-//! cursor is advanced to that newly emitted node. The cursor can be retrieved
-//! and changed by \ref BaseBuilder::cursor() and \ref BaseBuilder::setCursor(),
-//! respectively.
+//! \ref BaseBuilder emitter stores its nodes in a double-linked list, which makes it easy to manipulate that
+//! list during the code generation or afterwards. Each node is always emitted next to the current cursor and
+//! the cursor is advanced to that newly emitted node. The cursor can be retrieved and changed by \ref
+//! BaseBuilder::cursor() and \ref BaseBuilder::setCursor(), respectively.
//!
//! The example below demonstrates how to remember a node and inject something
//! next to it.
diff --git a/src/asmjit/x86/x86compiler.cpp b/src/asmjit/x86/x86compiler.cpp
index 92ed645..014ba19 100644
--- a/src/asmjit/x86/x86compiler.cpp
+++ b/src/asmjit/x86/x86compiler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_COMPILER)
@@ -30,34 +12,22 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::Compiler - Construction / Destruction]
-// ============================================================================
-
Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() {
if (code)
code->attach(this);
}
Compiler::~Compiler() noexcept {}
-// ============================================================================
-// [asmjit::x86::Compiler - Finalize]
-// ============================================================================
-
Error Compiler::finalize() {
ASMJIT_PROPAGATE(runPasses());
Assembler a(_code);
a.addEncodingOptions(encodingOptions());
- a.addValidationOptions(validationOptions());
+ a.addDiagnosticOptions(diagnosticOptions());
return serializeTo(&a);
}
-// ============================================================================
-// [asmjit::x86::Compiler - Events]
-// ============================================================================
-
Error Compiler::onAttach(CodeHolder* code) noexcept {
- uint32_t arch = code->arch();
+ Arch arch = code->arch();
if (!Environment::isFamilyX86(arch))
return DebugUtils::errored(kErrorInvalidArch);
diff --git a/src/asmjit/x86/x86compiler.h b/src/asmjit/x86/x86compiler.h
index 7ca506a..466ffa2 100644
--- a/src/asmjit/x86/x86compiler.h
+++ b/src/asmjit/x86/x86compiler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86COMPILER_H_INCLUDED
#define ASMJIT_X86_X86COMPILER_H_INCLUDED
@@ -28,7 +10,6 @@
#ifndef ASMJIT_NO_COMPILER
#include "../core/compiler.h"
-#include "../core/datatypes.h"
#include "../core/type.h"
#include "../x86/x86emitter.h"
@@ -37,16 +18,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::Compiler]
-// ============================================================================
-
//! X86/X64 compiler implementation.
//!
//! ### Compiler Basics
//!
-//! The first \ref x86::Compiler example shows how to generate a function that
-//! simply returns an integer value. It's an analogy to the first Assembler example:
+//! The first \ref x86::Compiler example shows how to generate a function that simply returns an integer value. It's
+//! an analogy to the first Assembler example:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -87,12 +64,10 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! }
//! ```
//!
-//! The \ref BaseCompiler::addFunc() and \ref BaseCompiler::endFunc() functions
-//! are used to define the function and its end. Both must be called per function,
-//! but the body doesn't have to be generated in sequence. An example of generating
-//! two functions will be shown later. The next example shows more complicated code
-//! that contain a loop and generates a simple memory copy function that uses
-//! `uint32_t` items:
+//! The \ref BaseCompiler::addFunc() and \ref BaseCompiler::endFunc() functions are used to define the function and
+//! its end. Both must be called per function, but the body doesn't have to be generated in sequence. An example of
+//! generating two functions will be shown later. The next example shows more complicated code that contain a loop
+//! and generates a simple memory copy function that uses `uint32_t` items:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -110,7 +85,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! code.init(rt.environment()); // Initialize code to match the JIT environment.
//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! cc.addFunc( // Begin the function of the following signature:
+//! FuncNode* funcNode = cc.addFunc( // Begin the function of the following signature:
//! FuncSignatureT<void, // Return value - void (no return value).
//! uint32_t*, // 1st argument - uint32_t* (machine reg-size).
//! const uint32_t*, // 2nd argument - uint32_t* (machine reg-size).
@@ -123,9 +98,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! x86::Gp src = cc.newIntPtr("src");// Create `src` register (source pointer).
//! x86::Gp i = cc.newUIntPtr("i"); // Create `i` register (loop counter).
//!
-//! cc.setArg(0, dst); // Assign `dst` argument.
-//! cc.setArg(1, src); // Assign `src` argument.
-//! cc.setArg(2, i); // Assign `i` argument.
+//! funcNode->setArg(0, dst); // Assign `dst` argument.
+//! funcNode->setArg(1, src); // Assign `src` argument.
+//! funcNode->setArg(2, i); // Assign `i` argument.
//!
//! cc.test(i, i); // Early exit if length is zero.
//! cc.jz(L_Exit);
@@ -172,11 +147,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### AVX and AVX-512
//!
-//! AVX and AVX-512 code generation must be explicitly enabled via \ref FuncFrame
-//! to work properly. If it's not setup correctly then Prolog & Epilog would use
-//! SSE instead of AVX instructions to work with SIMD registers. In addition, Compiler
-//! requires explicitly enable AVX-512 via \ref FuncFrame in order to use all 32 SIMD
-//! registers.
+//! AVX and AVX-512 code generation must be explicitly enabled via \ref FuncFrame to work properly. If it's not setup
+//! correctly then Prolog & Epilog would use SSE instead of AVX instructions to work with SIMD registers. In addition,
+//! Compiler requires explicitly enable AVX-512 via \ref FuncFrame in order to use all 32 SIMD registers.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -194,17 +167,17 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! code.init(rt.environment()); // Initialize code to match the JIT environment.
//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! cc.addFunc(FuncSignatureT<void, void*>());
+//! FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*>());
//!
//! // Use the following to enable AVX and/or AVX-512.
-//! cc.func()->frame().setAvxEnabled();
-//! cc.func()->frame().setAvx512Enabled();
+//! funcNode->frame().setAvxEnabled();
+//! funcNode->frame().setAvx512Enabled();
//!
//! // Do something with the input pointer.
//! x86::Gp addr = cc.newIntPtr("addr");
//! x86::Zmm vreg = cc.newZmm("vreg");
//!
-//! cc.setArg(0, addr);
+//! funcNode->setArg(0, addr);
//!
//! cc.vmovdqu32(vreg, x86::ptr(addr));
//! cc.vpaddq(vreg, vreg, vreg);
@@ -231,9 +204,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Recursive Functions
//!
-//! It's possible to create more functions by using the same \ref x86::Compiler
-//! instance and make links between them. In such case it's important to keep
-//! the pointer to \ref FuncNode.
+//! It's possible to create more functions by using the same \ref x86::Compiler instance and make links between them.
+//! In such case it's important to keep the pointer to \ref FuncNode.
//!
//! The example below creates a simple Fibonacci function that calls itself recursively:
//!
@@ -253,14 +225,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! code.init(rt.environment()); // Initialize code to match the JIT environment.
//! x86::Compiler cc(&code); // Create and attach x86::Compiler to code.
//!
-//! FuncNode* func = cc.addFunc( // Begin of the Fibonacci function, addFunc()
+//! FuncNode* funcNode = cc.addFunc( // Begin of the Fibonacci function, addFunc()
//! FuncSignatureT<int, int>()); // Returns a pointer to the FuncNode node.
//!
//! Label L_Exit = cc.newLabel() // Exit label.
-//! x86::Gp x = cc.newU32(); // Function x argument.
-//! x86::Gp y = cc.newU32(); // Temporary.
+//! x86::Gp x = cc.newUInt32(); // Function x argument.
+//! x86::Gp y = cc.newUInt32(); // Temporary.
//!
-//! cc.setArg(0, x);
+//! funcNode->setArg(0, x);
//!
//! cc.cmp(x, 3); // Return x if less than 3.
//! cc.jb(L_Exit);
@@ -270,7 +242,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! InvokeNode* invokeNode; // Function invocation:
//! cc.invoke(&invokeNode, // - InvokeNode (output).
-//! func->label(), // - Function address or Label.
+//! funcNode->label(), // - Function address or Label.
//! FuncSignatureT<int, int>()); // - Function signature.
//!
//! invokeNode->setArg(0, x); // Assign x as the first argument.
@@ -300,7 +272,10 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Stack Management
//!
-//! Function's stack-frame is managed automatically, which is used by the register allocator to spill virtual registers. It also provides an interface to allocate user-defined block of the stack, which can be used as a temporary storage by the generated function. 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.
+//! Function's stack-frame is managed automatically, which is used by the register allocator to spill virtual
+//! registers. It also provides an interface to allocate user-defined block of the stack, which can be used as
+//! a temporary storage by the generated function. 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.
//!
//! ```
//! #include <asmjit/x86.h>
@@ -349,8 +324,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! cc.jb(L1); // goto L1;
//!
//! // Second loop, sum all bytes stored in `stack`.
-//! x86::Gp sum = cc.newI32("sum");
-//! x86::Gp val = cc.newI32("val");
+//! x86::Gp sum = cc.newInt32("sum");
+//! x86::Gp val = cc.newInt32("val");
//!
//! cc.xor_(i, i);
//! cc.xor_(sum, sum);
@@ -386,12 +361,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! Compiler provides two constant pools for a general purpose code generation:
//!
-//! - Local constant pool - Part of \ref FuncNode, can be only used by a
-//! single function and added after the function epilog sequence (after
-//! `ret` instruction).
+//! - Local constant pool - Part of \ref FuncNode, can be only used by a single function and added after the
+//! function epilog sequence (after `ret` instruction).
//!
-//! - Global constant pool - Part of \ref BaseCompiler, flushed at the end
-//! of the generated code by \ref BaseEmitter::finalize().
+//! - Global constant pool - Part of \ref BaseCompiler, flushed at the end of the generated code by \ref
+//! BaseEmitter::finalize().
//!
//! The example below illustrates how a built-in constant pool can be used:
//!
@@ -406,8 +380,8 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! x86::Gp v0 = cc.newGpd("v0");
//! x86::Gp v1 = cc.newGpd("v1");
//!
-//! x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeLocal, 200);
-//! x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeLocal, 33);
+//! x86::Mem c0 = cc.newInt32Const(ConstPoolScope::kLocal, 200);
+//! x86::Mem c1 = cc.newInt32Const(ConstPoolScope::kLocal, 33);
//!
//! cc.mov(v0, c0);
//! cc.mov(v1, c1);
@@ -420,16 +394,14 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//!
//! ### Jump Tables
//!
-//! x86::Compiler supports `jmp` instruction with reg/mem operand, which is a
-//! commonly used pattern to implement indirect jumps within a function, for
-//! example to implement `switch()` statement in a programming languages. By
-//! default AsmJit assumes that every basic block can be a possible jump
-//! target as it's unable to deduce targets from instruction's operands. This
-//! is a very pessimistic default that should be avoided if possible as it's
-//! costly and very unfriendly to liveness analysis and register allocation.
+//! x86::Compiler supports `jmp` instruction with reg/mem operand, which is a commonly used pattern to implement
+//! indirect jumps within a function, for example to implement `switch()` statement in a programming languages.
+//! By default AsmJit assumes that every basic block can be a possible jump target as it's unable to deduce targets
+//! from instruction's operands. This is a very pessimistic default that should be avoided if possible as it's costly
+//! and very unfriendly to liveness analysis and register allocation.
//!
-//! Instead of relying on such pessimistic default behavior, let's use \ref
-//! JumpAnnotation to annotate a jump where all targets are known:
+//! Instead of relying on such pessimistic default behavior, let's use \ref JumpAnnotation to annotate a jump where
+//! all targets are known:
//!
//! ```
//! #include <asmjit/x86.h>
@@ -437,7 +409,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! using namespace asmjit;
//!
//! static void exampleUseOfIndirectJump(x86::Compiler& cc) {
-//! cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConv::kIdHost));
+//! FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConvId::kHost));
//!
//! // Function arguments
//! x86::Xmm a = cc.newXmmSs("a");
@@ -454,13 +426,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! Label L_Div = cc.newLabel();
//! Label L_End = cc.newLabel();
//!
-//! cc.setArg(0, a);
-//! cc.setArg(1, b);
-//! cc.setArg(2, op);
+//! funcNode->setArg(0, a);
+//! funcNode->setArg(1, b);
+//! funcNode->setArg(2, op);
//!
-//! // Jump annotation is a building block that allows to annotate all
-//! // possible targets where `jmp()` can jump. It then drives the CFG
-//! // construction and liveness analysis, which impacts register allocation.
+//! // Jump annotation is a building block that allows to annotate all possible targets where `jmp()` can
+//! // jump. It then drives the CFG construction and liveness analysis, which impacts register allocation.
//! JumpAnnotation* annotation = cc.newJumpAnnotation();
//! annotation->addLabel(L_Add);
//! annotation->addLabel(L_Sub);
@@ -536,14 +507,14 @@ public:
#endif
#define ASMJIT_NEW_REG_CUSTOM(FUNC, REG) \
- inline REG FUNC(uint32_t typeId) { \
+ inline REG FUNC(TypeId typeId) { \
REG reg(Globals::NoInit); \
_newReg(&reg, typeId); \
return reg; \
} \
\
template<typename... Args> \
- inline REG FUNC(uint32_t typeId, const char* fmt, Args&&... args) { \
+ inline REG FUNC(TypeId typeId, const char* fmt, Args&&... args) { \
REG reg(Globals::NoInit); \
ASMJIT_NEW_REG_FMT(reg, typeId, fmt, std::forward<Args>(args)...); \
return reg; \
@@ -582,46 +553,38 @@ public:
ASMJIT_NEW_REG_CUSTOM(newVec , Vec )
ASMJIT_NEW_REG_CUSTOM(newK , KReg)
- ASMJIT_NEW_REG_TYPED(newI8 , Gp , Type::kIdI8 )
- ASMJIT_NEW_REG_TYPED(newU8 , Gp , Type::kIdU8 )
- ASMJIT_NEW_REG_TYPED(newI16 , Gp , Type::kIdI16 )
- ASMJIT_NEW_REG_TYPED(newU16 , Gp , Type::kIdU16 )
- ASMJIT_NEW_REG_TYPED(newI32 , Gp , Type::kIdI32 )
- ASMJIT_NEW_REG_TYPED(newU32 , Gp , Type::kIdU32 )
- ASMJIT_NEW_REG_TYPED(newI64 , Gp , Type::kIdI64 )
- ASMJIT_NEW_REG_TYPED(newU64 , Gp , Type::kIdU64 )
- ASMJIT_NEW_REG_TYPED(newInt8 , Gp , Type::kIdI8 )
- ASMJIT_NEW_REG_TYPED(newUInt8 , Gp , Type::kIdU8 )
- ASMJIT_NEW_REG_TYPED(newInt16 , Gp , Type::kIdI16 )
- ASMJIT_NEW_REG_TYPED(newUInt16 , Gp , Type::kIdU16 )
- ASMJIT_NEW_REG_TYPED(newInt32 , Gp , Type::kIdI32 )
- ASMJIT_NEW_REG_TYPED(newUInt32 , Gp , Type::kIdU32 )
- ASMJIT_NEW_REG_TYPED(newInt64 , Gp , Type::kIdI64 )
- ASMJIT_NEW_REG_TYPED(newUInt64 , Gp , Type::kIdU64 )
- ASMJIT_NEW_REG_TYPED(newIntPtr , Gp , Type::kIdIntPtr )
- ASMJIT_NEW_REG_TYPED(newUIntPtr, Gp , Type::kIdUIntPtr)
-
- ASMJIT_NEW_REG_TYPED(newGpb , Gp , Type::kIdU8 )
- ASMJIT_NEW_REG_TYPED(newGpw , Gp , Type::kIdU16 )
- ASMJIT_NEW_REG_TYPED(newGpd , Gp , Type::kIdU32 )
- ASMJIT_NEW_REG_TYPED(newGpq , Gp , Type::kIdU64 )
- ASMJIT_NEW_REG_TYPED(newGpz , Gp , Type::kIdUIntPtr)
- ASMJIT_NEW_REG_TYPED(newXmm , Xmm , Type::kIdI32x4 )
- ASMJIT_NEW_REG_TYPED(newXmmSs , Xmm , Type::kIdF32x1 )
- ASMJIT_NEW_REG_TYPED(newXmmSd , Xmm , Type::kIdF64x1 )
- ASMJIT_NEW_REG_TYPED(newXmmPs , Xmm , Type::kIdF32x4 )
- ASMJIT_NEW_REG_TYPED(newXmmPd , Xmm , Type::kIdF64x2 )
- ASMJIT_NEW_REG_TYPED(newYmm , Ymm , Type::kIdI32x8 )
- ASMJIT_NEW_REG_TYPED(newYmmPs , Ymm , Type::kIdF32x8 )
- ASMJIT_NEW_REG_TYPED(newYmmPd , Ymm , Type::kIdF64x4 )
- ASMJIT_NEW_REG_TYPED(newZmm , Zmm , Type::kIdI32x16 )
- ASMJIT_NEW_REG_TYPED(newZmmPs , Zmm , Type::kIdF32x16 )
- ASMJIT_NEW_REG_TYPED(newZmmPd , Zmm , Type::kIdF64x8 )
- ASMJIT_NEW_REG_TYPED(newMm , Mm , Type::kIdMmx64 )
- ASMJIT_NEW_REG_TYPED(newKb , KReg, Type::kIdMask8 )
- ASMJIT_NEW_REG_TYPED(newKw , KReg, Type::kIdMask16 )
- ASMJIT_NEW_REG_TYPED(newKd , KReg, Type::kIdMask32 )
- ASMJIT_NEW_REG_TYPED(newKq , KReg, Type::kIdMask64 )
+ ASMJIT_NEW_REG_TYPED(newInt8 , Gp , TypeId::kInt8)
+ ASMJIT_NEW_REG_TYPED(newUInt8 , Gp , TypeId::kUInt8)
+ ASMJIT_NEW_REG_TYPED(newInt16 , Gp , TypeId::kInt16)
+ ASMJIT_NEW_REG_TYPED(newUInt16 , Gp , TypeId::kUInt16)
+ ASMJIT_NEW_REG_TYPED(newInt32 , Gp , TypeId::kInt32)
+ ASMJIT_NEW_REG_TYPED(newUInt32 , Gp , TypeId::kUInt32)
+ ASMJIT_NEW_REG_TYPED(newInt64 , Gp , TypeId::kInt64)
+ ASMJIT_NEW_REG_TYPED(newUInt64 , Gp , TypeId::kUInt64)
+ ASMJIT_NEW_REG_TYPED(newIntPtr , Gp , TypeId::kIntPtr)
+ ASMJIT_NEW_REG_TYPED(newUIntPtr, Gp , TypeId::kUIntPtr)
+
+ ASMJIT_NEW_REG_TYPED(newGpb , Gp , TypeId::kUInt8)
+ ASMJIT_NEW_REG_TYPED(newGpw , Gp , TypeId::kUInt16)
+ ASMJIT_NEW_REG_TYPED(newGpd , Gp , TypeId::kUInt32)
+ ASMJIT_NEW_REG_TYPED(newGpq , Gp , TypeId::kUInt64)
+ ASMJIT_NEW_REG_TYPED(newGpz , Gp , TypeId::kUIntPtr)
+ ASMJIT_NEW_REG_TYPED(newXmm , Xmm , TypeId::kInt32x4)
+ ASMJIT_NEW_REG_TYPED(newXmmSs , Xmm , TypeId::kFloat32x1)
+ ASMJIT_NEW_REG_TYPED(newXmmSd , Xmm , TypeId::kFloat64x1)
+ ASMJIT_NEW_REG_TYPED(newXmmPs , Xmm , TypeId::kFloat32x4)
+ ASMJIT_NEW_REG_TYPED(newXmmPd , Xmm , TypeId::kFloat64x2)
+ ASMJIT_NEW_REG_TYPED(newYmm , Ymm , TypeId::kInt32x8)
+ ASMJIT_NEW_REG_TYPED(newYmmPs , Ymm , TypeId::kFloat32x8)
+ ASMJIT_NEW_REG_TYPED(newYmmPd , Ymm , TypeId::kFloat64x4)
+ ASMJIT_NEW_REG_TYPED(newZmm , Zmm , TypeId::kInt32x16)
+ ASMJIT_NEW_REG_TYPED(newZmmPs , Zmm , TypeId::kFloat32x16)
+ ASMJIT_NEW_REG_TYPED(newZmmPd , Zmm , TypeId::kFloat64x8)
+ ASMJIT_NEW_REG_TYPED(newMm , Mm , TypeId::kMmx64)
+ ASMJIT_NEW_REG_TYPED(newKb , KReg, TypeId::kMask8)
+ ASMJIT_NEW_REG_TYPED(newKw , KReg, TypeId::kMask16)
+ ASMJIT_NEW_REG_TYPED(newKd , KReg, TypeId::kMask32)
+ ASMJIT_NEW_REG_TYPED(newKq , KReg, TypeId::kMask64)
#undef ASMJIT_NEW_REG_TYPED
#undef ASMJIT_NEW_REG_CUSTOM
@@ -645,49 +608,38 @@ public:
//! \{
//! Put data to a constant-pool and get a memory reference to it.
- inline Mem newConst(uint32_t scope, const void* data, size_t size) {
+ inline Mem newConst(ConstPoolScope scope, const void* data, size_t size) {
Mem m(Globals::NoInit);
_newConst(&m, scope, data, size);
return m;
}
//! Put a BYTE `val` to a constant-pool.
- inline Mem newByteConst(uint32_t scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
+ inline Mem newByteConst(ConstPoolScope scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newWordConst(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ inline Mem newWordConst(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newDWordConst(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ inline Mem newDWordConst(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newQWordConst(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ inline Mem newQWordConst(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newInt16Const(uint32_t scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
+ inline Mem newInt16Const(ConstPoolScope scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a WORD `val` to a constant-pool.
- inline Mem newUInt16Const(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+ inline Mem newUInt16Const(ConstPoolScope scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newInt32Const(uint32_t scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
+ inline Mem newInt32Const(ConstPoolScope scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a DWORD `val` to a constant-pool.
- inline Mem newUInt32Const(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+ inline Mem newUInt32Const(ConstPoolScope scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newInt64Const(uint32_t scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
+ inline Mem newInt64Const(ConstPoolScope scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a QWORD `val` to a constant-pool.
- inline Mem newUInt64Const(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+ inline Mem newUInt64Const(ConstPoolScope scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
//! Put a SP-FP `val` to a constant-pool.
- inline Mem newFloatConst(uint32_t scope, float val) noexcept { return newConst(scope, &val, 4); }
+ inline Mem newFloatConst(ConstPoolScope scope, float val) noexcept { return newConst(scope, &val, 4); }
//! Put a DP-FP `val` to a constant-pool.
- inline Mem newDoubleConst(uint32_t scope, double val) noexcept { return newConst(scope, &val, 8); }
-
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("newMmConst() uses a deprecated Data64, use newConst() with your own data instead")
- inline Mem newMmConst(uint32_t scope, const Data64& val) noexcept { return newConst(scope, &val, 8); }
-
- ASMJIT_DEPRECATED("newXmmConst() uses a deprecated Data128, use newConst() with your own data instead")
- inline Mem newXmmConst(uint32_t scope, const Data128& val) noexcept { return newConst(scope, &val, 16); }
-
- ASMJIT_DEPRECATED("newYmmConst() uses a deprecated Data256, use newConst() with your own data instead")
- inline Mem newYmmConst(uint32_t scope, const Data256& val) noexcept { return newConst(scope, &val, 32); }
-#endif // !ASMJIT_NO_DEPRECATED
+ inline Mem newDoubleConst(ConstPoolScope scope, double val) noexcept { return newConst(scope, &val, 8); }
//! \}
@@ -695,9 +647,9 @@ public:
//! \{
//! Force the compiler to not follow the conditional or unconditional jump.
- inline Compiler& unfollow() noexcept { _instOptions |= Inst::kOptionUnfollow; return *this; }
+ inline Compiler& unfollow() noexcept { addInstOptions(InstOptions::kUnfollow); return *this; }
//! Tell the compiler that the destination variable will be overwritten.
- inline Compiler& overwrite() noexcept { _instOptions |= Inst::kOptionOverwrite; return *this; }
+ inline Compiler& overwrite() noexcept { addInstOptions(InstOptions::kOverwrite); return *this; }
//! \}
@@ -706,15 +658,13 @@ public:
//! Invoke a function call without `target` type enforcement.
inline Error invoke_(InvokeNode** out, const Operand_& target, const FuncSignature& signature) {
- return _addInvokeNode(out, Inst::kIdCall, target, signature);
+ return addInvokeNode(out, Inst::kIdCall, target, signature);
}
- //! Invoke a function call of the given `target` and `signature` and store
- //! the added node to `out`.
+ //! Invoke a function call of the given `target` and `signature` and store the added node to `out`.
//!
- //! Creates a new \ref InvokeNode, initializes all the necessary members to
- //! match the given function `signature`, adds the node to the compiler, and
- //! stores its pointer to `out`. The operation is atomic, if anything fails
+ //! Creates a new \ref InvokeNode, initializes all the necessary members to match the given function `signature`,
+ //! adds the node to the compiler, and stores its pointer to `out`. The operation is atomic, if anything fails
//! nullptr is stored in `out` and error code is returned.
inline Error invoke(InvokeNode** out, const Gp& target, const FuncSignature& signature) { return invoke_(out, target, signature); }
//! \overload
@@ -726,22 +676,12 @@ public:
//! \overload
inline Error invoke(InvokeNode** out, uint64_t target, const FuncSignature& signature) { return invoke_(out, Imm(int64_t(target)), signature); }
-#ifndef _DOXYGEN
- template<typename Target>
- ASMJIT_DEPRECATED("Use invoke() instead of call()")
- inline InvokeNode* call(const Target& target, const FuncSignature& signature) {
- InvokeNode* invokeNode;
- invoke(&invokeNode, target, signature);
- return invokeNode;
- }
-#endif
-
- //! Return.
- inline FuncRetNode* ret() { return addRet(Operand(), Operand()); }
+ //! Return from function.
+ inline Error ret() { return addRet(Operand(), Operand()); }
//! \overload
- inline FuncRetNode* ret(const BaseReg& o0) { return addRet(o0, Operand()); }
+ inline Error ret(const BaseReg& o0) { return addRet(o0, Operand()); }
//! \overload
- inline FuncRetNode* ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
+ inline Error ret(const BaseReg& o0, const BaseReg& o1) { return addRet(o0, o1); }
//! \}
diff --git a/src/asmjit/x86/x86emithelper.cpp b/src/asmjit/x86/x86emithelper.cpp
index e6290ea..4a85a16 100644
--- a/src/asmjit/x86/x86emithelper.cpp
+++ b/src/asmjit/x86/x86emithelper.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
@@ -35,11 +17,10 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::Internal - Helpers]
-// ============================================================================
+// x86::EmitHelper - Utilities
+// ===========================
-static ASMJIT_INLINE uint32_t getXmmMovInst(const FuncFrame& frame) {
+static inline uint32_t getXmmMovInst(const FuncFrame& frame) {
bool avx = frame.isAvxEnabled();
bool aligned = frame.hasAlignedVecSR();
@@ -58,21 +39,24 @@ static inline uint32_t kmovInstFromSize(uint32_t size) noexcept {
}
}
-// ============================================================================
-// [asmjit::X86Internal - Emit Helpers]
-// ============================================================================
+static inline uint32_t makeCastOp(TypeId dst, TypeId src) noexcept {
+ return (uint32_t(dst) << 8) | uint32_t(src);
+}
+
+// x86::EmitHelper - Emit Reg Move
+// ===============================
ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
const Operand_& dst_,
- const Operand_& src_, uint32_t typeId, const char* comment) {
+ const Operand_& src_, TypeId typeId, const char* comment) {
// Invalid or abstract TypeIds are not allowed.
- ASMJIT_ASSERT(Type::isValid(typeId) && !Type::isAbstract(typeId));
+ ASMJIT_ASSERT(TypeUtils::isValid(typeId) && !TypeUtils::isAbstract(typeId));
Operand dst(dst_);
Operand src(src_);
- uint32_t instId = Inst::kIdNone;
+ InstId instId = Inst::kIdNone;
uint32_t memFlags = 0;
uint32_t overrideMemSize = 0;
@@ -81,72 +65,70 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
kSrcMem = 0x2
};
- // Detect memory operands and patch them to have the same size as the register.
- // BaseCompiler always sets memory size of allocs and spills, so it shouldn't
- // be really necessary, however, after this function was separated from Compiler
- // it's better to make sure that the size is always specified, as we can use
- // 'movzx' and 'movsx' that rely on it.
+ // Detect memory operands and patch them to have the same size as the register. BaseCompiler always sets memory size
+ // of allocs and spills, so it shouldn't be really necessary, however, after this function was separated from Compiler
+ // it's better to make sure that the size is always specified, as we can use 'movzx' and 'movsx' that rely on it.
if (dst.isMem()) { memFlags |= kDstMem; dst.as<Mem>().setSize(src.size()); }
if (src.isMem()) { memFlags |= kSrcMem; src.as<Mem>().setSize(dst.size()); }
switch (typeId) {
- case Type::kIdI8:
- case Type::kIdU8:
- case Type::kIdI16:
- case Type::kIdU16:
+ case TypeId::kInt8:
+ case TypeId::kUInt8:
+ case TypeId::kInt16:
+ case TypeId::kUInt16:
// Special case - 'movzx' load.
if (memFlags & kSrcMem) {
instId = Inst::kIdMovzx;
- dst.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
}
else if (!memFlags) {
// Change both destination and source registers to GPD (safer, no dependencies).
- dst.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
- src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
}
ASMJIT_FALLTHROUGH;
- case Type::kIdI32:
- case Type::kIdU32:
- case Type::kIdI64:
- case Type::kIdU64:
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
instId = Inst::kIdMov;
break;
- case Type::kIdMmx32:
+ case TypeId::kMmx32:
instId = Inst::kIdMovd;
if (memFlags) break;
ASMJIT_FALLTHROUGH;
- case Type::kIdMmx64 : instId = Inst::kIdMovq ; break;
- case Type::kIdMask8 : instId = Inst::kIdKmovb; break;
- case Type::kIdMask16: instId = Inst::kIdKmovw; break;
- case Type::kIdMask32: instId = Inst::kIdKmovd; break;
- case Type::kIdMask64: instId = Inst::kIdKmovq; break;
+ case TypeId::kMmx64 : instId = Inst::kIdMovq ; break;
+ case TypeId::kMask8 : instId = Inst::kIdKmovb; break;
+ case TypeId::kMask16: instId = Inst::kIdKmovw; break;
+ case TypeId::kMask32: instId = Inst::kIdKmovd; break;
+ case TypeId::kMask64: instId = Inst::kIdKmovq; break;
default: {
- uint32_t elementTypeId = Type::baseOf(typeId);
- if (Type::isVec32(typeId) && memFlags) {
+ TypeId scalarTypeId = TypeUtils::scalarOf(typeId);
+ if (TypeUtils::isVec32(typeId) && memFlags) {
overrideMemSize = 4;
- if (elementTypeId == Type::kIdF32)
+ if (scalarTypeId == TypeId::kFloat32)
instId = _avxEnabled ? Inst::kIdVmovss : Inst::kIdMovss;
else
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
break;
}
- if (Type::isVec64(typeId) && memFlags) {
+ if (TypeUtils::isVec64(typeId) && memFlags) {
overrideMemSize = 8;
- if (elementTypeId == Type::kIdF64)
+ if (scalarTypeId == TypeId::kFloat64)
instId = _avxEnabled ? Inst::kIdVmovsd : Inst::kIdMovsd;
else
instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
break;
}
- if (elementTypeId == Type::kIdF32)
+ if (scalarTypeId == TypeId::kFloat32)
instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
- else if (elementTypeId == Type::kIdF64)
+ else if (scalarTypeId == TypeId::kFloat64)
instId = _avxEnabled ? Inst::kIdVmovapd : Inst::kIdMovapd;
else if (!_avx512Enabled)
instId = _avxEnabled ? Inst::kIdVmovdqa : Inst::kIdMovdqa;
@@ -168,75 +150,77 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
return _emitter->emit(instId, dst, src);
}
+// x86::EmitHelper - Emit Arg Move
+// ===============================
+
ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
- const BaseReg& dst_, uint32_t dstTypeId,
- const Operand_& src_, uint32_t srcTypeId, const char* comment) {
+ const BaseReg& dst_, TypeId dstTypeId,
+ const Operand_& src_, TypeId srcTypeId, const char* comment) {
- // Deduce optional `dstTypeId`, which may be `Type::kIdVoid` in some cases.
- if (!dstTypeId) {
+ // Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
+ if (dstTypeId == TypeId::kVoid) {
const ArchTraits& archTraits = ArchTraits::byArch(_emitter->arch());
dstTypeId = archTraits.regTypeToTypeId(dst_.type());
}
// Invalid or abstract TypeIds are not allowed.
- ASMJIT_ASSERT(Type::isValid(dstTypeId) && !Type::isAbstract(dstTypeId));
- ASMJIT_ASSERT(Type::isValid(srcTypeId) && !Type::isAbstract(srcTypeId));
+ ASMJIT_ASSERT(TypeUtils::isValid(dstTypeId) && !TypeUtils::isAbstract(dstTypeId));
+ ASMJIT_ASSERT(TypeUtils::isValid(srcTypeId) && !TypeUtils::isAbstract(srcTypeId));
Reg dst(dst_.as<Reg>());
Operand src(src_);
- uint32_t dstSize = Type::sizeOf(dstTypeId);
- uint32_t srcSize = Type::sizeOf(srcTypeId);
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
- uint32_t instId = Inst::kIdNone;
+ InstId instId = Inst::kIdNone;
// Not a real loop, just 'break' is nicer than 'goto'.
for (;;) {
- if (Type::isInt(dstTypeId)) {
- if (Type::isInt(srcTypeId)) {
+ if (TypeUtils::isInt(dstTypeId)) {
+ if (TypeUtils::isInt(srcTypeId)) {
instId = Inst::kIdMovsx;
- uint32_t typeOp = (dstTypeId << 8) | srcTypeId;
+ uint32_t castOp = makeCastOp(dstTypeId, srcTypeId);
// Sign extend by using 'movsx'.
- if (typeOp == ((Type::kIdI16 << 8) | Type::kIdI8 ) ||
- typeOp == ((Type::kIdI32 << 8) | Type::kIdI8 ) ||
- typeOp == ((Type::kIdI32 << 8) | Type::kIdI16) ||
- typeOp == ((Type::kIdI64 << 8) | Type::kIdI8 ) ||
- typeOp == ((Type::kIdI64 << 8) | Type::kIdI16))
+ if (castOp == makeCastOp(TypeId::kInt16, TypeId::kInt8 ) ||
+ castOp == makeCastOp(TypeId::kInt32, TypeId::kInt8 ) ||
+ castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) ||
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt8 ) ||
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16))
break;
// Sign extend by using 'movsxd'.
instId = Inst::kIdMovsxd;
- if (typeOp == ((Type::kIdI64 << 8) | Type::kIdI32))
+ if (castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32))
break;
}
- if (Type::isInt(srcTypeId) || src_.isMem()) {
+ if (TypeUtils::isInt(srcTypeId) || src_.isMem()) {
// Zero extend by using 'movzx' or 'mov'.
if (dstSize <= 4 && srcSize < 4) {
instId = Inst::kIdMovzx;
- dst.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
}
else {
- // We should have caught all possibilities where `srcSize` is less
- // than 4, so we don't have to worry about 'movzx' anymore. Minimum
- // size is enough to determine if we want 32-bit or 64-bit move.
+ // We should have caught all possibilities where `srcSize` is less than 4, so we don't have to worry
+ // about 'movzx' anymore. Minimum size is enough to determine if we want 32-bit or 64-bit move.
instId = Inst::kIdMov;
srcSize = Support::min(srcSize, dstSize);
- dst.setSignature(srcSize == 4 ? Reg::signatureOfT<Reg::kTypeGpd>()
- : Reg::signatureOfT<Reg::kTypeGpq>());
+ dst.setSignature(srcSize == 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
+ : Reg::signatureOfT<RegType::kX86_Gpq>());
if (src.isReg())
src.setSignature(dst.signature());
}
break;
}
- // NOTE: The previous branch caught all memory sources, from here it's
- // always register to register conversion, so catch the remaining cases.
+ // NOTE: The previous branch caught all memory sources, from here it's always register to register conversion,
+ // so catch the remaining cases.
srcSize = Support::min(srcSize, dstSize);
- if (Type::isMmx(srcTypeId)) {
+ if (TypeUtils::isMmx(srcTypeId)) {
// 64-bit move.
instId = Inst::kIdMovq;
if (srcSize == 8)
@@ -244,18 +228,18 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
// 32-bit move.
instId = Inst::kIdMovd;
- dst.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
break;
}
- if (Type::isMask(srcTypeId)) {
+ if (TypeUtils::isMask(srcTypeId)) {
instId = kmovInstFromSize(srcSize);
- dst.setSignature(srcSize <= 4 ? Reg::signatureOfT<Reg::kTypeGpd>()
- : Reg::signatureOfT<Reg::kTypeGpq>());
+ dst.setSignature(srcSize <= 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
+ : Reg::signatureOfT<RegType::kX86_Gpq>());
break;
}
- if (Type::isVec(srcTypeId)) {
+ if (TypeUtils::isVec(srcTypeId)) {
// 64-bit move.
instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
if (srcSize == 8)
@@ -263,16 +247,16 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
// 32-bit move.
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
- dst.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
break;
}
}
- if (Type::isMmx(dstTypeId)) {
+ if (TypeUtils::isMmx(dstTypeId)) {
instId = Inst::kIdMovq;
srcSize = Support::min(srcSize, dstSize);
- if (Type::isInt(srcTypeId) || src.isMem()) {
+ if (TypeUtils::isInt(srcTypeId) || src.isMem()) {
// 64-bit move.
if (srcSize == 8)
break;
@@ -280,33 +264,33 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
// 32-bit move.
instId = Inst::kIdMovd;
if (src.isReg())
- src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
break;
}
- if (Type::isMmx(srcTypeId))
+ if (TypeUtils::isMmx(srcTypeId))
break;
// This will hurt if AVX is enabled.
instId = Inst::kIdMovdq2q;
- if (Type::isVec(srcTypeId))
+ if (TypeUtils::isVec(srcTypeId))
break;
}
- if (Type::isMask(dstTypeId)) {
+ if (TypeUtils::isMask(dstTypeId)) {
srcSize = Support::min(srcSize, dstSize);
- if (Type::isInt(srcTypeId) || Type::isMask(srcTypeId) || src.isMem()) {
+ if (TypeUtils::isInt(srcTypeId) || TypeUtils::isMask(srcTypeId) || src.isMem()) {
instId = kmovInstFromSize(srcSize);
if (Reg::isGp(src) && srcSize <= 4)
- src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
break;
}
}
- if (Type::isVec(dstTypeId)) {
+ if (TypeUtils::isVec(dstTypeId)) {
// By default set destination to XMM, will be set to YMM|ZMM if needed.
- dst.setSignature(Reg::signatureOfT<Reg::kTypeXmm>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Xmm>());
// This will hurt if AVX is enabled.
if (Reg::isMm(src)) {
@@ -316,10 +300,10 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
}
// Argument conversion.
- uint32_t dstElement = Type::baseOf(dstTypeId);
- uint32_t srcElement = Type::baseOf(srcTypeId);
+ TypeId dstScalarId = TypeUtils::scalarOf(dstTypeId);
+ TypeId srcScalarId = TypeUtils::scalarOf(srcTypeId);
- if (dstElement == Type::kIdF32 && srcElement == Type::kIdF64) {
+ if (dstScalarId == TypeId::kFloat32 && srcScalarId == TypeId::kFloat64) {
srcSize = Support::min(dstSize * 2, srcSize);
dstSize = srcSize / 2;
@@ -329,13 +313,13 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
instId = _avxEnabled ? Inst::kIdVcvtps2pd : Inst::kIdCvtps2pd;
if (dstSize == 32)
- dst.setSignature(Reg::signatureOfT<Reg::kTypeYmm>());
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
if (src.isReg())
src.setSignature(Reg::signatureOfVecBySize(srcSize));
break;
}
- if (dstElement == Type::kIdF64 && srcElement == Type::kIdF32) {
+ if (dstScalarId == TypeId::kFloat64 && srcScalarId == TypeId::kFloat32) {
srcSize = Support::min(dstSize, srcSize * 2) / 2;
dstSize = srcSize * 2;
@@ -346,7 +330,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
dst.setSignature(Reg::signatureOfVecBySize(dstSize));
if (src.isReg() && srcSize >= 32)
- src.setSignature(Reg::signatureOfT<Reg::kTypeYmm>());
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
break;
}
@@ -356,7 +340,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
if (srcSize <= 4) {
instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
if (src.isReg())
- src.setSignature(Reg::signatureOfT<Reg::kTypeGpd>());
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
break;
}
@@ -373,7 +357,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
if (src.isMem() && srcSize < _emitter->environment().stackAlignment())
instId = _avxEnabled ? Inst::kIdVmovups : Inst::kIdMovups;
- uint32_t signature = Reg::signatureOfVecBySize(srcSize);
+ OperandSignature signature = Reg::signatureOfVecBySize(srcSize);
dst.setSignature(signature);
if (src.isReg())
src.setSignature(signature);
@@ -403,33 +387,34 @@ Error EmitHelper::emitRegSwap(
return DebugUtils::errored(kErrorInvalidState);
}
-// ============================================================================
-// [asmjit::X86Internal - Emit Prolog & Epilog]
-// ============================================================================
+// x86::EmitHelper - Emit Prolog & Epilog
+// ======================================
-static ASMJIT_INLINE void X86Internal_setupSaveRestoreInfo(uint32_t group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
+static inline void X86Internal_setupSaveRestoreInfo(RegGroup group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
switch (group) {
- case Reg::kGroupVec:
+ case RegGroup::kVec:
xReg = xmm(0);
xInst = getXmmMovInst(frame);
xSize = xReg.size();
break;
- case Reg::kGroupMm:
+ case RegGroup::kX86_K:
+ xReg = k(0);
+ xInst = Inst::kIdKmovq;
+ xSize = xReg.size();
+ break;
+ case RegGroup::kX86_MM:
xReg = mm(0);
xInst = Inst::kIdMovq;
xSize = xReg.size();
break;
- case Reg::kGroupKReg:
- xReg = k(0);
- xInst = Inst::kIdKmovq;
- xSize = xReg.size();
+ default:
break;
}
}
ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
Emitter* emitter = _emitter->as<Emitter>();
- uint32_t gpSaved = frame.savedRegs(Reg::kGroupGp);
+ uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
Gp zsp = emitter->zsp(); // ESP|RSP register.
Gp zbp = emitter->zbp(); // EBP|RBP register.
@@ -446,7 +431,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
// Emit: 'push gp' sequence.
{
- Support::BitWordIterator<uint32_t> it(gpSaved);
+ Support::BitWordIterator<RegMask> it(gpSaved);
while (it.hasNext()) {
gpReg.setId(it.next());
ASMJIT_PROPAGATE(emitter->push(gpReg));
@@ -490,8 +475,8 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
uint32_t xInst;
uint32_t xSize;
- for (uint32_t group = 1; group < BaseReg::kGroupVirt; group++) {
- Support::BitWordIterator<uint32_t> it(frame.savedRegs(group));
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
+ Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
if (it.hasNext()) {
X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
do {
@@ -513,7 +498,7 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
uint32_t regId;
uint32_t registerSize = emitter->registerSize();
- uint32_t gpSaved = frame.savedRegs(Reg::kGroupGp);
+ uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
Gp zsp = emitter->zsp(); // ESP|RSP register.
Gp zbp = emitter->zbp(); // EBP|RBP register.
@@ -531,8 +516,8 @@ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
uint32_t xInst;
uint32_t xSize;
- for (uint32_t group = 1; group < BaseReg::kGroupVirt; group++) {
- Support::BitWordIterator<uint32_t> it(frame.savedRegs(group));
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
+ Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
if (it.hasNext()) {
X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
do {
diff --git a/src/asmjit/x86/x86emithelper_p.h b/src/asmjit/x86/x86emithelper_p.h
index dd3b0c9..98d16da 100644
--- a/src/asmjit/x86/x86emithelper_p.h
+++ b/src/asmjit/x86/x86emithelper_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
#define ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
@@ -37,13 +19,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::EmitHelper]
-// ============================================================================
-
-static ASMJIT_INLINE uint32_t vecTypeIdToRegType(uint32_t typeId) noexcept {
- return typeId <= Type::_kIdVec128End ? Reg::kTypeXmm :
- typeId <= Type::_kIdVec256End ? Reg::kTypeYmm : Reg::kTypeZmm;
+static inline RegType vecTypeIdToRegType(TypeId typeId) noexcept {
+ return uint32_t(typeId) <= uint32_t(TypeId::_kVec128End) ? RegType::kX86_Xmm :
+ uint32_t(typeId) <= uint32_t(TypeId::_kVec256End) ? RegType::kX86_Ymm : RegType::kX86_Zmm;
}
class EmitHelper : public BaseEmitHelper {
@@ -58,11 +36,11 @@ public:
Error emitRegMove(
const Operand_& dst_,
- const Operand_& src_, uint32_t typeId, const char* comment = nullptr) override;
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr) override;
Error emitArgMove(
- const BaseReg& dst_, uint32_t dstTypeId,
- const Operand_& src_, uint32_t srcTypeId, const char* comment = nullptr) override;
+ const BaseReg& dst_, TypeId dstTypeId,
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) override;
Error emitRegSwap(
const BaseReg& a,
diff --git a/src/asmjit/x86/x86emitter.h b/src/asmjit/x86/x86emitter.h
index 24f2fb6..1f85dec 100644
--- a/src/asmjit/x86/x86emitter.h
+++ b/src/asmjit/x86/x86emitter.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86EMITTER_H_INCLUDED
#define ASMJIT_X86_X86EMITTER_H_INCLUDED
@@ -38,7 +20,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
inline Error NAME(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID, o0); }
#define ASMJIT_INST_1c(NAME, ID, CONV, T0) \
- inline Error NAME(uint32_t cc, const T0& o0) { return _emitter()->_emitI(CONV(cc), o0); } \
+ inline Error NAME(CondCode cc, const T0& o0) { return _emitter()->_emitI(CONV(cc), o0); } \
inline Error NAME##a(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID##a, o0); } \
inline Error NAME##ae(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID##ae, o0); } \
inline Error NAME##b(const T0& o0) { return _emitter()->_emitI(Inst::kId##ID##b, o0); } \
@@ -74,7 +56,7 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
inline Error NAME(const T0& o0, const T1& o1) { return _emitter()->_emitI(Inst::kId##ID, o0, o1); }
#define ASMJIT_INST_2c(NAME, ID, CONV, T0, T1) \
- inline Error NAME(uint32_t cc, const T0& o0, const T1& o1) { return _emitter()->_emitI(CONV(cc), o0, o1); } \
+ inline Error NAME(CondCode cc, const T0& o0, const T1& o1) { return _emitter()->_emitI(CONV(cc), o0, o1); } \
inline Error NAME##a(const T0& o0, const T1& o1) { return _emitter()->_emitI(Inst::kId##ID##a, o0, o1); } \
inline Error NAME##ae(const T0& o0, const T1& o1) { return _emitter()->_emitI(Inst::kId##ID##ae, o0, o1); } \
inline Error NAME##b(const T0& o0, const T1& o1) { return _emitter()->_emitI(Inst::kId##ID##b, o0, o1); } \
@@ -121,10 +103,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::EmitterExplicitT]
-// ============================================================================
-
//! Emitter (X86 - explicit).
template<typename This>
struct EmitterExplicitT {
@@ -159,9 +137,8 @@ struct EmitterExplicitT {
typedef Xmm XMM0;
- // These two are unfortunately reported by the sanitizer. We know what we do,
- // however, the sanitizer doesn't. I have tried to use reinterpret_cast instead,
- // but that would generate bad code when compiled by MSC.
+ // These two are unfortunately reported by the sanitizer. We know what we do, however, the sanitizer doesn't.
+ // I have tried to use reinterpret_cast instead, but that would generate bad code when compiled by MSC.
ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF inline This* _emitter() noexcept { return static_cast<This*>(this); }
ASMJIT_ATTRIBUTE_NO_SANITIZE_UNDEF inline const This* _emitter() const noexcept { return static_cast<const This*>(this); }
@@ -171,16 +148,16 @@ struct EmitterExplicitT {
//! \{
//! Returns either GPD or GPQ register of the given `id` depending on the emitter's architecture.
- inline Gp gpz(uint32_t id) const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), id); }
+ inline Gp gpz(uint32_t id) const noexcept { return Gp(_emitter()->_gpSignature, id); }
- inline Gp zax() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdAx); }
- inline Gp zcx() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdCx); }
- inline Gp zdx() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdDx); }
- inline Gp zbx() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdBx); }
- inline Gp zsp() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdSp); }
- inline Gp zbp() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdBp); }
- inline Gp zsi() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdSi); }
- inline Gp zdi() const noexcept { return Gp::fromSignatureAndId(_emitter()->_gpRegInfo.signature(), Gp::kIdDi); }
+ inline Gp zax() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdAx); }
+ inline Gp zcx() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdCx); }
+ inline Gp zdx() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdDx); }
+ inline Gp zbx() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdBx); }
+ inline Gp zsp() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdSp); }
+ inline Gp zbp() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdBp); }
+ inline Gp zsi() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdSi); }
+ inline Gp zdi() const noexcept { return Gp(_emitter()->_gpSignature, Gp::kIdDi); }
//! \}
@@ -189,7 +166,10 @@ struct EmitterExplicitT {
//! Creates a target dependent pointer of which base register's id is `baseId`.
inline Mem ptr_base(uint32_t baseId, int32_t off = 0, uint32_t size = 0) const noexcept {
- return Mem(Mem::Decomposed { _emitter()->_gpRegInfo.type(), baseId, 0, 0, off, size, 0 });
+ return Mem(OperandSignature::fromOpType(OperandType::kMem) |
+ OperandSignature::fromMemBaseType(_emitter()->_gpSignature.regType()) |
+ OperandSignature::fromSize(size),
+ baseId, 0, off);
}
inline Mem ptr_zax(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(Gp::kIdAx, off, size); }
@@ -249,12 +229,12 @@ struct EmitterExplicitT {
//! \overload
inline Mem intptr_ptr_abs(uint64_t base) const noexcept {
uint32_t nativeGpSize = _emitter()->registerSize();
- return Mem(base, nativeGpSize, Mem::kSignatureMemAbs);
+ return Mem(base, nativeGpSize, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! \overload
inline Mem intptr_ptr_abs(uint64_t base, const Gp& index, uint32_t shift = 0) const noexcept {
uint32_t nativeGpSize = _emitter()->registerSize();
- return Mem(base, index, shift, nativeGpSize, Mem::kSignatureMemAbs);
+ return Mem(base, index, shift, nativeGpSize, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
//! \}
@@ -271,47 +251,6 @@ struct EmitterExplicitT {
//! Embeds 64-bit integer data.
inline Error dq(uint64_t x, size_t repeatCount = 1) { return _emitter()->embedUInt64(x, repeatCount); }
-#ifndef ASMJIT_NO_DEPRECATED
- ASMJIT_DEPRECATED("Use embedInt8() instead of dint8()")
- inline Error dint8(int8_t x) { return _emitter()->embed(&x, sizeof(int8_t)); }
-
- ASMJIT_DEPRECATED("Use embedUInt8() instead of duint8()")
- inline Error duint8(uint8_t x) { return _emitter()->embed(&x, sizeof(uint8_t)); }
-
- ASMJIT_DEPRECATED("Use embedInt16() instead of dint16()")
- inline Error dint16(int16_t x) { return _emitter()->embed(&x, sizeof(int16_t)); }
-
- ASMJIT_DEPRECATED("Use embedUInt16() instead of duint16()")
- inline Error duint16(uint16_t x) { return _emitter()->embed(&x, sizeof(uint16_t)); }
-
- ASMJIT_DEPRECATED("Use embedInt32() instead of dint32()")
- inline Error dint32(int32_t x) { return _emitter()->embed(&x, sizeof(int32_t)); }
-
- ASMJIT_DEPRECATED("Use embedUInt32() instead of duint32()")
- inline Error duint32(uint32_t x) { return _emitter()->embed(&x, sizeof(uint32_t)); }
-
- ASMJIT_DEPRECATED("Use embedInt64() instead of dint64()")
- inline Error dint64(int64_t x) { return _emitter()->embed(&x, sizeof(int64_t)); }
-
- ASMJIT_DEPRECATED("Use embedUInt64() instead of duint64()")
- inline Error duint64(uint64_t x) { return _emitter()->embed(&x, sizeof(uint64_t)); }
-
- ASMJIT_DEPRECATED("Use embedFloat() instead of float()")
- inline Error dfloat(float x) { return _emitter()->embed(&x, sizeof(float)); }
-
- ASMJIT_DEPRECATED("Use embedDouble() instead of ddouble()")
- inline Error ddouble(double x) { return _emitter()->embed(&x, sizeof(double)); }
-
- ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dmm()")
- inline Error dmm(const Data64& x) { return _emitter()->embed(&x, 8); }
-
- ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dxmm()")
- inline Error dxmm(const Data128& x) { return _emitter()->embed(&x, 16); }
-
- ASMJIT_DEPRECATED("Use embed[U]IntN() or embed[Float|Double]() instead of dymm()")
- inline Error dymm(const Data256& x) { return _emitter()->embed(&x, 32); }
-#endif // !ASMJIT_NO_DEPRECATED
-
//! Adds data in a given structure instance to the CodeBuffer.
template<typename T>
inline Error dstruct(const T& x) { return _emitter()->embed(&x, uint32_t(sizeof(T))); }
@@ -320,7 +259,7 @@ struct EmitterExplicitT {
protected:
//! \cond
- inline This& _addInstOptions(uint32_t options) noexcept {
+ inline This& _addInstOptions(InstOptions options) noexcept {
_emitter()->addInstOptions(options);
return *_emitter();
}
@@ -331,9 +270,9 @@ public:
//! \{
//! Force short form of jmp/jcc instruction.
- inline This& short_() noexcept { return _addInstOptions(Inst::kOptionShortForm); }
+ inline This& short_() noexcept { return _addInstOptions(InstOptions::kShortForm); }
//! Force long form of jmp/jcc instruction.
- inline This& long_() noexcept { return _addInstOptions(Inst::kOptionLongForm); }
+ inline This& long_() noexcept { return _addInstOptions(InstOptions::kLongForm); }
//! \}
@@ -341,10 +280,10 @@ public:
//! \{
//! Prefer MOD/RM encoding when both MOD/RM and MOD/MR forms are applicable.
- inline This& mod_rm() noexcept { return _addInstOptions(Inst::kOptionModRM); }
+ inline This& mod_rm() noexcept { return _addInstOptions(InstOptions::kX86_ModRM); }
//! Prefer MOD/MR encoding when both MOD/RM and MOD/MR forms are applicable.
- inline This& mod_mr() noexcept { return _addInstOptions(Inst::kOptionModMR); }
+ inline This& mod_mr() noexcept { return _addInstOptions(InstOptions::kX86_ModMR); }
//! \}
@@ -352,28 +291,28 @@ public:
//! \{
//! Condition is likely to be taken (has only benefit on P4).
- inline This& taken() noexcept { return _addInstOptions(Inst::kOptionTaken); }
+ inline This& taken() noexcept { return _addInstOptions(InstOptions::kTaken); }
//! Condition is unlikely to be taken (has only benefit on P4).
- inline This& notTaken() noexcept { return _addInstOptions(Inst::kOptionNotTaken); }
+ inline This& notTaken() noexcept { return _addInstOptions(InstOptions::kNotTaken); }
//! Use LOCK prefix.
- inline This& lock() noexcept { return _addInstOptions(Inst::kOptionLock); }
+ inline This& lock() noexcept { return _addInstOptions(InstOptions::kX86_Lock); }
//! Use XACQUIRE prefix.
- inline This& xacquire() noexcept { return _addInstOptions(Inst::kOptionXAcquire); }
+ inline This& xacquire() noexcept { return _addInstOptions(InstOptions::kX86_XAcquire); }
//! Use XRELEASE prefix.
- inline This& xrelease() noexcept { return _addInstOptions(Inst::kOptionXRelease); }
+ inline This& xrelease() noexcept { return _addInstOptions(InstOptions::kX86_XRelease); }
//! Use BND/REPNE prefix.
//!
//! \note This is the same as using `repne()` or `repnz()` prefix.
- inline This& bnd() noexcept { return _addInstOptions(Inst::kOptionRepne); }
+ inline This& bnd() noexcept { return _addInstOptions(InstOptions::kX86_Repne); }
//! Use REP/REPZ prefix.
//!
//! \note This is the same as using `repe()` or `repz()` prefix.
inline This& rep(const Gp& zcx) noexcept {
_emitter()->_extraReg.init(zcx);
- return _addInstOptions(Inst::kOptionRep);
+ return _addInstOptions(InstOptions::kX86_Rep);
}
//! Use REP/REPE prefix.
@@ -391,7 +330,7 @@ public:
//! \note This is the same as using `bnd()` or `repnz()` prefix.
inline This& repne(const Gp& zcx) noexcept {
_emitter()->_extraReg.init(zcx);
- return _addInstOptions(Inst::kOptionRepne);
+ return _addInstOptions(InstOptions::kX86_Repne);
}
//! Use REPNE prefix.
@@ -406,18 +345,18 @@ public:
//! Force REX prefix to be emitted even when it's not needed (X86_64).
//!
- //! \note Don't use when using high 8-bit registers as REX prefix makes them
- //! inaccessible and `x86::Assembler` would fail to encode such instruction.
- inline This& rex() noexcept { return _addInstOptions(Inst::kOptionRex); }
+ //! \note Don't use when using high 8-bit registers as REX prefix makes them inaccessible and `x86::Assembler`
+ //! would fail to encode such instruction.
+ inline This& rex() noexcept { return _addInstOptions(InstOptions::kX86_Rex); }
//! Force REX.B prefix (X64) [It exists for special purposes only].
- inline This& rex_b() noexcept { return _addInstOptions(Inst::kOptionOpCodeB); }
+ inline This& rex_b() noexcept { return _addInstOptions(InstOptions::kX86_OpCodeB); }
//! Force REX.X prefix (X64) [It exists for special purposes only].
- inline This& rex_x() noexcept { return _addInstOptions(Inst::kOptionOpCodeX); }
+ inline This& rex_x() noexcept { return _addInstOptions(InstOptions::kX86_OpCodeX); }
//! Force REX.R prefix (X64) [It exists for special purposes only].
- inline This& rex_r() noexcept { return _addInstOptions(Inst::kOptionOpCodeR); }
+ inline This& rex_r() noexcept { return _addInstOptions(InstOptions::kX86_OpCodeR); }
//! Force REX.W prefix (X64) [It exists for special purposes only].
- inline This& rex_w() noexcept { return _addInstOptions(Inst::kOptionOpCodeW); }
+ inline This& rex_w() noexcept { return _addInstOptions(InstOptions::kX86_OpCodeW); }
//! \}
@@ -425,11 +364,11 @@ public:
//! \{
//! Use VEX prefix instead of EVEX prefix (useful to select AVX_VNNI instruction instead of AVX512_VNNI).
- inline This& vex() noexcept { return _addInstOptions(Inst::kOptionVex); }
+ inline This& vex() noexcept { return _addInstOptions(InstOptions::kX86_Vex); }
//! Force 3-byte VEX prefix (AVX+).
- inline This& vex3() noexcept { return _addInstOptions(Inst::kOptionVex3); }
+ inline This& vex3() noexcept { return _addInstOptions(InstOptions::kX86_Vex3); }
//! Force 4-byte EVEX prefix (AVX512+).
- inline This& evex() noexcept { return _addInstOptions(Inst::kOptionEvex); }
+ inline This& evex() noexcept { return _addInstOptions(InstOptions::kX86_Evex); }
//! \}
@@ -443,18 +382,18 @@ public:
}
//! Use zeroing instead of merging (AVX512+).
- inline This& z() noexcept { return _addInstOptions(Inst::kOptionZMask); }
+ inline This& z() noexcept { return _addInstOptions(InstOptions::kX86_ZMask); }
//! Suppress all exceptions (AVX512+).
- inline This& sae() noexcept { return _addInstOptions(Inst::kOptionSAE); }
+ inline This& sae() noexcept { return _addInstOptions(InstOptions::kX86_SAE); }
//! Static rounding mode {rn} (round-to-nearest even) and {sae} (AVX512+).
- inline This& rn_sae() noexcept { return _addInstOptions(Inst::kOptionER | Inst::kOptionRN_SAE); }
+ inline This& rn_sae() noexcept { return _addInstOptions(InstOptions::kX86_ER | InstOptions::kX86_RN_SAE); }
//! Static rounding mode {rd} (round-down, toward -inf) and {sae} (AVX512+).
- inline This& rd_sae() noexcept { return _addInstOptions(Inst::kOptionER | Inst::kOptionRD_SAE); }
+ inline This& rd_sae() noexcept { return _addInstOptions(InstOptions::kX86_ER | InstOptions::kX86_RD_SAE); }
//! Static rounding mode {ru} (round-up, toward +inf) and {sae} (AVX512+).
- inline This& ru_sae() noexcept { return _addInstOptions(Inst::kOptionER | Inst::kOptionRU_SAE); }
+ inline This& ru_sae() noexcept { return _addInstOptions(InstOptions::kX86_ER | InstOptions::kX86_RU_SAE); }
//! Static rounding mode {rz} (round-toward-zero, truncate) and {sae} (AVX512+).
- inline This& rz_sae() noexcept { return _addInstOptions(Inst::kOptionER | Inst::kOptionRZ_SAE); }
+ inline This& rz_sae() noexcept { return _addInstOptions(InstOptions::kX86_ER | InstOptions::kX86_RZ_SAE); }
//! \}
@@ -508,8 +447,8 @@ public:
ASMJIT_INST_1x(call, Call, Mem) // ANY
ASMJIT_INST_1x(call, Call, Label) // ANY
ASMJIT_INST_1x(call, Call, Imm) // ANY
- ASMJIT_INST_2c(cmov, Cmov, Condition::toCmovcc, Gp, Gp) // CMOV
- ASMJIT_INST_2c(cmov, Cmov, Condition::toCmovcc, Gp, Mem) // CMOV
+ ASMJIT_INST_2c(cmov, Cmov, Inst::cmovccFromCond, Gp, Gp) // CMOV
+ ASMJIT_INST_2c(cmov, Cmov, Inst::cmovccFromCond, Gp, Mem) // CMOV
ASMJIT_INST_2x(cmp, Cmp, Gp, Gp) // ANY
ASMJIT_INST_2x(cmp, Cmp, Gp, Mem) // ANY
ASMJIT_INST_2x(cmp, Cmp, Gp, Imm) // ANY
@@ -539,8 +478,8 @@ public:
ASMJIT_INST_3x(imul, Imul, Gp, Gp, Mem) // ANY [EXPLICIT] xDX:xAX <- xAX * m16|m32|m64
ASMJIT_INST_1x(inc, Inc, Gp) // ANY
ASMJIT_INST_1x(inc, Inc, Mem) // ANY
- ASMJIT_INST_1c(j, J, Condition::toJcc, Label) // ANY
- ASMJIT_INST_1c(j, J, Condition::toJcc, Imm) // ANY
+ ASMJIT_INST_1c(j, J, Inst::jccFromCond, Label) // ANY
+ ASMJIT_INST_1c(j, J, Inst::jccFromCond, Imm) // ANY
ASMJIT_INST_2x(jecxz, Jecxz, Gp, Label) // ANY [EXPLICIT] Short jump if CX/ECX/RCX is zero.
ASMJIT_INST_2x(jecxz, Jecxz, Gp, Imm) // ANY [EXPLICIT] Short jump if CX/ECX/RCX is zero.
ASMJIT_INST_1x(jmp, Jmp, Gp) // ANY
@@ -648,8 +587,8 @@ public:
ASMJIT_INST_2x(sar, Sar, Gp, Imm) // ANY
ASMJIT_INST_2x(sar, Sar, Mem, Imm) // ANY
ASMJIT_INST_2x(scas, Scas, Gp_ZAX, ES_ZDI) // ANY [EXPLICIT]
- ASMJIT_INST_1c(set, Set, Condition::toSetcc, Gp) // ANY
- ASMJIT_INST_1c(set, Set, Condition::toSetcc, Mem) // ANY
+ ASMJIT_INST_1c(set, Set, Inst::setccFromCond, Gp) // ANY
+ ASMJIT_INST_1c(set, Set, Inst::setccFromCond, Mem) // ANY
ASMJIT_INST_2x(shl, Shl, Gp, Gp_CL) // ANY
ASMJIT_INST_2x(shl, Shl, Mem, Gp_CL) // ANY
ASMJIT_INST_2x(shl, Shl, Gp, Imm) // ANY
@@ -3720,6 +3659,227 @@ public:
//! \}
+ //! \name AVX512_FP16 Instructions
+ //! \{
+
+ ASMJIT_INST_3x(vaddph, Vaddph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vaddph, Vaddph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vaddsh, Vaddsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vaddsh, Vaddsh, Vec, Vec, Mem)
+ ASMJIT_INST_4x(vcmpph, Vcmpph, KReg, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vcmpph, Vcmpph, KReg, Vec, Mem, Imm)
+ ASMJIT_INST_4x(vcmpsh, Vcmpsh, KReg, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vcmpsh, Vcmpsh, KReg, Vec, Mem, Imm)
+ ASMJIT_INST_2x(vcomish, Vcomish, Vec, Vec)
+ ASMJIT_INST_2x(vcomish, Vcomish, Vec, Mem)
+ ASMJIT_INST_2x(vcvtdq2ph, Vcvtdq2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtdq2ph, Vcvtdq2ph, Vec, Mem)
+ ASMJIT_INST_2x(vcvtpd2ph, Vcvtpd2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtpd2ph, Vcvtpd2ph, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2dq, Vcvtph2dq, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2dq, Vcvtph2dq, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2pd, Vcvtph2pd, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2pd, Vcvtph2pd, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2psx, Vcvtph2psx, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2psx, Vcvtph2psx, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2qq, Vcvtph2qq, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2qq, Vcvtph2qq, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2udq, Vcvtph2udq, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2udq, Vcvtph2udq, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2uqq, Vcvtph2uqq, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2uqq, Vcvtph2uqq, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2uw, Vcvtph2uw, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2uw, Vcvtph2uw, Vec, Mem)
+ ASMJIT_INST_2x(vcvtph2w, Vcvtph2w, Vec, Vec)
+ ASMJIT_INST_2x(vcvtph2w, Vcvtph2w, Vec, Mem)
+ ASMJIT_INST_2x(vcvtps2phx, Vcvtps2phx, Vec, Vec)
+ ASMJIT_INST_2x(vcvtps2phx, Vcvtps2phx, Vec, Mem)
+ ASMJIT_INST_2x(vcvtqq2ph, Vcvtqq2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtqq2ph, Vcvtqq2ph, Vec, Mem)
+ ASMJIT_INST_3x(vcvtsd2sh, Vcvtsd2sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vcvtsd2sh, Vcvtsd2sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vcvtsh2sd, Vcvtsh2sd, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vcvtsh2sd, Vcvtsh2sd, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vcvtsh2si, Vcvtsh2si, Gp, Vec)
+ ASMJIT_INST_2x(vcvtsh2si, Vcvtsh2si, Gp, Mem)
+ ASMJIT_INST_3x(vcvtsh2ss, Vcvtsh2ss, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vcvtsh2ss, Vcvtsh2ss, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vcvtsh2usi, Vcvtsh2usi, Gp, Vec)
+ ASMJIT_INST_2x(vcvtsh2usi, Vcvtsh2usi, Gp, Mem)
+ ASMJIT_INST_3x(vcvtsi2sh, Vcvtsi2sh, Vec, Vec, Gp)
+ ASMJIT_INST_3x(vcvtsi2sh, Vcvtsi2sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vcvtss2sh, Vcvtss2sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vcvtss2sh, Vcvtss2sh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2dq, Vcvttph2dq, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2dq, Vcvttph2dq, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2qq, Vcvttph2qq, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2qq, Vcvttph2qq, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2udq, Vcvttph2udq, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2udq, Vcvttph2udq, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2uqq, Vcvttph2uqq, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2uqq, Vcvttph2uqq, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2uw, Vcvttph2uw, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2uw, Vcvttph2uw, Vec, Mem)
+ ASMJIT_INST_2x(vcvttph2w, Vcvttph2w, Vec, Vec)
+ ASMJIT_INST_2x(vcvttph2w, Vcvttph2w, Vec, Mem)
+ ASMJIT_INST_2x(vcvttsh2si, Vcvttsh2si, Gp, Vec)
+ ASMJIT_INST_2x(vcvttsh2si, Vcvttsh2si, Gp, Mem)
+ ASMJIT_INST_2x(vcvttsh2usi, Vcvttsh2usi, Gp, Vec)
+ ASMJIT_INST_2x(vcvttsh2usi, Vcvttsh2usi, Gp, Mem)
+ ASMJIT_INST_2x(vcvtudq2ph, Vcvtudq2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtudq2ph, Vcvtudq2ph, Vec, Mem)
+ ASMJIT_INST_2x(vcvtuqq2ph, Vcvtuqq2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtuqq2ph, Vcvtuqq2ph, Vec, Mem)
+ ASMJIT_INST_3x(vcvtusi2sh, Vcvtusi2sh, Vec, Vec, Gp)
+ ASMJIT_INST_3x(vcvtusi2sh, Vcvtusi2sh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vcvtuw2ph, Vcvtuw2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtuw2ph, Vcvtuw2ph, Vec, Mem)
+ ASMJIT_INST_2x(vcvtw2ph, Vcvtw2ph, Vec, Vec)
+ ASMJIT_INST_2x(vcvtw2ph, Vcvtw2ph, Vec, Mem)
+ ASMJIT_INST_3x(vdivph, Vdivph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vdivph, Vdivph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vdivsh, Vdivsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vdivsh, Vdivsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfcmaddcph, Vfcmaddcph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfcmaddcph, Vfcmaddcph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfcmaddcsh, Vfcmaddcsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfcmaddcsh, Vfcmaddcsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfcmulcph, Vfcmulcph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfcmulcph, Vfcmulcph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfcmulcsh, Vfcmulcsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfcmulcsh, Vfcmulcsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd132ph, Vfmadd132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd132ph, Vfmadd132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd132sh, Vfmadd132sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd132sh, Vfmadd132sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd213ph, Vfmadd213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd213ph, Vfmadd213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd213sh, Vfmadd213sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd213sh, Vfmadd213sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd231ph, Vfmadd231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd231ph, Vfmadd231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmadd231sh, Vfmadd231sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmadd231sh, Vfmadd231sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmaddcph, Vfmaddcph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmaddcph, Vfmaddcph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmaddcsh, Vfmaddcsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmaddcsh, Vfmaddcsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmaddsub132ph, Vfmaddsub132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmaddsub132ph, Vfmaddsub132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmaddsub213ph, Vfmaddsub213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmaddsub213ph, Vfmaddsub213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmaddsub231ph, Vfmaddsub231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmaddsub231ph, Vfmaddsub231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub132ph, Vfmsub132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub132ph, Vfmsub132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub132sh, Vfmsub132sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub132sh, Vfmsub132sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub213ph, Vfmsub213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub213ph, Vfmsub213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub213sh, Vfmsub213sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub213sh, Vfmsub213sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub231ph, Vfmsub231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub231ph, Vfmsub231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsub231sh, Vfmsub231sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsub231sh, Vfmsub231sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsubadd132ph, Vfmsubadd132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsubadd132ph, Vfmsubadd132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsubadd213ph, Vfmsubadd213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsubadd213ph, Vfmsubadd213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmsubadd231ph, Vfmsubadd231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmsubadd231ph, Vfmsubadd231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmulcph, Vfmulcph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmulcph, Vfmulcph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfmulcsh, Vfmulcsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfmulcsh, Vfmulcsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd132ph, Vfnmadd132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd132ph, Vfnmadd132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd132sh, Vfnmadd132sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd132sh, Vfnmadd132sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd213ph, Vfnmadd213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd213ph, Vfnmadd213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd213sh, Vfnmadd213sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd213sh, Vfnmadd213sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd231ph, Vfnmadd231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd231ph, Vfnmadd231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmadd231sh, Vfnmadd231sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmadd231sh, Vfnmadd231sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub132ph, Vfnmsub132ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub132ph, Vfnmsub132ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub132sh, Vfnmsub132sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub132sh, Vfnmsub132sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub213ph, Vfnmsub213ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub213ph, Vfnmsub213ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub213sh, Vfnmsub213sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub213sh, Vfnmsub213sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub231ph, Vfnmsub231ph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub231ph, Vfnmsub231ph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfnmsub231sh, Vfnmsub231sh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vfnmsub231sh, Vfnmsub231sh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vfpclassph, Vfpclassph, KReg, Vec, Imm)
+ ASMJIT_INST_3x(vfpclassph, Vfpclassph, KReg, Mem, Imm)
+ ASMJIT_INST_3x(vfpclasssh, Vfpclasssh, KReg, Vec, Imm)
+ ASMJIT_INST_3x(vfpclasssh, Vfpclasssh, KReg, Mem, Imm)
+ ASMJIT_INST_2x(vgetexpph, Vgetexpph, Vec, Vec)
+ ASMJIT_INST_2x(vgetexpph, Vgetexpph, Vec, Mem)
+ ASMJIT_INST_3x(vgetexpsh, Vgetexpsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vgetexpsh, Vgetexpsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vgetmantph, Vgetmantph, Vec, Vec, Imm)
+ ASMJIT_INST_3x(vgetmantph, Vgetmantph, Vec, Mem, Imm)
+ ASMJIT_INST_4x(vgetmantsh, Vgetmantsh, Vec, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vgetmantsh, Vgetmantsh, Vec, Vec, Mem, Imm)
+ ASMJIT_INST_3x(vmaxph, Vmaxph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vmaxph, Vmaxph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vmaxsh, Vmaxsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vmaxsh, Vmaxsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vminph, Vminph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vminph, Vminph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vminsh, Vminsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vminsh, Vminsh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vmovsh, Vmovsh, Mem, Xmm)
+ ASMJIT_INST_2x(vmovsh, Vmovsh, Xmm, Mem)
+ ASMJIT_INST_3x(vmovsh, Vmovsh, Xmm, Xmm, Xmm)
+ ASMJIT_INST_2x(vmovw, Vmovw, Gp, Xmm)
+ ASMJIT_INST_2x(vmovw, Vmovw, Mem, Xmm)
+ ASMJIT_INST_2x(vmovw, Vmovw, Xmm, Gp)
+ ASMJIT_INST_2x(vmovw, Vmovw, Xmm, Mem)
+ ASMJIT_INST_3x(vmulph, Vmulph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vmulph, Vmulph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vmulsh, Vmulsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vmulsh, Vmulsh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vrcpph, Vrcpph, Vec, Vec)
+ ASMJIT_INST_2x(vrcpph, Vrcpph, Vec, Mem)
+ ASMJIT_INST_3x(vrcpsh, Vrcpsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vrcpsh, Vrcpsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vreduceph, Vreduceph, Vec, Vec, Imm)
+ ASMJIT_INST_3x(vreduceph, Vreduceph, Vec, Mem, Imm)
+ ASMJIT_INST_4x(vreducesh, Vreducesh, Vec, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vreducesh, Vreducesh, Vec, Vec, Mem, Imm)
+ ASMJIT_INST_3x(vrndscaleph, Vrndscaleph, Vec, Vec, Imm)
+ ASMJIT_INST_3x(vrndscaleph, Vrndscaleph, Vec, Mem, Imm)
+ ASMJIT_INST_4x(vrndscalesh, Vrndscalesh, Vec, Vec, Vec, Imm)
+ ASMJIT_INST_4x(vrndscalesh, Vrndscalesh, Vec, Vec, Mem, Imm)
+ ASMJIT_INST_2x(vrsqrtph, Vrsqrtph, Vec, Vec)
+ ASMJIT_INST_2x(vrsqrtph, Vrsqrtph, Vec, Mem)
+ ASMJIT_INST_3x(vrsqrtsh, Vrsqrtsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vrsqrtsh, Vrsqrtsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vscalefph, Vscalefph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vscalefph, Vscalefph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vscalefsh, Vscalefsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vscalefsh, Vscalefsh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vsqrtph, Vsqrtph, Vec, Vec)
+ ASMJIT_INST_2x(vsqrtph, Vsqrtph, Vec, Mem)
+ ASMJIT_INST_3x(vsqrtsh, Vsqrtsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsqrtsh, Vsqrtsh, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vsubph, Vsubph, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsubph, Vsubph, Vec, Vec, Mem)
+ ASMJIT_INST_3x(vsubsh, Vsubsh, Vec, Vec, Vec)
+ ASMJIT_INST_3x(vsubsh, Vsubsh, Vec, Vec, Mem)
+ ASMJIT_INST_2x(vucomish, Vucomish, Vec, Vec)
+ ASMJIT_INST_2x(vucomish, Vucomish, Vec, Mem)
+
+ //! \}
+
//! \name AMX Instructions
//! \{
@@ -3740,10 +3900,6 @@ public:
//! \}
};
-// ============================================================================
-// [asmjit::x86::EmitterImplicitT]
-// ============================================================================
-
//! Emitter (X86 - implicit).
template<typename This>
struct EmitterImplicitT : public EmitterExplicitT<This> {
@@ -3755,14 +3911,14 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \{
//! Use REP/REPE prefix.
- inline This& rep() noexcept { return EmitterExplicitT<This>::_addInstOptions(Inst::kOptionRep); }
+ inline This& rep() noexcept { return EmitterExplicitT<This>::_addInstOptions(InstOptions::kX86_Rep); }
//! Use REP/REPE prefix.
inline This& repe() noexcept { return rep(); }
//! Use REP/REPE prefix.
inline This& repz() noexcept { return rep(); }
//! Use REPNE prefix.
- inline This& repne() noexcept { return EmitterExplicitT<This>::_addInstOptions(Inst::kOptionRepne); }
+ inline This& repne() noexcept { return EmitterExplicitT<This>::_addInstOptions(InstOptions::kX86_Repne); }
//! Use REPNE prefix.
inline This& repnz() noexcept { return repne(); }
@@ -4133,16 +4289,11 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \}
};
-// ============================================================================
-// [asmjit::x86::Emitter]
-// ============================================================================
-
//! Emitter (X86).
//!
-//! \note This class cannot be instantiated, you can only cast to it and use
-//! it as emitter that emits to either `x86::Assembler`, `x86::Builder`, or
-//! `x86::Compiler` (use with caution with `x86::Compiler` as it requires virtual
-//! registers).
+//! \note This class cannot be instantiated, you can only cast to it and use it as emitter that emits to either
+//! `x86::Assembler`, `x86::Builder`, or `x86::Compiler` (use with caution with `x86::Compiler` as it requires
+//! virtual registers).
class Emitter : public BaseEmitter, public EmitterImplicitT<Emitter> {
ASMJIT_NONCONSTRUCTIBLE(Emitter)
};
diff --git a/src/asmjit/x86/x86features.cpp b/src/asmjit/x86/x86features.cpp
deleted file mode 100644
index e04aebd..0000000
--- a/src/asmjit/x86/x86features.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#include "../core/api-build_p.h"
-#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
-
-#include "../core/cpuinfo.h"
-#include "../core/support.h"
-#include "../x86/x86features.h"
-
-// Required by `__cpuidex()` and `_xgetbv()`.
-#if defined(_MSC_VER)
- #include <intrin.h>
-#endif
-
-ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-
-// ============================================================================
-// [asmjit::x86::Features - Detect]
-// ============================================================================
-
-struct cpuid_t { uint32_t eax, ebx, ecx, edx; };
-struct xgetbv_t { uint32_t eax, edx; };
-
-// Executes `cpuid` instruction.
-static inline void cpuidQuery(cpuid_t* out, uint32_t inEax, uint32_t inEcx = 0) noexcept {
-#if defined(_MSC_VER)
- __cpuidex(reinterpret_cast<int*>(out), inEax, inEcx);
-#elif defined(__GNUC__) && ASMJIT_ARCH_X86 == 32
- __asm__ __volatile__(
- "mov %%ebx, %%edi\n"
- "cpuid\n"
- "xchg %%edi, %%ebx\n" : "=a"(out->eax), "=D"(out->ebx), "=c"(out->ecx), "=d"(out->edx) : "a"(inEax), "c"(inEcx));
-#elif defined(__GNUC__) && ASMJIT_ARCH_X86 == 64
- __asm__ __volatile__(
- "mov %%rbx, %%rdi\n"
- "cpuid\n"
- "xchg %%rdi, %%rbx\n" : "=a"(out->eax), "=D"(out->ebx), "=c"(out->ecx), "=d"(out->edx) : "a"(inEax), "c"(inEcx));
-#else
- #error "[asmjit] x86::cpuidQuery() - Unsupported compiler."
-#endif
-}
-
-// Executes 'xgetbv' instruction.
-static inline void xgetbvQuery(xgetbv_t* out, uint32_t inEcx) noexcept {
-#if defined(_MSC_VER)
- uint64_t value = _xgetbv(inEcx);
- out->eax = uint32_t(value & 0xFFFFFFFFu);
- out->edx = uint32_t(value >> 32);
-#elif defined(__GNUC__)
- uint32_t outEax;
- uint32_t outEdx;
-
- // Replaced, because the world is not perfect:
- // __asm__ __volatile__("xgetbv" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
- __asm__ __volatile__(".byte 0x0F, 0x01, 0xD0" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
-
- out->eax = outEax;
- out->edx = outEdx;
-#else
- out->eax = 0;
- out->edx = 0;
-#endif
-}
-
-// Map a 12-byte vendor string returned by `cpuid` into a `CpuInfo::Vendor` ID.
-static inline void simplifyCpuVendor(CpuInfo& cpu, uint32_t d0, uint32_t d1, uint32_t d2) noexcept {
- struct Vendor {
- char normalized[8];
- union { char text[12]; uint32_t d[3]; };
- };
-
- static const Vendor table[] = {
- { { 'A', 'M', 'D' }, {{ 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' }} },
- { { 'I', 'N', 'T', 'E', 'L' }, {{ 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' }} },
- { { 'V', 'I', 'A' }, {{ 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' }} },
- { { 'V', 'I', 'A' }, {{ 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 }} },
- { { 'U', 'N', 'K', 'N', 'O', 'W', 'N' }, {{ 0 }} }
- };
-
- uint32_t i;
- for (i = 0; i < ASMJIT_ARRAY_SIZE(table) - 1; i++)
- if (table[i].d[0] == d0 && table[i].d[1] == d1 && table[i].d[2] == d2)
- break;
- memcpy(cpu._vendor.str, table[i].normalized, 8);
-}
-
-static inline void simplifyCpuBrand(char* s) noexcept {
- char* d = s;
-
- char c = s[0];
- char prev = 0;
-
- // Used to always clear the current character to ensure that the result
- // doesn't contain garbage after a new null terminator is placed at the end.
- s[0] = '\0';
-
- for (;;) {
- if (!c)
- break;
-
- if (!(c == ' ' && (prev == '@' || s[1] == ' ' || s[1] == '@'))) {
- *d++ = c;
- prev = c;
- }
-
- c = *++s;
- s[0] = '\0';
- }
-
- d[0] = '\0';
-}
-
-ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
- using Support::bitTest;
-
- cpuid_t regs;
- xgetbv_t xcr0 { 0, 0 };
- Features& features = cpu._features.as<Features>();
-
- cpu.reset();
- cpu._arch = Environment::kArchHost;
- cpu._subArch = Environment::kSubArchUnknown;
- cpu._reserved = 0;
- cpu._maxLogicalProcessors = 1;
- features.add(Features::kI486);
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=0]
- // --------------------------------------------------------------------------
-
- // Get vendor string/id.
- cpuidQuery(&regs, 0x0);
-
- uint32_t maxId = regs.eax;
- uint32_t maxSubLeafId_0x7 = 0;
-
- simplifyCpuVendor(cpu, regs.ebx, regs.edx, regs.ecx);
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=1]
- // --------------------------------------------------------------------------
-
- if (maxId >= 0x1) {
- // Get feature flags in ECX/EDX and family/model in EAX.
- cpuidQuery(&regs, 0x1);
-
- // Fill family and model fields.
- uint32_t modelId = (regs.eax >> 4) & 0x0F;
- uint32_t familyId = (regs.eax >> 8) & 0x0F;
-
- // Use extended family and model fields.
- if (familyId == 0x06u || familyId == 0x0Fu)
- modelId += (((regs.eax >> 16) & 0x0Fu) << 4);
-
- if (familyId == 0x0Fu)
- familyId += ((regs.eax >> 20) & 0xFFu);
-
- cpu._modelId = modelId;
- cpu._familyId = familyId;
- cpu._brandId = ((regs.ebx ) & 0xFF);
- cpu._processorType = ((regs.eax >> 12) & 0x03);
- cpu._maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
- cpu._stepping = ((regs.eax ) & 0x0F);
- cpu._cacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8;
-
- if (bitTest(regs.ecx, 0)) features.add(Features::kSSE3);
- if (bitTest(regs.ecx, 1)) features.add(Features::kPCLMULQDQ);
- if (bitTest(regs.ecx, 3)) features.add(Features::kMONITOR);
- if (bitTest(regs.ecx, 5)) features.add(Features::kVMX);
- if (bitTest(regs.ecx, 6)) features.add(Features::kSMX);
- if (bitTest(regs.ecx, 9)) features.add(Features::kSSSE3);
- if (bitTest(regs.ecx, 13)) features.add(Features::kCMPXCHG16B);
- if (bitTest(regs.ecx, 19)) features.add(Features::kSSE4_1);
- if (bitTest(regs.ecx, 20)) features.add(Features::kSSE4_2);
- if (bitTest(regs.ecx, 22)) features.add(Features::kMOVBE);
- if (bitTest(regs.ecx, 23)) features.add(Features::kPOPCNT);
- if (bitTest(regs.ecx, 25)) features.add(Features::kAESNI);
- if (bitTest(regs.ecx, 26)) features.add(Features::kXSAVE);
- if (bitTest(regs.ecx, 27)) features.add(Features::kOSXSAVE);
- if (bitTest(regs.ecx, 30)) features.add(Features::kRDRAND);
- if (bitTest(regs.edx, 0)) features.add(Features::kFPU);
- if (bitTest(regs.edx, 4)) features.add(Features::kRDTSC);
- if (bitTest(regs.edx, 5)) features.add(Features::kMSR);
- if (bitTest(regs.edx, 8)) features.add(Features::kCMPXCHG8B);
- if (bitTest(regs.edx, 15)) features.add(Features::kCMOV);
- if (bitTest(regs.edx, 19)) features.add(Features::kCLFLUSH);
- if (bitTest(regs.edx, 23)) features.add(Features::kMMX);
- if (bitTest(regs.edx, 24)) features.add(Features::kFXSR);
- if (bitTest(regs.edx, 25)) features.add(Features::kSSE);
- if (bitTest(regs.edx, 26)) features.add(Features::kSSE, Features::kSSE2);
- if (bitTest(regs.edx, 28)) features.add(Features::kMT);
-
- // Get the content of XCR0 if supported by the CPU and enabled by the OS.
- if (features.hasXSAVE() && features.hasOSXSAVE()) {
- xgetbvQuery(&xcr0, 0);
- }
-
- // Detect AVX+.
- if (bitTest(regs.ecx, 28)) {
- // - XCR0[2:1] == 11b
- // XMM & YMM states need to be enabled by OS.
- if ((xcr0.eax & 0x00000006u) == 0x00000006u) {
- features.add(Features::kAVX);
-
- if (bitTest(regs.ecx, 12)) features.add(Features::kFMA);
- if (bitTest(regs.ecx, 29)) features.add(Features::kF16C);
- }
- }
- }
-
- constexpr uint32_t kXCR0_AMX_Bits = 0x3u << 17;
- bool amxEnabledByOS = (xcr0.eax & kXCR0_AMX_Bits) == kXCR0_AMX_Bits;
-
-#if defined(__APPLE__)
- // Apple platform provides on-demand AVX512 support. When an AVX512 instruction is used
- // the first time it results in #UD, which would cause the thread being promoted to use
- // AVX512 support by the OS in addition to enabling the necessary bits in XCR0 register.
- bool avx512EnabledByOS = true;
-#else
- // - XCR0[2:1] == 11b - XMM/YMM states need to be enabled by OS.
- // - XCR0[7:5] == 111b - Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by OS.
- constexpr uint32_t kXCR0_AVX512_Bits = (0x3u << 1) | (0x7u << 5);
- bool avx512EnabledByOS = (xcr0.eax & kXCR0_AVX512_Bits) == kXCR0_AVX512_Bits;
-#endif
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=7 ECX=0]
- // --------------------------------------------------------------------------
-
- // Detect new features if the processor supports CPUID-07.
- bool maybeMPX = false;
-
- if (maxId >= 0x7) {
- cpuidQuery(&regs, 0x7);
-
- maybeMPX = bitTest(regs.ebx, 14);
- maxSubLeafId_0x7 = regs.eax;
-
- if (bitTest(regs.ebx, 0)) features.add(Features::kFSGSBASE);
- if (bitTest(regs.ebx, 3)) features.add(Features::kBMI);
- if (bitTest(regs.ebx, 4)) features.add(Features::kHLE);
- if (bitTest(regs.ebx, 7)) features.add(Features::kSMEP);
- if (bitTest(regs.ebx, 8)) features.add(Features::kBMI2);
- if (bitTest(regs.ebx, 9)) features.add(Features::kERMS);
- if (bitTest(regs.ebx, 11)) features.add(Features::kRTM);
- if (bitTest(regs.ebx, 18)) features.add(Features::kRDSEED);
- if (bitTest(regs.ebx, 19)) features.add(Features::kADX);
- if (bitTest(regs.ebx, 20)) features.add(Features::kSMAP);
- if (bitTest(regs.ebx, 23)) features.add(Features::kCLFLUSHOPT);
- if (bitTest(regs.ebx, 24)) features.add(Features::kCLWB);
- if (bitTest(regs.ebx, 29)) features.add(Features::kSHA);
- if (bitTest(regs.ecx, 0)) features.add(Features::kPREFETCHWT1);
- if (bitTest(regs.ecx, 4)) features.add(Features::kOSPKE);
- if (bitTest(regs.ecx, 5)) features.add(Features::kWAITPKG);
- if (bitTest(regs.ecx, 7)) features.add(Features::kCET_SS);
- if (bitTest(regs.ecx, 8)) features.add(Features::kGFNI);
- if (bitTest(regs.ecx, 9)) features.add(Features::kVAES);
- if (bitTest(regs.ecx, 10)) features.add(Features::kVPCLMULQDQ);
- if (bitTest(regs.ecx, 22)) features.add(Features::kRDPID);
- if (bitTest(regs.ecx, 25)) features.add(Features::kCLDEMOTE);
- if (bitTest(regs.ecx, 27)) features.add(Features::kMOVDIRI);
- if (bitTest(regs.ecx, 28)) features.add(Features::kMOVDIR64B);
- if (bitTest(regs.ecx, 29)) features.add(Features::kENQCMD);
- if (bitTest(regs.edx, 5)) features.add(Features::kUINTR);
- if (bitTest(regs.edx, 14)) features.add(Features::kSERIALIZE);
- if (bitTest(regs.edx, 16)) features.add(Features::kTSXLDTRK);
- if (bitTest(regs.edx, 18)) features.add(Features::kPCONFIG);
- if (bitTest(regs.edx, 20)) features.add(Features::kCET_IBT);
-
- // Detect 'TSX' - Requires at least one of `HLE` and `RTM` features.
- if (features.hasHLE() || features.hasRTM())
- features.add(Features::kTSX);
-
- // Detect 'AVX2' - Requires AVX as well.
- if (bitTest(regs.ebx, 5) && features.hasAVX())
- features.add(Features::kAVX2);
-
- // Detect 'AMX'.
- if (amxEnabledByOS) {
- if (bitTest(regs.edx, 22)) features.add(Features::kAMX_BF16);
- if (bitTest(regs.edx, 24)) features.add(Features::kAMX_TILE);
- if (bitTest(regs.edx, 25)) features.add(Features::kAMX_INT8);
- }
-
- // Detect 'AVX_512'.
- if (avx512EnabledByOS && bitTest(regs.ebx, 16)) {
- features.add(Features::kAVX512_F);
-
- if (bitTest(regs.ebx, 17)) features.add(Features::kAVX512_DQ);
- if (bitTest(regs.ebx, 21)) features.add(Features::kAVX512_IFMA);
- if (bitTest(regs.ebx, 26)) features.add(Features::kAVX512_PFI);
- if (bitTest(regs.ebx, 27)) features.add(Features::kAVX512_ERI);
- if (bitTest(regs.ebx, 28)) features.add(Features::kAVX512_CDI);
- if (bitTest(regs.ebx, 30)) features.add(Features::kAVX512_BW);
- if (bitTest(regs.ebx, 31)) features.add(Features::kAVX512_VL);
- if (bitTest(regs.ecx, 1)) features.add(Features::kAVX512_VBMI);
- if (bitTest(regs.ecx, 6)) features.add(Features::kAVX512_VBMI2);
- if (bitTest(regs.ecx, 11)) features.add(Features::kAVX512_VNNI);
- if (bitTest(regs.ecx, 12)) features.add(Features::kAVX512_BITALG);
- if (bitTest(regs.ecx, 14)) features.add(Features::kAVX512_VPOPCNTDQ);
- if (bitTest(regs.edx, 2)) features.add(Features::kAVX512_4VNNIW);
- if (bitTest(regs.edx, 3)) features.add(Features::kAVX512_4FMAPS);
- if (bitTest(regs.edx, 8)) features.add(Features::kAVX512_VP2INTERSECT);
- }
- }
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=7 ECX=1]
- // --------------------------------------------------------------------------
-
- if (features.hasAVX512_F() && maxSubLeafId_0x7 >= 1) {
- cpuidQuery(&regs, 0x7, 1);
-
- if (bitTest(regs.eax, 3)) features.add(Features::kAVX_VNNI);
- if (bitTest(regs.eax, 5)) features.add(Features::kAVX512_BF16);
- if (bitTest(regs.eax, 22)) features.add(Features::kHRESET);
- }
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=13 ECX=0]
- // --------------------------------------------------------------------------
-
- if (maxId >= 0xD) {
- cpuidQuery(&regs, 0xD, 0);
-
- // Both CPUID result and XCR0 has to be enabled to have support for MPX.
- if (((regs.eax & xcr0.eax) & 0x00000018u) == 0x00000018u && maybeMPX)
- features.add(Features::kMPX);
-
- cpuidQuery(&regs, 0xD, 1);
-
- if (bitTest(regs.eax, 0)) features.add(Features::kXSAVEOPT);
- if (bitTest(regs.eax, 1)) features.add(Features::kXSAVEC);
- if (bitTest(regs.eax, 3)) features.add(Features::kXSAVES);
- }
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=14 ECX=0]
- // --------------------------------------------------------------------------
-
- if (maxId >= 0xE) {
- cpuidQuery(&regs, 0xE, 0);
-
- if (bitTest(regs.ebx, 4)) features.add(Features::kPTWRITE);
- }
-
- // --------------------------------------------------------------------------
- // [CPUID EAX=0x80000000...maxId]
- // --------------------------------------------------------------------------
-
- maxId = 0x80000000u;
- uint32_t i = maxId;
-
- // The highest EAX that we understand.
- uint32_t kHighestProcessedEAX = 0x8000001Fu;
-
- // Several CPUID calls are required to get the whole branc string. It's easy
- // to copy one DWORD at a time instead of performing a byte copy.
- uint32_t* brand = cpu._brand.u32;
- do {
- cpuidQuery(&regs, i);
- switch (i) {
- case 0x80000000u:
- maxId = Support::min<uint32_t>(regs.eax, kHighestProcessedEAX);
- break;
-
- case 0x80000001u:
- if (bitTest(regs.ecx, 0)) features.add(Features::kLAHFSAHF);
- if (bitTest(regs.ecx, 2)) features.add(Features::kSVM);
- if (bitTest(regs.ecx, 5)) features.add(Features::kLZCNT);
- if (bitTest(regs.ecx, 6)) features.add(Features::kSSE4A);
- if (bitTest(regs.ecx, 7)) features.add(Features::kMSSE);
- if (bitTest(regs.ecx, 8)) features.add(Features::kPREFETCHW);
- if (bitTest(regs.ecx, 12)) features.add(Features::kSKINIT);
- if (bitTest(regs.ecx, 15)) features.add(Features::kLWP);
- if (bitTest(regs.ecx, 21)) features.add(Features::kTBM);
- if (bitTest(regs.ecx, 29)) features.add(Features::kMONITORX);
- if (bitTest(regs.edx, 20)) features.add(Features::kNX);
- if (bitTest(regs.edx, 21)) features.add(Features::kFXSROPT);
- if (bitTest(regs.edx, 22)) features.add(Features::kMMX2);
- if (bitTest(regs.edx, 27)) features.add(Features::kRDTSCP);
- if (bitTest(regs.edx, 29)) features.add(Features::kPREFETCHW);
- if (bitTest(regs.edx, 30)) features.add(Features::k3DNOW2, Features::kMMX2);
- if (bitTest(regs.edx, 31)) features.add(Features::kPREFETCHW);
-
- if (cpu.hasFeature(Features::kAVX)) {
- if (bitTest(regs.ecx, 11)) features.add(Features::kXOP);
- if (bitTest(regs.ecx, 16)) features.add(Features::kFMA4);
- }
-
- // These seem to be only supported by AMD.
- if (cpu.isVendor("AMD")) {
- if (bitTest(regs.ecx, 4)) features.add(Features::kALTMOVCR8);
- }
- break;
-
- case 0x80000002u:
- case 0x80000003u:
- case 0x80000004u:
- *brand++ = regs.eax;
- *brand++ = regs.ebx;
- *brand++ = regs.ecx;
- *brand++ = regs.edx;
-
- // Go directly to the next one we are interested in.
- if (i == 0x80000004u) i = 0x80000008u - 1;
- break;
-
- case 0x80000008u:
- if (bitTest(regs.ebx, 0)) features.add(Features::kCLZERO);
- if (bitTest(regs.ebx, 0)) features.add(Features::kRDPRU);
- if (bitTest(regs.ebx, 8)) features.add(Features::kMCOMMIT);
- if (bitTest(regs.ebx, 9)) features.add(Features::kWBNOINVD);
-
- // Go directly to the next one we are interested in.
- i = 0x8000001Fu - 1;
- break;
-
- case 0x8000001Fu:
- if (bitTest(regs.eax, 4)) features.add(Features::kSNP);
- break;
- }
- } while (++i <= maxId);
-
- // Simplify CPU brand string a bit by removing some unnecessary spaces.
- simplifyCpuBrand(cpu._brand.str);
-}
-
-ASMJIT_END_SUB_NAMESPACE
-
-#endif // !ASMJIT_NO_X86 && ASMJIT_ARCH_X86
diff --git a/src/asmjit/x86/x86features.h b/src/asmjit/x86/x86features.h
deleted file mode 100644
index 4d098ec..0000000
--- a/src/asmjit/x86/x86features.h
+++ /dev/null
@@ -1,318 +0,0 @@
-// AsmJit - Machine code generation for C++
-//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-
-#ifndef ASMJIT_X86_X86FEATURES_H_INCLUDED
-#define ASMJIT_X86_X86FEATURES_H_INCLUDED
-
-#include "../core/features.h"
-
-ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-
-//! \addtogroup asmjit_x86
-//! \{
-
-// ============================================================================
-// [asmjit::x86::Features]
-// ============================================================================
-
-//! CPU features (X86).
-class Features : public BaseFeatures {
-public:
- //! CPU feature ID.
- enum Id : uint32_t {
- // @EnumValuesBegin{"enum": "x86::Features::Id"}@
-
- kNone = 0, //!< No feature (never set, used internally).
-
- kMT, //!< CPU has multi-threading capabilities.
- kNX, //!< CPU has Not-Execute-Bit aka DEP (data-execution prevention).
-
- k3DNOW, //!< CPU has 3DNOW (3DNOW base instructions) [AMD].
- k3DNOW2, //!< CPU has 3DNOW2 (enhanced 3DNOW) [AMD].
- kADX, //!< CPU has ADX (multi-precision add-carry instruction extensions).
- kAESNI, //!< CPU has AESNI (AES encode/decode instructions).
- kALTMOVCR8, //!< CPU has LOCK MOV R<->CR0 (supports `MOV R<->CR8` via `LOCK MOV R<->CR0` in 32-bit mode) [AMD].
- kAMX_BF16, //!< CPU has AMX_BF16 (advanced matrix extensions - BF16 instructions).
- kAMX_INT8, //!< CPU has AMX_INT8 (advanced matrix extensions - INT8 instructions).
- kAMX_TILE, //!< CPU has AMX_TILE (advanced matrix extensions).
- kAVX, //!< CPU has AVX (advanced vector extensions).
- kAVX2, //!< CPU has AVX2 (advanced vector extensions 2).
- kAVX512_4FMAPS, //!< CPU has AVX512_FMAPS (FMA packed single).
- kAVX512_4VNNIW, //!< CPU has AVX512_VNNIW (vector NN instructions word variable precision).
- kAVX512_BF16, //!< CPU has AVX512_BF16 (BFLOAT16 support instruction).
- kAVX512_BITALG, //!< CPU has AVX512_BITALG (VPOPCNT[B|W], VPSHUFBITQMB).
- kAVX512_BW, //!< CPU has AVX512_BW (packed BYTE|WORD).
- kAVX512_CDI, //!< CPU has AVX512_CDI (conflict detection).
- kAVX512_DQ, //!< CPU has AVX512_DQ (packed DWORD|QWORD).
- kAVX512_ERI, //!< CPU has AVX512_ERI (exponential and reciprocal).
- kAVX512_F, //!< CPU has AVX512_F (AVX512 foundation).
- kAVX512_IFMA, //!< CPU has AVX512_IFMA (integer fused-multiply-add using 52-bit precision).
- kAVX512_PFI, //!< CPU has AVX512_PFI (prefetch instructions).
- kAVX512_VBMI, //!< CPU has AVX512_VBMI (vector byte manipulation).
- kAVX512_VBMI2, //!< CPU has AVX512_VBMI2 (vector byte manipulation 2).
- kAVX512_VL, //!< CPU has AVX512_VL (vector length extensions).
- kAVX512_VNNI, //!< CPU has AVX512_VNNI (vector neural network instructions).
- kAVX512_VP2INTERSECT, //!< CPU has AVX512_VP2INTERSECT
- kAVX512_VPOPCNTDQ, //!< CPU has AVX512_VPOPCNTDQ (VPOPCNT[D|Q] instructions).
- kAVX_VNNI, //!< CPU has AVX_VNNI (VEX encoding of vpdpbusd/vpdpbusds/vpdpwssd/vpdpwssds).
- kBMI, //!< CPU has BMI (bit manipulation instructions #1).
- kBMI2, //!< CPU has BMI2 (bit manipulation instructions #2).
- kCET_IBT, //!< CPU has CET-IBT (indirect branch tracking).
- kCET_SS, //!< CPU has CET-SS.
- kCLDEMOTE, //!< CPU has CLDEMOTE (cache line demote).
- kCLFLUSH, //!< CPU has CLFUSH (Cache Line flush).
- kCLFLUSHOPT, //!< CPU has CLFUSHOPT (Cache Line flush - optimized).
- kCLWB, //!< CPU has CLWB.
- kCLZERO, //!< CPU has CLZERO.
- kCMOV, //!< CPU has CMOV (CMOV and FCMOV instructions).
- kCMPXCHG16B, //!< CPU has CMPXCHG16B (compare-exchange 16 bytes) [X86_64].
- kCMPXCHG8B, //!< CPU has CMPXCHG8B (compare-exchange 8 bytes).
- kENCLV, //!< CPU has ENCLV.
- kENQCMD, //!< CPU has ENQCMD (enqueue stores).
- kERMS, //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
- kF16C, //!< CPU has F16C.
- kFMA, //!< CPU has FMA (fused-multiply-add 3 operand form).
- kFMA4, //!< CPU has FMA4 (fused-multiply-add 4 operand form).
- kFPU, //!< CPU has FPU (FPU support).
- kFSGSBASE, //!< CPU has FSGSBASE.
- kFXSR, //!< CPU has FXSR (FXSAVE/FXRSTOR instructions).
- kFXSROPT, //!< CPU has FXSROTP (FXSAVE/FXRSTOR is optimized).
- kGEODE, //!< CPU has GEODE extensions (3DNOW additions).
- kGFNI, //!< CPU has GFNI (Galois field instructions).
- kHLE, //!< CPU has HLE.
- kHRESET, //!< CPU has HRESET.
- kI486, //!< CPU has I486 features (I486+ support).
- kLAHFSAHF, //!< CPU has LAHF/SAHF (LAHF/SAHF in 64-bit mode) [X86_64].
- kLWP, //!< CPU has LWP (lightweight profiling) [AMD].
- kLZCNT, //!< CPU has LZCNT (LZCNT instruction).
- kMCOMMIT, //!< CPU has MCOMMIT (MCOMMIT instruction).
- kMMX, //!< CPU has MMX (MMX base instructions).
- kMMX2, //!< CPU has MMX2 (MMX extensions or MMX2).
- kMONITOR, //!< CPU has MONITOR (MONITOR/MWAIT instructions).
- kMONITORX, //!< CPU has MONITORX (MONITORX/MWAITX instructions).
- kMOVBE, //!< CPU has MOVBE (move with byte-order swap).
- kMOVDIR64B, //!< CPU has MOVDIR64B (move 64 bytes as direct store).
- kMOVDIRI, //!< CPU has MOVDIRI (move dword/qword as direct store).
- kMPX, //!< CPU has MPX (memory protection extensions).
- kMSR, //!< CPU has MSR (RDMSR/WRMSR instructions).
- kMSSE, //!< CPU has MSSE (misaligned SSE support).
- kOSXSAVE, //!< CPU has OSXSAVE (XSAVE enabled by OS).
- kOSPKE, //!< CPU has OSPKE (PKE enabled by OS).
- kPCLMULQDQ, //!< CPU has PCLMULQDQ (packed carry-less multiplication).
- kPCONFIG, //!< CPU has PCONFIG (PCONFIG instruction).
- kPOPCNT, //!< CPU has POPCNT (POPCNT instruction).
- kPREFETCHW, //!< CPU has PREFETCHW.
- kPREFETCHWT1, //!< CPU has PREFETCHWT1.
- kPTWRITE, //!< CPU has PTWRITE.
- kRDPID, //!< CPU has RDPID.
- kRDPRU, //!< CPU has RDPRU.
- kRDRAND, //!< CPU has RDRAND.
- kRDSEED, //!< CPU has RDSEED.
- kRDTSC, //!< CPU has RDTSC.
- kRDTSCP, //!< CPU has RDTSCP.
- kRTM, //!< CPU has RTM.
- kSERIALIZE, //!< CPU has SERIALIZE.
- kSHA, //!< CPU has SHA (SHA-1 and SHA-256 instructions).
- kSKINIT, //!< CPU has SKINIT (SKINIT/STGI instructions) [AMD].
- kSMAP, //!< CPU has SMAP (supervisor-mode access prevention).
- kSMEP, //!< CPU has SMEP (supervisor-mode execution prevention).
- kSMX, //!< CPU has SMX (safer mode extensions).
- kSNP, //!< CPU has SNP.
- kSSE, //!< CPU has SSE.
- kSSE2, //!< CPU has SSE2.
- kSSE3, //!< CPU has SSE3.
- kSSE4_1, //!< CPU has SSE4.1.
- kSSE4_2, //!< CPU has SSE4.2.
- kSSE4A, //!< CPU has SSE4A [AMD].
- kSSSE3, //!< CPU has SSSE3.
- kSVM, //!< CPU has SVM (virtualization) [AMD].
- kTBM, //!< CPU has TBM (trailing bit manipulation) [AMD].
- kTSX, //!< CPU has TSX.
- kTSXLDTRK, //!< CPU has TSXLDTRK.
- kUINTR, //!< CPU has UINTR (user interrupts).
- kVAES, //!< CPU has VAES (vector AES 256|512 bit support).
- kVMX, //!< CPU has VMX (virtualization) [INTEL].
- kVPCLMULQDQ, //!< CPU has VPCLMULQDQ (vector PCLMULQDQ 256|512-bit support).
- kWAITPKG, //!< CPU has WAITPKG (UMONITOR, UMWAIT, TPAUSE).
- kWBNOINVD, //!< CPU has WBNOINVD.
- kXOP, //!< CPU has XOP (XOP instructions) [AMD].
- kXSAVE, //!< CPU has XSAVE.
- kXSAVEC, //!< CPU has XSAVEC.
- kXSAVEOPT, //!< CPU has XSAVEOPT.
- kXSAVES, //!< CPU has XSAVES.
-
- // @EnumValuesEnd@
-
- kCount //!< Count of X86 CPU features.
- };
-
- //! \name Construction / Destruction
- //! \{
-
- inline Features() noexcept
- : BaseFeatures() {}
-
- inline Features(const Features& other) noexcept
- : BaseFeatures(other) {}
-
- //! \}
-
- //! \name Overloaded Operators
- //! \{
-
- inline Features& operator=(const Features& other) noexcept = default;
-
- //! \}
-
- //! \name Accessors
- //! \{
-
- #define ASMJIT_X86_FEATURE(FEATURE) \
- inline bool has##FEATURE() const noexcept { return has(k##FEATURE); }
-
- ASMJIT_X86_FEATURE(MT)
- ASMJIT_X86_FEATURE(NX)
-
- ASMJIT_X86_FEATURE(3DNOW)
- ASMJIT_X86_FEATURE(3DNOW2)
- ASMJIT_X86_FEATURE(ADX)
- ASMJIT_X86_FEATURE(AESNI)
- ASMJIT_X86_FEATURE(ALTMOVCR8)
- ASMJIT_X86_FEATURE(AMX_BF16)
- ASMJIT_X86_FEATURE(AMX_INT8)
- ASMJIT_X86_FEATURE(AMX_TILE)
- ASMJIT_X86_FEATURE(AVX)
- ASMJIT_X86_FEATURE(AVX2)
- ASMJIT_X86_FEATURE(AVX512_4FMAPS)
- ASMJIT_X86_FEATURE(AVX512_4VNNIW)
- ASMJIT_X86_FEATURE(AVX512_BF16)
- ASMJIT_X86_FEATURE(AVX512_BITALG)
- ASMJIT_X86_FEATURE(AVX512_BW)
- ASMJIT_X86_FEATURE(AVX512_CDI)
- ASMJIT_X86_FEATURE(AVX512_DQ)
- ASMJIT_X86_FEATURE(AVX512_ERI)
- ASMJIT_X86_FEATURE(AVX512_F)
- ASMJIT_X86_FEATURE(AVX512_IFMA)
- ASMJIT_X86_FEATURE(AVX512_PFI)
- ASMJIT_X86_FEATURE(AVX512_VBMI)
- ASMJIT_X86_FEATURE(AVX512_VBMI2)
- ASMJIT_X86_FEATURE(AVX512_VL)
- ASMJIT_X86_FEATURE(AVX512_VNNI)
- ASMJIT_X86_FEATURE(AVX512_VP2INTERSECT)
- ASMJIT_X86_FEATURE(AVX512_VPOPCNTDQ)
- ASMJIT_X86_FEATURE(AVX_VNNI)
- ASMJIT_X86_FEATURE(BMI)
- ASMJIT_X86_FEATURE(BMI2)
- ASMJIT_X86_FEATURE(CET_IBT)
- ASMJIT_X86_FEATURE(CET_SS)
- ASMJIT_X86_FEATURE(CLDEMOTE)
- ASMJIT_X86_FEATURE(CLFLUSH)
- ASMJIT_X86_FEATURE(CLFLUSHOPT)
- ASMJIT_X86_FEATURE(CLWB)
- ASMJIT_X86_FEATURE(CLZERO)
- ASMJIT_X86_FEATURE(CMOV)
- ASMJIT_X86_FEATURE(CMPXCHG16B)
- ASMJIT_X86_FEATURE(CMPXCHG8B)
- ASMJIT_X86_FEATURE(ENCLV)
- ASMJIT_X86_FEATURE(ENQCMD)
- ASMJIT_X86_FEATURE(ERMS)
- ASMJIT_X86_FEATURE(F16C)
- ASMJIT_X86_FEATURE(FMA)
- ASMJIT_X86_FEATURE(FMA4)
- ASMJIT_X86_FEATURE(FPU)
- ASMJIT_X86_FEATURE(FSGSBASE)
- ASMJIT_X86_FEATURE(FXSR)
- ASMJIT_X86_FEATURE(FXSROPT)
- ASMJIT_X86_FEATURE(GEODE)
- ASMJIT_X86_FEATURE(GFNI)
- ASMJIT_X86_FEATURE(HLE)
- ASMJIT_X86_FEATURE(HRESET)
- ASMJIT_X86_FEATURE(I486)
- ASMJIT_X86_FEATURE(LAHFSAHF)
- ASMJIT_X86_FEATURE(LWP)
- ASMJIT_X86_FEATURE(LZCNT)
- ASMJIT_X86_FEATURE(MCOMMIT)
- ASMJIT_X86_FEATURE(MMX)
- ASMJIT_X86_FEATURE(MMX2)
- ASMJIT_X86_FEATURE(MONITOR)
- ASMJIT_X86_FEATURE(MONITORX)
- ASMJIT_X86_FEATURE(MOVBE)
- ASMJIT_X86_FEATURE(MOVDIR64B)
- ASMJIT_X86_FEATURE(MOVDIRI)
- ASMJIT_X86_FEATURE(MPX)
- ASMJIT_X86_FEATURE(MSR)
- ASMJIT_X86_FEATURE(MSSE)
- ASMJIT_X86_FEATURE(OSXSAVE)
- ASMJIT_X86_FEATURE(PCLMULQDQ)
- ASMJIT_X86_FEATURE(PCONFIG)
- ASMJIT_X86_FEATURE(POPCNT)
- ASMJIT_X86_FEATURE(PREFETCHW)
- ASMJIT_X86_FEATURE(PREFETCHWT1)
- ASMJIT_X86_FEATURE(PTWRITE)
- ASMJIT_X86_FEATURE(RDPID)
- ASMJIT_X86_FEATURE(RDPRU)
- ASMJIT_X86_FEATURE(RDRAND)
- ASMJIT_X86_FEATURE(RDSEED)
- ASMJIT_X86_FEATURE(RDTSC)
- ASMJIT_X86_FEATURE(RDTSCP)
- ASMJIT_X86_FEATURE(RTM)
- ASMJIT_X86_FEATURE(SERIALIZE)
- ASMJIT_X86_FEATURE(SHA)
- ASMJIT_X86_FEATURE(SKINIT)
- ASMJIT_X86_FEATURE(SMAP)
- ASMJIT_X86_FEATURE(SMEP)
- ASMJIT_X86_FEATURE(SMX)
- ASMJIT_X86_FEATURE(SNP)
- ASMJIT_X86_FEATURE(SSE)
- ASMJIT_X86_FEATURE(SSE2)
- ASMJIT_X86_FEATURE(SSE3)
- ASMJIT_X86_FEATURE(SSSE3)
- ASMJIT_X86_FEATURE(SSE4A)
- ASMJIT_X86_FEATURE(SSE4_1)
- ASMJIT_X86_FEATURE(SSE4_2)
- ASMJIT_X86_FEATURE(SVM)
- ASMJIT_X86_FEATURE(TBM)
- ASMJIT_X86_FEATURE(TSX)
- ASMJIT_X86_FEATURE(TSXLDTRK)
- ASMJIT_X86_FEATURE(UINTR)
- ASMJIT_X86_FEATURE(XSAVE)
- ASMJIT_X86_FEATURE(XSAVEC)
- ASMJIT_X86_FEATURE(XSAVEOPT)
- ASMJIT_X86_FEATURE(XSAVES)
- ASMJIT_X86_FEATURE(VAES)
- ASMJIT_X86_FEATURE(VMX)
- ASMJIT_X86_FEATURE(VPCLMULQDQ)
- ASMJIT_X86_FEATURE(WAITPKG)
- ASMJIT_X86_FEATURE(WBNOINVD)
- ASMJIT_X86_FEATURE(XOP)
-
- #undef ASMJIT_X86_FEATURE
-
- //! \}
-};
-
-//! \}
-
-ASMJIT_END_SUB_NAMESPACE
-
-#endif // ASMJIT_X86_X86FEATURES_H_INCLUDED
diff --git a/src/asmjit/x86/x86formatter.cpp b/src/asmjit/x86/x86formatter.cpp
index 2ae0f94..b667019 100644
--- a/src/asmjit/x86/x86formatter.cpp
+++ b/src/asmjit/x86/x86formatter.cpp
@@ -1,32 +1,14 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_LOGGING
+#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
#include "../core/support.h"
-#include "../x86/x86features.h"
#include "../x86/x86formatter_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86operand.h"
@@ -37,9 +19,8 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Constants]
-// ============================================================================
+// x86::FormatterInternal - Constants
+// ==================================
struct RegFormatInfo {
struct TypeEntry {
@@ -53,67 +34,67 @@ struct RegFormatInfo {
uint8_t specialCount;
};
- TypeEntry typeEntries[BaseReg::kTypeMax + 1];
+ TypeEntry typeEntries[uint32_t(RegType::kMaxValue) + 1];
char typeStrings[128 - 32];
- NameEntry nameEntries[BaseReg::kTypeMax + 1];
+ NameEntry nameEntries[uint32_t(RegType::kMaxValue) + 1];
char nameStrings[280];
};
template<uint32_t X>
struct RegFormatInfo_T {
enum {
- kTypeIndex = X == Reg::kTypeGpbLo ? 1 :
- X == Reg::kTypeGpbHi ? 8 :
- X == Reg::kTypeGpw ? 15 :
- X == Reg::kTypeGpd ? 19 :
- X == Reg::kTypeGpq ? 23 :
- X == Reg::kTypeXmm ? 27 :
- X == Reg::kTypeYmm ? 31 :
- X == Reg::kTypeZmm ? 35 :
- X == Reg::kTypeMm ? 50 :
- X == Reg::kTypeKReg ? 53 :
- X == Reg::kTypeSReg ? 43 :
- X == Reg::kTypeCReg ? 59 :
- X == Reg::kTypeDReg ? 62 :
- X == Reg::kTypeSt ? 47 :
- X == Reg::kTypeBnd ? 55 :
- X == Reg::kTypeTmm ? 65 :
- X == Reg::kTypeRip ? 39 : 0,
-
- kFormatIndex = X == Reg::kTypeGpbLo ? 1 :
- X == Reg::kTypeGpbHi ? 6 :
- X == Reg::kTypeGpw ? 11 :
- X == Reg::kTypeGpd ? 16 :
- X == Reg::kTypeGpq ? 21 :
- X == Reg::kTypeXmm ? 25 :
- X == Reg::kTypeYmm ? 31 :
- X == Reg::kTypeZmm ? 37 :
- X == Reg::kTypeMm ? 60 :
- X == Reg::kTypeKReg ? 65 :
- X == Reg::kTypeSReg ? 49 :
- X == Reg::kTypeCReg ? 75 :
- X == Reg::kTypeDReg ? 80 :
- X == Reg::kTypeSt ? 55 :
- X == Reg::kTypeBnd ? 69 :
- X == Reg::kTypeTmm ? 89 :
- X == Reg::kTypeRip ? 43 : 0,
-
- kSpecialIndex = X == Reg::kTypeGpbLo ? 96 :
- X == Reg::kTypeGpbHi ? 128 :
- X == Reg::kTypeGpw ? 161 :
- X == Reg::kTypeGpd ? 160 :
- X == Reg::kTypeGpq ? 192 :
- X == Reg::kTypeSReg ? 224 :
- X == Reg::kTypeRip ? 85 : 0,
-
- kSpecialCount = X == Reg::kTypeGpbLo ? 8 :
- X == Reg::kTypeGpbHi ? 4 :
- X == Reg::kTypeGpw ? 8 :
- X == Reg::kTypeGpd ? 8 :
- X == Reg::kTypeGpq ? 8 :
- X == Reg::kTypeSReg ? 7 :
- X == Reg::kTypeRip ? 1 : 0
+ kTypeIndex = X == uint32_t(RegType::kX86_GpbLo) ? 1 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 8 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 15 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 19 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 23 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 27 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 31 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 35 :
+ X == uint32_t(RegType::kX86_Mm ) ? 50 :
+ X == uint32_t(RegType::kX86_KReg ) ? 53 :
+ X == uint32_t(RegType::kX86_SReg ) ? 43 :
+ X == uint32_t(RegType::kX86_CReg ) ? 59 :
+ X == uint32_t(RegType::kX86_DReg ) ? 62 :
+ X == uint32_t(RegType::kX86_St ) ? 47 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 55 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 65 :
+ X == uint32_t(RegType::kX86_Rip ) ? 39 : 0,
+
+ kFormatIndex = X == uint32_t(RegType::kX86_GpbLo) ? 1 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 6 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 11 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 16 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 21 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 25 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 31 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 37 :
+ X == uint32_t(RegType::kX86_Mm ) ? 60 :
+ X == uint32_t(RegType::kX86_KReg ) ? 65 :
+ X == uint32_t(RegType::kX86_SReg ) ? 49 :
+ X == uint32_t(RegType::kX86_CReg ) ? 75 :
+ X == uint32_t(RegType::kX86_DReg ) ? 80 :
+ X == uint32_t(RegType::kX86_St ) ? 55 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 69 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 89 :
+ X == uint32_t(RegType::kX86_Rip ) ? 43 : 0,
+
+ kSpecialIndex = X == uint32_t(RegType::kX86_GpbLo) ? 96 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 128 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 161 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 160 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 192 :
+ X == uint32_t(RegType::kX86_SReg ) ? 224 :
+ X == uint32_t(RegType::kX86_Rip ) ? 85 : 0,
+
+ kSpecialCount = X == uint32_t(RegType::kX86_GpbLo) ? 8 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 4 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 8 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 8 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 8 :
+ X == uint32_t(RegType::kX86_SReg ) ? 7 :
+ X == uint32_t(RegType::kX86_Rip ) ? 1 : 0
};
};
@@ -122,7 +103,7 @@ struct RegFormatInfo_T {
}
#define ASMJIT_REG_NAME_ENTRY(TYPE) { \
- RegTraits<TYPE>::kCount, \
+ RegTraits<RegType(TYPE)>::kCount, \
RegFormatInfo_T<TYPE>::kFormatIndex, \
RegFormatInfo_T<TYPE>::kSpecialIndex, \
RegFormatInfo_T<TYPE>::kSpecialCount \
@@ -201,12 +182,11 @@ static const char* x86GetAddressSizeString(uint32_t size) noexcept {
}
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Feature]
-// ============================================================================
+// x86::FormatterInternal - Format FeatureId
+// =========================================
Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept {
- // @EnumStringBegin{"enum": "x86::Features::Id", "output": "sFeature", "strip": "k"}@
+ // @EnumStringBegin{"enum": "CpuFeatures::X86", "output": "sFeature", "strip": "k"}@
static const char sFeatureString[] =
"None\0"
"MT\0"
@@ -230,6 +210,7 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"AVX512_DQ\0"
"AVX512_ERI\0"
"AVX512_F\0"
+ "AVX512_FP16\0"
"AVX512_IFMA\0"
"AVX512_PFI\0"
"AVX512_VBMI\0"
@@ -328,43 +309,42 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
static const uint16_t sFeatureIndex[] = {
0, 5, 8, 11, 17, 24, 28, 34, 44, 53, 62, 71, 75, 80, 94, 108, 120, 134, 144,
- 155, 165, 176, 185, 197, 208, 220, 233, 243, 255, 275, 292, 301, 305, 310,
- 318, 325, 334, 342, 353, 358, 365, 370, 381, 391, 397, 404, 409, 414, 418,
- 423, 427, 436, 441, 449, 455, 460, 464, 471, 476, 485, 489, 495, 503, 507,
- 512, 520, 529, 535, 545, 553, 557, 561, 566, 574, 580, 590, 598, 605, 615,
- 627, 635, 641, 647, 654, 661, 667, 674, 678, 688, 692, 699, 704, 709, 713,
- 717, 721, 726, 731, 738, 745, 751, 757, 761, 765, 769, 778, 784, 789, 793,
- 804, 812, 821, 825, 831, 838, 847, 854
+ 155, 165, 176, 185, 197, 209, 220, 232, 245, 255, 267, 287, 304, 313, 317,
+ 322, 330, 337, 346, 354, 365, 370, 377, 382, 393, 403, 409, 416, 421, 426,
+ 430, 435, 439, 448, 453, 461, 467, 472, 476, 483, 488, 497, 501, 507, 515,
+ 519, 524, 532, 541, 547, 557, 565, 569, 573, 578, 586, 592, 602, 610, 617,
+ 627, 639, 647, 653, 659, 666, 673, 679, 686, 690, 700, 704, 711, 716, 721,
+ 725, 729, 733, 738, 743, 750, 757, 763, 769, 773, 777, 781, 790, 796, 801,
+ 805, 816, 824, 833, 837, 843, 850, 859, 866
};
// @EnumStringEnd@
- return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, x86::Features::kCount)]);
+ return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, uint32_t(CpuFeatures::X86::kMaxValue) + 1)]);
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Register]
-// ============================================================================
+// x86::FormatterInternal - Format Register
+// ========================================
-ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, uint32_t flags, const BaseEmitter* emitter, uint32_t arch, uint32_t rType, uint32_t rId) noexcept {
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, FormatFlags formatFlags, const BaseEmitter* emitter, Arch arch, RegType type, uint32_t id) noexcept {
DebugUtils::unused(arch);
const RegFormatInfo& info = x86RegFormatInfo;
#ifndef ASMJIT_NO_COMPILER
- if (Operand::isVirtId(rId)) {
- if (emitter && emitter->emitterType() == BaseEmitter::kTypeCompiler) {
+ if (Operand::isVirtId(id)) {
+ if (emitter && emitter->emitterType() == EmitterType::kCompiler) {
const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
- if (cc->isVirtIdValid(rId)) {
- VirtReg* vReg = cc->virtRegById(rId);
+ if (cc->isVirtIdValid(id)) {
+ VirtReg* vReg = cc->virtRegById(id);
ASMJIT_ASSERT(vReg != nullptr);
const char* name = vReg->name();
if (name && name[0] != '\0')
ASMJIT_PROPAGATE(sb.append(name));
else
- ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(rId))));
+ ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(id))));
- if (vReg->type() != rType && rType <= BaseReg::kTypeMax && (flags & FormatOptions::kFlagRegCasts) != 0) {
- const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[rType];
+ if (vReg->type() != type && uint32_t(type) <= uint32_t(RegType::kMaxValue) && Support::test(formatFlags, FormatFlags::kRegCasts)) {
+ const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)];
if (typeEntry.index)
ASMJIT_PROPAGATE(sb.appendFormat("@%s", info.typeStrings + typeEntry.index));
}
@@ -374,39 +354,38 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, uint32_t f
}
}
#else
- DebugUtils::unused(emitter, flags);
+ DebugUtils::unused(emitter, formatFlags);
#endif
- if (ASMJIT_LIKELY(rType <= BaseReg::kTypeMax)) {
- const RegFormatInfo::NameEntry& nameEntry = info.nameEntries[rType];
+ if (uint32_t(type) <= uint32_t(RegType::kMaxValue)) {
+ const RegFormatInfo::NameEntry& nameEntry = info.nameEntries[size_t(type)];
- if (rId < nameEntry.specialCount)
- return sb.append(info.nameStrings + nameEntry.specialIndex + rId * 4);
+ if (id < nameEntry.specialCount)
+ return sb.append(info.nameStrings + nameEntry.specialIndex + id * 4);
- if (rId < nameEntry.count)
- return sb.appendFormat(info.nameStrings + nameEntry.formatIndex, unsigned(rId));
+ if (id < nameEntry.count)
+ return sb.appendFormat(info.nameStrings + nameEntry.formatIndex, unsigned(id));
- const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[rType];
+ const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)];
if (typeEntry.index)
- return sb.appendFormat("%s@%u", info.typeStrings + typeEntry.index, rId);
+ return sb.appendFormat("%s@%u", info.typeStrings + typeEntry.index, id);
}
- return sb.appendFormat("<Reg-%u>?%u", rType, rId);
+ return sb.appendFormat("<Reg-%u>?%u", uint32_t(type), id);
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Operand]
-// ============================================================================
+// x86::FormatterInternal - Format Operand
+// =======================================
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
String& sb,
- uint32_t flags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const Operand_& op) noexcept {
if (op.isReg())
- return formatRegister(sb, flags, emitter, arch, op.as<BaseReg>().type(), op.as<BaseReg>().id());
+ return formatRegister(sb, formatFlags, emitter, arch, op.as<BaseReg>().type(), op.as<BaseReg>().id());
if (op.isMem()) {
const Mem& m = op.as<Mem>();
@@ -419,21 +398,27 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append('['));
switch (m.addrType()) {
- case Mem::kAddrTypeAbs: ASMJIT_PROPAGATE(sb.append("abs ")); break;
- case Mem::kAddrTypeRel: ASMJIT_PROPAGATE(sb.append("rel ")); break;
+ case Mem::AddrType::kDefault:
+ break;
+ case Mem::AddrType::kAbs:
+ ASMJIT_PROPAGATE(sb.append("abs "));
+ break;
+ case Mem::AddrType::kRel:
+ ASMJIT_PROPAGATE(sb.append("rel "));
+ break;
}
char opSign = '\0';
if (m.hasBase()) {
opSign = '+';
if (m.hasBaseLabel()) {
- ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
+ ASMJIT_PROPAGATE(Formatter::formatLabel(sb, formatFlags, emitter, m.baseId()));
}
else {
- uint32_t modifiedFlags = flags;
+ FormatFlags modifiedFlags = formatFlags;
if (m.isRegHome()) {
ASMJIT_PROPAGATE(sb.append("&"));
- modifiedFlags &= ~FormatOptions::kFlagRegCasts;
+ modifiedFlags &= ~FormatFlags::kRegCasts;
}
ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
}
@@ -444,7 +429,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append(opSign));
opSign = '+';
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
+ ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, arch, m.indexType(), m.indexId()));
if (m.hasShift())
ASMJIT_PROPAGATE(sb.appendFormat("*%u", 1 << m.shift()));
}
@@ -460,7 +445,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append(opSign));
uint32_t base = 10;
- if ((flags & FormatOptions::kFlagHexOffsets) != 0 && off > 9) {
+ if (Support::test(formatFlags, FormatFlags::kHexOffsets) && off > 9) {
ASMJIT_PROPAGATE(sb.append("0x", 2));
base = 16;
}
@@ -475,7 +460,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
const Imm& i = op.as<Imm>();
int64_t val = i.value();
- if ((flags & FormatOptions::kFlagHexImms) != 0 && uint64_t(val) > 9) {
+ if (Support::test(formatFlags, FormatFlags::kHexImms) && uint64_t(val) > 9) {
ASMJIT_PROPAGATE(sb.append("0x", 2));
return sb.appendUInt(uint64_t(val), 16);
}
@@ -485,15 +470,14 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
}
if (op.isLabel()) {
- return Formatter::formatLabel(sb, flags, emitter, op.id());
+ return Formatter::formatLabel(sb, formatFlags, emitter, op.id());
}
return sb.append("<None>");
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Immediate (Extension)]
-// ============================================================================
+// x86::FormatterInternal - Format Immediate (Extension)
+// =====================================================
static constexpr char kImmCharStart = '{';
static constexpr char kImmCharEnd = '}';
@@ -581,12 +565,12 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint3
ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
String& sb,
- uint32_t flags,
- uint32_t instId,
+ FormatFlags formatFlags,
+ InstId instId,
uint32_t vecSize,
const Imm& imm) noexcept {
- DebugUtils::unused(flags);
+ DebugUtils::unused(formatFlags);
static const char vcmpx[] =
"EQ_OQ\0" "LT_OS\0" "LE_OS\0" "UNORD_Q\0" "NEQ_UQ\0" "NLT_US\0" "NLE_US\0" "ORD_Q\0"
@@ -819,64 +803,76 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
}
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Instruction]
-// ============================================================================
+// x86::FormatterInternal - Format Instruction
+// ===========================================
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
String& sb,
- uint32_t flags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
- uint32_t instId = inst.id();
- uint32_t options = inst.options();
+ InstId instId = inst.id();
+ InstOptions options = inst.options();
// Format instruction options and instruction mnemonic.
if (instId < Inst::_kIdCount) {
// VEX|EVEX options.
- if (options & Inst::kOptionVex) ASMJIT_PROPAGATE(sb.append("{vex} "));
- if (options & Inst::kOptionVex3) ASMJIT_PROPAGATE(sb.append("{vex3} "));
- if (options & Inst::kOptionEvex) ASMJIT_PROPAGATE(sb.append("{evex} "));
+ if (Support::test(options, InstOptions::kX86_Vex))
+ ASMJIT_PROPAGATE(sb.append("{vex} "));
+
+ if (Support::test(options, InstOptions::kX86_Vex3))
+ ASMJIT_PROPAGATE(sb.append("{vex3} "));
+
+ if (Support::test(options, InstOptions::kX86_Evex))
+ ASMJIT_PROPAGATE(sb.append("{evex} "));
// MOD/RM and MOD/MR options
- if (options & Inst::kOptionModRM)
+ if (Support::test(options, InstOptions::kX86_ModRM))
ASMJIT_PROPAGATE(sb.append("{modrm} "));
- else if (options & Inst::kOptionModMR)
+ else if (Support::test(options, InstOptions::kX86_ModMR))
ASMJIT_PROPAGATE(sb.append("{modmr} "));
// SHORT|LONG options.
- if (options & Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.append("short "));
- if (options & Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.append("long "));
+ if (Support::test(options, InstOptions::kShortForm))
+ ASMJIT_PROPAGATE(sb.append("short "));
+
+ if (Support::test(options, InstOptions::kLongForm))
+ ASMJIT_PROPAGATE(sb.append("long "));
// LOCK|XACQUIRE|XRELEASE options.
- if (options & Inst::kOptionXAcquire) ASMJIT_PROPAGATE(sb.append("xacquire "));
- if (options & Inst::kOptionXRelease) ASMJIT_PROPAGATE(sb.append("xrelease "));
- if (options & Inst::kOptionLock) ASMJIT_PROPAGATE(sb.append("lock "));
+ if (Support::test(options, InstOptions::kX86_XAcquire))
+ ASMJIT_PROPAGATE(sb.append("xacquire "));
+
+ if (Support::test(options, InstOptions::kX86_XRelease))
+ ASMJIT_PROPAGATE(sb.append("xrelease "));
+
+ if (Support::test(options, InstOptions::kX86_Lock))
+ ASMJIT_PROPAGATE(sb.append("lock "));
// REP|REPNE options.
- if (options & (Inst::kOptionRep | Inst::kOptionRepne)) {
- sb.append((options & Inst::kOptionRep) ? "rep " : "repnz ");
+ if (Support::test(options, InstOptions::kX86_Rep | InstOptions::kX86_Repne)) {
+ sb.append(Support::test(options, InstOptions::kX86_Rep) ? "rep " : "repnz ");
if (inst.hasExtraReg()) {
ASMJIT_PROPAGATE(sb.append("{"));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, inst.extraReg().toReg<BaseReg>()));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, emitter, arch, inst.extraReg().toReg<BaseReg>()));
ASMJIT_PROPAGATE(sb.append("} "));
}
}
// REX options.
- if (options & Inst::kOptionRex) {
- const uint32_t kRXBWMask = Inst::kOptionOpCodeR |
- Inst::kOptionOpCodeX |
- Inst::kOptionOpCodeB |
- Inst::kOptionOpCodeW ;
- if (options & kRXBWMask) {
- sb.append("rex.");
- if (options & Inst::kOptionOpCodeR) sb.append('r');
- if (options & Inst::kOptionOpCodeX) sb.append('x');
- if (options & Inst::kOptionOpCodeB) sb.append('b');
- if (options & Inst::kOptionOpCodeW) sb.append('w');
+ if (Support::test(options, InstOptions::kX86_Rex)) {
+ const InstOptions kRXBWMask = InstOptions::kX86_OpCodeR |
+ InstOptions::kX86_OpCodeX |
+ InstOptions::kX86_OpCodeB |
+ InstOptions::kX86_OpCodeW ;
+ if (Support::test(options, kRXBWMask)) {
+ ASMJIT_PROPAGATE(sb.append("rex."));
+ if (Support::test(options, InstOptions::kX86_OpCodeR)) sb.append('r');
+ if (Support::test(options, InstOptions::kX86_OpCodeX)) sb.append('x');
+ if (Support::test(options, InstOptions::kX86_OpCodeB)) sb.append('b');
+ if (Support::test(options, InstOptions::kX86_OpCodeW)) sb.append('w');
sb.append(' ');
}
else {
@@ -895,34 +891,47 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
if (op.isNone()) break;
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, op));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, emitter, arch, op));
- if (op.isImm() && (flags & FormatOptions::kFlagExplainImms)) {
+ if (op.isImm() && uint32_t(formatFlags & FormatFlags::kExplainImms)) {
uint32_t vecSize = 16;
for (uint32_t j = 0; j < opCount; j++)
if (operands[j].isReg())
vecSize = Support::max<uint32_t>(vecSize, operands[j].size());
- ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, flags, instId, vecSize, op.as<Imm>()));
+ ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, formatFlags, instId, vecSize, op.as<Imm>()));
}
// Support AVX-512 masking - {k}{z}.
if (i == 0) {
- if (inst.extraReg().group() == Reg::kGroupKReg) {
+ if (inst.extraReg().group() == RegGroup::kX86_K) {
ASMJIT_PROPAGATE(sb.append(" {"));
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, inst.extraReg().type(), inst.extraReg().id()));
+ ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, arch, inst.extraReg().type(), inst.extraReg().id()));
ASMJIT_PROPAGATE(sb.append('}'));
- if (options & Inst::kOptionZMask)
+ if (Support::test(options, InstOptions::kX86_ZMask))
ASMJIT_PROPAGATE(sb.append("{z}"));
}
- else if (options & Inst::kOptionZMask) {
+ else if (Support::test(options, InstOptions::kX86_ZMask)) {
ASMJIT_PROPAGATE(sb.append(" {z}"));
}
}
// Support AVX-512 broadcast - {1tox}.
if (op.isMem() && op.as<Mem>().hasBroadcast()) {
- ASMJIT_PROPAGATE(sb.appendFormat(" {1to%u}", Support::bitMask(op.as<Mem>().getBroadcast())));
+ ASMJIT_PROPAGATE(sb.appendFormat(" {1to%u}", Support::bitMask(uint32_t(op.as<Mem>().getBroadcast()))));
+ }
+ }
+
+ // Support AVX-512 embedded rounding and suppress-all-exceptions {sae}.
+ if (inst.hasOption(InstOptions::kX86_ER | InstOptions::kX86_SAE)) {
+ if (inst.hasOption(InstOptions::kX86_ER)) {
+ uint32_t bits = uint32_t(inst.options() & InstOptions::kX86_ERMask) >> Support::ConstCTZ<uint32_t(InstOptions::kX86_ERMask)>::value;
+
+ const char roundingModes[] = "rn\0rd\0ru\0rz";
+ ASMJIT_PROPAGATE(sb.appendFormat(", {%s-sae}", roundingModes + bits * 3));
+ }
+ else {
+ ASMJIT_PROPAGATE(sb.append(", {sae}"));
}
}
diff --git a/src/asmjit/x86/x86formatter_p.h b/src/asmjit/x86/x86formatter_p.h
index d7d58e4..1dbdb68 100644
--- a/src/asmjit/x86/x86formatter_p.h
+++ b/src/asmjit/x86/x86formatter_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86FORMATTER_P_H_INCLUDED
#define ASMJIT_X86_X86FORMATTER_P_H_INCLUDED
@@ -37,10 +19,6 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::FormatterInternal]
-// ============================================================================
-
namespace FormatterInternal {
Error formatFeature(
@@ -49,24 +27,24 @@ Error formatFeature(
Error formatRegister(
String& sb,
- uint32_t flags,
+ FormatFlags flags,
const BaseEmitter* emitter,
- uint32_t arch,
- uint32_t regType,
+ Arch arch,
+ RegType regType,
uint32_t regId) noexcept;
Error formatOperand(
String& sb,
- uint32_t flags,
+ FormatFlags flags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const Operand_& op) noexcept;
Error formatInstruction(
String& sb,
- uint32_t flags,
+ FormatFlags flags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
} // {FormatterInternal}
diff --git a/src/asmjit/x86/x86func.cpp b/src/asmjit/x86/x86func.cpp
index 8f2f077..bba9eef 100644
--- a/src/asmjit/x86/x86func.cpp
+++ b/src/asmjit/x86/x86func.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
@@ -30,28 +12,19 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::FuncInternal - Init]
-// ============================================================================
-
namespace FuncInternal {
-static inline bool shouldThreatAsCDeclIn64BitMode(uint32_t ccId) noexcept {
- return ccId == CallConv::kIdCDecl ||
- ccId == CallConv::kIdStdCall ||
- ccId == CallConv::kIdThisCall ||
- ccId == CallConv::kIdFastCall ||
- ccId == CallConv::kIdRegParm1 ||
- ccId == CallConv::kIdRegParm2 ||
- ccId == CallConv::kIdRegParm3;
+static inline bool shouldThreatAsCDeclIn64BitMode(CallConvId ccId) noexcept {
+ return ccId == CallConvId::kCDecl ||
+ ccId == CallConvId::kStdCall ||
+ ccId == CallConvId::kThisCall ||
+ ccId == CallConvId::kFastCall ||
+ ccId == CallConvId::kRegParm1 ||
+ ccId == CallConvId::kRegParm2 ||
+ ccId == CallConvId::kRegParm3;
}
-ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, uint32_t ccId, const Environment& environment) noexcept {
- constexpr uint32_t kGroupGp = Reg::kGroupGp;
- constexpr uint32_t kGroupVec = Reg::kGroupVec;
- constexpr uint32_t kGroupMm = Reg::kGroupMm;
- constexpr uint32_t kGroupKReg = Reg::kGroupKReg;
-
+ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, CallConvId ccId, const Environment& environment) noexcept {
constexpr uint32_t kZax = Gp::kIdAx;
constexpr uint32_t kZbx = Gp::kIdBx;
constexpr uint32_t kZcx = Gp::kIdCx;
@@ -61,80 +34,80 @@ ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, uint32_t ccId, const Environm
constexpr uint32_t kZsi = Gp::kIdSi;
constexpr uint32_t kZdi = Gp::kIdDi;
- bool winABI = environment.isPlatformWindows() || environment.isAbiMSVC();
+ bool winABI = environment.isPlatformWindows() || environment.isMSVC();
cc.setArch(environment.arch());
- cc.setSaveRestoreRegSize(Reg::kGroupVec, 16);
- cc.setSaveRestoreRegSize(Reg::kGroupMm, 8);
- cc.setSaveRestoreRegSize(Reg::kGroupKReg, 8);
- cc.setSaveRestoreAlignment(Reg::kGroupVec, 16);
- cc.setSaveRestoreAlignment(Reg::kGroupMm, 8);
- cc.setSaveRestoreAlignment(Reg::kGroupKReg, 8);
+ cc.setSaveRestoreRegSize(RegGroup::kVec, 16);
+ cc.setSaveRestoreRegSize(RegGroup::kX86_MM, 8);
+ cc.setSaveRestoreRegSize(RegGroup::kX86_K, 8);
+ cc.setSaveRestoreAlignment(RegGroup::kVec, 16);
+ cc.setSaveRestoreAlignment(RegGroup::kX86_MM, 8);
+ cc.setSaveRestoreAlignment(RegGroup::kX86_K, 8);
if (environment.is32Bit()) {
bool isStandardCallConv = true;
- cc.setSaveRestoreRegSize(Reg::kGroupGp, 4);
- cc.setSaveRestoreAlignment(Reg::kGroupGp, 4);
+ cc.setSaveRestoreRegSize(RegGroup::kGp, 4);
+ cc.setSaveRestoreAlignment(RegGroup::kGp, 4);
- cc.setPreservedRegs(Reg::kGroupGp, Support::bitMask(Gp::kIdBx, Gp::kIdSp, Gp::kIdBp, Gp::kIdSi, Gp::kIdDi));
+ cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(Gp::kIdBx, Gp::kIdSp, Gp::kIdBp, Gp::kIdSi, Gp::kIdDi));
cc.setNaturalStackAlignment(4);
switch (ccId) {
- case CallConv::kIdCDecl:
+ case CallConvId::kCDecl:
break;
- case CallConv::kIdStdCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
+ case CallConvId::kStdCall:
+ cc.setFlags(CallConvFlags::kCalleePopsStack);
break;
- case CallConv::kIdFastCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx);
+ case CallConvId::kFastCall:
+ cc.setFlags(CallConvFlags::kCalleePopsStack);
+ cc.setPassedOrder(RegGroup::kGp, kZcx, kZdx);
break;
- case CallConv::kIdVectorCall:
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5);
+ case CallConvId::kVectorCall:
+ cc.setFlags(CallConvFlags::kCalleePopsStack);
+ cc.setPassedOrder(RegGroup::kGp, kZcx, kZdx);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5);
break;
- case CallConv::kIdThisCall:
- // NOTE: Even MINGW (starting with GCC 4.7.0) now uses __thiscall on MS Windows,
- // so we won't bail to any other calling convention if __thiscall was specified.
+ case CallConvId::kThisCall:
+ // NOTE: Even MINGW (starting with GCC 4.7.0) now uses __thiscall on MS Windows, so we won't bail to any
+ // other calling convention if __thiscall was specified.
if (winABI) {
- cc.setFlags(CallConv::kFlagCalleePopsStack);
- cc.setPassedOrder(kGroupGp, kZcx);
+ cc.setFlags(CallConvFlags::kCalleePopsStack);
+ cc.setPassedOrder(RegGroup::kGp, kZcx);
}
else {
- ccId = CallConv::kIdCDecl;
+ ccId = CallConvId::kCDecl;
}
break;
- case CallConv::kIdRegParm1:
- cc.setPassedOrder(kGroupGp, kZax);
+ case CallConvId::kRegParm1:
+ cc.setPassedOrder(RegGroup::kGp, kZax);
break;
- case CallConv::kIdRegParm2:
- cc.setPassedOrder(kGroupGp, kZax, kZdx);
+ case CallConvId::kRegParm2:
+ cc.setPassedOrder(RegGroup::kGp, kZax, kZdx);
break;
- case CallConv::kIdRegParm3:
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx);
+ case CallConvId::kRegParm3:
+ cc.setPassedOrder(RegGroup::kGp, kZax, kZdx, kZcx);
break;
- case CallConv::kIdLightCall2:
- case CallConv::kIdLightCall3:
- case CallConv::kIdLightCall4: {
- uint32_t n = (ccId - CallConv::kIdLightCall2) + 2;
+ case CallConvId::kLightCall2:
+ case CallConvId::kLightCall3:
+ case CallConvId::kLightCall4: {
+ uint32_t n = uint32_t(ccId) - uint32_t(CallConvId::kLightCall2) + 2;
- cc.setFlags(CallConv::kFlagPassFloatsByVec);
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
- cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPreservedRegs(kGroupGp, Support::lsbMask<uint32_t>(8));
- cc.setPreservedRegs(kGroupVec, Support::lsbMask<uint32_t>(8) & ~Support::lsbMask<uint32_t>(n));
+ cc.setFlags(CallConvFlags::kPassFloatsByVec);
+ cc.setPassedOrder(RegGroup::kGp, kZax, kZdx, kZcx, kZsi, kZdi);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(RegGroup::kX86_K, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(RegGroup::kX86_MM, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPreservedRegs(RegGroup::kGp, Support::lsbMask<uint32_t>(8));
+ cc.setPreservedRegs(RegGroup::kVec, Support::lsbMask<uint32_t>(8) & ~Support::lsbMask<uint32_t>(n));
cc.setNaturalStackAlignment(16);
isStandardCallConv = false;
@@ -146,92 +119,90 @@ ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, uint32_t ccId, const Environm
}
if (isStandardCallConv) {
- // MMX arguments is something where compiler vendors disagree. For example
- // GCC and MSVC would pass first three via registers and the rest via stack,
- // however Clang passes all via stack. Returning MMX registers is even more
- // fun, where GCC uses MM0, but Clang uses EAX:EDX pair. I'm not sure it's
- // something we should be worried about as MMX is deprecated anyway.
- cc.setPassedOrder(kGroupMm, 0, 1, 2);
-
- // Vector arguments (XMM|YMM|ZMM) are passed via registers. However, if the
- // function is variadic then they have to be passed via stack.
- cc.setPassedOrder(kGroupVec, 0, 1, 2);
-
- // Functions with variable arguments always use stack for MM and vector
- // arguments.
- cc.addFlags(CallConv::kFlagPassVecByStackIfVA);
+ // MMX arguments is something where compiler vendors disagree. For example GCC and MSVC would pass first three
+ // via registers and the rest via stack, however Clang passes all via stack. Returning MMX registers is even
+ // more fun, where GCC uses MM0, but Clang uses EAX:EDX pair. I'm not sure it's something we should be worried
+ // about as MMX is deprecated anyway.
+ cc.setPassedOrder(RegGroup::kX86_MM, 0, 1, 2);
+
+ // Vector arguments (XMM|YMM|ZMM) are passed via registers. However, if the function is variadic then they have
+ // to be passed via stack.
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2);
+
+ // Functions with variable arguments always use stack for MM and vector arguments.
+ cc.addFlags(CallConvFlags::kPassVecByStackIfVA);
}
- if (ccId == CallConv::kIdCDecl) {
- cc.addFlags(CallConv::kFlagVarArgCompatible);
+ if (ccId == CallConvId::kCDecl) {
+ cc.addFlags(CallConvFlags::kVarArgCompatible);
}
}
else {
- cc.setSaveRestoreRegSize(Reg::kGroupGp, 8);
- cc.setSaveRestoreAlignment(Reg::kGroupGp, 8);
+ cc.setSaveRestoreRegSize(RegGroup::kGp, 8);
+ cc.setSaveRestoreAlignment(RegGroup::kGp, 8);
- // Preprocess the calling convention into a common id as many conventions
- // are normally ignored even by C/C++ compilers and treated as `__cdecl`.
+ // Preprocess the calling convention into a common id as many conventions are normally ignored even by C/C++
+ // compilers and treated as `__cdecl`.
if (shouldThreatAsCDeclIn64BitMode(ccId))
- ccId = winABI ? CallConv::kIdX64Windows : CallConv::kIdX64SystemV;
+ ccId = winABI ? CallConvId::kX64Windows : CallConvId::kX64SystemV;
switch (ccId) {
- case CallConv::kIdX64SystemV: {
- cc.setFlags(CallConv::kFlagPassFloatsByVec |
- CallConv::kFlagPassMmxByXmm |
- CallConv::kFlagVarArgCompatible);
+ case CallConvId::kX64SystemV: {
+ cc.setFlags(CallConvFlags::kPassFloatsByVec |
+ CallConvFlags::kPassMmxByXmm |
+ CallConvFlags::kVarArgCompatible);
cc.setNaturalStackAlignment(16);
cc.setRedZoneSize(128);
- cc.setPassedOrder(kGroupGp, kZdi, kZsi, kZdx, kZcx, 8, 9);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, 12, 13, 14, 15));
+ cc.setPassedOrder(RegGroup::kGp, kZdi, kZsi, kZdx, kZcx, 8, 9);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(kZbx, kZsp, kZbp, 12, 13, 14, 15));
break;
}
- case CallConv::kIdX64Windows: {
- cc.setStrategy(CallConv::kStrategyX64Windows);
- cc.setFlags(CallConv::kFlagPassFloatsByVec |
- CallConv::kFlagIndirectVecArgs |
- CallConv::kFlagPassMmxByGp |
- CallConv::kFlagVarArgCompatible);
+ case CallConvId::kX64Windows: {
+ cc.setStrategy(CallConvStrategy::kX64Windows);
+ cc.setFlags(CallConvFlags::kPassFloatsByVec |
+ CallConvFlags::kIndirectVecArgs |
+ CallConvFlags::kPassMmxByGp |
+ CallConvFlags::kVarArgCompatible);
cc.setNaturalStackAlignment(16);
// Maximum 4 arguments in registers, each adds 8 bytes to the spill zone.
cc.setSpillZoneSize(4 * 8);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3);
- cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
- cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+ cc.setPassedOrder(RegGroup::kGp, kZcx, kZdx, 8, 9);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3);
+ cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
+ cc.setPreservedRegs(RegGroup::kVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
break;
}
- case CallConv::kIdVectorCall: {
- cc.setStrategy(CallConv::kStrategyX64VectorCall);
- cc.setFlags(CallConv::kFlagPassFloatsByVec |
- CallConv::kFlagPassMmxByGp );
+ case CallConvId::kVectorCall: {
+ cc.setStrategy(CallConvStrategy::kX64VectorCall);
+ cc.setFlags(CallConvFlags::kPassFloatsByVec |
+ CallConvFlags::kPassMmxByGp );
cc.setNaturalStackAlignment(16);
// Maximum 6 arguments in registers, each adds 8 bytes to the spill zone.
cc.setSpillZoneSize(6 * 8);
- cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5);
- cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
- cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+ cc.setPassedOrder(RegGroup::kGp, kZcx, kZdx, 8, 9);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5);
+ cc.setPreservedRegs(RegGroup::kGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
+ cc.setPreservedRegs(RegGroup::kVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
break;
}
- case CallConv::kIdLightCall2:
- case CallConv::kIdLightCall3:
- case CallConv::kIdLightCall4: {
- uint32_t n = (ccId - CallConv::kIdLightCall2) + 2;
+ case CallConvId::kLightCall2:
+ case CallConvId::kLightCall3:
+ case CallConvId::kLightCall4: {
+ uint32_t n = uint32_t(ccId) - uint32_t(CallConvId::kLightCall2) + 2;
- cc.setFlags(CallConv::kFlagPassFloatsByVec);
+ cc.setFlags(CallConvFlags::kPassFloatsByVec);
cc.setNaturalStackAlignment(16);
- cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi);
- cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(RegGroup::kGp, kZax, kZdx, kZcx, kZsi, kZdi);
+ cc.setPassedOrder(RegGroup::kVec, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(RegGroup::kX86_K, 0, 1, 2, 3, 4, 5, 6, 7);
+ cc.setPassedOrder(RegGroup::kX86_MM, 0, 1, 2, 3, 4, 5, 6, 7);
- cc.setPreservedRegs(kGroupGp, Support::lsbMask<uint32_t>(16));
- cc.setPreservedRegs(kGroupVec, ~Support::lsbMask<uint32_t>(n));
+ cc.setPreservedRegs(RegGroup::kGp, Support::lsbMask<uint32_t>(16));
+ cc.setPreservedRegs(RegGroup::kVec, ~Support::lsbMask<uint32_t>(n));
break;
}
@@ -245,24 +216,28 @@ ASMJIT_FAVOR_SIZE Error initCallConv(CallConv& cc, uint32_t ccId, const Environm
}
ASMJIT_FAVOR_SIZE void unpackValues(FuncDetail& func, FuncValuePack& pack) noexcept {
- uint32_t typeId = pack[0].typeId();
+ TypeId typeId = pack[0].typeId();
switch (typeId) {
- case Type::kIdI64:
- case Type::kIdU64: {
+ case TypeId::kInt64:
+ case TypeId::kUInt64: {
if (Environment::is32Bit(func.callConv().arch())) {
// Convert a 64-bit return value to two 32-bit return values.
- pack[0].initTypeId(Type::kIdU32);
- pack[1].initTypeId(typeId - 2);
+ pack[0].initTypeId(TypeId::kUInt32);
+ pack[1].initTypeId(TypeId(uint32_t(typeId) - 2));
break;
}
break;
}
+
+ default: {
+ break;
+ }
}
}
ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept {
const CallConv& cc = func.callConv();
- uint32_t arch = cc.arch();
+ Arch arch = cc.arch();
uint32_t stackOffset = cc._spillZoneSize;
uint32_t argCount = func.argCount();
@@ -277,63 +252,63 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
if (func.hasRet()) {
unpackValues(func, func._rets);
for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
- uint32_t typeId = func._rets[valueIndex].typeId();
+ TypeId typeId = func._rets[valueIndex].typeId();
// Terminate at the first void type (end of the pack).
- if (!typeId)
+ if (typeId == TypeId::kVoid)
break;
switch (typeId) {
- case Type::kIdI64:
- case Type::kIdU64: {
+ case TypeId::kInt64:
+ case TypeId::kUInt64: {
if (gpReturnIndexes[valueIndex] != BaseReg::kIdBad)
- func._rets[valueIndex].initReg(Reg::kTypeGpq, gpReturnIndexes[valueIndex], typeId);
+ func._rets[valueIndex].initReg(RegType::kX86_Gpq, gpReturnIndexes[valueIndex], typeId);
else
return DebugUtils::errored(kErrorInvalidState);
break;
}
- case Type::kIdI8:
- case Type::kIdI16:
- case Type::kIdI32: {
+ case TypeId::kInt8:
+ case TypeId::kInt16:
+ case TypeId::kInt32: {
if (gpReturnIndexes[valueIndex] != BaseReg::kIdBad)
- func._rets[valueIndex].initReg(Reg::kTypeGpd, gpReturnIndexes[valueIndex], Type::kIdI32);
+ func._rets[valueIndex].initReg(RegType::kX86_Gpd, gpReturnIndexes[valueIndex], TypeId::kInt32);
else
return DebugUtils::errored(kErrorInvalidState);
break;
}
- case Type::kIdU8:
- case Type::kIdU16:
- case Type::kIdU32: {
+ case TypeId::kUInt8:
+ case TypeId::kUInt16:
+ case TypeId::kUInt32: {
if (gpReturnIndexes[valueIndex] != BaseReg::kIdBad)
- func._rets[valueIndex].initReg(Reg::kTypeGpd, gpReturnIndexes[valueIndex], Type::kIdU32);
+ func._rets[valueIndex].initReg(RegType::kX86_Gpd, gpReturnIndexes[valueIndex], TypeId::kUInt32);
else
return DebugUtils::errored(kErrorInvalidState);
break;
}
- case Type::kIdF32:
- case Type::kIdF64: {
- uint32_t regType = Environment::is32Bit(arch) ? Reg::kTypeSt : Reg::kTypeXmm;
+ case TypeId::kFloat32:
+ case TypeId::kFloat64: {
+ RegType regType = Environment::is32Bit(arch) ? RegType::kX86_St : RegType::kX86_Xmm;
func._rets[valueIndex].initReg(regType, valueIndex, typeId);
break;
}
- case Type::kIdF80: {
+ case TypeId::kFloat80: {
// 80-bit floats are always returned by FP0.
- func._rets[valueIndex].initReg(Reg::kTypeSt, valueIndex, typeId);
+ func._rets[valueIndex].initReg(RegType::kX86_St, valueIndex, typeId);
break;
}
- case Type::kIdMmx32:
- case Type::kIdMmx64: {
+ case TypeId::kMmx32:
+ case TypeId::kMmx64: {
// MM registers are returned through XMM (SystemV) or GPQ (Win64).
- uint32_t regType = Reg::kTypeMm;
+ RegType regType = RegType::kX86_Mm;
uint32_t regIndex = valueIndex;
if (Environment::is64Bit(arch)) {
- regType = cc.strategy() == CallConv::kStrategyDefault ? Reg::kTypeXmm : Reg::kTypeGpq;
- regIndex = cc.strategy() == CallConv::kStrategyDefault ? valueIndex : gpReturnIndexes[valueIndex];
+ regType = cc.strategy() == CallConvStrategy::kDefault ? RegType::kX86_Xmm : RegType::kX86_Gpq;
+ regIndex = cc.strategy() == CallConvStrategy::kDefault ? valueIndex : gpReturnIndexes[valueIndex];
if (regIndex == BaseReg::kIdBad)
return DebugUtils::errored(kErrorInvalidState);
@@ -352,7 +327,7 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
}
switch (cc.strategy()) {
- case CallConv::kStrategyDefault: {
+ case CallConvStrategy::kDefault: {
uint32_t gpzPos = 0;
uint32_t vecPos = 0;
@@ -366,56 +341,55 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
if (!arg)
break;
- uint32_t typeId = arg.typeId();
+ TypeId typeId = arg.typeId();
- if (Type::isInt(typeId)) {
+ if (TypeUtils::isInt(typeId)) {
uint32_t regId = BaseReg::kIdBad;
if (gpzPos < CallConv::kMaxRegArgsPerGroup)
- regId = cc._passedOrder[Reg::kGroupGp].id[gpzPos];
+ regId = cc._passedOrder[RegGroup::kGp].id[gpzPos];
if (regId != BaseReg::kIdBad) {
- uint32_t regType = (typeId <= Type::kIdU32) ? Reg::kTypeGpd : Reg::kTypeGpq;
+ RegType regType = typeId <= TypeId::kUInt32 ? RegType::kX86_Gpd : RegType::kX86_Gpq;
arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
+ func.addUsedRegs(RegGroup::kGp, Support::bitMask(regId));
gpzPos++;
}
else {
- uint32_t size = Support::max<uint32_t>(Type::sizeOf(typeId), registerSize);
+ uint32_t size = Support::max<uint32_t>(TypeUtils::sizeOf(typeId), registerSize);
arg.assignStackOffset(int32_t(stackOffset));
stackOffset += size;
}
continue;
}
- if (Type::isFloat(typeId) || Type::isVec(typeId)) {
+ if (TypeUtils::isFloat(typeId) || TypeUtils::isVec(typeId)) {
uint32_t regId = BaseReg::kIdBad;
if (vecPos < CallConv::kMaxRegArgsPerGroup)
- regId = cc._passedOrder[Reg::kGroupVec].id[vecPos];
+ regId = cc._passedOrder[RegGroup::kVec].id[vecPos];
- if (Type::isFloat(typeId)) {
- // If this is a float, but `kFlagPassFloatsByVec` is false, we have
- // to use stack instead. This should be only used by 32-bit calling
- // conventions.
- if (!cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+ if (TypeUtils::isFloat(typeId)) {
+ // If this is a float, but `kFlagPassFloatsByVec` is false, we have to use stack instead. This should
+ // be only used by 32-bit calling conventions.
+ if (!cc.hasFlag(CallConvFlags::kPassFloatsByVec))
regId = BaseReg::kIdBad;
}
else {
- // Pass vector registers via stack if this is a variable arguments
- // function. This should be only used by 32-bit calling conventions.
- if (signature.hasVarArgs() && cc.hasFlag(CallConv::kFlagPassVecByStackIfVA))
+ // Pass vector registers via stack if this is a variable arguments function. This should be only used
+ // by 32-bit calling conventions.
+ if (signature.hasVarArgs() && cc.hasFlag(CallConvFlags::kPassVecByStackIfVA))
regId = BaseReg::kIdBad;
}
if (regId != BaseReg::kIdBad) {
arg.initTypeId(typeId);
arg.assignRegData(vecTypeIdToRegType(typeId), regId);
- func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
+ func.addUsedRegs(RegGroup::kVec, Support::bitMask(regId));
vecPos++;
}
else {
- uint32_t size = Type::sizeOf(typeId);
+ uint32_t size = TypeUtils::sizeOf(typeId);
arg.assignStackOffset(int32_t(stackOffset));
stackOffset += size;
}
@@ -426,12 +400,11 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
break;
}
- case CallConv::kStrategyX64Windows:
- case CallConv::kStrategyX64VectorCall: {
- // Both X64 and VectorCall behave similarly - arguments are indexed
- // from left to right. The position of the argument determines in
- // which register the argument is allocated, so it's either GP or
- // one of XMM/YMM/ZMM registers.
+ case CallConvStrategy::kX64Windows:
+ case CallConvStrategy::kX64VectorCall: {
+ // Both X64 and VectorCall behave similarly - arguments are indexed from left to right. The position of the
+ // argument determines in which register the argument is allocated, so it's either GP or one of XMM/YMM/ZMM
+ // registers.
//
// [ X64 ] [VecCall]
// Index: #0 #1 #2 #3 #4 #5
@@ -445,7 +418,7 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
// RCX XMM1 R8 XMM3
//
// Unused vector registers are used by HVA.
- bool isVectorCall = (cc.strategy() == CallConv::kStrategyX64VectorCall);
+ bool isVectorCall = (cc.strategy() == CallConvStrategy::kX64VectorCall);
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
unpackValues(func, func._args[argIndex]);
@@ -457,19 +430,19 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
if (!arg)
break;
- uint32_t typeId = arg.typeId();
- uint32_t size = Type::sizeOf(typeId);
+ TypeId typeId = arg.typeId();
+ uint32_t size = TypeUtils::sizeOf(typeId);
- if (Type::isInt(typeId) || Type::isMmx(typeId)) {
+ if (TypeUtils::isInt(typeId) || TypeUtils::isMmx(typeId)) {
uint32_t regId = BaseReg::kIdBad;
if (argIndex < CallConv::kMaxRegArgsPerGroup)
- regId = cc._passedOrder[Reg::kGroupGp].id[argIndex];
+ regId = cc._passedOrder[RegGroup::kGp].id[argIndex];
if (regId != BaseReg::kIdBad) {
- uint32_t regType = (size <= 4 && !Type::isMmx(typeId)) ? Reg::kTypeGpd : Reg::kTypeGpq;
+ RegType regType = size <= 4 && !TypeUtils::isMmx(typeId) ? RegType::kX86_Gpd : RegType::kX86_Gpq;
arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupGp, Support::bitMask(regId));
+ func.addUsedRegs(RegGroup::kGp, Support::bitMask(regId));
}
else {
arg.assignStackOffset(int32_t(stackOffset));
@@ -478,33 +451,32 @@ ASMJIT_FAVOR_SIZE Error initFuncDetail(FuncDetail& func, const FuncSignature& si
continue;
}
- if (Type::isFloat(typeId) || Type::isVec(typeId)) {
+ if (TypeUtils::isFloat(typeId) || TypeUtils::isVec(typeId)) {
uint32_t regId = BaseReg::kIdBad;
if (argIndex < CallConv::kMaxRegArgsPerGroup)
- regId = cc._passedOrder[Reg::kGroupVec].id[argIndex];
+ regId = cc._passedOrder[RegGroup::kVec].id[argIndex];
if (regId != BaseReg::kIdBad) {
- // X64-ABI doesn't allow vector types (XMM|YMM|ZMM) to be passed
- // via registers, however, VectorCall was designed for that purpose.
- if (Type::isFloat(typeId) || isVectorCall) {
- uint32_t regType = vecTypeIdToRegType(typeId);
+ // X64-ABI doesn't allow vector types (XMM|YMM|ZMM) to be passed via registers, however, VectorCall
+ // was designed for that purpose.
+ if (TypeUtils::isFloat(typeId) || isVectorCall) {
+ RegType regType = vecTypeIdToRegType(typeId);
arg.assignRegData(regType, regId);
- func.addUsedRegs(Reg::kGroupVec, Support::bitMask(regId));
+ func.addUsedRegs(RegGroup::kVec, Support::bitMask(regId));
continue;
}
}
- // Passed via stack if the argument is float/double or indirectly.
- // The trap is - if the argument is passed indirectly, the address
- // can be passed via register, if the argument's index has GP one.
- if (Type::isFloat(typeId)) {
+ // Passed via stack if the argument is float/double or indirectly. The trap is - if the argument is
+ // passed indirectly, the address can be passed via register, if the argument's index has GP one.
+ if (TypeUtils::isFloat(typeId)) {
arg.assignStackOffset(int32_t(stackOffset));
}
else {
- uint32_t gpRegId = cc._passedOrder[Reg::kGroupGp].id[argIndex];
+ uint32_t gpRegId = cc._passedOrder[RegGroup::kGp].id[argIndex];
if (gpRegId != BaseReg::kIdBad)
- arg.assignRegData(Reg::kTypeGpq, gpRegId);
+ arg.assignRegData(RegType::kX86_Gpq, gpRegId);
else
arg.assignStackOffset(int32_t(stackOffset));
arg.addFlags(FuncValue::kFlagIsIndirect);
diff --git a/src/asmjit/x86/x86func_p.h b/src/asmjit/x86/x86func_p.h
index 94745ca..0fe1da1 100644
--- a/src/asmjit/x86/x86func_p.h
+++ b/src/asmjit/x86/x86func_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86FUNC_P_H_INCLUDED
#define ASMJIT_X86_X86FUNC_P_H_INCLUDED
@@ -32,15 +14,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::FuncInternal]
-// ============================================================================
-
//! X86-specific function API (calling conventions and other utilities).
namespace FuncInternal {
//! Initialize `CallConv` structure (X86 specific).
-Error initCallConv(CallConv& cc, uint32_t ccId, const Environment& environment) noexcept;
+Error initCallConv(CallConv& cc, CallConvId ccId, const Environment& environment) noexcept;
//! Initialize `FuncDetail` (X86 specific).
Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept;
diff --git a/src/asmjit/x86/x86globals.h b/src/asmjit/x86/x86globals.h
index 77458e7..803c813 100644
--- a/src/asmjit/x86/x86globals.h
+++ b/src/asmjit/x86/x86globals.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86GLOBALS_H_INCLUDED
#define ASMJIT_X86_X86GLOBALS_H_INCLUDED
@@ -37,14 +19,100 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::Inst]
-// ============================================================================
+//! Condition code.
+enum class CondCode : uint8_t {
+ kO = 0x00u, //!< OF==1
+ kNO = 0x01u, //!< OF==0
+ kC = 0x02u, //!< CF==1
+ kB = 0x02u, //!< CF==1 (unsigned < )
+ kNAE = 0x02u, //!< CF==1 (unsigned < )
+ kNC = 0x03u, //!< CF==0
+ kAE = 0x03u, //!< CF==0 (unsigned >=)
+ kNB = 0x03u, //!< CF==0 (unsigned >=)
+ kE = 0x04u, //!< ZF==1 (any_sign ==)
+ kZ = 0x04u, //!< ZF==1 (any_sign ==)
+ kNE = 0x05u, //!< ZF==0 (any_sign !=)
+ kNZ = 0x05u, //!< ZF==0 (any_sign !=)
+ kBE = 0x06u, //!< CF==1 | ZF==1 (unsigned <=)
+ kNA = 0x06u, //!< CF==1 | ZF==1 (unsigned <=)
+ kA = 0x07u, //!< CF==0 & ZF==0 (unsigned > )
+ kNBE = 0x07u, //!< CF==0 & ZF==0 (unsigned > )
+ kS = 0x08u, //!< SF==1 (is negative)
+ kNS = 0x09u, //!< SF==0 (is positive or zero)
+ kP = 0x0Au, //!< PF==1
+ kPE = 0x0Au, //!< PF==1
+ kPO = 0x0Bu, //!< PF==0
+ kNP = 0x0Bu, //!< PF==0
+ kL = 0x0Cu, //!< SF!=OF (signed < )
+ kNGE = 0x0Cu, //!< SF!=OF (signed < )
+ kGE = 0x0Du, //!< SF==OF (signed >=)
+ kNL = 0x0Du, //!< SF==OF (signed >=)
+ kLE = 0x0Eu, //!< ZF==1 | SF!=OF (signed <=)
+ kNG = 0x0Eu, //!< ZF==1 | SF!=OF (signed <=)
+ kG = 0x0Fu, //!< ZF==0 & SF==OF (signed > )
+ kNLE = 0x0Fu, //!< ZF==0 & SF==OF (signed > )
+
+ kZero = kZ, //!< Zero flag.
+ kNotZero = kNZ, //!< Non-zero flag.
+
+ kSign = kS, //!< Sign flag.
+ kNotSign = kNS, //!< No sign flag.
+
+ kNegative = kS, //!< Sign flag.
+ kPositive = kNS, //!< No sign flag.
+
+ kOverflow = kO, //!< Overflow (signed).
+ kNotOverflow = kNO, //!< Not overflow (signed).
+
+ kEqual = kE, //!< `a == b` (equal).
+ kNotEqual = kNE, //!< `a != b` (not equal).
+
+ kSignedLT = kL, //!< `a < b` (signed).
+ kSignedLE = kLE, //!< `a <= b` (signed).
+ kSignedGT = kG, //!< `a > b` (signed).
+ kSignedGE = kGE, //!< `a >= b` (signed).
+
+ kUnsignedLT = kB, //!< `a < b` (unsigned).
+ kUnsignedLE = kBE, //!< `a <= b` (unsigned).
+ kUnsignedGT = kA, //!< `a > b` (unsigned).
+ kUnsignedGE = kAE, //!< `a >= b` (unsigned).
+
+ kParityEven = kP, //!< Even parity flag.
+ kParityOdd = kPO, //!< Odd parity flag.
+
+ kMaxValue = 0x0Fu
+};
+
+//! \cond
+static constexpr CondCode _reverseCondTable[] = {
+ CondCode::kO, // O <- O
+ CondCode::kNO, // NO <- NO
+ CondCode::kA , // A <- B
+ CondCode::kBE, // BE <- AE
+ CondCode::kE, // E <- E
+ CondCode::kNE, // NE <- NE
+ CondCode::kAE, // AE <- BE
+ CondCode::kB , // B <- A
+ CondCode::kS, // S <- S
+ CondCode::kNS, // NS <- NS
+ CondCode::kPE, // PE <- PE
+ CondCode::kPO, // PO <- PO
+ CondCode::kG, // G <- L
+ CondCode::kLE, // LE <- GE
+ CondCode::kGE, // GE <- LE
+ CondCode::kL // L <- G
+};
+//! \endcond
+
+//! Reverses a condition code (reverses the corresponding operands of a comparison).
+static inline constexpr CondCode reverseCond(CondCode cond) noexcept { return _reverseCondTable[uint8_t(cond)]; }
+//! Negates a condition code.
+static inline constexpr CondCode negateCond(CondCode cond) noexcept { return CondCode(uint8_t(cond) ^ 1u); }
//! Instruction.
//!
-//! \note Only used to hold x86-specific enumerations and static functions.
-struct Inst : public BaseInst {
+//! \note Only used to hold x86-specific instruction identifiers and some additional helper functions.
+namespace Inst {
//! Instruction id.
enum Id : uint32_t {
// ${InstId:Begin}
@@ -851,8 +919,10 @@ struct Inst : public BaseInst {
kIdV4fnmaddps, //!< Instruction 'v4fnmaddps' {AVX512_4FMAPS}.
kIdV4fnmaddss, //!< Instruction 'v4fnmaddss' {AVX512_4FMAPS}.
kIdVaddpd, //!< Instruction 'vaddpd' {AVX|AVX512_F+VL}.
+ kIdVaddph, //!< Instruction 'vaddph' {AVX512_FP16+VL}.
kIdVaddps, //!< Instruction 'vaddps' {AVX|AVX512_F+VL}.
kIdVaddsd, //!< Instruction 'vaddsd' {AVX|AVX512_F}.
+ kIdVaddsh, //!< Instruction 'vaddsh' {AVX512_FP16}.
kIdVaddss, //!< Instruction 'vaddss' {AVX|AVX512_F}.
kIdVaddsubpd, //!< Instruction 'vaddsubpd' {AVX}.
kIdVaddsubps, //!< Instruction 'vaddsubps' {AVX}.
@@ -889,61 +959,98 @@ struct Inst : public BaseInst {
kIdVbroadcastsd, //!< Instruction 'vbroadcastsd' {AVX|AVX2|AVX512_F+VL}.
kIdVbroadcastss, //!< Instruction 'vbroadcastss' {AVX|AVX2|AVX512_F+VL}.
kIdVcmppd, //!< Instruction 'vcmppd' {AVX|AVX512_F+VL}.
+ kIdVcmpph, //!< Instruction 'vcmpph' {AVX512_FP16+VL}.
kIdVcmpps, //!< Instruction 'vcmpps' {AVX|AVX512_F+VL}.
kIdVcmpsd, //!< Instruction 'vcmpsd' {AVX|AVX512_F}.
+ kIdVcmpsh, //!< Instruction 'vcmpsh' {AVX512_FP16}.
kIdVcmpss, //!< Instruction 'vcmpss' {AVX|AVX512_F}.
kIdVcomisd, //!< Instruction 'vcomisd' {AVX|AVX512_F}.
+ kIdVcomish, //!< Instruction 'vcomish' {AVX512_FP16}.
kIdVcomiss, //!< Instruction 'vcomiss' {AVX|AVX512_F}.
kIdVcompresspd, //!< Instruction 'vcompresspd' {AVX512_F+VL}.
kIdVcompressps, //!< Instruction 'vcompressps' {AVX512_F+VL}.
kIdVcvtdq2pd, //!< Instruction 'vcvtdq2pd' {AVX|AVX512_F+VL}.
+ kIdVcvtdq2ph, //!< Instruction 'vcvtdq2ph' {AVX512_FP16+VL}.
kIdVcvtdq2ps, //!< Instruction 'vcvtdq2ps' {AVX|AVX512_F+VL}.
kIdVcvtne2ps2bf16, //!< Instruction 'vcvtne2ps2bf16' {AVX512_BF16+VL}.
kIdVcvtneps2bf16, //!< Instruction 'vcvtneps2bf16' {AVX512_BF16+VL}.
kIdVcvtpd2dq, //!< Instruction 'vcvtpd2dq' {AVX|AVX512_F+VL}.
+ kIdVcvtpd2ph, //!< Instruction 'vcvtpd2ph' {AVX512_FP16+VL}.
kIdVcvtpd2ps, //!< Instruction 'vcvtpd2ps' {AVX|AVX512_F+VL}.
kIdVcvtpd2qq, //!< Instruction 'vcvtpd2qq' {AVX512_DQ+VL}.
kIdVcvtpd2udq, //!< Instruction 'vcvtpd2udq' {AVX512_F+VL}.
kIdVcvtpd2uqq, //!< Instruction 'vcvtpd2uqq' {AVX512_DQ+VL}.
+ kIdVcvtph2dq, //!< Instruction 'vcvtph2dq' {AVX512_FP16+VL}.
+ kIdVcvtph2pd, //!< Instruction 'vcvtph2pd' {AVX512_FP16+VL}.
kIdVcvtph2ps, //!< Instruction 'vcvtph2ps' {AVX512_F+VL & F16C}.
+ kIdVcvtph2psx, //!< Instruction 'vcvtph2psx' {AVX512_FP16+VL}.
+ kIdVcvtph2qq, //!< Instruction 'vcvtph2qq' {AVX512_FP16+VL}.
+ kIdVcvtph2udq, //!< Instruction 'vcvtph2udq' {AVX512_FP16+VL}.
+ kIdVcvtph2uqq, //!< Instruction 'vcvtph2uqq' {AVX512_FP16+VL}.
+ kIdVcvtph2uw, //!< Instruction 'vcvtph2uw' {AVX512_FP16+VL}.
+ kIdVcvtph2w, //!< Instruction 'vcvtph2w' {AVX512_FP16+VL}.
kIdVcvtps2dq, //!< Instruction 'vcvtps2dq' {AVX|AVX512_F+VL}.
kIdVcvtps2pd, //!< Instruction 'vcvtps2pd' {AVX|AVX512_F+VL}.
kIdVcvtps2ph, //!< Instruction 'vcvtps2ph' {AVX512_F+VL & F16C}.
+ kIdVcvtps2phx, //!< Instruction 'vcvtps2phx' {AVX512_FP16+VL}.
kIdVcvtps2qq, //!< Instruction 'vcvtps2qq' {AVX512_DQ+VL}.
kIdVcvtps2udq, //!< Instruction 'vcvtps2udq' {AVX512_F+VL}.
kIdVcvtps2uqq, //!< Instruction 'vcvtps2uqq' {AVX512_DQ+VL}.
kIdVcvtqq2pd, //!< Instruction 'vcvtqq2pd' {AVX512_DQ+VL}.
+ kIdVcvtqq2ph, //!< Instruction 'vcvtqq2ph' {AVX512_FP16+VL}.
kIdVcvtqq2ps, //!< Instruction 'vcvtqq2ps' {AVX512_DQ+VL}.
+ kIdVcvtsd2sh, //!< Instruction 'vcvtsd2sh' {AVX512_FP16}.
kIdVcvtsd2si, //!< Instruction 'vcvtsd2si' {AVX|AVX512_F}.
kIdVcvtsd2ss, //!< Instruction 'vcvtsd2ss' {AVX|AVX512_F}.
kIdVcvtsd2usi, //!< Instruction 'vcvtsd2usi' {AVX512_F}.
+ kIdVcvtsh2sd, //!< Instruction 'vcvtsh2sd' {AVX512_FP16}.
+ kIdVcvtsh2si, //!< Instruction 'vcvtsh2si' {AVX512_FP16}.
+ kIdVcvtsh2ss, //!< Instruction 'vcvtsh2ss' {AVX512_FP16}.
+ kIdVcvtsh2usi, //!< Instruction 'vcvtsh2usi' {AVX512_FP16}.
kIdVcvtsi2sd, //!< Instruction 'vcvtsi2sd' {AVX|AVX512_F}.
+ kIdVcvtsi2sh, //!< Instruction 'vcvtsi2sh' {AVX512_FP16}.
kIdVcvtsi2ss, //!< Instruction 'vcvtsi2ss' {AVX|AVX512_F}.
kIdVcvtss2sd, //!< Instruction 'vcvtss2sd' {AVX|AVX512_F}.
+ kIdVcvtss2sh, //!< Instruction 'vcvtss2sh' {AVX512_FP16}.
kIdVcvtss2si, //!< Instruction 'vcvtss2si' {AVX|AVX512_F}.
kIdVcvtss2usi, //!< Instruction 'vcvtss2usi' {AVX512_F}.
kIdVcvttpd2dq, //!< Instruction 'vcvttpd2dq' {AVX|AVX512_F+VL}.
kIdVcvttpd2qq, //!< Instruction 'vcvttpd2qq' {AVX512_F+VL}.
kIdVcvttpd2udq, //!< Instruction 'vcvttpd2udq' {AVX512_F+VL}.
kIdVcvttpd2uqq, //!< Instruction 'vcvttpd2uqq' {AVX512_DQ+VL}.
+ kIdVcvttph2dq, //!< Instruction 'vcvttph2dq' {AVX512_FP16+VL}.
+ kIdVcvttph2qq, //!< Instruction 'vcvttph2qq' {AVX512_FP16+VL}.
+ kIdVcvttph2udq, //!< Instruction 'vcvttph2udq' {AVX512_FP16+VL}.
+ kIdVcvttph2uqq, //!< Instruction 'vcvttph2uqq' {AVX512_FP16+VL}.
+ kIdVcvttph2uw, //!< Instruction 'vcvttph2uw' {AVX512_FP16+VL}.
+ kIdVcvttph2w, //!< Instruction 'vcvttph2w' {AVX512_FP16+VL}.
kIdVcvttps2dq, //!< Instruction 'vcvttps2dq' {AVX|AVX512_F+VL}.
kIdVcvttps2qq, //!< Instruction 'vcvttps2qq' {AVX512_DQ+VL}.
kIdVcvttps2udq, //!< Instruction 'vcvttps2udq' {AVX512_F+VL}.
kIdVcvttps2uqq, //!< Instruction 'vcvttps2uqq' {AVX512_DQ+VL}.
kIdVcvttsd2si, //!< Instruction 'vcvttsd2si' {AVX|AVX512_F}.
kIdVcvttsd2usi, //!< Instruction 'vcvttsd2usi' {AVX512_F}.
+ kIdVcvttsh2si, //!< Instruction 'vcvttsh2si' {AVX512_FP16}.
+ kIdVcvttsh2usi, //!< Instruction 'vcvttsh2usi' {AVX512_FP16}.
kIdVcvttss2si, //!< Instruction 'vcvttss2si' {AVX|AVX512_F}.
kIdVcvttss2usi, //!< Instruction 'vcvttss2usi' {AVX512_F}.
kIdVcvtudq2pd, //!< Instruction 'vcvtudq2pd' {AVX512_F+VL}.
+ kIdVcvtudq2ph, //!< Instruction 'vcvtudq2ph' {AVX512_FP16+VL}.
kIdVcvtudq2ps, //!< Instruction 'vcvtudq2ps' {AVX512_F+VL}.
kIdVcvtuqq2pd, //!< Instruction 'vcvtuqq2pd' {AVX512_DQ+VL}.
+ kIdVcvtuqq2ph, //!< Instruction 'vcvtuqq2ph' {AVX512_FP16+VL}.
kIdVcvtuqq2ps, //!< Instruction 'vcvtuqq2ps' {AVX512_DQ+VL}.
kIdVcvtusi2sd, //!< Instruction 'vcvtusi2sd' {AVX512_F}.
+ kIdVcvtusi2sh, //!< Instruction 'vcvtusi2sh' {AVX512_FP16}.
kIdVcvtusi2ss, //!< Instruction 'vcvtusi2ss' {AVX512_F}.
+ kIdVcvtuw2ph, //!< Instruction 'vcvtuw2ph' {AVX512_FP16+VL}.
+ kIdVcvtw2ph, //!< Instruction 'vcvtw2ph' {AVX512_FP16+VL}.
kIdVdbpsadbw, //!< Instruction 'vdbpsadbw' {AVX512_BW+VL}.
kIdVdivpd, //!< Instruction 'vdivpd' {AVX|AVX512_F+VL}.
+ kIdVdivph, //!< Instruction 'vdivph' {AVX512_FP16+VL}.
kIdVdivps, //!< Instruction 'vdivps' {AVX|AVX512_F+VL}.
kIdVdivsd, //!< Instruction 'vdivsd' {AVX|AVX512_F}.
+ kIdVdivsh, //!< Instruction 'vdivsh' {AVX512_FP16}.
kIdVdivss, //!< Instruction 'vdivss' {AVX|AVX512_F}.
kIdVdpbf16ps, //!< Instruction 'vdpbf16ps' {AVX512_BF16+VL}.
kIdVdppd, //!< Instruction 'vdppd' {AVX}.
@@ -965,51 +1072,75 @@ struct Inst : public BaseInst {
kIdVextracti64x2, //!< Instruction 'vextracti64x2' {AVX512_DQ+VL}.
kIdVextracti64x4, //!< Instruction 'vextracti64x4' {AVX512_F}.
kIdVextractps, //!< Instruction 'vextractps' {AVX|AVX512_F}.
+ kIdVfcmaddcph, //!< Instruction 'vfcmaddcph' {AVX512_FP16+VL}.
+ kIdVfcmaddcsh, //!< Instruction 'vfcmaddcsh' {AVX512_FP16+VL}.
+ kIdVfcmulcph, //!< Instruction 'vfcmulcph' {AVX512_FP16+VL}.
+ kIdVfcmulcsh, //!< Instruction 'vfcmulcsh' {AVX512_FP16+VL}.
kIdVfixupimmpd, //!< Instruction 'vfixupimmpd' {AVX512_F+VL}.
kIdVfixupimmps, //!< Instruction 'vfixupimmps' {AVX512_F+VL}.
kIdVfixupimmsd, //!< Instruction 'vfixupimmsd' {AVX512_F}.
kIdVfixupimmss, //!< Instruction 'vfixupimmss' {AVX512_F}.
kIdVfmadd132pd, //!< Instruction 'vfmadd132pd' {FMA|AVX512_F+VL}.
+ kIdVfmadd132ph, //!< Instruction 'vfmadd132ph' {AVX512_FP16+VL}.
kIdVfmadd132ps, //!< Instruction 'vfmadd132ps' {FMA|AVX512_F+VL}.
kIdVfmadd132sd, //!< Instruction 'vfmadd132sd' {FMA|AVX512_F}.
+ kIdVfmadd132sh, //!< Instruction 'vfmadd132sh' {AVX512_FP16}.
kIdVfmadd132ss, //!< Instruction 'vfmadd132ss' {FMA|AVX512_F}.
kIdVfmadd213pd, //!< Instruction 'vfmadd213pd' {FMA|AVX512_F+VL}.
+ kIdVfmadd213ph, //!< Instruction 'vfmadd213ph' {AVX512_FP16+VL}.
kIdVfmadd213ps, //!< Instruction 'vfmadd213ps' {FMA|AVX512_F+VL}.
kIdVfmadd213sd, //!< Instruction 'vfmadd213sd' {FMA|AVX512_F}.
+ kIdVfmadd213sh, //!< Instruction 'vfmadd213sh' {AVX512_FP16}.
kIdVfmadd213ss, //!< Instruction 'vfmadd213ss' {FMA|AVX512_F}.
kIdVfmadd231pd, //!< Instruction 'vfmadd231pd' {FMA|AVX512_F+VL}.
+ kIdVfmadd231ph, //!< Instruction 'vfmadd231ph' {AVX512_FP16+VL}.
kIdVfmadd231ps, //!< Instruction 'vfmadd231ps' {FMA|AVX512_F+VL}.
kIdVfmadd231sd, //!< Instruction 'vfmadd231sd' {FMA|AVX512_F}.
+ kIdVfmadd231sh, //!< Instruction 'vfmadd231sh' {AVX512_FP16}.
kIdVfmadd231ss, //!< Instruction 'vfmadd231ss' {FMA|AVX512_F}.
+ kIdVfmaddcph, //!< Instruction 'vfmaddcph' {AVX512_FP16+VL}.
+ kIdVfmaddcsh, //!< Instruction 'vfmaddcsh' {AVX512_FP16+VL}.
kIdVfmaddpd, //!< Instruction 'vfmaddpd' {FMA4}.
kIdVfmaddps, //!< Instruction 'vfmaddps' {FMA4}.
kIdVfmaddsd, //!< Instruction 'vfmaddsd' {FMA4}.
kIdVfmaddss, //!< Instruction 'vfmaddss' {FMA4}.
kIdVfmaddsub132pd, //!< Instruction 'vfmaddsub132pd' {FMA|AVX512_F+VL}.
+ kIdVfmaddsub132ph, //!< Instruction 'vfmaddsub132ph' {AVX512_FP16+VL}.
kIdVfmaddsub132ps, //!< Instruction 'vfmaddsub132ps' {FMA|AVX512_F+VL}.
kIdVfmaddsub213pd, //!< Instruction 'vfmaddsub213pd' {FMA|AVX512_F+VL}.
+ kIdVfmaddsub213ph, //!< Instruction 'vfmaddsub213ph' {AVX512_FP16+VL}.
kIdVfmaddsub213ps, //!< Instruction 'vfmaddsub213ps' {FMA|AVX512_F+VL}.
kIdVfmaddsub231pd, //!< Instruction 'vfmaddsub231pd' {FMA|AVX512_F+VL}.
+ kIdVfmaddsub231ph, //!< Instruction 'vfmaddsub231ph' {AVX512_FP16+VL}.
kIdVfmaddsub231ps, //!< Instruction 'vfmaddsub231ps' {FMA|AVX512_F+VL}.
kIdVfmaddsubpd, //!< Instruction 'vfmaddsubpd' {FMA4}.
kIdVfmaddsubps, //!< Instruction 'vfmaddsubps' {FMA4}.
kIdVfmsub132pd, //!< Instruction 'vfmsub132pd' {FMA|AVX512_F+VL}.
+ kIdVfmsub132ph, //!< Instruction 'vfmsub132ph' {AVX512_FP16+VL}.
kIdVfmsub132ps, //!< Instruction 'vfmsub132ps' {FMA|AVX512_F+VL}.
kIdVfmsub132sd, //!< Instruction 'vfmsub132sd' {FMA|AVX512_F}.
+ kIdVfmsub132sh, //!< Instruction 'vfmsub132sh' {AVX512_FP16}.
kIdVfmsub132ss, //!< Instruction 'vfmsub132ss' {FMA|AVX512_F}.
kIdVfmsub213pd, //!< Instruction 'vfmsub213pd' {FMA|AVX512_F+VL}.
+ kIdVfmsub213ph, //!< Instruction 'vfmsub213ph' {AVX512_FP16+VL}.
kIdVfmsub213ps, //!< Instruction 'vfmsub213ps' {FMA|AVX512_F+VL}.
kIdVfmsub213sd, //!< Instruction 'vfmsub213sd' {FMA|AVX512_F}.
+ kIdVfmsub213sh, //!< Instruction 'vfmsub213sh' {AVX512_FP16}.
kIdVfmsub213ss, //!< Instruction 'vfmsub213ss' {FMA|AVX512_F}.
kIdVfmsub231pd, //!< Instruction 'vfmsub231pd' {FMA|AVX512_F+VL}.
+ kIdVfmsub231ph, //!< Instruction 'vfmsub231ph' {AVX512_FP16+VL}.
kIdVfmsub231ps, //!< Instruction 'vfmsub231ps' {FMA|AVX512_F+VL}.
kIdVfmsub231sd, //!< Instruction 'vfmsub231sd' {FMA|AVX512_F}.
+ kIdVfmsub231sh, //!< Instruction 'vfmsub231sh' {AVX512_FP16}.
kIdVfmsub231ss, //!< Instruction 'vfmsub231ss' {FMA|AVX512_F}.
kIdVfmsubadd132pd, //!< Instruction 'vfmsubadd132pd' {FMA|AVX512_F+VL}.
+ kIdVfmsubadd132ph, //!< Instruction 'vfmsubadd132ph' {AVX512_FP16+VL}.
kIdVfmsubadd132ps, //!< Instruction 'vfmsubadd132ps' {FMA|AVX512_F+VL}.
kIdVfmsubadd213pd, //!< Instruction 'vfmsubadd213pd' {FMA|AVX512_F+VL}.
+ kIdVfmsubadd213ph, //!< Instruction 'vfmsubadd213ph' {AVX512_FP16+VL}.
kIdVfmsubadd213ps, //!< Instruction 'vfmsubadd213ps' {FMA|AVX512_F+VL}.
kIdVfmsubadd231pd, //!< Instruction 'vfmsubadd231pd' {FMA|AVX512_F+VL}.
+ kIdVfmsubadd231ph, //!< Instruction 'vfmsubadd231ph' {AVX512_FP16+VL}.
kIdVfmsubadd231ps, //!< Instruction 'vfmsubadd231ps' {FMA|AVX512_F+VL}.
kIdVfmsubaddpd, //!< Instruction 'vfmsubaddpd' {FMA4}.
kIdVfmsubaddps, //!< Instruction 'vfmsubaddps' {FMA4}.
@@ -1017,41 +1148,57 @@ struct Inst : public BaseInst {
kIdVfmsubps, //!< Instruction 'vfmsubps' {FMA4}.
kIdVfmsubsd, //!< Instruction 'vfmsubsd' {FMA4}.
kIdVfmsubss, //!< Instruction 'vfmsubss' {FMA4}.
+ kIdVfmulcph, //!< Instruction 'vfmulcph' {AVX512_FP16+VL}.
+ kIdVfmulcsh, //!< Instruction 'vfmulcsh' {AVX512_FP16+VL}.
kIdVfnmadd132pd, //!< Instruction 'vfnmadd132pd' {FMA|AVX512_F+VL}.
+ kIdVfnmadd132ph, //!< Instruction 'vfnmadd132ph' {AVX512_FP16+VL}.
kIdVfnmadd132ps, //!< Instruction 'vfnmadd132ps' {FMA|AVX512_F+VL}.
kIdVfnmadd132sd, //!< Instruction 'vfnmadd132sd' {FMA|AVX512_F}.
+ kIdVfnmadd132sh, //!< Instruction 'vfnmadd132sh' {AVX512_FP16}.
kIdVfnmadd132ss, //!< Instruction 'vfnmadd132ss' {FMA|AVX512_F}.
kIdVfnmadd213pd, //!< Instruction 'vfnmadd213pd' {FMA|AVX512_F+VL}.
+ kIdVfnmadd213ph, //!< Instruction 'vfnmadd213ph' {AVX512_FP16+VL}.
kIdVfnmadd213ps, //!< Instruction 'vfnmadd213ps' {FMA|AVX512_F+VL}.
kIdVfnmadd213sd, //!< Instruction 'vfnmadd213sd' {FMA|AVX512_F}.
+ kIdVfnmadd213sh, //!< Instruction 'vfnmadd213sh' {AVX512_FP16}.
kIdVfnmadd213ss, //!< Instruction 'vfnmadd213ss' {FMA|AVX512_F}.
kIdVfnmadd231pd, //!< Instruction 'vfnmadd231pd' {FMA|AVX512_F+VL}.
+ kIdVfnmadd231ph, //!< Instruction 'vfnmadd231ph' {AVX512_FP16+VL}.
kIdVfnmadd231ps, //!< Instruction 'vfnmadd231ps' {FMA|AVX512_F+VL}.
kIdVfnmadd231sd, //!< Instruction 'vfnmadd231sd' {FMA|AVX512_F}.
+ kIdVfnmadd231sh, //!< Instruction 'vfnmadd231sh' {AVX512_FP16}.
kIdVfnmadd231ss, //!< Instruction 'vfnmadd231ss' {FMA|AVX512_F}.
kIdVfnmaddpd, //!< Instruction 'vfnmaddpd' {FMA4}.
kIdVfnmaddps, //!< Instruction 'vfnmaddps' {FMA4}.
kIdVfnmaddsd, //!< Instruction 'vfnmaddsd' {FMA4}.
kIdVfnmaddss, //!< Instruction 'vfnmaddss' {FMA4}.
kIdVfnmsub132pd, //!< Instruction 'vfnmsub132pd' {FMA|AVX512_F+VL}.
+ kIdVfnmsub132ph, //!< Instruction 'vfnmsub132ph' {AVX512_FP16+VL}.
kIdVfnmsub132ps, //!< Instruction 'vfnmsub132ps' {FMA|AVX512_F+VL}.
kIdVfnmsub132sd, //!< Instruction 'vfnmsub132sd' {FMA|AVX512_F}.
+ kIdVfnmsub132sh, //!< Instruction 'vfnmsub132sh' {AVX512_FP16}.
kIdVfnmsub132ss, //!< Instruction 'vfnmsub132ss' {FMA|AVX512_F}.
kIdVfnmsub213pd, //!< Instruction 'vfnmsub213pd' {FMA|AVX512_F+VL}.
+ kIdVfnmsub213ph, //!< Instruction 'vfnmsub213ph' {AVX512_FP16+VL}.
kIdVfnmsub213ps, //!< Instruction 'vfnmsub213ps' {FMA|AVX512_F+VL}.
kIdVfnmsub213sd, //!< Instruction 'vfnmsub213sd' {FMA|AVX512_F}.
+ kIdVfnmsub213sh, //!< Instruction 'vfnmsub213sh' {AVX512_FP16}.
kIdVfnmsub213ss, //!< Instruction 'vfnmsub213ss' {FMA|AVX512_F}.
kIdVfnmsub231pd, //!< Instruction 'vfnmsub231pd' {FMA|AVX512_F+VL}.
+ kIdVfnmsub231ph, //!< Instruction 'vfnmsub231ph' {AVX512_FP16+VL}.
kIdVfnmsub231ps, //!< Instruction 'vfnmsub231ps' {FMA|AVX512_F+VL}.
kIdVfnmsub231sd, //!< Instruction 'vfnmsub231sd' {FMA|AVX512_F}.
+ kIdVfnmsub231sh, //!< Instruction 'vfnmsub231sh' {AVX512_FP16}.
kIdVfnmsub231ss, //!< Instruction 'vfnmsub231ss' {FMA|AVX512_F}.
kIdVfnmsubpd, //!< Instruction 'vfnmsubpd' {FMA4}.
kIdVfnmsubps, //!< Instruction 'vfnmsubps' {FMA4}.
kIdVfnmsubsd, //!< Instruction 'vfnmsubsd' {FMA4}.
kIdVfnmsubss, //!< Instruction 'vfnmsubss' {FMA4}.
kIdVfpclasspd, //!< Instruction 'vfpclasspd' {AVX512_DQ+VL}.
+ kIdVfpclassph, //!< Instruction 'vfpclassph' {AVX512_FP16+VL}.
kIdVfpclassps, //!< Instruction 'vfpclassps' {AVX512_DQ+VL}.
kIdVfpclasssd, //!< Instruction 'vfpclasssd' {AVX512_DQ}.
+ kIdVfpclasssh, //!< Instruction 'vfpclasssh' {AVX512_FP16}.
kIdVfpclassss, //!< Instruction 'vfpclassss' {AVX512_DQ}.
kIdVfrczpd, //!< Instruction 'vfrczpd' {XOP}.
kIdVfrczps, //!< Instruction 'vfrczps' {XOP}.
@@ -1070,12 +1217,16 @@ struct Inst : public BaseInst {
kIdVgatherqpd, //!< Instruction 'vgatherqpd' {AVX2|AVX512_F+VL}.
kIdVgatherqps, //!< Instruction 'vgatherqps' {AVX2|AVX512_F+VL}.
kIdVgetexppd, //!< Instruction 'vgetexppd' {AVX512_F+VL}.
+ kIdVgetexpph, //!< Instruction 'vgetexpph' {AVX512_FP16+VL}.
kIdVgetexpps, //!< Instruction 'vgetexpps' {AVX512_F+VL}.
kIdVgetexpsd, //!< Instruction 'vgetexpsd' {AVX512_F}.
+ kIdVgetexpsh, //!< Instruction 'vgetexpsh' {AVX512_FP16}.
kIdVgetexpss, //!< Instruction 'vgetexpss' {AVX512_F}.
kIdVgetmantpd, //!< Instruction 'vgetmantpd' {AVX512_F+VL}.
+ kIdVgetmantph, //!< Instruction 'vgetmantph' {AVX512_FP16+VL}.
kIdVgetmantps, //!< Instruction 'vgetmantps' {AVX512_F+VL}.
kIdVgetmantsd, //!< Instruction 'vgetmantsd' {AVX512_F}.
+ kIdVgetmantsh, //!< Instruction 'vgetmantsh' {AVX512_FP16}.
kIdVgetmantss, //!< Instruction 'vgetmantss' {AVX512_F}.
kIdVgf2p8affineinvqb, //!< Instruction 'vgf2p8affineinvqb' {AVX|AVX512_F+VL & GFNI}.
kIdVgf2p8affineqb, //!< Instruction 'vgf2p8affineqb' {AVX|AVX512_F+VL & GFNI}.
@@ -1101,15 +1252,19 @@ struct Inst : public BaseInst {
kIdVmaskmovpd, //!< Instruction 'vmaskmovpd' {AVX}.
kIdVmaskmovps, //!< Instruction 'vmaskmovps' {AVX}.
kIdVmaxpd, //!< Instruction 'vmaxpd' {AVX|AVX512_F+VL}.
+ kIdVmaxph, //!< Instruction 'vmaxph' {AVX512_FP16+VL}.
kIdVmaxps, //!< Instruction 'vmaxps' {AVX|AVX512_F+VL}.
kIdVmaxsd, //!< Instruction 'vmaxsd' {AVX|AVX512_F+VL}.
+ kIdVmaxsh, //!< Instruction 'vmaxsh' {AVX512_FP16}.
kIdVmaxss, //!< Instruction 'vmaxss' {AVX|AVX512_F+VL}.
kIdVmcall, //!< Instruction 'vmcall' {VMX}.
kIdVmclear, //!< Instruction 'vmclear' {VMX}.
kIdVmfunc, //!< Instruction 'vmfunc' {VMX}.
kIdVminpd, //!< Instruction 'vminpd' {AVX|AVX512_F+VL}.
+ kIdVminph, //!< Instruction 'vminph' {AVX512_FP16+VL}.
kIdVminps, //!< Instruction 'vminps' {AVX|AVX512_F+VL}.
kIdVminsd, //!< Instruction 'vminsd' {AVX|AVX512_F+VL}.
+ kIdVminsh, //!< Instruction 'vminsh' {AVX512_FP16}.
kIdVminss, //!< Instruction 'vminss' {AVX|AVX512_F+VL}.
kIdVmlaunch, //!< Instruction 'vmlaunch' {VMX}.
kIdVmload, //!< Instruction 'vmload' {SVM}.
@@ -1140,11 +1295,13 @@ struct Inst : public BaseInst {
kIdVmovntps, //!< Instruction 'vmovntps' {AVX|AVX512_F+VL}.
kIdVmovq, //!< Instruction 'vmovq' {AVX|AVX512_F}.
kIdVmovsd, //!< Instruction 'vmovsd' {AVX|AVX512_F}.
+ kIdVmovsh, //!< Instruction 'vmovsh' {AVX512_FP16}.
kIdVmovshdup, //!< Instruction 'vmovshdup' {AVX|AVX512_F+VL}.
kIdVmovsldup, //!< Instruction 'vmovsldup' {AVX|AVX512_F+VL}.
kIdVmovss, //!< Instruction 'vmovss' {AVX|AVX512_F}.
kIdVmovupd, //!< Instruction 'vmovupd' {AVX|AVX512_F+VL}.
kIdVmovups, //!< Instruction 'vmovups' {AVX|AVX512_F+VL}.
+ kIdVmovw, //!< Instruction 'vmovw' {AVX512_FP16}.
kIdVmpsadbw, //!< Instruction 'vmpsadbw' {AVX|AVX2}.
kIdVmptrld, //!< Instruction 'vmptrld' {VMX}.
kIdVmptrst, //!< Instruction 'vmptrst' {VMX}.
@@ -1153,8 +1310,10 @@ struct Inst : public BaseInst {
kIdVmrun, //!< Instruction 'vmrun' {SVM}.
kIdVmsave, //!< Instruction 'vmsave' {SVM}.
kIdVmulpd, //!< Instruction 'vmulpd' {AVX|AVX512_F+VL}.
+ kIdVmulph, //!< Instruction 'vmulph' {AVX512_FP16+VL}.
kIdVmulps, //!< Instruction 'vmulps' {AVX|AVX512_F+VL}.
kIdVmulsd, //!< Instruction 'vmulsd' {AVX|AVX512_F}.
+ kIdVmulsh, //!< Instruction 'vmulsh' {AVX512_FP16}.
kIdVmulss, //!< Instruction 'vmulss' {AVX|AVX512_F}.
kIdVmwrite, //!< Instruction 'vmwrite' {VMX}.
kIdVmxon, //!< Instruction 'vmxon' {VMX}.
@@ -1503,15 +1662,21 @@ struct Inst : public BaseInst {
kIdVrcp28ps, //!< Instruction 'vrcp28ps' {AVX512_ERI}.
kIdVrcp28sd, //!< Instruction 'vrcp28sd' {AVX512_ERI}.
kIdVrcp28ss, //!< Instruction 'vrcp28ss' {AVX512_ERI}.
+ kIdVrcpph, //!< Instruction 'vrcpph' {AVX512_FP16}.
kIdVrcpps, //!< Instruction 'vrcpps' {AVX}.
+ kIdVrcpsh, //!< Instruction 'vrcpsh' {AVX512_FP16}.
kIdVrcpss, //!< Instruction 'vrcpss' {AVX}.
kIdVreducepd, //!< Instruction 'vreducepd' {AVX512_DQ+VL}.
+ kIdVreduceph, //!< Instruction 'vreduceph' {AVX512_FP16+VL}.
kIdVreduceps, //!< Instruction 'vreduceps' {AVX512_DQ+VL}.
kIdVreducesd, //!< Instruction 'vreducesd' {AVX512_DQ}.
+ kIdVreducesh, //!< Instruction 'vreducesh' {AVX512_FP16}.
kIdVreducess, //!< Instruction 'vreducess' {AVX512_DQ}.
kIdVrndscalepd, //!< Instruction 'vrndscalepd' {AVX512_F+VL}.
+ kIdVrndscaleph, //!< Instruction 'vrndscaleph' {AVX512_FP16+VL}.
kIdVrndscaleps, //!< Instruction 'vrndscaleps' {AVX512_F+VL}.
kIdVrndscalesd, //!< Instruction 'vrndscalesd' {AVX512_F}.
+ kIdVrndscalesh, //!< Instruction 'vrndscalesh' {AVX512_FP16}.
kIdVrndscaless, //!< Instruction 'vrndscaless' {AVX512_F}.
kIdVroundpd, //!< Instruction 'vroundpd' {AVX}.
kIdVroundps, //!< Instruction 'vroundps' {AVX}.
@@ -1525,11 +1690,15 @@ struct Inst : public BaseInst {
kIdVrsqrt28ps, //!< Instruction 'vrsqrt28ps' {AVX512_ERI}.
kIdVrsqrt28sd, //!< Instruction 'vrsqrt28sd' {AVX512_ERI}.
kIdVrsqrt28ss, //!< Instruction 'vrsqrt28ss' {AVX512_ERI}.
+ kIdVrsqrtph, //!< Instruction 'vrsqrtph' {AVX512_FP16+VL}.
kIdVrsqrtps, //!< Instruction 'vrsqrtps' {AVX}.
+ kIdVrsqrtsh, //!< Instruction 'vrsqrtsh' {AVX512_FP16}.
kIdVrsqrtss, //!< Instruction 'vrsqrtss' {AVX}.
kIdVscalefpd, //!< Instruction 'vscalefpd' {AVX512_F+VL}.
+ kIdVscalefph, //!< Instruction 'vscalefph' {AVX512_FP16+VL}.
kIdVscalefps, //!< Instruction 'vscalefps' {AVX512_F+VL}.
kIdVscalefsd, //!< Instruction 'vscalefsd' {AVX512_F}.
+ kIdVscalefsh, //!< Instruction 'vscalefsh' {AVX512_FP16}.
kIdVscalefss, //!< Instruction 'vscalefss' {AVX512_F}.
kIdVscatterdpd, //!< Instruction 'vscatterdpd' {AVX512_F+VL}.
kIdVscatterdps, //!< Instruction 'vscatterdps' {AVX512_F+VL}.
@@ -1550,17 +1719,22 @@ struct Inst : public BaseInst {
kIdVshufpd, //!< Instruction 'vshufpd' {AVX|AVX512_F+VL}.
kIdVshufps, //!< Instruction 'vshufps' {AVX|AVX512_F+VL}.
kIdVsqrtpd, //!< Instruction 'vsqrtpd' {AVX|AVX512_F+VL}.
+ kIdVsqrtph, //!< Instruction 'vsqrtph' {AVX512_FP16+VL}.
kIdVsqrtps, //!< Instruction 'vsqrtps' {AVX|AVX512_F+VL}.
kIdVsqrtsd, //!< Instruction 'vsqrtsd' {AVX|AVX512_F}.
+ kIdVsqrtsh, //!< Instruction 'vsqrtsh' {AVX512_FP16}.
kIdVsqrtss, //!< Instruction 'vsqrtss' {AVX|AVX512_F}.
kIdVstmxcsr, //!< Instruction 'vstmxcsr' {AVX}.
kIdVsubpd, //!< Instruction 'vsubpd' {AVX|AVX512_F+VL}.
+ kIdVsubph, //!< Instruction 'vsubph' {AVX512_FP16+VL}.
kIdVsubps, //!< Instruction 'vsubps' {AVX|AVX512_F+VL}.
kIdVsubsd, //!< Instruction 'vsubsd' {AVX|AVX512_F}.
+ kIdVsubsh, //!< Instruction 'vsubsh' {AVX512_FP16}.
kIdVsubss, //!< Instruction 'vsubss' {AVX|AVX512_F}.
kIdVtestpd, //!< Instruction 'vtestpd' {AVX}.
kIdVtestps, //!< Instruction 'vtestps' {AVX}.
kIdVucomisd, //!< Instruction 'vucomisd' {AVX|AVX512_F}.
+ kIdVucomish, //!< Instruction 'vucomish' {AVX512_FP16}.
kIdVucomiss, //!< Instruction 'vucomiss' {AVX|AVX512_F}.
kIdVunpckhpd, //!< Instruction 'vunpckhpd' {AVX|AVX512_F+VL}.
kIdVunpckhps, //!< Instruction 'vunpckhps' {AVX|AVX512_F+VL}.
@@ -1609,560 +1783,383 @@ struct Inst : public BaseInst {
// ${InstId:End}
};
- //! Instruction options.
- enum Options : uint32_t {
- kOptionModMR = 0x00000100u, //!< Use ModMR instead of ModRM if applicable.
- kOptionModRM = 0x00000200u, //!< Use ModRM instead of ModMR if applicable.
- kOptionVex3 = 0x00000400u, //!< Use 3-byte VEX prefix if possible (AVX) (must be 0x00000400).
- kOptionVex = 0x00000800u, //!< Use VEX prefix when both VEX|EVEX prefixes are available (HINT: AVX_VNNI).
- kOptionEvex = 0x00001000u, //!< Use 4-byte EVEX prefix if possible (AVX-512) (must be 0x00001000).
-
- kOptionLock = 0x00002000u, //!< LOCK prefix (lock-enabled instructions only).
- kOptionRep = 0x00004000u, //!< REP prefix (string instructions only).
- kOptionRepne = 0x00008000u, //!< REPNE prefix (string instructions only).
-
- kOptionXAcquire = 0x00010000u, //!< XACQUIRE prefix (only allowed instructions).
- kOptionXRelease = 0x00020000u, //!< XRELEASE prefix (only allowed instructions).
-
- kOptionER = 0x00040000u, //!< AVX-512: embedded-rounding {er} and implicit {sae}.
- kOptionSAE = 0x00080000u, //!< AVX-512: suppress-all-exceptions {sae}.
- kOptionRN_SAE = 0x00000000u, //!< AVX-512: round-to-nearest (even) {rn-sae} (bits 00).
- kOptionRD_SAE = 0x00200000u, //!< AVX-512: round-down (toward -inf) {rd-sae} (bits 01).
- kOptionRU_SAE = 0x00400000u, //!< AVX-512: round-up (toward +inf) {ru-sae} (bits 10).
- kOptionRZ_SAE = 0x00600000u, //!< AVX-512: round-toward-zero (truncate) {rz-sae} (bits 11).
- kOptionZMask = 0x00800000u, //!< AVX-512: Use zeroing {k}{z} instead of merging {k}.
- _kOptionAvx512Mask = 0x00FC0000u, //!< AVX-512: Mask of all possible AVX-512 options except EVEX prefix flag.
-
- kOptionOpCodeB = 0x01000000u, //!< REX.B and/or VEX.B field (X64).
- kOptionOpCodeX = 0x02000000u, //!< REX.X and/or VEX.X field (X64).
- kOptionOpCodeR = 0x04000000u, //!< REX.R and/or VEX.R field (X64).
- kOptionOpCodeW = 0x08000000u, //!< REX.W and/or VEX.W field (X64).
- kOptionRex = 0x40000000u, //!< Force REX prefix (X64).
- _kOptionInvalidRex = 0x80000000u //!< Invalid REX prefix (set by X86 or when AH|BH|CH|DH regs are used on X64).
- };
-
- // --------------------------------------------------------------------------
- // [Statics]
- // --------------------------------------------------------------------------
-
- //! Tests whether the `instId` is defined (counts also Inst::kIdNone, which must be zero).
- static inline bool isDefinedId(uint32_t instId) noexcept { return instId < _kIdCount; }
-};
-
-// ============================================================================
-// [asmjit::x86::Condition]
-// ============================================================================
-
-namespace Condition {
- //! Condition code.
- enum Code : uint32_t {
- kO = 0x00u, //!< OF==1
- kNO = 0x01u, //!< OF==0
- kB = 0x02u, //!< CF==1 (unsigned < )
- kC = 0x02u, //!< CF==1
- kNAE = 0x02u, //!< CF==1 (unsigned < )
- kAE = 0x03u, //!< CF==0 (unsigned >=)
- kNB = 0x03u, //!< CF==0 (unsigned >=)
- kNC = 0x03u, //!< CF==0
- kE = 0x04u, //!< ZF==1 (any_sign ==)
- kZ = 0x04u, //!< ZF==1 (any_sign ==)
- kNE = 0x05u, //!< ZF==0 (any_sign !=)
- kNZ = 0x05u, //!< ZF==0 (any_sign !=)
- kBE = 0x06u, //!< CF==1 | ZF==1 (unsigned <=)
- kNA = 0x06u, //!< CF==1 | ZF==1 (unsigned <=)
- kA = 0x07u, //!< CF==0 & ZF==0 (unsigned > )
- kNBE = 0x07u, //!< CF==0 & ZF==0 (unsigned > )
- kS = 0x08u, //!< SF==1 (is negative)
- kNS = 0x09u, //!< SF==0 (is positive or zero)
- kP = 0x0Au, //!< PF==1
- kPE = 0x0Au, //!< PF==1
- kPO = 0x0Bu, //!< PF==0
- kNP = 0x0Bu, //!< PF==0
- kL = 0x0Cu, //!< SF!=OF (signed < )
- kNGE = 0x0Cu, //!< SF!=OF (signed < )
- kGE = 0x0Du, //!< SF==OF (signed >=)
- kNL = 0x0Du, //!< SF==OF (signed >=)
- kLE = 0x0Eu, //!< ZF==1 | SF!=OF (signed <=)
- kNG = 0x0Eu, //!< ZF==1 | SF!=OF (signed <=)
- kG = 0x0Fu, //!< ZF==0 & SF==OF (signed > )
- kNLE = 0x0Fu, //!< ZF==0 & SF==OF (signed > )
- kCount = 0x10u,
-
- kSign = kS, //!< Sign.
- kNotSign = kNS, //!< Not Sign.
-
- kOverflow = kO, //!< Signed overflow.
- kNotOverflow = kNO, //!< Not signed overflow.
-
- kEqual = kE, //!< Equal `a == b`.
- kNotEqual = kNE, //!< Not Equal `a != b`.
-
- kSignedLT = kL, //!< Signed `a < b`.
- kSignedLE = kLE, //!< Signed `a <= b`.
- kSignedGT = kG, //!< Signed `a > b`.
- kSignedGE = kGE, //!< Signed `a >= b`.
-
- kUnsignedLT = kB, //!< Unsigned `a < b`.
- kUnsignedLE = kBE, //!< Unsigned `a <= b`.
- kUnsignedGT = kA, //!< Unsigned `a > b`.
- kUnsignedGE = kAE, //!< Unsigned `a >= b`.
-
- kZero = kZ, //!< Zero flag.
- kNotZero = kNZ, //!< Non-zero flag.
-
- kNegative = kS, //!< Sign flag.
- kPositive = kNS, //!< No sign flag.
-
- kParityEven = kP, //!< Even parity flag.
- kParityOdd = kPO //!< Odd parity flag.
- };
-
- static constexpr uint8_t reverseTable[kCount] = {
- kO, kNO, kA , kBE, // O|NO|B |AE
- kE, kNE, kAE, kB , // E|NE|BE|A
- kS, kNS, kPE, kPO, // S|NS|PE|PO
- kG, kLE, kGE, kL // L|GE|LE|G
- };
+ //! Tests whether the `instId` is defined.
+ static inline constexpr bool isDefinedId(InstId instId) noexcept { return instId < _kIdCount; }
+ //! \cond
#define ASMJIT_INST_FROM_COND(ID) \
ID##o, ID##no, ID##b , ID##ae, \
ID##e, ID##ne, ID##be, ID##a , \
ID##s, ID##ns, ID##pe, ID##po, \
ID##l, ID##ge, ID##le, ID##g
- static constexpr uint16_t jccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdJ) };
- static constexpr uint16_t setccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdSet) };
- static constexpr uint16_t cmovccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdCmov) };
- #undef ASMJIT_INST_FROM_COND
- //! Reverses a condition code (reverses the corresponding operands of a comparison).
- static constexpr uint32_t reverse(uint32_t cond) noexcept { return reverseTable[cond]; }
- //! Negates a condition code.
- static constexpr uint32_t negate(uint32_t cond) noexcept { return cond ^ 1u; }
+ static constexpr uint16_t _jccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdJ) };
+ static constexpr uint16_t _setccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdSet) };
+ static constexpr uint16_t _cmovccTable[] = { ASMJIT_INST_FROM_COND(Inst::kIdCmov) };
+
+ #undef ASMJIT_INST_FROM_COND
+ //! \endcond
//! Translates a condition code `cond` to a `jcc` instruction id.
- static constexpr uint32_t toJcc(uint32_t cond) noexcept { return jccTable[cond]; }
+ static constexpr InstId jccFromCond(CondCode cond) noexcept { return _jccTable[uint8_t(cond)]; }
//! Translates a condition code `cond` to a `setcc` instruction id.
- static constexpr uint32_t toSetcc(uint32_t cond) noexcept { return setccTable[cond]; }
+ static constexpr InstId setccFromCond(CondCode cond) noexcept { return _setccTable[uint8_t(cond)]; }
//! Translates a condition code `cond` to a `cmovcc` instruction id.
- static constexpr uint32_t toCmovcc(uint32_t cond) noexcept { return cmovccTable[cond]; }
-}
+ static constexpr InstId cmovccFromCond(CondCode cond) noexcept { return _cmovccTable[uint8_t(cond)]; }
+} // {Inst}
+
+//! FPU status word bits.
+enum class FpuStatusWord : uint16_t {
+ kNone = 0x0000u, //!< No bits set.
+
+ kInvalid = 0x0001u, //!< Invalid operation.
+ kDenormalized = 0x0002u, //!< Denormalized operand.
+ kDivByZero = 0x0004u, //!< Division by zero.
+ kOverflow = 0x0008u, //!< Overflown.
+ kUnderflow = 0x0010u, //!< Underflown.
+ kPrecision = 0x0020u, //!< Precision lost.
+ kStackFault = 0x0040u, //!< Stack fault.
+ kInterrupt = 0x0080u, //!< Interrupt.
+ kC0 = 0x0100u, //!< C0 flag.
+ kC1 = 0x0200u, //!< C1 flag.
+ kC2 = 0x0400u, //!< C2 flag.
+ kTopMask = 0x3800u, //!< Top of the stack (mask).
+ kC3 = 0x4000u, //!< C3 flag.
+ kBusy = 0x8000u //!< FPU is busy.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(FpuStatusWord)
+
+//! FPU control word bits.
+enum class FpuControlWord : uint16_t {
+ kNone = 0x0000u, //!< No bits set.
+
+ // Bits 0-5
+ // --------
+
+ kEM_Mask = 0x003Fu, //!< Exception mask (0x3F).
+ kEM_Invalid = 0x0001u, //!< Invalid operation exception.
+ kEM_Denormal = 0x0002u, //!< Denormalized operand exception.
+ kEM_DivByZero = 0x0004u, //!< Division by zero exception.
+ kEM_Overflow = 0x0008u, //!< Overflow exception.
+ kEM_Underflow = 0x0010u, //!< Underflow exception.
+ kEM_Inexact = 0x0020u, //!< Inexact operation exception.
+
+ // Bits 8-9
+ // --------
+
+ kPC_Mask = 0x0300u, //!< Precision control mask.
+ kPC_Float = 0x0000u, //!< Single precision (24 bits).
+ kPC_Reserved = 0x0100u, //!< Reserved.
+ kPC_Double = 0x0200u, //!< Double precision (53 bits).
+ kPC_Extended = 0x0300u, //!< Extended precision (64 bits).
+
+ // Bits 10-11
+ // ----------
+
+ kRC_Mask = 0x0C00u, //!< Rounding control mask.
+ kRC_Nearest = 0x0000u, //!< Round to nearest even.
+ kRC_Down = 0x0400u, //!< Round down (floor).
+ kRC_Up = 0x0800u, //!< Round up (ceil).
+ kRC_Truncate = 0x0C00u, //!< Round towards zero (truncate).
+
+ // Bit 12
+ // ------
+
+ kIC_Mask = 0x1000u, //!< Infinity control.
+ kIC_Projective = 0x0000u, //!< Projective (not supported on X64).
+ kIC_Affine = 0x1000u //!< Affine (default).
+};
+ASMJIT_DEFINE_ENUM_FLAGS(FpuControlWord)
+
+//! An immediate value that can be used with CMP[PD|PS|SD|SS] instructions.
+enum class CmpImm : uint8_t {
+ kEQ = 0x00u, //!< Equal (Quiet), same as \ref VCmpImm::kEQ_OQ.
+ kLT = 0x01u, //!< Less (Signaling), same as \ref VCmpImm::kLT_OS.
+ kLE = 0x02u, //!< Less/Equal (Signaling), same as \ref VCmpImm::kLE_OS.
+ kUNORD = 0x03u, //!< Unordered (Quiet), same as \ref VCmpImm::kUNORD_Q.
+ kNEQ = 0x04u, //!< Not Equal (Quiet), same as \ref VCmpImm::kNEQ_UQ.
+ kNLT = 0x05u, //!< Not Less (Signaling), same as \ref VCmpImm::kNLT_US.
+ kNLE = 0x06u, //!< Not Less/Equal (Signaling), same as \ref VCmpImm::kNLE_US.
+ kORD = 0x07u //!< Ordered (Quiet), same as \ref VCmpImm::kORD_Q.
+};
-// ============================================================================
-// [asmjit::x86::FpuWord]
-// ============================================================================
-
-//! FPU control and status words.
-namespace FpuWord {
- //! FPU status word.
- enum Status : uint32_t {
- //! Invalid operation.
- kStatusInvalid = 0x0001u,
- //! Denormalized operand.
- kStatusDenormalized = 0x0002u,
- //! Division by zero.
- kStatusDivByZero = 0x0004u,
- //! Overflown.
- kStatusOverflow = 0x0008u,
- //! Underflown.
- kStatusUnderflow = 0x0010u,
- //! Precision lost.
- kStatusPrecision = 0x0020u,
- //! Stack fault.
- kStatusStackFault = 0x0040u,
- //! Interrupt.
- kStatusInterrupt = 0x0080u,
- //! C0 flag.
- kStatusC0 = 0x0100u,
- //! C1 flag.
- kStatusC1 = 0x0200u,
- //! C2 flag.
- kStatusC2 = 0x0400u,
- //! Top of the stack.
- kStatusTop = 0x3800u,
- //! C3 flag.
- kStatusC3 = 0x4000u,
- //! FPU is busy.
- kStatusBusy = 0x8000u
- };
+//! An immediate value that can be used with [V]PCMP[I|E]STR[I|M] instructions.
+enum class PCmpStrImm : uint8_t {
+ // Source Data Format
+ // ------------------
- //! FPU control word.
- enum Control : uint32_t {
- // [Bits 0-5]
-
- //! Exception mask (0x3F).
- kControlEM_Mask = 0x003Fu,
- //! Invalid operation exception.
- kControlEM_Invalid = 0x0001u,
- //! Denormalized operand exception.
- kControlEM_Denormal = 0x0002u,
- //! Division by zero exception.
- kControlEM_DivByZero = 0x0004u,
- //! Overflow exception.
- kControlEM_Overflow = 0x0008u,
- //! Underflow exception.
- kControlEM_Underflow = 0x0010u,
- //! Inexact operation exception.
- kControlEM_Inexact = 0x0020u,
-
- // [Bits 8-9]
-
- //! Precision control mask.
- kControlPC_Mask = 0x0300u,
- //! Single precision (24 bits).
- kControlPC_Float = 0x0000u,
- //! Reserved.
- kControlPC_Reserved = 0x0100u,
- //! Double precision (53 bits).
- kControlPC_Double = 0x0200u,
- //! Extended precision (64 bits).
- kControlPC_Extended = 0x0300u,
-
- // [Bits 10-11]
-
- //! Rounding control mask.
- kControlRC_Mask = 0x0C00u,
- //! Round to nearest even.
- kControlRC_Nearest = 0x0000u,
- //! Round down (floor).
- kControlRC_Down = 0x0400u,
- //! Round up (ceil).
- kControlRC_Up = 0x0800u,
- //! Round towards zero (truncate).
- kControlRC_Truncate = 0x0C00u,
-
- // [Bit 12]
-
- //! Infinity control.
- kControlIC_Mask = 0x1000u,
- //! Projective (not supported on X64).
- kControlIC_Projective = 0x0000u,
- //! Affine (default).
- kControlIC_Affine = 0x1000u
- };
-}
+ kUB = 0x00u << 0, //!< The source data format is unsigned bytes.
+ kUW = 0x01u << 0, //!< The source data format is unsigned words.
+ kSB = 0x02u << 0, //!< The source data format is signed bytes.
+ kSW = 0x03u << 0, //!< The source data format is signed words.
-// ============================================================================
-// [asmjit::x86::Status]
-// ============================================================================
-
-//! CPU and FPU status flags.
-namespace Status {
- //! CPU and FPU status flags used by `InstRWInfo`
- enum Flags : uint32_t {
- // ------------------------------------------------------------------------
- // [Architecture Neutral Flags - 0x000000FF]
- // ------------------------------------------------------------------------
-
- //! Carry flag.
- kCF = 0x00000001u,
- //! Signed overflow flag.
- kOF = 0x00000002u,
- //! Sign flag (negative/sign, if set).
- kSF = 0x00000004u,
- //! Zero and/or equality flag (1 if zero/equal).
- kZF = 0x00000008u,
-
- // ------------------------------------------------------------------------
- // [Architecture Specific Flags - 0xFFFFFF00]
- // ------------------------------------------------------------------------
-
- //! Adjust flag.
- kAF = 0x00000100u,
- //! Parity flag.
- kPF = 0x00000200u,
- //! Direction flag.
- kDF = 0x00000400u,
- //! Interrupt enable flag.
- kIF = 0x00000800u,
-
- //! Alignment check.
- kAC = 0x00001000u,
-
- //! FPU C0 status flag.
- kC0 = 0x00010000u,
- //! FPU C1 status flag.
- kC1 = 0x00020000u,
- //! FPU C2 status flag.
- kC2 = 0x00040000u,
- //! FPU C3 status flag.
- kC3 = 0x00080000u
- };
-}
+ // Aggregation Operation
+ // ---------------------
-// ============================================================================
-// [asmjit::x86::Predicate]
-// ============================================================================
-
-//! Contains predicates used by SIMD instructions.
-namespace Predicate {
- //! A predicate used by CMP[PD|PS|SD|SS] instructions.
- enum Cmp : uint32_t {
- kCmpEQ = 0x00u, //!< Equal (Quiet).
- kCmpLT = 0x01u, //!< Less (Signaling).
- kCmpLE = 0x02u, //!< Less/Equal (Signaling).
- kCmpUNORD = 0x03u, //!< Unordered (Quiet).
- kCmpNEQ = 0x04u, //!< Not Equal (Quiet).
- kCmpNLT = 0x05u, //!< Not Less (Signaling).
- kCmpNLE = 0x06u, //!< Not Less/Equal (Signaling).
- kCmpORD = 0x07u //!< Ordered (Quiet).
- };
+ kEqualAny = 0x00u << 2, //!< The arithmetic comparison is "equal".
+ kRanges = 0x01u << 2, //!< The arithmetic comparison is "greater than or equal" between even indexed
+ //!< elements and "less than or equal" between odd indexed elements.
+ kEqualEach = 0x02u << 2, //!< The arithmetic comparison is "equal".
+ kEqualOrdered = 0x03u << 2, //!< The arithmetic comparison is "equal".
- //! A predicate used by [V]PCMP[I|E]STR[I|M] instructions.
- enum PCmpStr : uint32_t {
- // Source data format:
- kPCmpStrUB = 0x00u << 0, //!< The source data format is unsigned bytes.
- kPCmpStrUW = 0x01u << 0, //!< The source data format is unsigned words.
- kPCmpStrSB = 0x02u << 0, //!< The source data format is signed bytes.
- kPCmpStrSW = 0x03u << 0, //!< The source data format is signed words.
-
- // Aggregation operation:
- kPCmpStrEqualAny = 0x00u << 2, //!< The arithmetic comparison is "equal".
- kPCmpStrRanges = 0x01u << 2, //!< The arithmetic comparison is "greater than or equal"
- //!< between even indexed elements and "less than or equal"
- //!< between odd indexed elements.
- kPCmpStrEqualEach = 0x02u << 2, //!< The arithmetic comparison is "equal".
- kPCmpStrEqualOrdered = 0x03u << 2, //!< The arithmetic comparison is "equal".
-
- // Polarity:
- kPCmpStrPosPolarity = 0x00u << 4, //!< IntRes2 = IntRes1.
- kPCmpStrNegPolarity = 0x01u << 4, //!< IntRes2 = -1 XOR IntRes1.
- kPCmpStrPosMasked = 0x02u << 4, //!< IntRes2 = IntRes1.
- kPCmpStrNegMasked = 0x03u << 4, //!< IntRes2[i] = second[i] == invalid ? IntRes1[i] : ~IntRes1[i].
-
- // Output selection (pcmpstri):
- kPCmpStrOutputLSI = 0x00u << 6, //!< The index returned to ECX is of the least significant set bit in IntRes2.
- kPCmpStrOutputMSI = 0x01u << 6, //!< The index returned to ECX is of the most significant set bit in IntRes2.
-
- // Output selection (pcmpstrm):
- kPCmpStrBitMask = 0x00u << 6, //!< IntRes2 is returned as the mask to the least significant bits of XMM0.
- kPCmpStrIndexMask = 0x01u << 6 //!< IntRes2 is expanded into a byte/word mask and placed in XMM0.
- };
+ // Polarity
+ // --------
- //! A predicate used by ROUND[PD|PS|SD|SS] instructions.
- enum Round : uint32_t {
- //! Round to nearest (even).
- kRoundNearest = 0x00u,
- //! Round to down toward -INF (floor),
- kRoundDown = 0x01u,
- //! Round to up toward +INF (ceil).
- kRoundUp = 0x02u,
- //! Round toward zero (truncate).
- kRoundTrunc = 0x03u,
- //! Round to the current rounding mode set (ignores other RC bits).
- kRoundCurrent = 0x04u,
- //! Avoids inexact exception, if set.
- kRoundInexact = 0x08u
- };
+ kPosPolarity = 0x00u << 4, //!< IntRes2 = IntRes1.
+ kNegPolarity = 0x01u << 4, //!< IntRes2 = -1 XOR IntRes1.
+ kPosMasked = 0x02u << 4, //!< IntRes2 = IntRes1.
+ kNegMasked = 0x03u << 4, //!< IntRes2[i] = second[i] == invalid ? IntRes1[i] : ~IntRes1[i].
- //! A predicate used by VCMP[PD|PS|SD|SS] instructions.
- //!
- //! The first 8 values are compatible with `Cmp`.
- enum VCmp : uint32_t {
- kVCmpEQ_OQ = kCmpEQ, //!< Equal (Quiet , Ordered).
- kVCmpLT_OS = kCmpLT, //!< Less (Signaling, Ordered).
- kVCmpLE_OS = kCmpLE, //!< Less/Equal (Signaling, Ordered).
- kVCmpUNORD_Q = kCmpUNORD, //!< Unordered (Quiet).
- kVCmpNEQ_UQ = kCmpNEQ, //!< Not Equal (Quiet , Unordered).
- kVCmpNLT_US = kCmpNLT, //!< Not Less (Signaling, Unordered).
- kVCmpNLE_US = kCmpNLE, //!< Not Less/Equal (Signaling, Unordered).
- kVCmpORD_Q = kCmpORD, //!< Ordered (Quiet).
- kVCmpEQ_UQ = 0x08u, //!< Equal (Quiet , Unordered).
- kVCmpNGE_US = 0x09u, //!< Not Greater/Equal (Signaling, Unordered).
- kVCmpNGT_US = 0x0Au, //!< Not Greater (Signaling, Unordered).
- kVCmpFALSE_OQ = 0x0Bu, //!< False (Quiet , Ordered).
- kVCmpNEQ_OQ = 0x0Cu, //!< Not Equal (Quiet , Ordered).
- kVCmpGE_OS = 0x0Du, //!< Greater/Equal (Signaling, Ordered).
- kVCmpGT_OS = 0x0Eu, //!< Greater (Signaling, Ordered).
- kVCmpTRUE_UQ = 0x0Fu, //!< True (Quiet , Unordered).
- kVCmpEQ_OS = 0x10u, //!< Equal (Signaling, Ordered).
- kVCmpLT_OQ = 0x11u, //!< Less (Quiet , Ordered).
- kVCmpLE_OQ = 0x12u, //!< Less/Equal (Quiet , Ordered).
- kVCmpUNORD_S = 0x13u, //!< Unordered (Signaling).
- kVCmpNEQ_US = 0x14u, //!< Not Equal (Signaling, Unordered).
- kVCmpNLT_UQ = 0x15u, //!< Not Less (Quiet , Unordered).
- kVCmpNLE_UQ = 0x16u, //!< Not Less/Equal (Quiet , Unordered).
- kVCmpORD_S = 0x17u, //!< Ordered (Signaling).
- kVCmpEQ_US = 0x18u, //!< Equal (Signaling, Unordered).
- kVCmpNGE_UQ = 0x19u, //!< Not Greater/Equal (Quiet , Unordered).
- kVCmpNGT_UQ = 0x1Au, //!< Not Greater (Quiet , Unordered).
- kVCmpFALSE_OS = 0x1Bu, //!< False (Signaling, Ordered).
- kVCmpNEQ_OS = 0x1Cu, //!< Not Equal (Signaling, Ordered).
- kVCmpGE_OQ = 0x1Du, //!< Greater/Equal (Quiet , Ordered).
- kVCmpGT_OQ = 0x1Eu, //!< Greater (Quiet , Ordered).
- kVCmpTRUE_US = 0x1Fu //!< True (Signaling, Unordered).
- };
+ // Output Selection (pcmpstri)
+ // ---------------------------
- //! A predicate used by VFIXUPIMM[PD|PS|SD|SS] instructions (AVX-512).
- enum VFixupImm : uint32_t {
- kVFixupImmZEOnZero = 0x01u,
- kVFixupImmIEOnZero = 0x02u,
- kVFixupImmZEOnOne = 0x04u,
- kVFixupImmIEOnOne = 0x08u,
- kVFixupImmIEOnSNaN = 0x10u,
- kVFixupImmIEOnNInf = 0x20u,
- kVFixupImmIEOnNegative= 0x40u,
- kVFixupImmIEOnPInf = 0x80u
- };
+ kOutputLSI = 0x00u << 6, //!< The index returned to ECX is of the least significant set bit in IntRes2.
+ kOutputMSI = 0x01u << 6, //!< The index returned to ECX is of the most significant set bit in IntRes2.
- //! A predicate used by VFPCLASS[PD|PS|SD|SS] instructions (AVX-512).
- //!
- //! \note Values can be combined together to form the final 8-bit mask.
- enum VFPClass : uint32_t {
- kVFPClassQNaN = 0x01u, //!< Checks for QNaN.
- kVFPClassPZero = 0x02u, //!< Checks for +0.
- kVFPClassNZero = 0x04u, //!< Checks for -0.
- kVFPClassPInf = 0x08u, //!< Checks for +Inf.
- kVFPClassNInf = 0x10u, //!< Checks for -Inf.
- kVFPClassDenormal = 0x20u, //!< Checks for denormal.
- kVFPClassNegative = 0x40u, //!< Checks for negative finite value.
- kVFPClassSNaN = 0x80u //!< Checks for SNaN.
- };
+ // Output Selection (pcmpstrm)
+ // ---------------------------
- //! A predicate used by VGETMANT[PD|PS|SD|SS] instructions (AVX-512).
- enum VGetMant : uint32_t {
- kVGetMant1To2 = 0x00u,
- kVGetMant1Div2To2 = 0x01u,
- kVGetMant1Div2To1 = 0x02u,
- kVGetMant3Div4To3Div2 = 0x03u,
- kVGetMantNoSign = 0x04u,
- kVGetMantQNaNIfSign = 0x08u
- };
+ kBitMask = 0x00u << 6, //!< IntRes2 is returned as the mask to the least significant bits of XMM0.
+ kIndexMask = 0x01u << 6 //!< IntRes2 is expanded into a byte/word mask and placed in XMM0.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(PCmpStrImm)
- //! A predicate used by VPCMP[U][B|W|D|Q] instructions (AVX-512).
- enum VPCmp : uint32_t {
- kVPCmpEQ = 0x00u, //!< Equal.
- kVPCmpLT = 0x01u, //!< Less.
- kVPCmpLE = 0x02u, //!< Less/Equal.
- kVPCmpFALSE = 0x03u, //!< False.
- kVPCmpNE = 0x04u, //!< Not Equal.
- kVPCmpGE = 0x05u, //!< Greater/Equal.
- kVPCmpGT = 0x06u, //!< Greater.
- kVPCmpTRUE = 0x07u //!< True.
- };
+//! An immediate value that can be used with ROUND[PD|PS|SD|SS] instructions.
+//!
+//! \note `kSuppress` is a mask that can be used with any other value.
+enum class RoundImm : uint8_t {
+ kNearest = 0x00u, //!< Round to nearest (even).
+ kDown = 0x01u, //!< Round to down toward -INF (floor),
+ kUp = 0x02u, //!< Round to up toward +INF (ceil).
+ kTrunc = 0x03u, //!< Round toward zero (truncate).
+ kCurrent = 0x04u, //!< Round to the current rounding mode set (ignores other RC bits).
+ kSuppress = 0x08u //!< Supress exceptions (avoids inexact exception, if set).
+};
+ASMJIT_DEFINE_ENUM_FLAGS(RoundImm)
- //! A predicate used by VPCOM[U][B|W|D|Q] instructions (XOP).
- enum VPCom : uint32_t {
- kVPComLT = 0x00u, //!< Less.
- kVPComLE = 0x01u, //!< Less/Equal
- kVPComGT = 0x02u, //!< Greater.
- kVPComGE = 0x03u, //!< Greater/Equal.
- kVPComEQ = 0x04u, //!< Equal.
- kVPComNE = 0x05u, //!< Not Equal.
- kVPComFALSE = 0x06u, //!< False.
- kVPComTRUE = 0x07u //!< True.
- };
+//! An immediate value that can be used with VCMP[PD|PS|SD|SS] instructions (AVX).
+//!
+//! The first 8 values are compatible with \ref CmpImm.
+enum class VCmpImm : uint8_t {
+ kEQ_OQ = 0x00u, //!< Equal (Quiet , Ordered) , same as \ref CmpImm::kEQ.
+ kLT_OS = 0x01u, //!< Less (Signaling, Ordered) , same as \ref CmpImm::kLT.
+ kLE_OS = 0x02u, //!< Less/Equal (Signaling, Ordered) , same as \ref CmpImm::kLE.
+ kUNORD_Q = 0x03u, //!< Unordered (Quiet) , same as \ref CmpImm::kUNORD.
+ kNEQ_UQ = 0x04u, //!< Not Equal (Quiet , Unordered), same as \ref CmpImm::kNEQ.
+ kNLT_US = 0x05u, //!< Not Less (Signaling, Unordered), same as \ref CmpImm::kNLT.
+ kNLE_US = 0x06u, //!< Not Less/Equal (Signaling, Unordered), same as \ref CmpImm::kNLE.
+ kORD_Q = 0x07u, //!< Ordered (Quiet) , same as \ref CmpImm::kORD.
+ kEQ_UQ = 0x08u, //!< Equal (Quiet , Unordered).
+ kNGE_US = 0x09u, //!< Not Greater/Equal (Signaling, Unordered).
+ kNGT_US = 0x0Au, //!< Not Greater (Signaling, Unordered).
+ kFALSE_OQ = 0x0Bu, //!< False (Quiet , Ordered).
+ kNEQ_OQ = 0x0Cu, //!< Not Equal (Quiet , Ordered).
+ kGE_OS = 0x0Du, //!< Greater/Equal (Signaling, Ordered).
+ kGT_OS = 0x0Eu, //!< Greater (Signaling, Ordered).
+ kTRUE_UQ = 0x0Fu, //!< True (Quiet , Unordered).
+ kEQ_OS = 0x10u, //!< Equal (Signaling, Ordered).
+ kLT_OQ = 0x11u, //!< Less (Quiet , Ordered).
+ kLE_OQ = 0x12u, //!< Less/Equal (Quiet , Ordered).
+ kUNORD_S = 0x13u, //!< Unordered (Signaling).
+ kNEQ_US = 0x14u, //!< Not Equal (Signaling, Unordered).
+ kNLT_UQ = 0x15u, //!< Not Less (Quiet , Unordered).
+ kNLE_UQ = 0x16u, //!< Not Less/Equal (Quiet , Unordered).
+ kORD_S = 0x17u, //!< Ordered (Signaling).
+ kEQ_US = 0x18u, //!< Equal (Signaling, Unordered).
+ kNGE_UQ = 0x19u, //!< Not Greater/Equal (Quiet , Unordered).
+ kNGT_UQ = 0x1Au, //!< Not Greater (Quiet , Unordered).
+ kFALSE_OS = 0x1Bu, //!< False (Signaling, Ordered).
+ kNEQ_OS = 0x1Cu, //!< Not Equal (Signaling, Ordered).
+ kGE_OQ = 0x1Du, //!< Greater/Equal (Quiet , Ordered).
+ kGT_OQ = 0x1Eu, //!< Greater (Quiet , Ordered).
+ kTRUE_US = 0x1Fu //!< True (Signaling, Unordered).
+};
- //! A predicate used by VRANGE[PD|PS|SD|SS] instructions (AVX-512).
- enum VRange : uint32_t {
- kVRangeSelectMin = 0x00u, //!< Select minimum value.
- kVRangeSelectMax = 0x01u, //!< Select maximum value.
- kVRangeSelectAbsMin = 0x02u, //!< Select minimum absolute value.
- kVRangeSelectAbsMax = 0x03u, //!< Select maximum absolute value.
- kVRangeSignSrc1 = 0x00u, //!< Select sign of SRC1.
- kVRangeSignSrc2 = 0x04u, //!< Select sign of SRC2.
- kVRangeSign0 = 0x08u, //!< Set sign to 0.
- kVRangeSign1 = 0x0Cu //!< Set sign to 1.
- };
+//! An immediate value that can be used with VFIXUPIMM[PD|PS|SD|SS] instructions (AVX-512).
+//!
+//! The final immediate is a combination of all possible control bits.
+enum class VFixupImm : uint8_t {
+ kNone = 0x00u,
+ kZEOnZero = 0x01u,
+ kIEOnZero = 0x02u,
+ kZEOnOne = 0x04u,
+ kIEOnOne = 0x08u,
+ kIEOnSNaN = 0x10u,
+ kIEOnNInf = 0x20u,
+ kIEOnNegative = 0x40u,
+ kIEOnPInf = 0x80u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(VFixupImm)
- //! A predicate used by VREDUCE[PD|PS|SD|SS] instructions (AVX-512).
- enum VReduce : uint32_t {
- kVReduceRoundCurrent = 0x00u, //!< Round to the current mode set.
- kVReduceRoundEven = 0x04u, //!< Round to nearest even.
- kVReduceRoundDown = 0x05u, //!< Round down.
- kVReduceRoundUp = 0x06u, //!< Round up.
- kVReduceRoundTrunc = 0x07u, //!< Truncate.
- kVReduceSuppress = 0x08u //!< Suppress exceptions.
- };
+//! An immediate value that can be used with VFPCLASS[PD|PS|SD|SS] instructions (AVX-512).
+//!
+//! The values can be combined together to form the final 8-bit mask.
+enum class VFPClassImm : uint8_t {
+ kNone = 0x00u,
+ kQNaN = 0x01u, //!< Checks for QNaN.
+ kPZero = 0x02u, //!< Checks for +0.
+ kNZero = 0x04u, //!< Checks for -0.
+ kPInf = 0x08u, //!< Checks for +Inf.
+ kNInf = 0x10u, //!< Checks for -Inf.
+ kDenormal = 0x20u, //!< Checks for denormal.
+ kNegative = 0x40u, //!< Checks for negative finite value.
+ kSNaN = 0x80u //!< Checks for SNaN.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(VFPClassImm)
+
+//! An immediate value that can be used with VGETMANT[PD|PS|SD|SS] instructions (AVX-512).
+//!
+//! The value is a combination of a normalization interval and a sign control.
+enum class VGetMantImm : uint8_t {
+ // Normalization Interval
+ // ----------------------
+
+ k1To2 = 0x00u, //!< Normalization interval is [1, 2)
+ k1Div2To2 = 0x01u, //!< Normalization interval is [0.5, 2)
+ k1Div2To1 = 0x02u, //!< Normalization interval is [0.5, 1)
+ k3Div4To3Div2 = 0x03u, //!< Normalization interval is [3/4, 3/2)
+
+ // Sign Control
+ // ------------
+
+ kSrcSign = 0x00u, //!< Source sign.
+ kNoSign = 0x04u, //!< Zero sign
+ kQNaNIfSign = 0x08u //!< QNAN_Indefinite if sign(src) != 0, regardless of `kSignSrc` or `kNoSign`.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(VGetMantImm)
+
+//! A predicate used by VPCMP[U][B|W|D|Q] instructions (AVX-512).
+enum class VPCmpImm : uint8_t {
+ kEQ = 0x00u, //!< Equal.
+ kLT = 0x01u, //!< Less.
+ kLE = 0x02u, //!< Less/Equal.
+ kFALSE = 0x03u, //!< False.
+ kNE = 0x04u, //!< Not Equal.
+ kGE = 0x05u, //!< Greater/Equal.
+ kGT = 0x06u, //!< Greater.
+ kTRUE = 0x07u //!< True.
+};
+
+//! A predicate used by VPCOM[U][B|W|D|Q] instructions (XOP).
+enum class VPComImm : uint8_t {
+ kLT = 0x00u, //!< Less.
+ kLE = 0x01u, //!< Less/Equal
+ kGT = 0x02u, //!< Greater.
+ kGE = 0x03u, //!< Greater/Equal.
+ kEQ = 0x04u, //!< Equal.
+ kNE = 0x05u, //!< Not Equal.
+ kFALSE = 0x06u, //!< False.
+ kTRUE = 0x07u //!< True.
+};
- //! Pack a shuffle constant to be used by SSE/AVX/AVX-512 instructions (2 values).
- //!
- //! \param a Position of the first component [0, 1].
- //! \param b Position of the second component [0, 1].
- //!
- //! Shuffle constants can be used to encode an immediate for these instructions:
- //! - `shufpd|vshufpd`
- static constexpr uint32_t shuf(uint32_t a, uint32_t b) noexcept {
- return (a << 1) | b;
- }
-
- //! Pack a shuffle constant to be used by SSE/AVX/AVX-512 instructions (4 values).
- //!
- //! \param a Position of the first component [0, 3].
- //! \param b Position of the second component [0, 3].
- //! \param c Position of the third component [0, 3].
- //! \param d Position of the fourth component [0, 3].
- //!
- //! Shuffle constants can be used to encode an immediate for these instructions:
- //! - `pshufw`
- //! - `pshuflw|vpshuflw`
- //! - `pshufhw|vpshufhw`
- //! - `pshufd|vpshufd`
- //! - `shufps|vshufps`
- static constexpr uint32_t shuf(uint32_t a, uint32_t b, uint32_t c, uint32_t d) noexcept {
- return (a << 6) | (b << 4) | (c << 2) | d;
- }
+//! A predicate used by VRANGE[PD|PS|SD|SS] instructions (AVX-512).
+enum class VRangeImm : uint8_t {
+ // Selector
+ // --------
+
+ kSelectMin = 0x00u, //!< Select minimum value.
+ kSelectMax = 0x01u, //!< Select maximum value.
+ kSelectAbsMin = 0x02u, //!< Select minimum absolute value.
+ kSelectAbsMax = 0x03u, //!< Select maximum absolute value.
+
+ // Sign
+ // ----
+
+ kSignSrc1 = 0x00u, //!< Select sign of SRC1.
+ kSignSrc2 = 0x04u, //!< Select sign of SRC2.
+ kSign0 = 0x08u, //!< Set sign to 0.
+ kSign1 = 0x0Cu //!< Set sign to 1.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(VRangeImm)
+
+//! A predicate used by VREDUCE[PD|PS|SD|SS] instructions (AVX-512).
+enum class VReduceImm : uint8_t {
+ kRoundEven = 0x00u, //!< Round to nearest even.
+ kRoundDown = 0x01u, //!< Round down.
+ kRoundUp = 0x02u, //!< Round up.
+ kRoundTrunc = 0x03u, //!< Truncate.
+ kRoundCurrent = 0x04u, //!< Round to the current mode set.
+ kSuppress = 0x08u, //!< Suppress exceptions.
+ kFixedImmMask = 0xF0u //!< Fixed length value mask.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(VReduceImm)
+
+//! Creates a \ref VReduceImm from a combination of `flags` and `fixedPointLength`.
+static inline constexpr VReduceImm vReduceImm(VReduceImm flags, uint32_t fixedPointLength) noexcept {
+ return flags | VReduceImm(fixedPointLength << 4);
}
-// ============================================================================
-// [asmjit::x86::TLog]
-// ============================================================================
-
-//! Bitwise ternary logic between 3 operands introduced by AVX-512.
-namespace TLog {
- //! A predicate that can be used to create a common predicate for VPTERNLOG[D|Q].
- //!
- //! There are 3 inputs to the instruction (\ref kA, \ref kB, \ref kC), and
- //! ternary logic can define any combination that would be performed on these
- //! 3 inputs to get the desired output - any combination of AND, OR, XOR, NOT.
- enum Operator : uint32_t {
- //! 0 value.
- k0 = 0x00u,
- //! 1 value.
- k1 = 0xFFu,
- //! A value.
- kA = 0xF0u,
- //! B value.
- kB = 0xCCu,
- //! C value.
- kC = 0xAAu,
-
- //! `!A` expression.
- kNotA = kA ^ k1,
- //! `!B` expression.
- kNotB = kB ^ k1,
- //! `!C` expression.
- kNotC = kC ^ k1,
-
- //! `A & B` expression.
- kAB = kA & kB,
- //! `A & C` expression.
- kAC = kA & kC,
- //! `B & C` expression.
- kBC = kB & kC,
- //! `!(A & B)` expression.
- kNotAB = kAB ^ k1,
- //! `!(A & C)` expression.
- kNotAC = kAC ^ k1,
- //! `!(B & C)` expression.
- kNotBC = kBC ^ k1,
-
- //! `A & B & C` expression.
- kABC = kAB & kC,
- //! `!(A & B & C)` expression.
- kNotABC = kABC ^ k1
- };
+//! A predicate that can be used as an immediate value with VPTERNLOG[D|Q] instruction.
+//!
+//! There are 3 inputs to the instruction (\ref kA, \ref kB, \ref kC). Ternary logic can define any combination
+//! that would be performed on these 3 inputs to get the desired output - any combination of AND, OR, XOR, NOT
+//! is possible.
+//!
+//! \sa \ref tLogFromBits and \ref fLogIfElse
+enum class TLogImm : uint8_t {
+ k0 = 0x00u, //!< 0 value.
+ k1 = 0xFFu, //!< 1 value.
+ kA = 0xF0u, //!< A value.
+ kB = 0xCCu, //!< B value.
+ kC = 0xAAu, //!< C value.
+
+ kNotA = kA ^ k1, //!< `!A` expression.
+ kNotB = kB ^ k1, //!< `!B` expression.
+ kNotC = kC ^ k1, //!< `!C` expression.
+
+ kAB = kA & kB, //!< `A & B` expression.
+ kAC = kA & kC, //!< `A & C` expression.
+ kBC = kB & kC, //!< `B & C` expression.
+ kNotAB = kAB ^ k1, //!< `!(A & B)` expression.
+ kNotAC = kAC ^ k1, //!< `!(A & C)` expression.
+ kNotBC = kBC ^ k1, //!< `!(B & C)` expression.
+
+ kABC = kAB & kC, //!< `A & B & C` expression.
+ kNotABC = kABC ^ k1 //!< `!(A & B & C)` expression.
+};
+ASMJIT_DEFINE_ENUM_FLAGS(TLogImm)
+
+//! Creates an immediate that can be used by VPTERNLOG[D|Q] instructions.
+static inline constexpr TLogImm tLogFromBits(uint8_t b000, uint8_t b001, uint8_t b010, uint8_t b011, uint8_t b100, uint8_t b101, uint8_t b110, uint8_t b111) noexcept {
+ return TLogImm(uint8_t(b000 << 0) |
+ uint8_t(b001 << 1) |
+ uint8_t(b010 << 2) |
+ uint8_t(b011 << 3) |
+ uint8_t(b100 << 4) |
+ uint8_t(b101 << 5) |
+ uint8_t(b110 << 6) |
+ uint8_t(b111 << 7));
+}
+
+//! Creates an if/else logic that can be used by VPTERNLOG[D|Q] instructions.
+static inline constexpr TLogImm fLogIfElse(TLogImm condition, TLogImm a, TLogImm b) noexcept { return (condition & a) | (~condition & b); }
- //! Creates an immediate that can be used by VPTERNLOG[D|Q] instructions.
- static constexpr uint32_t make(uint32_t b000, uint32_t b001, uint32_t b010, uint32_t b011, uint32_t b100, uint32_t b101, uint32_t b110, uint32_t b111) noexcept {
- return (b000 << 0) | (b001 << 1) | (b010 << 2) | (b011 << 3) | (b100 << 4) | (b101 << 5) | (b110 << 6) | (b111 << 7);
- }
-
- //! Creates an immediate that can be used by VPTERNLOG[D|Q] instructions.
- static constexpr uint32_t value(uint32_t x) noexcept { return x & 0xFF; }
- //! Negate an immediate that can be used by VPTERNLOG[D|Q] instructions.
- static constexpr uint32_t negate(uint32_t x) noexcept { return x ^ 0xFF; }
- //! Creates an if/else logic that can be used by VPTERNLOG[D|Q] instructions.
- static constexpr uint32_t ifElse(uint32_t condition, uint32_t a, uint32_t b) noexcept { return (condition & a) | (negate(condition) & b); }
+//! Creates a shuffle immediate value that be used with SSE/AVX/AVX-512 instructions to shuffle 2 elements in a vector.
+//!
+//! \param a Position of the first component [0, 1].
+//! \param b Position of the second component [0, 1].
+//!
+//! Shuffle constants can be used to encode an immediate for these instructions:
+//! - `shufpd|vshufpd`
+static inline constexpr uint32_t shuffleImm(uint32_t a, uint32_t b) noexcept {
+ return (a << 1) | b;
+}
+
+//! Creates a shuffle immediate value that be used with SSE/AVX/AVX-512 instructions to shuffle 4 elements in a vector.
+//!
+//! \param a Position of the first component [0, 3].
+//! \param b Position of the second component [0, 3].
+//! \param c Position of the third component [0, 3].
+//! \param d Position of the fourth component [0, 3].
+//!
+//! Shuffle constants can be used to encode an immediate for these instructions:
+//! - `pshufw`
+//! - `pshuflw|vpshuflw`
+//! - `pshufhw|vpshufhw`
+//! - `pshufd|vpshufd`
+//! - `shufps|vshufps`
+static inline constexpr uint32_t shuffleImm(uint32_t a, uint32_t b, uint32_t c, uint32_t d) noexcept {
+ return (a << 6) | (b << 4) | (c << 2) | d;
}
//! \}
diff --git a/src/asmjit/x86/x86instapi.cpp b/src/asmjit/x86/x86instapi.cpp
index 664cfae..3580fe6 100644
--- a/src/asmjit/x86/x86instapi.cpp
+++ b/src/asmjit/x86/x86instapi.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
// ----------------------------------------------------------------------------
// IMPORTANT: AsmJit now uses an external instruction database to populate
@@ -45,7 +27,6 @@
#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
#include "../core/support.h"
-#include "../x86/x86features.h"
#include "../x86/x86instapi_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86opcode_p.h"
@@ -53,12 +34,11 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::InstInternal - Text]
-// ============================================================================
+// x86::InstInternal - Text
+// ========================
#ifndef ASMJIT_NO_TEXT
-Error InstInternal::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept {
+Error InstInternal::instIdToString(Arch arch, InstId instId, String& output) noexcept {
DebugUtils::unused(arch);
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
@@ -68,7 +48,7 @@ Error InstInternal::instIdToString(uint32_t arch, uint32_t instId, String& outpu
return output.append(InstDB::_nameData + info._nameDataIndex);
}
-uint32_t InstInternal::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept {
+InstId InstInternal::stringToInstId(Arch arch, const char* s, size_t len) noexcept {
DebugUtils::unused(arch);
if (ASMJIT_UNLIKELY(!s))
@@ -107,109 +87,113 @@ uint32_t InstInternal::stringToInstId(uint32_t arch, const char* s, size_t len)
if (result > 0)
continue;
- return uint32_t((size_t)(cur - table));
+ return InstId((size_t)(cur - table));
}
return Inst::kIdNone;
}
#endif // !ASMJIT_NO_TEXT
-// ============================================================================
-// [asmjit::x86::InstInternal - Validate]
-// ============================================================================
+// x86::InstInternal - Validate
+// ============================
#ifndef ASMJIT_NO_VALIDATION
struct X86ValidationData {
- //! Allowed registers by reg-type (x86::Reg::kType...).
- uint32_t allowedRegMask[Reg::kTypeMax + 1];
+ //! Allowed registers by \ref RegType.
+ RegMask allowedRegMask[uint32_t(RegType::kMaxValue) + 1];
uint32_t allowedMemBaseRegs;
uint32_t allowedMemIndexRegs;
};
#define VALUE(x) \
- (x == Reg::kTypeGpbLo) ? InstDB::kOpGpbLo : \
- (x == Reg::kTypeGpbHi) ? InstDB::kOpGpbHi : \
- (x == Reg::kTypeGpw ) ? InstDB::kOpGpw : \
- (x == Reg::kTypeGpd ) ? InstDB::kOpGpd : \
- (x == Reg::kTypeGpq ) ? InstDB::kOpGpq : \
- (x == Reg::kTypeXmm ) ? InstDB::kOpXmm : \
- (x == Reg::kTypeYmm ) ? InstDB::kOpYmm : \
- (x == Reg::kTypeZmm ) ? InstDB::kOpZmm : \
- (x == Reg::kTypeMm ) ? InstDB::kOpMm : \
- (x == Reg::kTypeKReg ) ? InstDB::kOpKReg : \
- (x == Reg::kTypeSReg ) ? InstDB::kOpSReg : \
- (x == Reg::kTypeCReg ) ? InstDB::kOpCReg : \
- (x == Reg::kTypeDReg ) ? InstDB::kOpDReg : \
- (x == Reg::kTypeSt ) ? InstDB::kOpSt : \
- (x == Reg::kTypeBnd ) ? InstDB::kOpBnd : \
- (x == Reg::kTypeTmm ) ? InstDB::kOpTmm : \
- (x == Reg::kTypeRip ) ? InstDB::kOpNone : InstDB::kOpNone
-static const uint32_t _x86OpFlagFromRegType[Reg::kTypeMax + 1] = { ASMJIT_LOOKUP_TABLE_32(VALUE, 0) };
+ (x == uint32_t(RegType::kX86_GpbLo)) ? InstDB::OpFlags::kRegGpbLo : \
+ (x == uint32_t(RegType::kX86_GpbHi)) ? InstDB::OpFlags::kRegGpbHi : \
+ (x == uint32_t(RegType::kX86_Gpw )) ? InstDB::OpFlags::kRegGpw : \
+ (x == uint32_t(RegType::kX86_Gpd )) ? InstDB::OpFlags::kRegGpd : \
+ (x == uint32_t(RegType::kX86_Gpq )) ? InstDB::OpFlags::kRegGpq : \
+ (x == uint32_t(RegType::kX86_Xmm )) ? InstDB::OpFlags::kRegXmm : \
+ (x == uint32_t(RegType::kX86_Ymm )) ? InstDB::OpFlags::kRegYmm : \
+ (x == uint32_t(RegType::kX86_Zmm )) ? InstDB::OpFlags::kRegZmm : \
+ (x == uint32_t(RegType::kX86_Mm )) ? InstDB::OpFlags::kRegMm : \
+ (x == uint32_t(RegType::kX86_KReg )) ? InstDB::OpFlags::kRegKReg : \
+ (x == uint32_t(RegType::kX86_SReg )) ? InstDB::OpFlags::kRegSReg : \
+ (x == uint32_t(RegType::kX86_CReg )) ? InstDB::OpFlags::kRegCReg : \
+ (x == uint32_t(RegType::kX86_DReg )) ? InstDB::OpFlags::kRegDReg : \
+ (x == uint32_t(RegType::kX86_St )) ? InstDB::OpFlags::kRegSt : \
+ (x == uint32_t(RegType::kX86_Bnd )) ? InstDB::OpFlags::kRegBnd : \
+ (x == uint32_t(RegType::kX86_Tmm )) ? InstDB::OpFlags::kRegTmm : \
+ (x == uint32_t(RegType::kX86_Rip )) ? InstDB::OpFlags::kNone : InstDB::OpFlags::kNone
+static const InstDB::OpFlags _x86OpFlagFromRegType[uint32_t(RegType::kMaxValue) + 1] = { ASMJIT_LOOKUP_TABLE_32(VALUE, 0) };
#undef VALUE
#define REG_MASK_FROM_REG_TYPE_X86(x) \
- (x == Reg::kTypeGpbLo) ? 0x0000000Fu : \
- (x == Reg::kTypeGpbHi) ? 0x0000000Fu : \
- (x == Reg::kTypeGpw ) ? 0x000000FFu : \
- (x == Reg::kTypeGpd ) ? 0x000000FFu : \
- (x == Reg::kTypeGpq ) ? 0x000000FFu : \
- (x == Reg::kTypeXmm ) ? 0x000000FFu : \
- (x == Reg::kTypeYmm ) ? 0x000000FFu : \
- (x == Reg::kTypeZmm ) ? 0x000000FFu : \
- (x == Reg::kTypeMm ) ? 0x000000FFu : \
- (x == Reg::kTypeKReg ) ? 0x000000FFu : \
- (x == Reg::kTypeSReg ) ? 0x0000007Eu : \
- (x == Reg::kTypeCReg ) ? 0x0000FFFFu : \
- (x == Reg::kTypeDReg ) ? 0x000000FFu : \
- (x == Reg::kTypeSt ) ? 0x000000FFu : \
- (x == Reg::kTypeBnd ) ? 0x0000000Fu : \
- (x == Reg::kTypeTmm ) ? 0x000000FFu : \
- (x == Reg::kTypeRip ) ? 0x00000001u : 0u
+ (x == uint32_t(RegType::kX86_GpbLo)) ? 0x0000000Fu : \
+ (x == uint32_t(RegType::kX86_GpbHi)) ? 0x0000000Fu : \
+ (x == uint32_t(RegType::kX86_Gpw )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Gpd )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Gpq )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Xmm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Ymm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Zmm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Mm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_KReg )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_SReg )) ? 0x0000007Eu : \
+ (x == uint32_t(RegType::kX86_CReg )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_DReg )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_St )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Bnd )) ? 0x0000000Fu : \
+ (x == uint32_t(RegType::kX86_Tmm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Rip )) ? 0x00000001u : 0u
#define REG_MASK_FROM_REG_TYPE_X64(x) \
- (x == Reg::kTypeGpbLo) ? 0x0000FFFFu : \
- (x == Reg::kTypeGpbHi) ? 0x0000000Fu : \
- (x == Reg::kTypeGpw ) ? 0x0000FFFFu : \
- (x == Reg::kTypeGpd ) ? 0x0000FFFFu : \
- (x == Reg::kTypeGpq ) ? 0x0000FFFFu : \
- (x == Reg::kTypeXmm ) ? 0xFFFFFFFFu : \
- (x == Reg::kTypeYmm ) ? 0xFFFFFFFFu : \
- (x == Reg::kTypeZmm ) ? 0xFFFFFFFFu : \
- (x == Reg::kTypeMm ) ? 0x000000FFu : \
- (x == Reg::kTypeKReg ) ? 0x000000FFu : \
- (x == Reg::kTypeSReg ) ? 0x0000007Eu : \
- (x == Reg::kTypeCReg ) ? 0x0000FFFFu : \
- (x == Reg::kTypeDReg ) ? 0x0000FFFFu : \
- (x == Reg::kTypeSt ) ? 0x000000FFu : \
- (x == Reg::kTypeBnd ) ? 0x0000000Fu : \
- (x == Reg::kTypeTmm ) ? 0x000000FFu : \
- (x == Reg::kTypeRip ) ? 0x00000001u : 0u
+ (x == uint32_t(RegType::kX86_GpbLo)) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_GpbHi)) ? 0x0000000Fu : \
+ (x == uint32_t(RegType::kX86_Gpw )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_Gpd )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_Gpq )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_Xmm )) ? 0xFFFFFFFFu : \
+ (x == uint32_t(RegType::kX86_Ymm )) ? 0xFFFFFFFFu : \
+ (x == uint32_t(RegType::kX86_Zmm )) ? 0xFFFFFFFFu : \
+ (x == uint32_t(RegType::kX86_Mm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_KReg )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_SReg )) ? 0x0000007Eu : \
+ (x == uint32_t(RegType::kX86_CReg )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_DReg )) ? 0x0000FFFFu : \
+ (x == uint32_t(RegType::kX86_St )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Bnd )) ? 0x0000000Fu : \
+ (x == uint32_t(RegType::kX86_Tmm )) ? 0x000000FFu : \
+ (x == uint32_t(RegType::kX86_Rip )) ? 0x00000001u : 0u
+
+#define B(RegType) (uint32_t(1) << uint32_t(RegType))
static const X86ValidationData _x86ValidationData = {
{ ASMJIT_LOOKUP_TABLE_32(REG_MASK_FROM_REG_TYPE_X86, 0) },
- (1u << Reg::kTypeGpw) | (1u << Reg::kTypeGpd) | (1u << Reg::kTypeRip) | (1u << Label::kLabelTag),
- (1u << Reg::kTypeGpw) | (1u << Reg::kTypeGpd) | (1u << Reg::kTypeXmm) | (1u << Reg::kTypeYmm) | (1u << Reg::kTypeZmm)
+ B(RegType::kX86_Gpw) | B(RegType::kX86_Gpd) | B(RegType::kX86_Rip) | B(RegType::kLabelTag),
+ B(RegType::kX86_Gpw) | B(RegType::kX86_Gpd) | B(RegType::kX86_Xmm) | B(RegType::kX86_Ymm) | B(RegType::kX86_Zmm)
};
static const X86ValidationData _x64ValidationData = {
{ ASMJIT_LOOKUP_TABLE_32(REG_MASK_FROM_REG_TYPE_X64, 0) },
- (1u << Reg::kTypeGpd) | (1u << Reg::kTypeGpq) | (1u << Reg::kTypeRip) | (1u << Label::kLabelTag),
- (1u << Reg::kTypeGpd) | (1u << Reg::kTypeGpq) | (1u << Reg::kTypeXmm) | (1u << Reg::kTypeYmm) | (1u << Reg::kTypeZmm)
+ B(RegType::kX86_Gpd) | B(RegType::kX86_Gpq) | B(RegType::kX86_Rip) | B(RegType::kLabelTag),
+ B(RegType::kX86_Gpd) | B(RegType::kX86_Gpq) | B(RegType::kX86_Xmm) | B(RegType::kX86_Ymm) | B(RegType::kX86_Zmm)
};
+#undef B
+
#undef REG_MASK_FROM_REG_TYPE_X64
#undef REG_MASK_FROM_REG_TYPE_X86
-static ASMJIT_INLINE bool x86IsZmmOrM512(const Operand_& op) noexcept {
+static ASMJIT_FORCE_INLINE bool x86IsZmmOrM512(const Operand_& op) noexcept {
return Reg::isZmm(op) || (op.isMem() && op.size() == 64);
}
-static ASMJIT_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, const InstDB::OpSignature& ref, bool& immOutOfRange) noexcept {
+static ASMJIT_FORCE_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, const InstDB::OpSignature& ref, bool& immOutOfRange) noexcept {
// Fail if operand types are incompatible.
- uint32_t opFlags = op.opFlags;
- if ((opFlags & ref.opFlags) == 0) {
+ InstDB::OpFlags commonFlags = op.flags() & ref.flags();
+
+ if (!Support::test(commonFlags, InstDB::OpFlags::kOpMask)) {
// Mark temporarily `immOutOfRange` so we can return a more descriptive error later.
- if ((opFlags & InstDB::kOpAllImm) && (ref.opFlags & InstDB::kOpAllImm)) {
+ if (op.hasImm() && ref.hasImm()) {
immOutOfRange = true;
return true;
}
@@ -217,43 +201,37 @@ static ASMJIT_INLINE bool x86CheckOSig(const InstDB::OpSignature& op, const Inst
return false;
}
- // Fail if memory specific flags and sizes do not match the signature.
- uint32_t opMemFlags = op.memFlags;
- if (opMemFlags != 0) {
- uint32_t refMemFlags = ref.memFlags;
- if ((refMemFlags & opMemFlags) == 0)
- return false;
-
- if ((refMemFlags & InstDB::kMemOpBaseOnly) && !(opMemFlags & InstDB::kMemOpBaseOnly))
+ // Fail if some memory specific flags do not match.
+ if (Support::test(commonFlags, InstDB::OpFlags::kMemMask)) {
+ if (ref.hasFlag(InstDB::OpFlags::kFlagMemBase) && !op.hasFlag(InstDB::OpFlags::kFlagMemBase))
return false;
}
- // Specific register index.
- if (opFlags & InstDB::kOpAllRegs) {
- uint32_t refRegMask = ref.regMask;
- if (refRegMask && !(op.regMask & refRegMask))
+ // Fail if register indexes do not match.
+ if (Support::test(commonFlags, InstDB::OpFlags::kRegMask)) {
+ if (ref.regMask() && !Support::test(op.regMask(), ref.regMask()))
return false;
}
return true;
}
-ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept {
+ASMJIT_FAVOR_SIZE Error InstInternal::validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept {
// Only called when `arch` matches X86 family.
ASMJIT_ASSERT(Environment::isFamilyX86(arch));
const X86ValidationData* vd;
- if (arch == Environment::kArchX86)
+ if (arch == Arch::kX86)
vd = &_x86ValidationData;
else
vd = &_x64ValidationData;
uint32_t i;
- uint32_t mode = InstDB::modeFromArch(arch);
+ InstDB::Mode mode = InstDB::modeFromArch(arch);
// Get the instruction data.
- uint32_t instId = inst.id();
- uint32_t options = inst.options();
+ InstId instId = inst.id();
+ InstOptions options = inst.options();
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
return DebugUtils::errored(kErrorInvalidInstruction);
@@ -261,89 +239,87 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
const InstDB::CommonInfo& commonInfo = instInfo.commonInfo();
- uint32_t iFlags = instInfo.flags();
+ InstDB::InstFlags iFlags = instInfo.flags();
+
+ constexpr InstOptions kRepAny = InstOptions::kX86_Rep | InstOptions::kX86_Repne;
+ constexpr InstOptions kXAcqXRel = InstOptions::kX86_XAcquire | InstOptions::kX86_XRelease;
+ constexpr InstOptions kAvx512Options = InstOptions::kX86_ZMask | InstOptions::kX86_ER | InstOptions::kX86_SAE;
- // --------------------------------------------------------------------------
- // [Validate LOCK|XACQUIRE|XRELEASE]
- // --------------------------------------------------------------------------
+ // Validate LOCK|XACQUIRE|XRELEASE Prefixes
+ // ----------------------------------------
- const uint32_t kLockXAcqRel = Inst::kOptionXAcquire | Inst::kOptionXRelease;
- if (options & (Inst::kOptionLock | kLockXAcqRel)) {
- if (options & Inst::kOptionLock) {
- if (ASMJIT_UNLIKELY(!(iFlags & InstDB::kFlagLock) && !(options & kLockXAcqRel)))
+ if (Support::test(options, InstOptions::kX86_Lock | kXAcqXRel)) {
+ if (Support::test(options, InstOptions::kX86_Lock)) {
+ if (ASMJIT_UNLIKELY(!Support::test(iFlags, InstDB::InstFlags::kLock) && !Support::test(options, kXAcqXRel)))
return DebugUtils::errored(kErrorInvalidLockPrefix);
if (ASMJIT_UNLIKELY(opCount < 1 || !operands[0].isMem()))
return DebugUtils::errored(kErrorInvalidLockPrefix);
}
- if (options & kLockXAcqRel) {
- if (ASMJIT_UNLIKELY(!(options & Inst::kOptionLock) || (options & kLockXAcqRel) == kLockXAcqRel))
+ if (Support::test(options, kXAcqXRel)) {
+ if (ASMJIT_UNLIKELY(!Support::test(options, InstOptions::kX86_Lock) || (options & kXAcqXRel) == kXAcqXRel))
return DebugUtils::errored(kErrorInvalidPrefixCombination);
- if (ASMJIT_UNLIKELY((options & Inst::kOptionXAcquire) && !(iFlags & InstDB::kFlagXAcquire)))
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_XAcquire) && !Support::test(iFlags, InstDB::InstFlags::kXAcquire)))
return DebugUtils::errored(kErrorInvalidXAcquirePrefix);
- if (ASMJIT_UNLIKELY((options & Inst::kOptionXRelease) && !(iFlags & InstDB::kFlagXRelease)))
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_XRelease) && !Support::test(iFlags, InstDB::InstFlags::kXRelease)))
return DebugUtils::errored(kErrorInvalidXReleasePrefix);
}
}
- // Validate REP and REPNE prefixes.
- const uint32_t kRepAny = Inst::kOptionRep | Inst::kOptionRepne;
- if (options & kRepAny) {
+ // Validate REP and REPNE Prefixes
+ // -------------------------------
+
+ if (Support::test(options, kRepAny)) {
if (ASMJIT_UNLIKELY((options & kRepAny) == kRepAny))
return DebugUtils::errored(kErrorInvalidPrefixCombination);
- if (ASMJIT_UNLIKELY(!(iFlags & InstDB::kFlagRep)))
+ if (ASMJIT_UNLIKELY(!Support::test(iFlags, InstDB::InstFlags::kRep)))
return DebugUtils::errored(kErrorInvalidRepPrefix);
}
- // --------------------------------------------------------------------------
- // [Translate Each Operand to the Corresponding OpSignature]
- // --------------------------------------------------------------------------
+ // Translate Each Operand to the Corresponding OpSignature
+ // -------------------------------------------------------
InstDB::OpSignature oSigTranslated[Globals::kMaxOpCount];
- uint32_t combinedOpFlags = 0;
+ InstDB::OpFlags combinedOpFlags = InstDB::OpFlags::kNone;
uint32_t combinedRegMask = 0;
const Mem* memOp = nullptr;
for (i = 0; i < opCount; i++) {
const Operand_& op = operands[i];
- if (op.opType() == Operand::kOpNone)
+ if (op.opType() == OperandType::kNone)
break;
- uint32_t opFlags = 0;
- uint32_t memFlags = 0;
- uint32_t regMask = 0;
+ InstDB::OpFlags opFlags = InstDB::OpFlags::kNone;
+ RegMask regMask = 0;
switch (op.opType()) {
- case Operand::kOpReg: {
- uint32_t regType = op.as<BaseReg>().type();
- if (ASMJIT_UNLIKELY(regType >= Reg::kTypeCount))
- return DebugUtils::errored(kErrorInvalidRegType);
+ case OperandType::kReg: {
+ RegType regType = op.as<BaseReg>().type();
+ opFlags = _x86OpFlagFromRegType[size_t(regType)];
- opFlags = _x86OpFlagFromRegType[regType];
- if (ASMJIT_UNLIKELY(opFlags == 0))
+ if (ASMJIT_UNLIKELY(opFlags == InstDB::OpFlags::kNone))
return DebugUtils::errored(kErrorInvalidRegType);
- // If `regId` is equal or greater than Operand::kVirtIdMin it means
- // that the register is virtual and its index will be assigned later
- // by the register allocator. We must pass unless asked to disallow
- // virtual registers.
+ // If `regId` is equal or greater than Operand::kVirtIdMin it means that the register is virtual and its
+ // index will be assigned later by the register allocator. We must pass unless asked to disallow virtual
+ // registers.
uint32_t regId = op.id();
if (regId < Operand::kVirtIdMin) {
if (ASMJIT_UNLIKELY(regId >= 32))
return DebugUtils::errored(kErrorInvalidPhysId);
- if (ASMJIT_UNLIKELY(Support::bitTest(vd->allowedRegMask[regType], regId) == 0))
+ if (ASMJIT_UNLIKELY(Support::bitTest(vd->allowedRegMask[size_t(regType)], regId) == 0))
return DebugUtils::errored(kErrorInvalidPhysId);
regMask = Support::bitMask(regId);
combinedRegMask |= regMask;
}
else {
- if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ if (uint32_t(validationFlags & ValidationFlags::kEnableVirtRegs) == 0)
return DebugUtils::errored(kErrorIllegalVirtReg);
regMask = 0xFFFFFFFFu;
}
@@ -351,13 +327,13 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
}
// TODO: Validate base and index and combine these with `combinedRegMask`.
- case Operand::kOpMem: {
+ case OperandType::kMem: {
const Mem& m = op.as<Mem>();
memOp = &m;
uint32_t memSize = m.size();
- uint32_t baseType = m.baseType();
- uint32_t indexType = m.indexType();
+ RegType baseType = m.baseType();
+ RegType indexType = m.indexType();
if (m.segmentId() > 6)
return DebugUtils::errored(kErrorInvalidSegment);
@@ -374,28 +350,28 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
}
else {
// If there is no size we implicitly calculate it so we can validate N in {1toN} properly.
- memSize = commonInfo.hasAvx512B32() ? 4 : 8;
+ memSize = commonInfo.hasAvx512B64() ? 8 :
+ commonInfo.hasAvx512B32() ? 4 : 2;
}
- memSize <<= m.getBroadcast();
+ memSize <<= uint32_t(m.getBroadcast());
}
- if (baseType != 0 && baseType > Label::kLabelTag) {
+ if (baseType != RegType::kNone && baseType > RegType::kLabelTag) {
uint32_t baseId = m.baseId();
if (m.isRegHome()) {
- // Home address of a virtual register. In such case we don't want to
- // validate the type of the base register as it will always be patched
- // to ESP|RSP.
+ // Home address of a virtual register. In such case we don't want to validate the type of the
+ // base register as it will always be patched to ESP|RSP.
}
else {
- if (ASMJIT_UNLIKELY((vd->allowedMemBaseRegs & (1u << baseType)) == 0))
+ if (ASMJIT_UNLIKELY(!Support::bitTest(vd->allowedMemBaseRegs, baseType)))
return DebugUtils::errored(kErrorInvalidAddress);
}
- // Create information that will be validated only if this is an implicit
- // memory operand. Basically only usable for string instructions and other
- // instructions where memory operand is implicit and has 'seg:[reg]' form.
+ // Create information that will be validated only if this is an implicit memory operand. Basically
+ // only usable for string instructions and other instructions where memory operand is implicit and
+ // has 'seg:[reg]' form.
if (baseId < Operand::kVirtIdMin) {
if (ASMJIT_UNLIKELY(baseId >= 32))
return DebugUtils::errored(kErrorInvalidPhysId);
@@ -405,71 +381,66 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
combinedRegMask |= regMask;
}
else {
- // Virtual base id - fill the whole mask for implicit mem validation.
- // The register is not assigned yet, so we cannot predict the phys id.
- if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ // Virtual base id - fill the whole mask for implicit mem validation. The register is not assigned
+ // yet, so we cannot predict the phys id.
+ if (uint32_t(validationFlags & ValidationFlags::kEnableVirtRegs) == 0)
return DebugUtils::errored(kErrorIllegalVirtReg);
regMask = 0xFFFFFFFFu;
}
- if (!indexType && !m.offsetLo32())
- memFlags |= InstDB::kMemOpBaseOnly;
+ if (indexType == RegType::kNone && !m.offsetLo32())
+ opFlags |= InstDB::OpFlags::kFlagMemBase;
}
- else if (baseType == Label::kLabelTag) {
+ else if (baseType == RegType::kLabelTag) {
// [Label] - there is no need to validate the base as it's label.
}
else {
// Base is a 64-bit address.
int64_t offset = m.offset();
if (!Support::isInt32(offset)) {
- if (mode == InstDB::kModeX86) {
+ if (mode == InstDB::Mode::kX86) {
// 32-bit mode: Make sure that the address is either `int32_t` or `uint32_t`.
if (!Support::isUInt32(offset))
return DebugUtils::errored(kErrorInvalidAddress64Bit);
}
else {
- // 64-bit mode: Zero extension is allowed if the address has 32-bit index
- // register or the address has no index register (it's still encodable).
- if (indexType) {
+ // 64-bit mode: Zero extension is allowed if the address has 32-bit index register or the address
+ // has no index register (it's still encodable).
+ if (indexType != RegType::kNone) {
if (!Support::isUInt32(offset))
return DebugUtils::errored(kErrorInvalidAddress64Bit);
- if (indexType != Reg::kTypeGpd)
+ if (indexType != RegType::kX86_Gpd)
return DebugUtils::errored(kErrorInvalidAddress64BitZeroExtension);
}
else {
- // We don't validate absolute 64-bit addresses without an index register
- // as this also depends on the target's base address. We don't have the
- // information to do it at this moment.
+ // We don't validate absolute 64-bit addresses without an index register as this also depends
+ // on the target's base address. We don't have the information to do it at this moment.
}
}
}
}
- if (indexType) {
- if (ASMJIT_UNLIKELY((vd->allowedMemIndexRegs & (1u << indexType)) == 0))
+ if (indexType != RegType::kNone) {
+ if (ASMJIT_UNLIKELY(!Support::bitTest(vd->allowedMemIndexRegs, indexType)))
return DebugUtils::errored(kErrorInvalidAddress);
- if (indexType == Reg::kTypeXmm) {
- opFlags |= InstDB::kOpVm;
- memFlags |= InstDB::kMemOpVm32x | InstDB::kMemOpVm64x;
+ if (indexType == RegType::kX86_Xmm) {
+ opFlags |= InstDB::OpFlags::kVm32x | InstDB::OpFlags::kVm64x;
}
- else if (indexType == Reg::kTypeYmm) {
- opFlags |= InstDB::kOpVm;
- memFlags |= InstDB::kMemOpVm32y | InstDB::kMemOpVm64y;
+ else if (indexType == RegType::kX86_Ymm) {
+ opFlags |= InstDB::OpFlags::kVm32y | InstDB::OpFlags::kVm64y;
}
- else if (indexType == Reg::kTypeZmm) {
- opFlags |= InstDB::kOpVm;
- memFlags |= InstDB::kMemOpVm32z | InstDB::kMemOpVm64z;
+ else if (indexType == RegType::kX86_Zmm) {
+ opFlags |= InstDB::OpFlags::kVm32z | InstDB::OpFlags::kVm64z;
}
else {
- opFlags |= InstDB::kOpMem;
- if (baseType)
- memFlags |= InstDB::kMemOpMib;
+ if (baseType != RegType::kNone)
+ opFlags |= InstDB::OpFlags::kFlagMib;
}
// [RIP + {XMM|YMM|ZMM}] is not allowed.
- if (baseType == Reg::kTypeRip && (opFlags & InstDB::kOpVm))
+ if (baseType == RegType::kX86_Rip && Support::test(opFlags, InstDB::OpFlags::kVmMask))
return DebugUtils::errored(kErrorInvalidAddress);
uint32_t indexId = m.indexId();
@@ -480,28 +451,26 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
combinedRegMask |= Support::bitMask(indexId);
}
else {
- if (!(validationFlags & InstAPI::kValidationFlagVirtRegs))
+ if (uint32_t(validationFlags & ValidationFlags::kEnableVirtRegs) == 0)
return DebugUtils::errored(kErrorIllegalVirtReg);
}
// Only used for implicit memory operands having 'seg:[reg]' form, so clear it.
regMask = 0;
}
- else {
- opFlags |= InstDB::kOpMem;
- }
switch (memSize) {
- case 0: memFlags |= InstDB::kMemOpAny ; break;
- case 1: memFlags |= InstDB::kMemOpM8 ; break;
- case 2: memFlags |= InstDB::kMemOpM16 ; break;
- case 4: memFlags |= InstDB::kMemOpM32 ; break;
- case 6: memFlags |= InstDB::kMemOpM48 ; break;
- case 8: memFlags |= InstDB::kMemOpM64 ; break;
- case 10: memFlags |= InstDB::kMemOpM80 ; break;
- case 16: memFlags |= InstDB::kMemOpM128; break;
- case 32: memFlags |= InstDB::kMemOpM256; break;
- case 64: memFlags |= InstDB::kMemOpM512; break;
+ case 0: opFlags |= InstDB::OpFlags::kMemUnspecified; break;
+ case 1: opFlags |= InstDB::OpFlags::kMem8; break;
+ case 2: opFlags |= InstDB::OpFlags::kMem16; break;
+ case 4: opFlags |= InstDB::OpFlags::kMem32; break;
+ case 6: opFlags |= InstDB::OpFlags::kMem48; break;
+ case 8: opFlags |= InstDB::OpFlags::kMem64; break;
+ case 10: opFlags |= InstDB::OpFlags::kMem80; break;
+ case 16: opFlags |= InstDB::OpFlags::kMem128; break;
+ case 32: opFlags |= InstDB::OpFlags::kMem256; break;
+ case 64: opFlags |= InstDB::OpFlags::kMem512; break;
+
default:
return DebugUtils::errored(kErrorInvalidOperandSize);
}
@@ -509,59 +478,57 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
break;
}
- case Operand::kOpImm: {
+ case OperandType::kImm: {
uint64_t immValue = op.as<Imm>().valueAs<uint64_t>();
- uint32_t immFlags = 0;
if (int64_t(immValue) >= 0) {
if (immValue <= 0x7u)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpI16 | InstDB::kOpU16 | InstDB::kOpI8 | InstDB::kOpU8 |
- InstDB::kOpI4 | InstDB::kOpU4 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmU16 | InstDB::OpFlags::kImmI8 | InstDB::OpFlags::kImmU8 |
+ InstDB::OpFlags::kImmI4 | InstDB::OpFlags::kImmU4 ;
else if (immValue <= 0xFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpI16 | InstDB::kOpU16 | InstDB::kOpI8 | InstDB::kOpU8 |
- InstDB::kOpU4 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmU16 | InstDB::OpFlags::kImmI8 | InstDB::OpFlags::kImmU8 |
+ InstDB::OpFlags::kImmU4 ;
else if (immValue <= 0x7Fu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpI16 | InstDB::kOpU16 | InstDB::kOpI8 | InstDB::kOpU8 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmU16 | InstDB::OpFlags::kImmI8 | InstDB::OpFlags::kImmU8 ;
else if (immValue <= 0xFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpI16 | InstDB::kOpU16 | InstDB::kOpU8 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmU16 | InstDB::OpFlags::kImmU8 ;
else if (immValue <= 0x7FFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpI16 | InstDB::kOpU16 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmU16 ;
else if (immValue <= 0xFFFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32 |
- InstDB::kOpU16 ;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32 |
+ InstDB::OpFlags::kImmU16 ;
else if (immValue <= 0x7FFFFFFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpI32 | InstDB::kOpU32;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmU32;
else if (immValue <= 0xFFFFFFFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64 | InstDB::kOpU32;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64 | InstDB::OpFlags::kImmU32;
else if (immValue <= 0x7FFFFFFFFFFFFFFFu)
- immFlags = InstDB::kOpI64 | InstDB::kOpU64;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmU64;
else
- immFlags = InstDB::kOpU64;
+ opFlags = InstDB::OpFlags::kImmU64;
}
else {
immValue = Support::neg(immValue);
if (immValue <= 0x8u)
- immFlags = InstDB::kOpI64 | InstDB::kOpI32 | InstDB::kOpI16 | InstDB::kOpI8 | InstDB::kOpI4;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmI8 | InstDB::OpFlags::kImmI4;
else if (immValue <= 0x80u)
- immFlags = InstDB::kOpI64 | InstDB::kOpI32 | InstDB::kOpI16 | InstDB::kOpI8;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmI16 | InstDB::OpFlags::kImmI8;
else if (immValue <= 0x8000u)
- immFlags = InstDB::kOpI64 | InstDB::kOpI32 | InstDB::kOpI16;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmI32 | InstDB::OpFlags::kImmI16;
else if (immValue <= 0x80000000u)
- immFlags = InstDB::kOpI64 | InstDB::kOpI32;
+ opFlags = InstDB::OpFlags::kImmI64 | InstDB::OpFlags::kImmI32;
else
- immFlags = InstDB::kOpI64;
+ opFlags = InstDB::OpFlags::kImmI64;
}
- opFlags |= immFlags;
break;
}
- case Operand::kOpLabel: {
- opFlags |= InstDB::kOpRel8 | InstDB::kOpRel32;
+ case OperandType::kLabel: {
+ opFlags |= InstDB::OpFlags::kRel8 | InstDB::OpFlags::kRel32;
break;
}
@@ -570,16 +537,14 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
}
InstDB::OpSignature& oSigDst = oSigTranslated[i];
- oSigDst.opFlags = opFlags;
- oSigDst.memFlags = uint16_t(memFlags);
- oSigDst.regMask = uint8_t(regMask & 0xFFu);
+ oSigDst._flags = uint64_t(opFlags) & 0x00FFFFFFFFFFFFFFu;
+ oSigDst._regMask = uint8_t(regMask & 0xFFu);
combinedOpFlags |= opFlags;
}
- // Decrease the number of operands of those that are none. This is important
- // as Assembler and Compiler may just pass more operands padded with none
- // (which means that no operand is given at that index). However, validate
- // that there are no gaps (like [reg, none, reg] or [none, reg]).
+ // Decrease the number of operands of those that are none. This is important as Assembler and Compiler may just pass
+ // more operands padded with none (which means that no operand is given at that index). However, validate that there
+ // are no gaps (like [reg, none, reg] or [none, reg]).
if (i < opCount) {
while (--opCount > i)
if (ASMJIT_UNLIKELY(!operands[opCount].isNone()))
@@ -587,22 +552,20 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
}
// Validate X86 and X64 specific cases.
- if (mode == InstDB::kModeX86) {
+ if (mode == InstDB::Mode::kX86) {
// Illegal use of 64-bit register in 32-bit mode.
- if (ASMJIT_UNLIKELY((combinedOpFlags & InstDB::kOpGpq) != 0))
+ if (ASMJIT_UNLIKELY(Support::test(combinedOpFlags, InstDB::OpFlags::kRegGpq)))
return DebugUtils::errored(kErrorInvalidUseOfGpq);
}
else {
// Illegal use of a high 8-bit register with REX prefix.
- bool hasREX = inst.hasOption(Inst::kOptionRex) ||
- ((combinedRegMask & 0xFFFFFF00u) != 0);
- if (ASMJIT_UNLIKELY(hasREX && (combinedOpFlags & InstDB::kOpGpbHi) != 0))
+ bool hasREX = inst.hasOption(InstOptions::kX86_Rex) || (combinedRegMask & 0xFFFFFF00u) != 0;
+ if (ASMJIT_UNLIKELY(hasREX && Support::test(combinedOpFlags, InstDB::OpFlags::kRegGpbHi)))
return DebugUtils::errored(kErrorInvalidUseOfGpbHi);
}
- // --------------------------------------------------------------------------
- // [Validate Instruction Signature by Comparing Against All `iSig` Rows]
- // --------------------------------------------------------------------------
+ // Validate Instruction Signature by Comparing Against All `iSig` Rows
+ // -------------------------------------------------------------------
const InstDB::InstSignature* iSig = InstDB::_instSignatureTable + commonInfo._iSignatureIndex;
const InstDB::InstSignature* iEnd = iSig + commonInfo._iSignatureCount;
@@ -616,28 +579,28 @@ ASMJIT_FAVOR_SIZE Error InstInternal::validate(uint32_t arch, const BaseInst& in
do {
// Check if the architecture is compatible.
- if ((iSig->modes & mode) == 0)
+ if (!iSig->supportsMode(mode))
continue;
// Compare the operands table with reference operands.
uint32_t j = 0;
- uint32_t iSigCount = iSig->opCount;
+ uint32_t iSigCount = iSig->opCount();
bool localImmOutOfRange = false;
if (iSigCount == opCount) {
for (j = 0; j < opCount; j++)
- if (!x86CheckOSig(oSigTranslated[j], opSignatureTable[iSig->operands[j]], localImmOutOfRange))
+ if (!x86CheckOSig(oSigTranslated[j], iSig->opSignature(j), localImmOutOfRange))
break;
}
- else if (iSigCount - iSig->implicit == opCount) {
+ else if (iSigCount - iSig->implicitOpCount() == opCount) {
uint32_t r = 0;
for (j = 0; j < opCount && r < iSigCount; j++, r++) {
const InstDB::OpSignature* oChk = oSigTranslated + j;
const InstDB::OpSignature* oRef;
Next:
- oRef = opSignatureTable + iSig->operands[r];
- // Skip implicit.
- if ((oRef->opFlags & InstDB::kOpImplicit) != 0) {
+ oRef = opSignatureTable + iSig->opSignatureIndex(r);
+ // Skip implicit operands.
+ if (oRef->isImplicit()) {
if (++r >= iSigCount)
break;
else
@@ -667,31 +630,27 @@ Next:
}
}
- // --------------------------------------------------------------------------
- // [Validate AVX512 Options]
- // --------------------------------------------------------------------------
+ // Validate AVX512 Options
+ // -----------------------
const RegOnly& extraReg = inst.extraReg();
- const uint32_t kAvx512Options = Inst::kOptionZMask |
- Inst::kOptionER |
- Inst::kOptionSAE ;
- if (options & kAvx512Options) {
- if (commonInfo.hasFlag(InstDB::kFlagEvex)) {
+ if (Support::test(options, kAvx512Options)) {
+ if (commonInfo.hasFlag(InstDB::InstFlags::kEvex)) {
// Validate AVX-512 {z}.
- if ((options & Inst::kOptionZMask)) {
- if (ASMJIT_UNLIKELY((options & Inst::kOptionZMask) != 0 && !commonInfo.hasAvx512Z()))
+ if (Support::test(options, InstOptions::kX86_ZMask)) {
+ if (ASMJIT_UNLIKELY(Support::test(options, InstOptions::kX86_ZMask) && !commonInfo.hasAvx512Z()))
return DebugUtils::errored(kErrorInvalidKZeroUse);
}
// Validate AVX-512 {sae} and {er}.
- if (options & (Inst::kOptionSAE | Inst::kOptionER)) {
+ if (Support::test(options, InstOptions::kX86_SAE | InstOptions::kX86_ER)) {
// Rounding control is impossible if the instruction is not reg-to-reg.
if (ASMJIT_UNLIKELY(memOp))
return DebugUtils::errored(kErrorInvalidEROrSAE);
// Check if {sae} or {er} is supported by the instruction.
- if (options & Inst::kOptionER) {
+ if (Support::test(options, InstOptions::kX86_ER)) {
// NOTE: if both {sae} and {er} are set, we don't care, as {sae} is implied.
if (ASMJIT_UNLIKELY(!commonInfo.hasAvx512ER()))
return DebugUtils::errored(kErrorInvalidEROrSAE);
@@ -701,16 +660,13 @@ Next:
return DebugUtils::errored(kErrorInvalidEROrSAE);
}
- // {sae} and {er} are defined for either scalar ops or vector ops that
- // require LL to be 10 (512-bit vector operations). We don't need any
- // more bits in the instruction database to be able to validate this, as
- // each AVX512 instruction that has broadcast is vector instruction (in
- // this case we require zmm registers), otherwise it's a scalar instruction,
- // which is valid.
+ // {sae} and {er} are defined for either scalar ops or vector ops that require LL to be 10 (512-bit vector
+ // operations). We don't need any more bits in the instruction database to be able to validate this, as
+ // each AVX512 instruction that has broadcast is vector instruction (in this case we require zmm registers),
+ // otherwise it's a scalar instruction, which is valid.
if (commonInfo.hasAvx512B()) {
- // Supports broadcast, thus we require LL to be '10', which means there
- // have to be ZMM registers used. We don't calculate LL here, but we know
- // that it would be '10' if there is at least one ZMM register used.
+ // Supports broadcast, thus we require LL to be '10', which means there have to be ZMM registers used. We
+ // don't calculate LL here, but we know that it would be '10' if there is at least one ZMM register used.
// There is no {er}/{sae}-enabled instruction with less than two operands.
ASMJIT_ASSERT(opCount >= 2);
@@ -720,21 +676,19 @@ Next:
}
}
else {
- // Not AVX512 instruction - maybe OpExtra is xCX register used by REP/REPNE
- // prefix. Otherwise the instruction is invalid.
- if ((options & kAvx512Options) || (options & kRepAny) == 0)
+ // Not an AVX512 instruction - maybe OpExtra is xCX register used by REP/REPNE prefix.
+ if (Support::test(options, kAvx512Options) || !Support::test(options, kRepAny))
return DebugUtils::errored(kErrorInvalidInstruction);
}
}
- // --------------------------------------------------------------------------
- // [Validate {Extra} Register]
- // --------------------------------------------------------------------------
+ // Validate {Extra} Register
+ // -------------------------
if (extraReg.isReg()) {
- if (options & kRepAny) {
+ if (Support::test(options, kRepAny)) {
// Validate REP|REPNE {cx|ecx|rcx}.
- if (ASMJIT_UNLIKELY(iFlags & InstDB::kFlagRepIgnored))
+ if (ASMJIT_UNLIKELY(Support::test(iFlags, InstDB::InstFlags::kRepIgnored)))
return DebugUtils::errored(kErrorInvalidExtraReg);
if (extraReg.isPhysReg()) {
@@ -748,9 +702,9 @@ Next:
if (ASMJIT_UNLIKELY(!memOp || extraReg.type() != memOp->baseType()))
return DebugUtils::errored(kErrorInvalidExtraReg);
}
- else if (commonInfo.hasFlag(InstDB::kFlagEvex)) {
+ else if (commonInfo.hasFlag(InstDB::InstFlags::kEvex)) {
// Validate AVX-512 {k}.
- if (ASMJIT_UNLIKELY(extraReg.type() != Reg::kTypeKReg))
+ if (ASMJIT_UNLIKELY(extraReg.type() != RegType::kX86_KReg))
return DebugUtils::errored(kErrorInvalidExtraReg);
if (ASMJIT_UNLIKELY(extraReg.id() == 0 || !commonInfo.hasAvx512K()))
@@ -765,12 +719,11 @@ Next:
}
#endif // !ASMJIT_NO_VALIDATION
-// ============================================================================
-// [asmjit::x86::InstInternal - QueryRWInfo]
-// ============================================================================
+// x86::InstInternal - QueryRWInfo
+// ===============================
#ifndef ASMJIT_NO_INTROSPECTION
-static const uint64_t rwRegGroupByteMask[Reg::kGroupCount] = {
+static const Support::Array<uint64_t, uint32_t(RegGroup::kMaxValue) + 1> rwRegGroupByteMask = {{
0x00000000000000FFu, // GP.
0xFFFFFFFFFFFFFFFFu, // XMM|YMM|ZMM.
0x00000000000000FFu, // MM.
@@ -781,41 +734,41 @@ static const uint64_t rwRegGroupByteMask[Reg::kGroupCount] = {
0x00000000000003FFu, // St().
0x000000000000FFFFu, // BND.
0x00000000000000FFu // RIP.
-};
+}};
-static ASMJIT_INLINE void rwZeroExtendGp(OpRWInfo& opRwInfo, const Gp& reg, uint32_t nativeGpSize) noexcept {
+static ASMJIT_FORCE_INLINE void rwZeroExtendGp(OpRWInfo& opRwInfo, const Gp& reg, uint32_t nativeGpSize) noexcept {
ASMJIT_ASSERT(BaseReg::isGp(reg.as<Operand>()));
if (reg.size() + 4 == nativeGpSize) {
- opRwInfo.addOpFlags(OpRWInfo::kZExt);
+ opRwInfo.addOpFlags(OpRWFlags::kZExt);
opRwInfo.setExtendByteMask(~opRwInfo.writeByteMask() & 0xFFu);
}
}
-static ASMJIT_INLINE void rwZeroExtendAvxVec(OpRWInfo& opRwInfo, const Vec& reg) noexcept {
+static ASMJIT_FORCE_INLINE void rwZeroExtendAvxVec(OpRWInfo& opRwInfo, const Vec& reg) noexcept {
DebugUtils::unused(reg);
uint64_t msk = ~Support::fillTrailingBits(opRwInfo.writeByteMask());
if (msk) {
- opRwInfo.addOpFlags(OpRWInfo::kZExt);
+ opRwInfo.addOpFlags(OpRWFlags::kZExt);
opRwInfo.setExtendByteMask(msk);
}
}
-static ASMJIT_INLINE void rwZeroExtendNonVec(OpRWInfo& opRwInfo, const Reg& reg) noexcept {
+static ASMJIT_FORCE_INLINE void rwZeroExtendNonVec(OpRWInfo& opRwInfo, const Reg& reg) noexcept {
uint64_t msk = ~Support::fillTrailingBits(opRwInfo.writeByteMask()) & rwRegGroupByteMask[reg.group()];
if (msk) {
- opRwInfo.addOpFlags(OpRWInfo::kZExt);
+ opRwInfo.addOpFlags(OpRWFlags::kZExt);
opRwInfo.setExtendByteMask(msk);
}
}
-static ASMJIT_INLINE Error rwHandleAVX512(const BaseInst& inst, InstRWInfo* out) noexcept {
- if (inst.hasExtraReg() && inst.extraReg().type() == Reg::kTypeKReg && out->opCount() > 0) {
+static ASMJIT_FORCE_INLINE Error rwHandleAVX512(const BaseInst& inst, const InstDB::CommonInfo& commonInfo, InstRWInfo* out) noexcept {
+ if (inst.hasExtraReg() && inst.extraReg().type() == RegType::kX86_KReg && out->opCount() > 0) {
// AVX-512 instruction that uses a destination with {k} register (zeroing vs masking).
- out->_extraReg.addOpFlags(OpRWInfo::kRead);
+ out->_extraReg.addOpFlags(OpRWFlags::kRead);
out->_extraReg.setReadByteMask(0xFF);
- if (!inst.hasOption(Inst::kOptionZMask)) {
- out->_operands[0].addOpFlags(OpRWInfo::kRead);
+ if (!inst.hasOption(InstOptions::kX86_ZMask) && !commonInfo.hasAvx512Flag(InstDB::Avx512Flags::kImplicitZ)) {
+ out->_operands[0].addOpFlags(OpRWFlags::kRead);
out->_operands[0]._readByteMask |= out->_operands[0]._writeByteMask;
}
}
@@ -823,28 +776,27 @@ static ASMJIT_INLINE Error rwHandleAVX512(const BaseInst& inst, InstRWInfo* out)
return kErrorOk;
}
-Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
- using namespace Status;
-
+Error InstInternal::queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept {
// Only called when `arch` matches X86 family.
ASMJIT_ASSERT(Environment::isFamilyX86(arch));
// Get the instruction data.
- uint32_t instId = inst.id();
+ InstId instId = inst.id();
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
return DebugUtils::errored(kErrorInvalidInstruction);
// Read/Write flags.
- const InstDB::CommonInfoTableB& tabB = InstDB::_commonInfoTableB[InstDB::_instInfoTable[instId]._commonInfoIndexB];
- const InstDB::RWFlagsInfoTable& rwFlags = InstDB::_rwFlagsInfoTable[tabB._rwFlagsIndex];
-
+ const InstDB::InstInfo& instInfo = InstDB::_instInfoTable[instId];
+ const InstDB::CommonInfo& commonInfo = InstDB::_commonInfoTable[instInfo._commonInfoIndex];
+ const InstDB::AdditionalInfo& additionalInfo = InstDB::_additionalInfoTable[instInfo._additionalInfoIndex];
+ const InstDB::RWFlagsInfoTable& rwFlags = InstDB::_rwFlagsInfoTable[additionalInfo._rwFlagsIndex];
// There are two data tables, one for `opCount == 2` and the second for
// `opCount != 2`. There are two reasons for that:
- // - There are instructions that share the same name that have both 2
- // or 3 operands, which have different RW information / semantics.
- // - There must be 2 tables otherwise the lookup index won't fit into
- // 8 bits (there is more than 256 records of combined rwInfo A and B).
+ // - There are instructions that share the same name that have both 2 or 3 operands, which have different
+ // RW information / semantics.
+ // - There must be 2 tables otherwise the lookup index won't fit into 8 bits (there is more than 256 records
+ // of combined rwInfo A and B).
const InstDB::RWInfo& instRwInfo = opCount == 2 ? InstDB::rwInfoA[InstDB::rwInfoIndexA[instId]]
: InstDB::rwInfoB[InstDB::rwInfoIndexB[instId]];
const InstDB::RWInfoRm& instRmInfo = InstDB::rwInfoRm[instRwInfo.rmInfo];
@@ -853,17 +805,17 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
out->_opCount = uint8_t(opCount);
out->_rmFeature = instRmInfo.rmFeature;
out->_extraReg.reset();
- out->_readFlags = rwFlags.readFlags;
- out->_writeFlags = rwFlags.writeFlags;
+ out->_readFlags = CpuRWFlags(rwFlags.readFlags);
+ out->_writeFlags = CpuRWFlags(rwFlags.writeFlags);
uint32_t nativeGpSize = Environment::registerSizeFromArch(arch);
- constexpr uint32_t R = OpRWInfo::kRead;
- constexpr uint32_t W = OpRWInfo::kWrite;
- constexpr uint32_t X = OpRWInfo::kRW;
- constexpr uint32_t RegM = OpRWInfo::kRegMem;
- constexpr uint32_t RegPhys = OpRWInfo::kRegPhysId;
- constexpr uint32_t MibRead = OpRWInfo::kMemBaseRead | OpRWInfo::kMemIndexRead;
+ constexpr OpRWFlags R = OpRWFlags::kRead;
+ constexpr OpRWFlags W = OpRWFlags::kWrite;
+ constexpr OpRWFlags X = OpRWFlags::kRW;
+ constexpr OpRWFlags RegM = OpRWFlags::kRegMem;
+ constexpr OpRWFlags RegPhys = OpRWFlags::kRegPhysId;
+ constexpr OpRWFlags MibRead = OpRWFlags::kMemBaseRead | OpRWFlags::kMemIndexRead;
if (instRwInfo.category == InstDB::RWInfo::kCategoryGeneric) {
uint32_t i;
@@ -880,7 +832,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
continue;
}
- op._opFlags = rwOpData.flags & ~(OpRWInfo::kZExt);
+ op._opFlags = rwOpData.flags & ~OpRWFlags::kZExt;
op._physId = rwOpData.physId;
op._rmSize = 0;
op._resetReserved();
@@ -894,6 +846,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
op._readByteMask = rByteMask;
op._writeByteMask = wByteMask;
op._extendByteMask = 0;
+ op._consecutiveLeadCount = rwOpData.consecutiveLeadCount;
if (srcOp.isReg()) {
// Zero extension.
@@ -904,7 +857,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
// - 32-bit writes ARE zero extended.
rwZeroExtendGp(op, srcOp.as<Gp>(), nativeGpSize);
}
- else if (rwOpData.flags & OpRWInfo::kZExt) {
+ else if (Support::test(rwOpData.flags, OpRWFlags::kZExt)) {
// Otherwise follow ZExt.
rwZeroExtendNonVec(op, srcOp.as<Gp>());
}
@@ -918,10 +871,10 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
const x86::Mem& memOp = srcOp.as<x86::Mem>();
// The RW flags of BASE+INDEX are either provided by the data, which means
// that the instruction is border-case, or they are deduced from the operand.
- if (memOp.hasBaseReg() && !(op.opFlags() & OpRWInfo::kMemBaseRW))
- op.addOpFlags(OpRWInfo::kMemBaseRead);
- if (memOp.hasIndexReg() && !(op.opFlags() & OpRWInfo::kMemIndexRW))
- op.addOpFlags(OpRWInfo::kMemIndexRead);
+ if (memOp.hasBaseReg() && !op.hasOpFlag(OpRWFlags::kMemBaseRW))
+ op.addOpFlags(OpRWFlags::kMemBaseRead);
+ if (memOp.hasIndexReg() && !op.hasOpFlag(OpRWFlags::kMemIndexRW))
+ op.addOpFlags(OpRWFlags::kMemIndexRead);
}
}
@@ -954,14 +907,13 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
} while (it.hasNext());
}
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
switch (instRwInfo.category) {
case InstDB::RWInfo::kCategoryMov: {
- // Special case for 'mov' instruction. Here there are some variants that
- // we have to handle as 'mov' can be used to move between GP, segment,
- // control and debug registers. Moving between GP registers also allow to
+ // Special case for 'mov' instruction. Here there are some variants that we have to handle as 'mov' can be
+ // used to move between GP, segment, control and debug registers. Moving between GP registers also allow to
// use memory operand.
if (opCount == 2) {
@@ -994,14 +946,24 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
if (o0.isGp() && (o1.isCReg() || o1.isDReg())) {
out->_operands[0].reset(W, nativeGpSize);
out->_operands[1].reset(R, nativeGpSize);
- out->_writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
+ out->_writeFlags = CpuRWFlags::kX86_OF |
+ CpuRWFlags::kX86_SF |
+ CpuRWFlags::kX86_ZF |
+ CpuRWFlags::kX86_AF |
+ CpuRWFlags::kX86_PF |
+ CpuRWFlags::kX86_CF;
return kErrorOk;
}
if ((o0.isCReg() || o0.isDReg()) && o1.isGp()) {
out->_operands[0].reset(W, nativeGpSize);
out->_operands[1].reset(R, nativeGpSize);
- out->_writeFlags = kOF | kSF | kZF | kAF | kPF | kCF;
+ out->_writeFlags = CpuRWFlags::kX86_OF |
+ CpuRWFlags::kX86_SF |
+ CpuRWFlags::kX86_ZF |
+ CpuRWFlags::kX86_AF |
+ CpuRWFlags::kX86_PF |
+ CpuRWFlags::kX86_CF;
return kErrorOk;
}
}
@@ -1159,9 +1121,8 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
}
case InstDB::RWInfo::kCategoryMovh64: {
- // Special case for 'movhpd|movhps' instructions. Note that this is only
- // required for legacy (non-AVX) variants as AVX instructions use either
- // 2 or 3 operands that are in `kCategoryGeneric` category.
+ // Special case for 'movhpd|movhps' instructions. Note that this is only required for legacy (non-AVX)
+ // variants as AVX instructions use either 2 or 3 operands that are in `kCategoryGeneric` category.
if (opCount == 2) {
if (BaseReg::isVec(operands[0]) && operands[1].isMem()) {
out->_operands[0].reset(W, 8);
@@ -1243,9 +1204,8 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
}
case InstDB::RWInfo::kCategoryVmovddup: {
- // Special case for 'vmovddup' instruction. This instruction has an
- // interesting semantic as 128-bit XMM version only uses 64-bit memory
- // operand (m64), however, 256/512-bit versions use 256/512-bit memory
+ // Special case for 'vmovddup' instruction. This instruction has an interesting semantic as 128-bit XMM
+ // version only uses 64-bit memory operand (m64), however, 256/512-bit versions use 256/512-bit memory
// operand, respectively.
if (opCount == 2) {
if (BaseReg::isVec(operands[0]) && BaseReg::isVec(operands[1])) {
@@ -1257,7 +1217,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
out->_operands[1]._readByteMask &= 0x00FF00FF00FF00FFu;
rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
if (BaseReg::isVec(operands[0]) && operands[1].isMem()) {
@@ -1268,7 +1228,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
out->_operands[1].reset(R | MibRead, o1Size);
rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
}
break;
@@ -1342,7 +1302,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
if (BaseReg::isVec(operands[0]))
rwZeroExtendAvxVec(out->_operands[0], operands[0].as<Vec>());
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
if (operands[0].isReg() && operands[1].isMem()) {
@@ -1361,7 +1321,7 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
out->_operands[0].reset(W | MibRead, size0);
out->_operands[1].reset(R, size1);
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
}
break;
@@ -1413,13 +1373,13 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
out->_operands[1].setRmSize(size1);
}
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
if (operands[0].isReg() && operands[1].isMem()) {
out->_operands[1].addOpFlags(MibRead);
- return rwHandleAVX512(inst, out);
+ return rwHandleAVX512(inst, commonInfo, out);
}
}
break;
@@ -1430,16 +1390,15 @@ Error InstInternal::queryRWInfo(uint32_t arch, const BaseInst& inst, const Opera
}
#endif // !ASMJIT_NO_INTROSPECTION
-// ============================================================================
-// [asmjit::x86::InstInternal - QueryFeatures]
-// ============================================================================
+// x86::InstInternal - QueryFeatures
+// =================================
#ifndef ASMJIT_NO_INTROSPECTION
struct RegAnalysis {
uint32_t regTypeMask;
uint32_t highVecUsed;
- inline bool hasRegType(uint32_t regType) const noexcept {
+ inline bool hasRegType(RegType regType) const noexcept {
return Support::bitTest(regTypeMask, regType);
}
};
@@ -1469,31 +1428,31 @@ static RegAnalysis InstInternal_regAnalysis(const Operand_* operands, size_t opC
return RegAnalysis { mask, highVecUsed };
}
-static ASMJIT_INLINE uint32_t InstInternal_usesAvx512(uint32_t instOptions, const RegOnly& extraReg, const RegAnalysis& regAnalysis) noexcept {
- uint32_t hasEvex = instOptions & (Inst::kOptionEvex | Inst::_kOptionAvx512Mask);
- uint32_t hasKMask = extraReg.type() == Reg::kTypeKReg;
- uint32_t hasKOrZmm = regAnalysis.regTypeMask & Support::bitMask(Reg::kTypeZmm, Reg::kTypeKReg);
+static inline uint32_t InstInternal_usesAvx512(InstOptions instOptions, const RegOnly& extraReg, const RegAnalysis& regAnalysis) noexcept {
+ uint32_t hasEvex = uint32_t(instOptions & (InstOptions::kX86_Evex | InstOptions::kX86_AVX512Mask));
+ uint32_t hasKMask = extraReg.type() == RegType::kX86_KReg;
+ uint32_t hasKOrZmm = regAnalysis.regTypeMask & Support::bitMask(RegType::kX86_Zmm, RegType::kX86_KReg);
return hasEvex | hasKMask | hasKOrZmm;
}
-Error InstInternal::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept {
+Error InstInternal::queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept {
// Only called when `arch` matches X86 family.
DebugUtils::unused(arch);
ASMJIT_ASSERT(Environment::isFamilyX86(arch));
// Get the instruction data.
- uint32_t instId = inst.id();
- uint32_t options = inst.options();
+ InstId instId = inst.id();
+ InstOptions options = inst.options();
if (ASMJIT_UNLIKELY(!Inst::isDefinedId(instId)))
return DebugUtils::errored(kErrorInvalidInstruction);
const InstDB::InstInfo& instInfo = InstDB::infoById(instId);
- const InstDB::CommonInfoTableB& tableB = InstDB::_commonInfoTableB[instInfo._commonInfoIndexB];
+ const InstDB::AdditionalInfo& additionalInfo = InstDB::_additionalInfoTable[instInfo._additionalInfoIndex];
- const uint8_t* fData = tableB.featuresBegin();
- const uint8_t* fEnd = tableB.featuresEnd();
+ const uint8_t* fData = additionalInfo.featuresBegin();
+ const uint8_t* fEnd = additionalInfo.featuresEnd();
// Copy all features to `out`.
out->reset();
@@ -1506,92 +1465,87 @@ Error InstInternal::queryFeatures(uint32_t arch, const BaseInst& inst, const Ope
// Since AsmJit aggregates instructions that share the same name we have to
// deal with some special cases and also with MMX/SSE and AVX/AVX2 overlaps.
- if (fData != tableB.featuresBegin()) {
+ if (fData != additionalInfo.featuresBegin()) {
RegAnalysis regAnalysis = InstInternal_regAnalysis(operands, opCount);
// Handle MMX vs SSE overlap.
- if (out->has(Features::kMMX) || out->has(Features::kMMX2)) {
- // Only instructions defined by SSE and SSE2 overlap. Instructions
- // introduced by newer instruction sets like SSE3+ don't state MMX as
- // they require SSE3+.
- if (out->has(Features::kSSE) || out->has(Features::kSSE2)) {
- if (!regAnalysis.hasRegType(Reg::kTypeXmm)) {
+ if (out->has(CpuFeatures::X86::kMMX) || out->has(CpuFeatures::X86::kMMX2)) {
+ // Only instructions defined by SSE and SSE2 overlap. Instructions introduced by newer instruction sets like
+ // SSE3+ don't state MMX as they require SSE3+.
+ if (out->has(CpuFeatures::X86::kSSE) || out->has(CpuFeatures::X86::kSSE2)) {
+ if (!regAnalysis.hasRegType(RegType::kX86_Xmm)) {
// The instruction doesn't use XMM register(s), thus it's MMX/MMX2 only.
- out->remove(Features::kSSE);
- out->remove(Features::kSSE2);
- out->remove(Features::kSSE4_1);
+ out->remove(CpuFeatures::X86::kSSE);
+ out->remove(CpuFeatures::X86::kSSE2);
+ out->remove(CpuFeatures::X86::kSSE4_1);
}
else {
- out->remove(Features::kMMX);
- out->remove(Features::kMMX2);
+ out->remove(CpuFeatures::X86::kMMX);
+ out->remove(CpuFeatures::X86::kMMX2);
}
- // Special case: PEXTRW instruction is MMX/SSE2 instruction. However,
- // MMX/SSE version cannot access memory (only register to register
- // extract) so when SSE4.1 introduced the whole family of PEXTR/PINSR
- // instructions they also introduced PEXTRW with a new opcode 0x15 that
- // can extract directly to memory. This instruction is, of course, not
- // compatible with MMX/SSE2 and would #UD if SSE4.1 is not supported.
+ // Special case: PEXTRW instruction is MMX/SSE2 instruction. However, MMX/SSE version cannot access memory
+ // (only register to register extract) so when SSE4.1 introduced the whole family of PEXTR/PINSR instructions
+ // they also introduced PEXTRW with a new opcode 0x15 that can extract directly to memory. This instruction
+ // is, of course, not compatible with MMX/SSE2 and would #UD if SSE4.1 is not supported.
if (instId == Inst::kIdPextrw) {
if (opCount >= 1 && operands[0].isMem())
- out->remove(Features::kSSE2);
+ out->remove(CpuFeatures::X86::kSSE2);
else
- out->remove(Features::kSSE4_1);
+ out->remove(CpuFeatures::X86::kSSE4_1);
}
}
}
// Handle PCLMULQDQ vs VPCLMULQDQ.
- if (out->has(Features::kVPCLMULQDQ)) {
- if (regAnalysis.hasRegType(Reg::kTypeZmm) || Support::bitTest(options, Inst::kOptionEvex)) {
+ if (out->has(CpuFeatures::X86::kVPCLMULQDQ)) {
+ if (regAnalysis.hasRegType(RegType::kX86_Zmm) || Support::test(options, InstOptions::kX86_Evex)) {
// AVX512_F & VPCLMULQDQ.
- out->remove(Features::kAVX, Features::kPCLMULQDQ);
+ out->remove(CpuFeatures::X86::kAVX, CpuFeatures::X86::kPCLMULQDQ);
}
- else if (regAnalysis.hasRegType(Reg::kTypeYmm)) {
- out->remove(Features::kAVX512_F, Features::kAVX512_VL);
+ else if (regAnalysis.hasRegType(RegType::kX86_Ymm)) {
+ out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_VL);
}
else {
// AVX & PCLMULQDQ.
- out->remove(Features::kAVX512_F, Features::kAVX512_VL, Features::kVPCLMULQDQ);
+ out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_VL, CpuFeatures::X86::kVPCLMULQDQ);
}
}
// Handle AVX vs AVX2 overlap.
- if (out->has(Features::kAVX) && out->has(Features::kAVX2)) {
+ if (out->has(CpuFeatures::X86::kAVX) && out->has(CpuFeatures::X86::kAVX2)) {
bool isAVX2 = true;
- // Special case: VBROADCASTSS and VBROADCASTSD were introduced in AVX, but
- // only version that uses memory as a source operand. AVX2 then added support
- // for register source operand.
+ // Special case: VBROADCASTSS and VBROADCASTSD were introduced in AVX, but only version that uses memory as a
+ // source operand. AVX2 then added support for register source operand.
if (instId == Inst::kIdVbroadcastss || instId == Inst::kIdVbroadcastsd) {
if (opCount > 1 && operands[1].isMem())
isAVX2 = false;
}
else {
- // AVX instruction set doesn't support integer operations on YMM registers
- // as these were later introcuced by AVX2. In our case we have to check if
- // YMM register(s) are in use and if that is the case this is an AVX2 instruction.
- if (!(regAnalysis.regTypeMask & Support::bitMask(Reg::kTypeYmm, Reg::kTypeZmm)))
+ // AVX instruction set doesn't support integer operations on YMM registers as these were later introcuced by
+ // AVX2. In our case we have to check if YMM register(s) are in use and if that is the case this is an AVX2
+ // instruction.
+ if (!(regAnalysis.regTypeMask & Support::bitMask(RegType::kX86_Ymm, RegType::kX86_Zmm)))
isAVX2 = false;
}
if (isAVX2)
- out->remove(Features::kAVX);
+ out->remove(CpuFeatures::X86::kAVX);
else
- out->remove(Features::kAVX2);
+ out->remove(CpuFeatures::X86::kAVX2);
}
// Handle AVX|AVX2|FMA|F16C vs AVX512 overlap.
- if (out->has(Features::kAVX) || out->has(Features::kAVX2) || out->has(Features::kFMA) || out->has(Features::kF16C)) {
+ if (out->has(CpuFeatures::X86::kAVX) || out->has(CpuFeatures::X86::kAVX2) || out->has(CpuFeatures::X86::kFMA) || out->has(CpuFeatures::X86::kF16C)) {
// Only AVX512-F|BW|DQ allow to encode AVX/AVX2/FMA/F16C instructions
- if (out->has(Features::kAVX512_F) || out->has(Features::kAVX512_BW) || out->has(Features::kAVX512_DQ)) {
+ if (out->has(CpuFeatures::X86::kAVX512_F) || out->has(CpuFeatures::X86::kAVX512_BW) || out->has(CpuFeatures::X86::kAVX512_DQ)) {
uint32_t usesAvx512 = InstInternal_usesAvx512(options, inst.extraReg(), regAnalysis);
uint32_t mustUseEvex = 0;
switch (instId) {
- // Special case: VPSLLDQ and VPSRLDQ instructions only allow `reg, reg. imm`
- // combination in AVX|AVX2 mode, then AVX-512 introduced `reg, reg/mem, imm`
- // combination that uses EVEX prefix. This means that if the second operand
- // is memory then this is AVX-512_BW instruction and not AVX/AVX2 instruction.
+ // Special case: VPSLLDQ and VPSRLDQ instructions only allow `reg, reg. imm` combination in AVX|AVX2 mode,
+ // then AVX-512 introduced `reg, reg/mem, imm` combination that uses EVEX prefix. This means that if the
+ // second operand is memory then this is AVX-512_BW instruction and not AVX/AVX2 instruction.
case Inst::kIdVpslldq:
case Inst::kIdVpsrldq:
mustUseEvex = opCount >= 2 && operands[1].isMem();
@@ -1617,37 +1571,35 @@ Error InstInternal::queryFeatures(uint32_t arch, const BaseInst& inst, const Ope
}
if (!(usesAvx512 | mustUseEvex | regAnalysis.highVecUsed))
- out->remove(Features::kAVX512_F, Features::kAVX512_BW, Features::kAVX512_DQ, Features::kAVX512_VL);
+ out->remove(CpuFeatures::X86::kAVX512_F, CpuFeatures::X86::kAVX512_BW, CpuFeatures::X86::kAVX512_DQ, CpuFeatures::X86::kAVX512_VL);
else
- out->remove(Features::kAVX, Features::kAVX2, Features::kFMA, Features::kF16C);
+ out->remove(CpuFeatures::X86::kAVX, CpuFeatures::X86::kAVX2, CpuFeatures::X86::kFMA, CpuFeatures::X86::kF16C);
}
}
// Handle AVX_VNNI vs AVX512_VNNI overlap.
- if (out->has(Features::kAVX512_VNNI)) {
- // By default the AVX512_VNNI instruction should be used, because it was
- // introduced first. However, VEX|VEX3 prefix can be used to force AVX_VNNI
- // instead.
+ if (out->has(CpuFeatures::X86::kAVX512_VNNI)) {
+ // By default the AVX512_VNNI instruction should be used, because it was introduced first. However, VEX|VEX3
+ // prefix can be used to force AVX_VNNI instead.
uint32_t usesAvx512 = InstInternal_usesAvx512(options, inst.extraReg(), regAnalysis);
- if (!usesAvx512 && (options & (Inst::kOptionVex | Inst::kOptionVex3)) != 0)
- out->remove(Features::kAVX512_VNNI, Features::kAVX512_VL);
+ if (!usesAvx512 && Support::test(options, InstOptions::kX86_Vex | InstOptions::kX86_Vex3))
+ out->remove(CpuFeatures::X86::kAVX512_VNNI, CpuFeatures::X86::kAVX512_VL);
else
- out->remove(Features::kAVX_VNNI);
+ out->remove(CpuFeatures::X86::kAVX_VNNI);
}
// Clear AVX512_VL if ZMM register is used.
- if (regAnalysis.hasRegType(Reg::kTypeZmm))
- out->remove(Features::kAVX512_VL);
+ if (regAnalysis.hasRegType(RegType::kX86_Zmm))
+ out->remove(CpuFeatures::X86::kAVX512_VL);
}
return kErrorOk;
}
#endif // !ASMJIT_NO_INTROSPECTION
-// ============================================================================
-// [asmjit::x86::InstInternal - Unit]
-// ============================================================================
+// x86::InstInternal - Tests
+// =========================
#if defined(ASMJIT_TEST)
UNIT(x86_inst_api_text) {
@@ -1655,12 +1607,12 @@ UNIT(x86_inst_api_text) {
INFO("Matching all X86 instructions");
for (uint32_t a = 1; a < Inst::_kIdCount; a++) {
StringTmp<128> aName;
- EXPECT(InstInternal::instIdToString(0, a, aName) == kErrorOk,
+ EXPECT(InstInternal::instIdToString(Arch::kX86, a, aName) == kErrorOk,
"Failed to get the name of instruction #%u", a);
- uint32_t b = InstInternal::stringToInstId(0, aName.data(), aName.size());
+ uint32_t b = InstInternal::stringToInstId(Arch::kX86, aName.data(), aName.size());
StringTmp<128> bName;
- InstInternal::instIdToString(0, b, bName);
+ InstInternal::instIdToString(Arch::kX86, b, bName);
EXPECT(a == b,
"Instructions do not match \"%s\" (#%u) != \"%s\" (#%u)", aName.data(), a, bName.data(), b);
diff --git a/src/asmjit/x86/x86instapi_p.h b/src/asmjit/x86/x86instapi_p.h
index 83b3f77..0a4b10a 100644
--- a/src/asmjit/x86/x86instapi_p.h
+++ b/src/asmjit/x86/x86instapi_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86INSTAPI_P_H_INCLUDED
#define ASMJIT_X86_X86INSTAPI_P_H_INCLUDED
@@ -36,17 +18,17 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace InstInternal {
#ifndef ASMJIT_NO_TEXT
-Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept;
-uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept;
+Error instIdToString(Arch arch, InstId instId, String& output) noexcept;
+InstId stringToInstId(Arch arch, const char* s, size_t len) noexcept;
#endif // !ASMJIT_NO_TEXT
#ifndef ASMJIT_NO_VALIDATION
-Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept;
+Error validate(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, ValidationFlags validationFlags) noexcept;
#endif // !ASMJIT_NO_VALIDATION
#ifndef ASMJIT_NO_INTROSPECTION
-Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
-Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept;
+Error queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept;
+Error queryFeatures(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount, CpuFeatures* out) noexcept;
#endif // !ASMJIT_NO_INTROSPECTION
} // {InstInternal}
diff --git a/src/asmjit/x86/x86instdb.cpp b/src/asmjit/x86/x86instdb.cpp
index 374d878..3bf5d23 100644
--- a/src/asmjit/x86/x86instdb.cpp
+++ b/src/asmjit/x86/x86instdb.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
// ----------------------------------------------------------------------------
// IMPORTANT: AsmJit now uses an external instruction database to populate
@@ -45,28 +27,24 @@
#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
#include "../core/support.h"
-#include "../x86/x86features.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86opcode_p.h"
#include "../x86/x86operand.h"
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::InstDB - InstInfo]
-// ============================================================================
+// x86::InstDB - InstInfo
+// ======================
// Instruction opcode definitions:
// - `O` encodes X86|MMX|SSE instructions.
// - `V` encodes VEX|XOP|EVEX instructions.
// - `E` encodes EVEX instructions only.
-#define O_ENCODE(VEX, PREFIX, OPCODE, O, L, W, EvexW, N, TT) \
- ((PREFIX) | (OPCODE) | (O) | (L) | (W) | (EvexW) | (N) | (TT) | \
- (VEX && ((PREFIX) & Opcode::kMM_Mask) != Opcode::kMM_0F ? int(Opcode::kMM_ForceVex3) : 0))
+#define O_ENCODE(PREFIX, OPCODE, O, L, W, EvexW, N, TT) ((PREFIX) | (OPCODE) | (O) | (L) | (W) | (EvexW) | (N) | (TT))
-#define O(PREFIX, OPCODE, ModO, LL, W, EvexW, N, ModRM) (O_ENCODE(0, Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kModRM_##ModRM))
-#define V(PREFIX, OPCODE, ModO, LL, W, EvexW, N, TT) (O_ENCODE(1, Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kCDTT_##TT))
-#define E(PREFIX, OPCODE, ModO, LL, W, EvexW, N, TT) (O_ENCODE(1, Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kCDTT_##TT) | Opcode::kMM_ForceEvex)
+#define O(PREFIX, OPCODE, ModO, LL, W, EvexW, N, ModRM) (O_ENCODE(Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kModRM_##ModRM))
+#define V(PREFIX, OPCODE, ModO, LL, W, EvexW, N, TT) (O_ENCODE(Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kCDTT_##TT))
+#define E(PREFIX, OPCODE, ModO, LL, W, EvexW, N, TT) (O_ENCODE(Opcode::k##PREFIX, 0x##OPCODE, Opcode::kModO_##ModO, Opcode::kLL_##LL, Opcode::kW_##W, Opcode::kEvex_W_##EvexW, Opcode::kCDSHL_##N, Opcode::kCDTT_##TT) | Opcode::kMM_ForceEvex)
#define O_FPU(PREFIX, OPCODE, ModO) (Opcode::kFPU_##PREFIX | (0x##OPCODE & 0xFFu) | ((0x##OPCODE >> 8) << Opcode::kFPU_2B_Shift) | Opcode::kModO_##ModO)
// Don't store `_nameDataIndex` if instruction names are disabled. Since some
@@ -78,10 +56,10 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
#endif
// Defines an X86 instruction.
-#define INST(id, encoding, opcode0, opcode1, mainOpcodeIndex, altOpcodeIndex, nameDataIndex, commomInfoIndexA, commomInfoIndexB) { \
+#define INST(id, encoding, opcode0, opcode1, mainOpcodeIndex, altOpcodeIndex, nameDataIndex, commomInfoIndex, additionalInfoIndex) { \
uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
- uint32_t(commomInfoIndexA), \
- uint32_t(commomInfoIndexB), \
+ uint32_t(commomInfoIndex), \
+ uint32_t(additionalInfoIndex), \
uint8_t(InstDB::kEncoding##encoding), \
uint8_t((opcode0) & 0xFFu), \
uint8_t(mainOpcodeIndex), \
@@ -102,25 +80,25 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Adc , X86Arith , O(000000,10,2,_,x,_,_,_ ), 0 , 1 , 0 , 17 , 3 , 2 ), // #5
INST(Adcx , X86Rm , O(660F38,F6,_,_,x,_,_,_ ), 0 , 2 , 0 , 21 , 4 , 3 ), // #6
INST(Add , X86Arith , O(000000,00,0,_,x,_,_,_ ), 0 , 0 , 0 , 3146 , 3 , 1 ), // #7
- INST(Addpd , ExtRm , O(660F00,58,_,_,_,_,_,_ ), 0 , 3 , 0 , 5106 , 5 , 4 ), // #8
- INST(Addps , ExtRm , O(000F00,58,_,_,_,_,_,_ ), 0 , 4 , 0 , 5118 , 5 , 5 ), // #9
- INST(Addsd , ExtRm , O(F20F00,58,_,_,_,_,_,_ ), 0 , 5 , 0 , 5340 , 6 , 4 ), // #10
+ INST(Addpd , ExtRm , O(660F00,58,_,_,_,_,_,_ ), 0 , 3 , 0 , 5788 , 5 , 4 ), // #8
+ INST(Addps , ExtRm , O(000F00,58,_,_,_,_,_,_ ), 0 , 4 , 0 , 5800 , 5 , 5 ), // #9
+ INST(Addsd , ExtRm , O(F20F00,58,_,_,_,_,_,_ ), 0 , 5 , 0 , 6118 , 6 , 4 ), // #10
INST(Addss , ExtRm , O(F30F00,58,_,_,_,_,_,_ ), 0 , 6 , 0 , 3283 , 7 , 5 ), // #11
- INST(Addsubpd , ExtRm , O(660F00,D0,_,_,_,_,_,_ ), 0 , 3 , 0 , 4845 , 5 , 6 ), // #12
- INST(Addsubps , ExtRm , O(F20F00,D0,_,_,_,_,_,_ ), 0 , 5 , 0 , 4857 , 5 , 6 ), // #13
+ INST(Addsubpd , ExtRm , O(660F00,D0,_,_,_,_,_,_ ), 0 , 3 , 0 , 5410 , 5 , 6 ), // #12
+ INST(Addsubps , ExtRm , O(F20F00,D0,_,_,_,_,_,_ ), 0 , 5 , 0 , 5422 , 5 , 6 ), // #13
INST(Adox , X86Rm , O(F30F38,F6,_,_,x,_,_,_ ), 0 , 7 , 0 , 26 , 4 , 7 ), // #14
- INST(Aesdec , ExtRm , O(660F38,DE,_,_,_,_,_,_ ), 0 , 2 , 0 , 3338 , 5 , 8 ), // #15
- INST(Aesdeclast , ExtRm , O(660F38,DF,_,_,_,_,_,_ ), 0 , 2 , 0 , 3346 , 5 , 8 ), // #16
- INST(Aesenc , ExtRm , O(660F38,DC,_,_,_,_,_,_ ), 0 , 2 , 0 , 3358 , 5 , 8 ), // #17
- INST(Aesenclast , ExtRm , O(660F38,DD,_,_,_,_,_,_ ), 0 , 2 , 0 , 3366 , 5 , 8 ), // #18
- INST(Aesimc , ExtRm , O(660F38,DB,_,_,_,_,_,_ ), 0 , 2 , 0 , 3378 , 5 , 8 ), // #19
- INST(Aeskeygenassist , ExtRmi , O(660F3A,DF,_,_,_,_,_,_ ), 0 , 8 , 0 , 3386 , 8 , 8 ), // #20
+ INST(Aesdec , ExtRm , O(660F38,DE,_,_,_,_,_,_ ), 0 , 2 , 0 , 3352 , 5 , 8 ), // #15
+ INST(Aesdeclast , ExtRm , O(660F38,DF,_,_,_,_,_,_ ), 0 , 2 , 0 , 3360 , 5 , 8 ), // #16
+ INST(Aesenc , ExtRm , O(660F38,DC,_,_,_,_,_,_ ), 0 , 2 , 0 , 3372 , 5 , 8 ), // #17
+ INST(Aesenclast , ExtRm , O(660F38,DD,_,_,_,_,_,_ ), 0 , 2 , 0 , 3380 , 5 , 8 ), // #18
+ INST(Aesimc , ExtRm , O(660F38,DB,_,_,_,_,_,_ ), 0 , 2 , 0 , 3392 , 5 , 8 ), // #19
+ INST(Aeskeygenassist , ExtRmi , O(660F3A,DF,_,_,_,_,_,_ ), 0 , 8 , 0 , 3400 , 8 , 8 ), // #20
INST(And , X86Arith , O(000000,20,4,_,x,_,_,_ ), 0 , 9 , 0 , 2525 , 9 , 1 ), // #21
- INST(Andn , VexRvm_Wx , V(000F38,F2,_,0,x,_,_,_ ), 0 , 10 , 0 , 6814 , 10 , 9 ), // #22
- INST(Andnpd , ExtRm , O(660F00,55,_,_,_,_,_,_ ), 0 , 3 , 0 , 3419 , 5 , 4 ), // #23
- INST(Andnps , ExtRm , O(000F00,55,_,_,_,_,_,_ ), 0 , 4 , 0 , 3427 , 5 , 5 ), // #24
- INST(Andpd , ExtRm , O(660F00,54,_,_,_,_,_,_ ), 0 , 3 , 0 , 4359 , 11 , 4 ), // #25
- INST(Andps , ExtRm , O(000F00,54,_,_,_,_,_,_ ), 0 , 4 , 0 , 4369 , 11 , 5 ), // #26
+ INST(Andn , VexRvm_Wx , V(000F38,F2,_,0,x,_,_,_ ), 0 , 10 , 0 , 7789 , 10 , 9 ), // #22
+ INST(Andnpd , ExtRm , O(660F00,55,_,_,_,_,_,_ ), 0 , 3 , 0 , 3433 , 5 , 4 ), // #23
+ INST(Andnps , ExtRm , O(000F00,55,_,_,_,_,_,_ ), 0 , 4 , 0 , 3441 , 5 , 5 ), // #24
+ INST(Andpd , ExtRm , O(660F00,54,_,_,_,_,_,_ ), 0 , 3 , 0 , 4745 , 11 , 4 ), // #25
+ INST(Andps , ExtRm , O(000F00,54,_,_,_,_,_,_ ), 0 , 4 , 0 , 4755 , 11 , 5 ), // #26
INST(Arpl , X86Mr_NoSize , O(000000,63,_,_,_,_,_,_ ), 0 , 0 , 0 , 31 , 12 , 10 ), // #27
INST(Bextr , VexRmv_Wx , V(000F38,F7,_,0,x,_,_,_ ), 0 , 10 , 0 , 36 , 13 , 9 ), // #28
INST(Blcfill , VexVm_Wx , V(XOP_M9,01,1,0,x,_,_,_ ), 0 , 11 , 0 , 42 , 14 , 11 ), // #29
@@ -128,10 +106,10 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Blcic , VexVm_Wx , V(XOP_M9,01,5,0,x,_,_,_ ), 0 , 13 , 0 , 55 , 14 , 11 ), // #31
INST(Blcmsk , VexVm_Wx , V(XOP_M9,02,1,0,x,_,_,_ ), 0 , 11 , 0 , 61 , 14 , 11 ), // #32
INST(Blcs , VexVm_Wx , V(XOP_M9,01,3,0,x,_,_,_ ), 0 , 14 , 0 , 68 , 14 , 11 ), // #33
- INST(Blendpd , ExtRmi , O(660F3A,0D,_,_,_,_,_,_ ), 0 , 8 , 0 , 3469 , 8 , 12 ), // #34
- INST(Blendps , ExtRmi , O(660F3A,0C,_,_,_,_,_,_ ), 0 , 8 , 0 , 3478 , 8 , 12 ), // #35
- INST(Blendvpd , ExtRm_XMM0 , O(660F38,15,_,_,_,_,_,_ ), 0 , 2 , 0 , 3487 , 15 , 12 ), // #36
- INST(Blendvps , ExtRm_XMM0 , O(660F38,14,_,_,_,_,_,_ ), 0 , 2 , 0 , 3497 , 15 , 12 ), // #37
+ INST(Blendpd , ExtRmi , O(660F3A,0D,_,_,_,_,_,_ ), 0 , 8 , 0 , 3483 , 8 , 12 ), // #34
+ INST(Blendps , ExtRmi , O(660F3A,0C,_,_,_,_,_,_ ), 0 , 8 , 0 , 3492 , 8 , 12 ), // #35
+ INST(Blendvpd , ExtRm_XMM0 , O(660F38,15,_,_,_,_,_,_ ), 0 , 2 , 0 , 3501 , 15 , 12 ), // #36
+ INST(Blendvps , ExtRm_XMM0 , O(660F38,14,_,_,_,_,_,_ ), 0 , 2 , 0 , 3511 , 15 , 12 ), // #37
INST(Blsfill , VexVm_Wx , V(XOP_M9,01,2,0,x,_,_,_ ), 0 , 15 , 0 , 73 , 14 , 11 ), // #38
INST(Blsi , VexVm_Wx , V(000F38,F3,3,0,x,_,_,_ ), 0 , 16 , 0 , 81 , 14 , 9 ), // #39
INST(Blsic , VexVm_Wx , V(XOP_M9,01,6,0,x,_,_,_ ), 0 , 12 , 0 , 86 , 14 , 11 ), // #40
@@ -202,61 +180,61 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Cmovs , X86Rm , O(000F00,48,_,_,x,_,_,_ ), 0 , 4 , 0 , 438 , 22 , 36 ), // #105
INST(Cmovz , X86Rm , O(000F00,44,_,_,x,_,_,_ ), 0 , 4 , 0 , 444 , 22 , 31 ), // #106
INST(Cmp , X86Arith , O(000000,38,7,_,x,_,_,_ ), 0 , 27 , 0 , 450 , 35 , 1 ), // #107
- INST(Cmppd , ExtRmi , O(660F00,C2,_,_,_,_,_,_ ), 0 , 3 , 0 , 3723 , 8 , 4 ), // #108
- INST(Cmpps , ExtRmi , O(000F00,C2,_,_,_,_,_,_ ), 0 , 4 , 0 , 3730 , 8 , 5 ), // #109
+ INST(Cmppd , ExtRmi , O(660F00,C2,_,_,_,_,_,_ ), 0 , 3 , 0 , 3737 , 8 , 4 ), // #108
+ INST(Cmpps , ExtRmi , O(000F00,C2,_,_,_,_,_,_ ), 0 , 4 , 0 , 3751 , 8 , 5 ), // #109
INST(Cmps , X86StrMm , O(000000,A6,_,_,_,_,_,_ ), 0 , 0 , 0 , 454 , 36 , 37 ), // #110
- INST(Cmpsd , ExtRmi , O(F20F00,C2,_,_,_,_,_,_ ), 0 , 5 , 0 , 3737 , 37 , 4 ), // #111
- INST(Cmpss , ExtRmi , O(F30F00,C2,_,_,_,_,_,_ ), 0 , 6 , 0 , 3744 , 38 , 5 ), // #112
+ INST(Cmpsd , ExtRmi , O(F20F00,C2,_,_,_,_,_,_ ), 0 , 5 , 0 , 3758 , 37 , 4 ), // #111
+ INST(Cmpss , ExtRmi , O(F30F00,C2,_,_,_,_,_,_ ), 0 , 6 , 0 , 3772 , 38 , 5 ), // #112
INST(Cmpxchg , X86Cmpxchg , O(000F00,B0,_,_,x,_,_,_ ), 0 , 4 , 0 , 459 , 39 , 38 ), // #113
INST(Cmpxchg16b , X86Cmpxchg8b_16b , O(000F00,C7,1,_,1,_,_,_ ), 0 , 28 , 0 , 467 , 40 , 39 ), // #114
INST(Cmpxchg8b , X86Cmpxchg8b_16b , O(000F00,C7,1,_,_,_,_,_ ), 0 , 29 , 0 , 478 , 41 , 40 ), // #115
- INST(Comisd , ExtRm , O(660F00,2F,_,_,_,_,_,_ ), 0 , 3 , 0 , 10290, 6 , 41 ), // #116
- INST(Comiss , ExtRm , O(000F00,2F,_,_,_,_,_,_ ), 0 , 4 , 0 , 10299, 7 , 42 ), // #117
+ INST(Comisd , ExtRm , O(660F00,2F,_,_,_,_,_,_ ), 0 , 3 , 0 , 11391, 6 , 41 ), // #116
+ INST(Comiss , ExtRm , O(000F00,2F,_,_,_,_,_,_ ), 0 , 4 , 0 , 11409, 7 , 42 ), // #117
INST(Cpuid , X86Op , O(000F00,A2,_,_,_,_,_,_ ), 0 , 4 , 0 , 488 , 42 , 43 ), // #118
INST(Cqo , X86Op_xDX_xAX , O(000000,99,_,_,1,_,_,_ ), 0 , 20 , 0 , 494 , 43 , 0 ), // #119
INST(Crc32 , X86Crc , O(F20F38,F0,_,_,x,_,_,_ ), 0 , 30 , 0 , 498 , 44 , 44 ), // #120
- INST(Cvtdq2pd , ExtRm , O(F30F00,E6,_,_,_,_,_,_ ), 0 , 6 , 0 , 3791 , 6 , 4 ), // #121
- INST(Cvtdq2ps , ExtRm , O(000F00,5B,_,_,_,_,_,_ ), 0 , 4 , 0 , 3801 , 5 , 4 ), // #122
- INST(Cvtpd2dq , ExtRm , O(F20F00,E6,_,_,_,_,_,_ ), 0 , 5 , 0 , 3840 , 5 , 4 ), // #123
+ INST(Cvtdq2pd , ExtRm , O(F30F00,E6,_,_,_,_,_,_ ), 0 , 6 , 0 , 3827 , 6 , 4 ), // #121
+ INST(Cvtdq2ps , ExtRm , O(000F00,5B,_,_,_,_,_,_ ), 0 , 4 , 0 , 3847 , 5 , 4 ), // #122
+ INST(Cvtpd2dq , ExtRm , O(F20F00,E6,_,_,_,_,_,_ ), 0 , 5 , 0 , 3886 , 5 , 4 ), // #123
INST(Cvtpd2pi , ExtRm , O(660F00,2D,_,_,_,_,_,_ ), 0 , 3 , 0 , 504 , 45 , 4 ), // #124
- INST(Cvtpd2ps , ExtRm , O(660F00,5A,_,_,_,_,_,_ ), 0 , 3 , 0 , 3850 , 5 , 4 ), // #125
+ INST(Cvtpd2ps , ExtRm , O(660F00,5A,_,_,_,_,_,_ ), 0 , 3 , 0 , 3906 , 5 , 4 ), // #125
INST(Cvtpi2pd , ExtRm , O(660F00,2A,_,_,_,_,_,_ ), 0 , 3 , 0 , 513 , 46 , 4 ), // #126
INST(Cvtpi2ps , ExtRm , O(000F00,2A,_,_,_,_,_,_ ), 0 , 4 , 0 , 522 , 46 , 5 ), // #127
- INST(Cvtps2dq , ExtRm , O(660F00,5B,_,_,_,_,_,_ ), 0 , 3 , 0 , 3902 , 5 , 4 ), // #128
- INST(Cvtps2pd , ExtRm , O(000F00,5A,_,_,_,_,_,_ ), 0 , 4 , 0 , 3912 , 6 , 4 ), // #129
+ INST(Cvtps2dq , ExtRm , O(660F00,5B,_,_,_,_,_,_ ), 0 , 3 , 0 , 4040 , 5 , 4 ), // #128
+ INST(Cvtps2pd , ExtRm , O(000F00,5A,_,_,_,_,_,_ ), 0 , 4 , 0 , 4050 , 6 , 4 ), // #129
INST(Cvtps2pi , ExtRm , O(000F00,2D,_,_,_,_,_,_ ), 0 , 4 , 0 , 531 , 47 , 5 ), // #130
- INST(Cvtsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2D,_,_,x,_,_,_ ), 0 , 5 , 0 , 3984 , 48 , 4 ), // #131
- INST(Cvtsd2ss , ExtRm , O(F20F00,5A,_,_,_,_,_,_ ), 0 , 5 , 0 , 3994 , 6 , 4 ), // #132
- INST(Cvtsi2sd , ExtRm_Wx , O(F20F00,2A,_,_,x,_,_,_ ), 0 , 5 , 0 , 4015 , 49 , 4 ), // #133
- INST(Cvtsi2ss , ExtRm_Wx , O(F30F00,2A,_,_,x,_,_,_ ), 0 , 6 , 0 , 4025 , 49 , 5 ), // #134
- INST(Cvtss2sd , ExtRm , O(F30F00,5A,_,_,_,_,_,_ ), 0 , 6 , 0 , 4035 , 7 , 4 ), // #135
- INST(Cvtss2si , ExtRm_Wx_GpqOnly , O(F30F00,2D,_,_,x,_,_,_ ), 0 , 6 , 0 , 4045 , 50 , 5 ), // #136
- INST(Cvttpd2dq , ExtRm , O(660F00,E6,_,_,_,_,_,_ ), 0 , 3 , 0 , 4066 , 5 , 4 ), // #137
+ INST(Cvtsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2D,_,_,x,_,_,_ ), 0 , 5 , 0 , 4153 , 48 , 4 ), // #131
+ INST(Cvtsd2ss , ExtRm , O(F20F00,5A,_,_,_,_,_,_ ), 0 , 5 , 0 , 4163 , 6 , 4 ), // #132
+ INST(Cvtsi2sd , ExtRm_Wx , O(F20F00,2A,_,_,x,_,_,_ ), 0 , 5 , 0 , 4225 , 49 , 4 ), // #133
+ INST(Cvtsi2ss , ExtRm_Wx , O(F30F00,2A,_,_,x,_,_,_ ), 0 , 6 , 0 , 4245 , 49 , 5 ), // #134
+ INST(Cvtss2sd , ExtRm , O(F30F00,5A,_,_,_,_,_,_ ), 0 , 6 , 0 , 4255 , 7 , 4 ), // #135
+ INST(Cvtss2si , ExtRm_Wx_GpqOnly , O(F30F00,2D,_,_,x,_,_,_ ), 0 , 6 , 0 , 4275 , 50 , 5 ), // #136
+ INST(Cvttpd2dq , ExtRm , O(660F00,E6,_,_,_,_,_,_ ), 0 , 3 , 0 , 4296 , 5 , 4 ), // #137
INST(Cvttpd2pi , ExtRm , O(660F00,2C,_,_,_,_,_,_ ), 0 , 3 , 0 , 540 , 45 , 4 ), // #138
- INST(Cvttps2dq , ExtRm , O(F30F00,5B,_,_,_,_,_,_ ), 0 , 6 , 0 , 4112 , 5 , 4 ), // #139
+ INST(Cvttps2dq , ExtRm , O(F30F00,5B,_,_,_,_,_,_ ), 0 , 6 , 0 , 4409 , 5 , 4 ), // #139
INST(Cvttps2pi , ExtRm , O(000F00,2C,_,_,_,_,_,_ ), 0 , 4 , 0 , 550 , 47 , 5 ), // #140
- INST(Cvttsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2C,_,_,x,_,_,_ ), 0 , 5 , 0 , 4158 , 48 , 4 ), // #141
- INST(Cvttss2si , ExtRm_Wx_GpqOnly , O(F30F00,2C,_,_,x,_,_,_ ), 0 , 6 , 0 , 4181 , 50 , 5 ), // #142
+ INST(Cvttsd2si , ExtRm_Wx_GpqOnly , O(F20F00,2C,_,_,x,_,_,_ ), 0 , 5 , 0 , 4455 , 48 , 4 ), // #141
+ INST(Cvttss2si , ExtRm_Wx_GpqOnly , O(F30F00,2C,_,_,x,_,_,_ ), 0 , 6 , 0 , 4501 , 50 , 5 ), // #142
INST(Cwd , X86Op_xDX_xAX , O(660000,99,_,_,_,_,_,_ ), 0 , 19 , 0 , 560 , 51 , 0 ), // #143
INST(Cwde , X86Op_xAX , O(000000,98,_,_,_,_,_,_ ), 0 , 0 , 0 , 564 , 52 , 0 ), // #144
INST(Daa , X86Op , O(000000,27,_,_,_,_,_,_ ), 0 , 0 , 0 , 569 , 1 , 1 ), // #145
INST(Das , X86Op , O(000000,2F,_,_,_,_,_,_ ), 0 , 0 , 0 , 573 , 1 , 1 ), // #146
- INST(Dec , X86IncDec , O(000000,FE,1,_,x,_,_,_ ), O(000000,48,_,_,x,_,_,_ ), 31 , 6 , 3341 , 53 , 45 ), // #147
+ INST(Dec , X86IncDec , O(000000,FE,1,_,x,_,_,_ ), O(000000,48,_,_,x,_,_,_ ), 31 , 6 , 3355 , 53 , 45 ), // #147
INST(Div , X86M_GPB_MulDiv , O(000000,F6,6,_,x,_,_,_ ), 0 , 32 , 0 , 810 , 54 , 1 ), // #148
- INST(Divpd , ExtRm , O(660F00,5E,_,_,_,_,_,_ ), 0 , 3 , 0 , 4280 , 5 , 4 ), // #149
- INST(Divps , ExtRm , O(000F00,5E,_,_,_,_,_,_ ), 0 , 4 , 0 , 4287 , 5 , 5 ), // #150
- INST(Divsd , ExtRm , O(F20F00,5E,_,_,_,_,_,_ ), 0 , 5 , 0 , 4294 , 6 , 4 ), // #151
- INST(Divss , ExtRm , O(F30F00,5E,_,_,_,_,_,_ ), 0 , 6 , 0 , 4301 , 7 , 5 ), // #152
- INST(Dppd , ExtRmi , O(660F3A,41,_,_,_,_,_,_ ), 0 , 8 , 0 , 4318 , 8 , 12 ), // #153
- INST(Dpps , ExtRmi , O(660F3A,40,_,_,_,_,_,_ ), 0 , 8 , 0 , 4324 , 8 , 12 ), // #154
+ INST(Divpd , ExtRm , O(660F00,5E,_,_,_,_,_,_ ), 0 , 3 , 0 , 4652 , 5 , 4 ), // #149
+ INST(Divps , ExtRm , O(000F00,5E,_,_,_,_,_,_ ), 0 , 4 , 0 , 4666 , 5 , 5 ), // #150
+ INST(Divsd , ExtRm , O(F20F00,5E,_,_,_,_,_,_ ), 0 , 5 , 0 , 4673 , 6 , 4 ), // #151
+ INST(Divss , ExtRm , O(F30F00,5E,_,_,_,_,_,_ ), 0 , 6 , 0 , 4687 , 7 , 5 ), // #152
+ INST(Dppd , ExtRmi , O(660F3A,41,_,_,_,_,_,_ ), 0 , 8 , 0 , 4704 , 8 , 12 ), // #153
+ INST(Dpps , ExtRmi , O(660F3A,40,_,_,_,_,_,_ ), 0 , 8 , 0 , 4710 , 8 , 12 ), // #154
INST(Emms , X86Op , O(000F00,77,_,_,_,_,_,_ ), 0 , 4 , 0 , 778 , 55 , 46 ), // #155
INST(Endbr32 , X86Op_Mod11RM , O(F30F00,1E,7,_,_,_,_,3 ), 0 , 33 , 0 , 577 , 30 , 47 ), // #156
INST(Endbr64 , X86Op_Mod11RM , O(F30F00,1E,7,_,_,_,_,2 ), 0 , 34 , 0 , 585 , 30 , 47 ), // #157
INST(Enqcmd , X86EnqcmdMovdir64b , O(F20F38,F8,_,_,_,_,_,_ ), 0 , 30 , 0 , 593 , 56 , 48 ), // #158
INST(Enqcmds , X86EnqcmdMovdir64b , O(F30F38,F8,_,_,_,_,_,_ ), 0 , 7 , 0 , 600 , 56 , 48 ), // #159
INST(Enter , X86Enter , O(000000,C8,_,_,_,_,_,_ ), 0 , 0 , 0 , 3046 , 57 , 0 ), // #160
- INST(Extractps , ExtExtract , O(660F3A,17,_,_,_,_,_,_ ), 0 , 8 , 0 , 4514 , 58 , 12 ), // #161
- INST(Extrq , ExtExtrq , O(660F00,79,_,_,_,_,_,_ ), O(660F00,78,0,_,_,_,_,_ ), 3 , 7 , 7650 , 59 , 49 ), // #162
+ INST(Extractps , ExtExtract , O(660F3A,17,_,_,_,_,_,_ ), 0 , 8 , 0 , 4900 , 58 , 12 ), // #161
+ INST(Extrq , ExtExtrq , O(660F00,79,_,_,_,_,_,_ ), O(660F00,78,0,_,_,_,_,_ ), 3 , 7 , 8625 , 59 , 49 ), // #162
INST(F2xm1 , FpuOp , O_FPU(00,D9F0,_) , 0 , 35 , 0 , 608 , 30 , 0 ), // #163
INST(Fabs , FpuOp , O_FPU(00,D9E1,_) , 0 , 35 , 0 , 614 , 30 , 0 ), // #164
INST(Fadd , FpuArith , O_FPU(00,C0C0,0) , 0 , 36 , 0 , 2121 , 60 , 0 ), // #165
@@ -345,39 +323,39 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Fucomip , FpuR , O_FPU(00,DFE8,_) , 0 , 44 , 0 , 1124 , 63 , 50 ), // #248
INST(Fucomp , FpuRDef , O_FPU(00,DDE8,_) , 0 , 48 , 0 , 1132 , 61 , 0 ), // #249
INST(Fucompp , FpuOp , O_FPU(00,DAE9,_) , 0 , 41 , 0 , 1139 , 30 , 0 ), // #250
- INST(Fwait , X86Op , O_FPU(00,009B,_) , 0 , 60 , 0 , 1147 , 30 , 0 ), // #251
+ INST(Fwait , X86Op , O_FPU(00,009B,_) , 0 , 49 , 0 , 1147 , 30 , 0 ), // #251
INST(Fxam , FpuOp , O_FPU(00,D9E5,_) , 0 , 35 , 0 , 1153 , 30 , 0 ), // #252
INST(Fxch , FpuR , O_FPU(00,D9C8,_) , 0 , 35 , 0 , 1158 , 61 , 0 ), // #253
INST(Fxrstor , X86M_Only , O(000F00,AE,1,_,_,_,_,_ ), 0 , 29 , 0 , 1163 , 69 , 52 ), // #254
INST(Fxrstor64 , X86M_Only , O(000F00,AE,1,_,1,_,_,_ ), 0 , 28 , 0 , 1171 , 72 , 52 ), // #255
INST(Fxsave , X86M_Only , O(000F00,AE,0,_,_,_,_,_ ), 0 , 4 , 0 , 1181 , 69 , 52 ), // #256
- INST(Fxsave64 , X86M_Only , O(000F00,AE,0,_,1,_,_,_ ), 0 , 61 , 0 , 1188 , 72 , 52 ), // #257
+ INST(Fxsave64 , X86M_Only , O(000F00,AE,0,_,1,_,_,_ ), 0 , 60 , 0 , 1188 , 72 , 52 ), // #257
INST(Fxtract , FpuOp , O_FPU(00,D9F4,_) , 0 , 35 , 0 , 1197 , 30 , 0 ), // #258
INST(Fyl2x , FpuOp , O_FPU(00,D9F1,_) , 0 , 35 , 0 , 1205 , 30 , 0 ), // #259
INST(Fyl2xp1 , FpuOp , O_FPU(00,D9F9,_) , 0 , 35 , 0 , 1211 , 30 , 0 ), // #260
INST(Getsec , X86Op , O(000F00,37,_,_,_,_,_,_ ), 0 , 4 , 0 , 1219 , 30 , 53 ), // #261
- INST(Gf2p8affineinvqb , ExtRmi , O(660F3A,CF,_,_,_,_,_,_ ), 0 , 8 , 0 , 5869 , 8 , 54 ), // #262
- INST(Gf2p8affineqb , ExtRmi , O(660F3A,CE,_,_,_,_,_,_ ), 0 , 8 , 0 , 5887 , 8 , 54 ), // #263
- INST(Gf2p8mulb , ExtRm , O(660F38,CF,_,_,_,_,_,_ ), 0 , 2 , 0 , 5902 , 5 , 54 ), // #264
- INST(Haddpd , ExtRm , O(660F00,7C,_,_,_,_,_,_ ), 0 , 3 , 0 , 5913 , 5 , 6 ), // #265
- INST(Haddps , ExtRm , O(F20F00,7C,_,_,_,_,_,_ ), 0 , 5 , 0 , 5921 , 5 , 6 ), // #266
+ INST(Gf2p8affineinvqb , ExtRmi , O(660F3A,CF,_,_,_,_,_,_ ), 0 , 8 , 0 , 6789 , 8 , 54 ), // #262
+ INST(Gf2p8affineqb , ExtRmi , O(660F3A,CE,_,_,_,_,_,_ ), 0 , 8 , 0 , 6807 , 8 , 54 ), // #263
+ INST(Gf2p8mulb , ExtRm , O(660F38,CF,_,_,_,_,_,_ ), 0 , 2 , 0 , 6822 , 5 , 54 ), // #264
+ INST(Haddpd , ExtRm , O(660F00,7C,_,_,_,_,_,_ ), 0 , 3 , 0 , 6833 , 5 , 6 ), // #265
+ INST(Haddps , ExtRm , O(F20F00,7C,_,_,_,_,_,_ ), 0 , 5 , 0 , 6841 , 5 , 6 ), // #266
INST(Hlt , X86Op , O(000000,F4,_,_,_,_,_,_ ), 0 , 0 , 0 , 1226 , 30 , 0 ), // #267
- INST(Hreset , X86Op_Mod11RM_I8 , O(F30F3A,F0,0,_,_,_,_,_ ), 0 , 62 , 0 , 1230 , 73 , 55 ), // #268
- INST(Hsubpd , ExtRm , O(660F00,7D,_,_,_,_,_,_ ), 0 , 3 , 0 , 5929 , 5 , 6 ), // #269
- INST(Hsubps , ExtRm , O(F20F00,7D,_,_,_,_,_,_ ), 0 , 5 , 0 , 5937 , 5 , 6 ), // #270
+ INST(Hreset , X86Op_Mod11RM_I8 , O(F30F3A,F0,0,_,_,_,_,_ ), 0 , 61 , 0 , 1230 , 73 , 55 ), // #268
+ INST(Hsubpd , ExtRm , O(660F00,7D,_,_,_,_,_,_ ), 0 , 3 , 0 , 6849 , 5 , 6 ), // #269
+ INST(Hsubps , ExtRm , O(F20F00,7D,_,_,_,_,_,_ ), 0 , 5 , 0 , 6857 , 5 , 6 ), // #270
INST(Idiv , X86M_GPB_MulDiv , O(000000,F6,7,_,x,_,_,_ ), 0 , 27 , 0 , 809 , 54 , 1 ), // #271
- INST(Imul , X86Imul , O(000000,F6,5,_,x,_,_,_ ), 0 , 63 , 0 , 827 , 74 , 1 ), // #272
- INST(In , X86In , O(000000,EC,_,_,_,_,_,_ ), O(000000,E4,_,_,_,_,_,_ ), 0 , 15 , 10462, 75 , 0 ), // #273
+ INST(Imul , X86Imul , O(000000,F6,5,_,x,_,_,_ ), 0 , 62 , 0 , 827 , 74 , 1 ), // #272
+ INST(In , X86In , O(000000,EC,_,_,_,_,_,_ ), O(000000,E4,_,_,_,_,_,_ ), 0 , 15 , 11572, 75 , 0 ), // #273
INST(Inc , X86IncDec , O(000000,FE,0,_,x,_,_,_ ), O(000000,40,_,_,x,_,_,_ ), 0 , 16 , 1237 , 53 , 45 ), // #274
- INST(Incsspd , X86M , O(F30F00,AE,5,_,0,_,_,_ ), 0 , 64 , 0 , 1241 , 76 , 56 ), // #275
- INST(Incsspq , X86M , O(F30F00,AE,5,_,1,_,_,_ ), 0 , 65 , 0 , 1249 , 77 , 56 ), // #276
+ INST(Incsspd , X86M , O(F30F00,AE,5,_,0,_,_,_ ), 0 , 63 , 0 , 1241 , 76 , 56 ), // #275
+ INST(Incsspq , X86M , O(F30F00,AE,5,_,1,_,_,_ ), 0 , 64 , 0 , 1249 , 77 , 56 ), // #276
INST(Ins , X86Ins , O(000000,6C,_,_,_,_,_,_ ), 0 , 0 , 0 , 1916 , 78 , 0 ), // #277
- INST(Insertps , ExtRmi , O(660F3A,21,_,_,_,_,_,_ ), 0 , 8 , 0 , 6073 , 38 , 12 ), // #278
+ INST(Insertps , ExtRmi , O(660F3A,21,_,_,_,_,_,_ ), 0 , 8 , 0 , 6993 , 38 , 12 ), // #278
INST(Insertq , ExtInsertq , O(F20F00,79,_,_,_,_,_,_ ), O(F20F00,78,_,_,_,_,_,_ ), 5 , 17 , 1257 , 79 , 49 ), // #279
INST(Int , X86Int , O(000000,CD,_,_,_,_,_,_ ), 0 , 0 , 0 , 1022 , 80 , 0 ), // #280
INST(Int3 , X86Op , O(000000,CC,_,_,_,_,_,_ ), 0 , 0 , 0 , 1265 , 30 , 0 ), // #281
INST(Into , X86Op , O(000000,CE,_,_,_,_,_,_ ), 0 , 0 , 0 , 1270 , 81 , 57 ), // #282
- INST(Invd , X86Op , O(000F00,08,_,_,_,_,_,_ ), 0 , 4 , 0 , 10391, 30 , 43 ), // #283
+ INST(Invd , X86Op , O(000F00,08,_,_,_,_,_,_ ), 0 , 4 , 0 , 11501, 30 , 43 ), // #283
INST(Invept , X86Rm_NoSize , O(660F38,80,_,_,_,_,_,_ ), 0 , 2 , 0 , 1275 , 82 , 58 ), // #284
INST(Invlpg , X86M_Only , O(000F00,01,7,_,_,_,_,_ ), 0 , 22 , 0 , 1282 , 69 , 43 ), // #285
INST(Invlpga , X86Op_xAddr , O(000F01,DF,_,_,_,_,_,_ ), 0 , 21 , 0 , 1289 , 83 , 22 ), // #286
@@ -418,370 +396,370 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Jpo , X86Jcc , O(000F00,8B,_,_,_,_,_,_ ), O(000000,7B,_,_,_,_,_,_ ), 4 , 31 , 1435 , 86 , 64 ), // #321
INST(Js , X86Jcc , O(000F00,88,_,_,_,_,_,_ ), O(000000,78,_,_,_,_,_,_ ), 4 , 35 , 1439 , 86 , 65 ), // #322
INST(Jz , X86Jcc , O(000F00,84,_,_,_,_,_,_ ), O(000000,74,_,_,_,_,_,_ ), 4 , 22 , 1442 , 86 , 61 ), // #323
- INST(Kaddb , VexRvm , V(660F00,4A,_,1,0,_,_,_ ), 0 , 66 , 0 , 1445 , 89 , 66 ), // #324
- INST(Kaddd , VexRvm , V(660F00,4A,_,1,1,_,_,_ ), 0 , 67 , 0 , 1451 , 89 , 67 ), // #325
- INST(Kaddq , VexRvm , V(000F00,4A,_,1,1,_,_,_ ), 0 , 68 , 0 , 1457 , 89 , 67 ), // #326
- INST(Kaddw , VexRvm , V(000F00,4A,_,1,0,_,_,_ ), 0 , 69 , 0 , 1463 , 89 , 66 ), // #327
- INST(Kandb , VexRvm , V(660F00,41,_,1,0,_,_,_ ), 0 , 66 , 0 , 1469 , 89 , 66 ), // #328
- INST(Kandd , VexRvm , V(660F00,41,_,1,1,_,_,_ ), 0 , 67 , 0 , 1475 , 89 , 67 ), // #329
- INST(Kandnb , VexRvm , V(660F00,42,_,1,0,_,_,_ ), 0 , 66 , 0 , 1481 , 89 , 66 ), // #330
- INST(Kandnd , VexRvm , V(660F00,42,_,1,1,_,_,_ ), 0 , 67 , 0 , 1488 , 89 , 67 ), // #331
- INST(Kandnq , VexRvm , V(000F00,42,_,1,1,_,_,_ ), 0 , 68 , 0 , 1495 , 89 , 67 ), // #332
- INST(Kandnw , VexRvm , V(000F00,42,_,1,0,_,_,_ ), 0 , 69 , 0 , 1502 , 89 , 68 ), // #333
- INST(Kandq , VexRvm , V(000F00,41,_,1,1,_,_,_ ), 0 , 68 , 0 , 1509 , 89 , 67 ), // #334
- INST(Kandw , VexRvm , V(000F00,41,_,1,0,_,_,_ ), 0 , 69 , 0 , 1515 , 89 , 68 ), // #335
- INST(Kmovb , VexKmov , V(660F00,90,_,0,0,_,_,_ ), V(660F00,92,_,0,0,_,_,_ ), 70 , 36 , 1521 , 90 , 66 ), // #336
- INST(Kmovd , VexKmov , V(660F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,0,_,_,_ ), 71 , 37 , 8130 , 91 , 67 ), // #337
- INST(Kmovq , VexKmov , V(000F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,1,_,_,_ ), 72 , 38 , 8141 , 92 , 67 ), // #338
- INST(Kmovw , VexKmov , V(000F00,90,_,0,0,_,_,_ ), V(000F00,92,_,0,0,_,_,_ ), 73 , 39 , 1527 , 93 , 68 ), // #339
- INST(Knotb , VexRm , V(660F00,44,_,0,0,_,_,_ ), 0 , 70 , 0 , 1533 , 94 , 66 ), // #340
- INST(Knotd , VexRm , V(660F00,44,_,0,1,_,_,_ ), 0 , 71 , 0 , 1539 , 94 , 67 ), // #341
- INST(Knotq , VexRm , V(000F00,44,_,0,1,_,_,_ ), 0 , 72 , 0 , 1545 , 94 , 67 ), // #342
- INST(Knotw , VexRm , V(000F00,44,_,0,0,_,_,_ ), 0 , 73 , 0 , 1551 , 94 , 68 ), // #343
- INST(Korb , VexRvm , V(660F00,45,_,1,0,_,_,_ ), 0 , 66 , 0 , 1557 , 89 , 66 ), // #344
- INST(Kord , VexRvm , V(660F00,45,_,1,1,_,_,_ ), 0 , 67 , 0 , 1562 , 89 , 67 ), // #345
- INST(Korq , VexRvm , V(000F00,45,_,1,1,_,_,_ ), 0 , 68 , 0 , 1567 , 89 , 67 ), // #346
- INST(Kortestb , VexRm , V(660F00,98,_,0,0,_,_,_ ), 0 , 70 , 0 , 1572 , 94 , 69 ), // #347
- INST(Kortestd , VexRm , V(660F00,98,_,0,1,_,_,_ ), 0 , 71 , 0 , 1581 , 94 , 70 ), // #348
- INST(Kortestq , VexRm , V(000F00,98,_,0,1,_,_,_ ), 0 , 72 , 0 , 1590 , 94 , 70 ), // #349
- INST(Kortestw , VexRm , V(000F00,98,_,0,0,_,_,_ ), 0 , 73 , 0 , 1599 , 94 , 71 ), // #350
- INST(Korw , VexRvm , V(000F00,45,_,1,0,_,_,_ ), 0 , 69 , 0 , 1608 , 89 , 68 ), // #351
- INST(Kshiftlb , VexRmi , V(660F3A,32,_,0,0,_,_,_ ), 0 , 74 , 0 , 1613 , 95 , 66 ), // #352
- INST(Kshiftld , VexRmi , V(660F3A,33,_,0,0,_,_,_ ), 0 , 74 , 0 , 1622 , 95 , 67 ), // #353
- INST(Kshiftlq , VexRmi , V(660F3A,33,_,0,1,_,_,_ ), 0 , 75 , 0 , 1631 , 95 , 67 ), // #354
- INST(Kshiftlw , VexRmi , V(660F3A,32,_,0,1,_,_,_ ), 0 , 75 , 0 , 1640 , 95 , 68 ), // #355
- INST(Kshiftrb , VexRmi , V(660F3A,30,_,0,0,_,_,_ ), 0 , 74 , 0 , 1649 , 95 , 66 ), // #356
- INST(Kshiftrd , VexRmi , V(660F3A,31,_,0,0,_,_,_ ), 0 , 74 , 0 , 1658 , 95 , 67 ), // #357
- INST(Kshiftrq , VexRmi , V(660F3A,31,_,0,1,_,_,_ ), 0 , 75 , 0 , 1667 , 95 , 67 ), // #358
- INST(Kshiftrw , VexRmi , V(660F3A,30,_,0,1,_,_,_ ), 0 , 75 , 0 , 1676 , 95 , 68 ), // #359
- INST(Ktestb , VexRm , V(660F00,99,_,0,0,_,_,_ ), 0 , 70 , 0 , 1685 , 94 , 69 ), // #360
- INST(Ktestd , VexRm , V(660F00,99,_,0,1,_,_,_ ), 0 , 71 , 0 , 1692 , 94 , 70 ), // #361
- INST(Ktestq , VexRm , V(000F00,99,_,0,1,_,_,_ ), 0 , 72 , 0 , 1699 , 94 , 70 ), // #362
- INST(Ktestw , VexRm , V(000F00,99,_,0,0,_,_,_ ), 0 , 73 , 0 , 1706 , 94 , 69 ), // #363
- INST(Kunpckbw , VexRvm , V(660F00,4B,_,1,0,_,_,_ ), 0 , 66 , 0 , 1713 , 89 , 68 ), // #364
- INST(Kunpckdq , VexRvm , V(000F00,4B,_,1,1,_,_,_ ), 0 , 68 , 0 , 1722 , 89 , 67 ), // #365
- INST(Kunpckwd , VexRvm , V(000F00,4B,_,1,0,_,_,_ ), 0 , 69 , 0 , 1731 , 89 , 67 ), // #366
- INST(Kxnorb , VexRvm , V(660F00,46,_,1,0,_,_,_ ), 0 , 66 , 0 , 1740 , 96 , 66 ), // #367
- INST(Kxnord , VexRvm , V(660F00,46,_,1,1,_,_,_ ), 0 , 67 , 0 , 1747 , 96 , 67 ), // #368
- INST(Kxnorq , VexRvm , V(000F00,46,_,1,1,_,_,_ ), 0 , 68 , 0 , 1754 , 96 , 67 ), // #369
- INST(Kxnorw , VexRvm , V(000F00,46,_,1,0,_,_,_ ), 0 , 69 , 0 , 1761 , 96 , 68 ), // #370
- INST(Kxorb , VexRvm , V(660F00,47,_,1,0,_,_,_ ), 0 , 66 , 0 , 1768 , 96 , 66 ), // #371
- INST(Kxord , VexRvm , V(660F00,47,_,1,1,_,_,_ ), 0 , 67 , 0 , 1774 , 96 , 67 ), // #372
- INST(Kxorq , VexRvm , V(000F00,47,_,1,1,_,_,_ ), 0 , 68 , 0 , 1780 , 96 , 67 ), // #373
- INST(Kxorw , VexRvm , V(000F00,47,_,1,0,_,_,_ ), 0 , 69 , 0 , 1786 , 96 , 68 ), // #374
+ INST(Kaddb , VexRvm , V(660F00,4A,_,1,0,_,_,_ ), 0 , 65 , 0 , 1445 , 89 , 66 ), // #324
+ INST(Kaddd , VexRvm , V(660F00,4A,_,1,1,_,_,_ ), 0 , 66 , 0 , 1451 , 89 , 67 ), // #325
+ INST(Kaddq , VexRvm , V(000F00,4A,_,1,1,_,_,_ ), 0 , 67 , 0 , 1457 , 89 , 67 ), // #326
+ INST(Kaddw , VexRvm , V(000F00,4A,_,1,0,_,_,_ ), 0 , 68 , 0 , 1463 , 89 , 66 ), // #327
+ INST(Kandb , VexRvm , V(660F00,41,_,1,0,_,_,_ ), 0 , 65 , 0 , 1469 , 89 , 66 ), // #328
+ INST(Kandd , VexRvm , V(660F00,41,_,1,1,_,_,_ ), 0 , 66 , 0 , 1475 , 89 , 67 ), // #329
+ INST(Kandnb , VexRvm , V(660F00,42,_,1,0,_,_,_ ), 0 , 65 , 0 , 1481 , 89 , 66 ), // #330
+ INST(Kandnd , VexRvm , V(660F00,42,_,1,1,_,_,_ ), 0 , 66 , 0 , 1488 , 89 , 67 ), // #331
+ INST(Kandnq , VexRvm , V(000F00,42,_,1,1,_,_,_ ), 0 , 67 , 0 , 1495 , 89 , 67 ), // #332
+ INST(Kandnw , VexRvm , V(000F00,42,_,1,0,_,_,_ ), 0 , 68 , 0 , 1502 , 89 , 68 ), // #333
+ INST(Kandq , VexRvm , V(000F00,41,_,1,1,_,_,_ ), 0 , 67 , 0 , 1509 , 89 , 67 ), // #334
+ INST(Kandw , VexRvm , V(000F00,41,_,1,0,_,_,_ ), 0 , 68 , 0 , 1515 , 89 , 68 ), // #335
+ INST(Kmovb , VexKmov , V(660F00,90,_,0,0,_,_,_ ), V(660F00,92,_,0,0,_,_,_ ), 69 , 36 , 1521 , 90 , 66 ), // #336
+ INST(Kmovd , VexKmov , V(660F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,0,_,_,_ ), 70 , 37 , 9105 , 91 , 67 ), // #337
+ INST(Kmovq , VexKmov , V(000F00,90,_,0,1,_,_,_ ), V(F20F00,92,_,0,1,_,_,_ ), 71 , 38 , 9116 , 92 , 67 ), // #338
+ INST(Kmovw , VexKmov , V(000F00,90,_,0,0,_,_,_ ), V(000F00,92,_,0,0,_,_,_ ), 72 , 39 , 1527 , 93 , 68 ), // #339
+ INST(Knotb , VexRm , V(660F00,44,_,0,0,_,_,_ ), 0 , 69 , 0 , 1533 , 94 , 66 ), // #340
+ INST(Knotd , VexRm , V(660F00,44,_,0,1,_,_,_ ), 0 , 70 , 0 , 1539 , 94 , 67 ), // #341
+ INST(Knotq , VexRm , V(000F00,44,_,0,1,_,_,_ ), 0 , 71 , 0 , 1545 , 94 , 67 ), // #342
+ INST(Knotw , VexRm , V(000F00,44,_,0,0,_,_,_ ), 0 , 72 , 0 , 1551 , 94 , 68 ), // #343
+ INST(Korb , VexRvm , V(660F00,45,_,1,0,_,_,_ ), 0 , 65 , 0 , 1557 , 89 , 66 ), // #344
+ INST(Kord , VexRvm , V(660F00,45,_,1,1,_,_,_ ), 0 , 66 , 0 , 1562 , 89 , 67 ), // #345
+ INST(Korq , VexRvm , V(000F00,45,_,1,1,_,_,_ ), 0 , 67 , 0 , 1567 , 89 , 67 ), // #346
+ INST(Kortestb , VexRm , V(660F00,98,_,0,0,_,_,_ ), 0 , 69 , 0 , 1572 , 94 , 69 ), // #347
+ INST(Kortestd , VexRm , V(660F00,98,_,0,1,_,_,_ ), 0 , 70 , 0 , 1581 , 94 , 70 ), // #348
+ INST(Kortestq , VexRm , V(000F00,98,_,0,1,_,_,_ ), 0 , 71 , 0 , 1590 , 94 , 70 ), // #349
+ INST(Kortestw , VexRm , V(000F00,98,_,0,0,_,_,_ ), 0 , 72 , 0 , 1599 , 94 , 71 ), // #350
+ INST(Korw , VexRvm , V(000F00,45,_,1,0,_,_,_ ), 0 , 68 , 0 , 1608 , 89 , 68 ), // #351
+ INST(Kshiftlb , VexRmi , V(660F3A,32,_,0,0,_,_,_ ), 0 , 73 , 0 , 1613 , 95 , 66 ), // #352
+ INST(Kshiftld , VexRmi , V(660F3A,33,_,0,0,_,_,_ ), 0 , 73 , 0 , 1622 , 95 , 67 ), // #353
+ INST(Kshiftlq , VexRmi , V(660F3A,33,_,0,1,_,_,_ ), 0 , 74 , 0 , 1631 , 95 , 67 ), // #354
+ INST(Kshiftlw , VexRmi , V(660F3A,32,_,0,1,_,_,_ ), 0 , 74 , 0 , 1640 , 95 , 68 ), // #355
+ INST(Kshiftrb , VexRmi , V(660F3A,30,_,0,0,_,_,_ ), 0 , 73 , 0 , 1649 , 95 , 66 ), // #356
+ INST(Kshiftrd , VexRmi , V(660F3A,31,_,0,0,_,_,_ ), 0 , 73 , 0 , 1658 , 95 , 67 ), // #357
+ INST(Kshiftrq , VexRmi , V(660F3A,31,_,0,1,_,_,_ ), 0 , 74 , 0 , 1667 , 95 , 67 ), // #358
+ INST(Kshiftrw , VexRmi , V(660F3A,30,_,0,1,_,_,_ ), 0 , 74 , 0 , 1676 , 95 , 68 ), // #359
+ INST(Ktestb , VexRm , V(660F00,99,_,0,0,_,_,_ ), 0 , 69 , 0 , 1685 , 94 , 69 ), // #360
+ INST(Ktestd , VexRm , V(660F00,99,_,0,1,_,_,_ ), 0 , 70 , 0 , 1692 , 94 , 70 ), // #361
+ INST(Ktestq , VexRm , V(000F00,99,_,0,1,_,_,_ ), 0 , 71 , 0 , 1699 , 94 , 70 ), // #362
+ INST(Ktestw , VexRm , V(000F00,99,_,0,0,_,_,_ ), 0 , 72 , 0 , 1706 , 94 , 69 ), // #363
+ INST(Kunpckbw , VexRvm , V(660F00,4B,_,1,0,_,_,_ ), 0 , 65 , 0 , 1713 , 89 , 68 ), // #364
+ INST(Kunpckdq , VexRvm , V(000F00,4B,_,1,1,_,_,_ ), 0 , 67 , 0 , 1722 , 89 , 67 ), // #365
+ INST(Kunpckwd , VexRvm , V(000F00,4B,_,1,0,_,_,_ ), 0 , 68 , 0 , 1731 , 89 , 67 ), // #366
+ INST(Kxnorb , VexRvm , V(660F00,46,_,1,0,_,_,_ ), 0 , 65 , 0 , 1740 , 96 , 66 ), // #367
+ INST(Kxnord , VexRvm , V(660F00,46,_,1,1,_,_,_ ), 0 , 66 , 0 , 1747 , 96 , 67 ), // #368
+ INST(Kxnorq , VexRvm , V(000F00,46,_,1,1,_,_,_ ), 0 , 67 , 0 , 1754 , 96 , 67 ), // #369
+ INST(Kxnorw , VexRvm , V(000F00,46,_,1,0,_,_,_ ), 0 , 68 , 0 , 1761 , 96 , 68 ), // #370
+ INST(Kxorb , VexRvm , V(660F00,47,_,1,0,_,_,_ ), 0 , 65 , 0 , 1768 , 96 , 66 ), // #371
+ INST(Kxord , VexRvm , V(660F00,47,_,1,1,_,_,_ ), 0 , 66 , 0 , 1774 , 96 , 67 ), // #372
+ INST(Kxorq , VexRvm , V(000F00,47,_,1,1,_,_,_ ), 0 , 67 , 0 , 1780 , 96 , 67 ), // #373
+ INST(Kxorw , VexRvm , V(000F00,47,_,1,0,_,_,_ ), 0 , 68 , 0 , 1786 , 96 , 68 ), // #374
INST(Lahf , X86Op , O(000000,9F,_,_,_,_,_,_ ), 0 , 0 , 0 , 1792 , 97 , 72 ), // #375
INST(Lar , X86Rm , O(000F00,02,_,_,_,_,_,_ ), 0 , 4 , 0 , 1797 , 98 , 10 ), // #376
- INST(Lcall , X86LcallLjmp , O(000000,FF,3,_,_,_,_,_ ), O(000000,9A,_,_,_,_,_,_ ), 76 , 40 , 1801 , 99 , 1 ), // #377
- INST(Lddqu , ExtRm , O(F20F00,F0,_,_,_,_,_,_ ), 0 , 5 , 0 , 6083 , 100, 6 ), // #378
- INST(Ldmxcsr , X86M_Only , O(000F00,AE,2,_,_,_,_,_ ), 0 , 77 , 0 , 6090 , 101, 5 ), // #379
+ INST(Lcall , X86LcallLjmp , O(000000,FF,3,_,_,_,_,_ ), O(000000,9A,_,_,_,_,_,_ ), 75 , 40 , 1801 , 99 , 1 ), // #377
+ INST(Lddqu , ExtRm , O(F20F00,F0,_,_,_,_,_,_ ), 0 , 5 , 0 , 7003 , 100, 6 ), // #378
+ INST(Ldmxcsr , X86M_Only , O(000F00,AE,2,_,_,_,_,_ ), 0 , 76 , 0 , 7010 , 101, 5 ), // #379
INST(Lds , X86Rm , O(000000,C5,_,_,_,_,_,_ ), 0 , 0 , 0 , 1807 , 102, 0 ), // #380
INST(Ldtilecfg , AmxCfg , V(000F38,49,_,0,0,_,_,_ ), 0 , 10 , 0 , 1811 , 103, 73 ), // #381
INST(Lea , X86Lea , O(000000,8D,_,_,x,_,_,_ ), 0 , 0 , 0 , 1821 , 104, 0 ), // #382
INST(Leave , X86Op , O(000000,C9,_,_,_,_,_,_ ), 0 , 0 , 0 , 1825 , 30 , 0 ), // #383
INST(Les , X86Rm , O(000000,C4,_,_,_,_,_,_ ), 0 , 0 , 0 , 1831 , 102, 0 ), // #384
- INST(Lfence , X86Fence , O(000F00,AE,5,_,_,_,_,_ ), 0 , 78 , 0 , 1835 , 30 , 4 ), // #385
+ INST(Lfence , X86Fence , O(000F00,AE,5,_,_,_,_,_ ), 0 , 77 , 0 , 1835 , 30 , 4 ), // #385
INST(Lfs , X86Rm , O(000F00,B4,_,_,_,_,_,_ ), 0 , 4 , 0 , 1842 , 105, 0 ), // #386
- INST(Lgdt , X86M_Only , O(000F00,01,2,_,_,_,_,_ ), 0 , 77 , 0 , 1846 , 69 , 0 ), // #387
+ INST(Lgdt , X86M_Only , O(000F00,01,2,_,_,_,_,_ ), 0 , 76 , 0 , 1846 , 69 , 0 ), // #387
INST(Lgs , X86Rm , O(000F00,B5,_,_,_,_,_,_ ), 0 , 4 , 0 , 1851 , 105, 0 ), // #388
- INST(Lidt , X86M_Only , O(000F00,01,3,_,_,_,_,_ ), 0 , 79 , 0 , 1855 , 69 , 0 ), // #389
- INST(Ljmp , X86LcallLjmp , O(000000,FF,5,_,_,_,_,_ ), O(000000,EA,_,_,_,_,_,_ ), 63 , 41 , 1860 , 106, 0 ), // #390
- INST(Lldt , X86M_NoSize , O(000F00,00,2,_,_,_,_,_ ), 0 , 77 , 0 , 1865 , 107, 0 ), // #391
- INST(Llwpcb , VexR_Wx , V(XOP_M9,12,0,0,x,_,_,_ ), 0 , 80 , 0 , 1870 , 108, 74 ), // #392
- INST(Lmsw , X86M_NoSize , O(000F00,01,6,_,_,_,_,_ ), 0 , 81 , 0 , 1877 , 107, 0 ), // #393
+ INST(Lidt , X86M_Only , O(000F00,01,3,_,_,_,_,_ ), 0 , 78 , 0 , 1855 , 69 , 0 ), // #389
+ INST(Ljmp , X86LcallLjmp , O(000000,FF,5,_,_,_,_,_ ), O(000000,EA,_,_,_,_,_,_ ), 62 , 41 , 1860 , 106, 0 ), // #390
+ INST(Lldt , X86M_NoSize , O(000F00,00,2,_,_,_,_,_ ), 0 , 76 , 0 , 1865 , 107, 0 ), // #391
+ INST(Llwpcb , VexR_Wx , V(XOP_M9,12,0,0,x,_,_,_ ), 0 , 79 , 0 , 1870 , 108, 74 ), // #392
+ INST(Lmsw , X86M_NoSize , O(000F00,01,6,_,_,_,_,_ ), 0 , 80 , 0 , 1877 , 107, 0 ), // #393
INST(Lods , X86StrRm , O(000000,AC,_,_,_,_,_,_ ), 0 , 0 , 0 , 1882 , 109, 75 ), // #394
INST(Loop , X86JecxzLoop , 0 , O(000000,E2,_,_,_,_,_,_ ), 0 , 42 , 1887 , 110, 0 ), // #395
INST(Loope , X86JecxzLoop , 0 , O(000000,E1,_,_,_,_,_,_ ), 0 , 43 , 1892 , 110, 61 ), // #396
INST(Loopne , X86JecxzLoop , 0 , O(000000,E0,_,_,_,_,_,_ ), 0 , 44 , 1898 , 110, 61 ), // #397
INST(Lsl , X86Rm , O(000F00,03,_,_,_,_,_,_ ), 0 , 4 , 0 , 1905 , 111, 10 ), // #398
- INST(Lss , X86Rm , O(000F00,B2,_,_,_,_,_,_ ), 0 , 4 , 0 , 6581 , 105, 0 ), // #399
- INST(Ltr , X86M_NoSize , O(000F00,00,3,_,_,_,_,_ ), 0 , 79 , 0 , 1909 , 107, 0 ), // #400
- INST(Lwpins , VexVmi4_Wx , V(XOP_MA,12,0,0,x,_,_,_ ), 0 , 82 , 0 , 1913 , 112, 74 ), // #401
- INST(Lwpval , VexVmi4_Wx , V(XOP_MA,12,1,0,x,_,_,_ ), 0 , 83 , 0 , 1920 , 112, 74 ), // #402
+ INST(Lss , X86Rm , O(000F00,B2,_,_,_,_,_,_ ), 0 , 4 , 0 , 7556 , 105, 0 ), // #399
+ INST(Ltr , X86M_NoSize , O(000F00,00,3,_,_,_,_,_ ), 0 , 78 , 0 , 1909 , 107, 0 ), // #400
+ INST(Lwpins , VexVmi4_Wx , V(XOP_MA,12,0,0,x,_,_,_ ), 0 , 81 , 0 , 1913 , 112, 74 ), // #401
+ INST(Lwpval , VexVmi4_Wx , V(XOP_MA,12,1,0,x,_,_,_ ), 0 , 82 , 0 , 1920 , 112, 74 ), // #402
INST(Lzcnt , X86Rm_Raw66H , O(F30F00,BD,_,_,x,_,_,_ ), 0 , 6 , 0 , 1927 , 22 , 76 ), // #403
- INST(Maskmovdqu , ExtRm_ZDI , O(660F00,F7,_,_,_,_,_,_ ), 0 , 3 , 0 , 6099 , 113, 4 ), // #404
- INST(Maskmovq , ExtRm_ZDI , O(000F00,F7,_,_,_,_,_,_ ), 0 , 4 , 0 , 8138 , 114, 77 ), // #405
- INST(Maxpd , ExtRm , O(660F00,5F,_,_,_,_,_,_ ), 0 , 3 , 0 , 6133 , 5 , 4 ), // #406
- INST(Maxps , ExtRm , O(000F00,5F,_,_,_,_,_,_ ), 0 , 4 , 0 , 6140 , 5 , 5 ), // #407
- INST(Maxsd , ExtRm , O(F20F00,5F,_,_,_,_,_,_ ), 0 , 5 , 0 , 8157 , 6 , 4 ), // #408
- INST(Maxss , ExtRm , O(F30F00,5F,_,_,_,_,_,_ ), 0 , 6 , 0 , 6154 , 7 , 5 ), // #409
+ INST(Maskmovdqu , ExtRm_ZDI , O(660F00,F7,_,_,_,_,_,_ ), 0 , 3 , 0 , 7019 , 113, 4 ), // #404
+ INST(Maskmovq , ExtRm_ZDI , O(000F00,F7,_,_,_,_,_,_ ), 0 , 4 , 0 , 9113 , 114, 77 ), // #405
+ INST(Maxpd , ExtRm , O(660F00,5F,_,_,_,_,_,_ ), 0 , 3 , 0 , 7053 , 5 , 4 ), // #406
+ INST(Maxps , ExtRm , O(000F00,5F,_,_,_,_,_,_ ), 0 , 4 , 0 , 7067 , 5 , 5 ), // #407
+ INST(Maxsd , ExtRm , O(F20F00,5F,_,_,_,_,_,_ ), 0 , 5 , 0 , 9132 , 6 , 4 ), // #408
+ INST(Maxss , ExtRm , O(F30F00,5F,_,_,_,_,_,_ ), 0 , 6 , 0 , 7088 , 7 , 5 ), // #409
INST(Mcommit , X86Op , O(F30F01,FA,_,_,_,_,_,_ ), 0 , 25 , 0 , 1933 , 30 , 78 ), // #410
- INST(Mfence , X86Fence , O(000F00,AE,6,_,_,_,_,_ ), 0 , 81 , 0 , 1941 , 30 , 4 ), // #411
- INST(Minpd , ExtRm , O(660F00,5D,_,_,_,_,_,_ ), 0 , 3 , 0 , 6183 , 5 , 4 ), // #412
- INST(Minps , ExtRm , O(000F00,5D,_,_,_,_,_,_ ), 0 , 4 , 0 , 6190 , 5 , 5 ), // #413
- INST(Minsd , ExtRm , O(F20F00,5D,_,_,_,_,_,_ ), 0 , 5 , 0 , 8221 , 6 , 4 ), // #414
- INST(Minss , ExtRm , O(F30F00,5D,_,_,_,_,_,_ ), 0 , 6 , 0 , 6204 , 7 , 5 ), // #415
+ INST(Mfence , X86Fence , O(000F00,AE,6,_,_,_,_,_ ), 0 , 80 , 0 , 1941 , 30 , 4 ), // #411
+ INST(Minpd , ExtRm , O(660F00,5D,_,_,_,_,_,_ ), 0 , 3 , 0 , 7117 , 5 , 4 ), // #412
+ INST(Minps , ExtRm , O(000F00,5D,_,_,_,_,_,_ ), 0 , 4 , 0 , 7131 , 5 , 5 ), // #413
+ INST(Minsd , ExtRm , O(F20F00,5D,_,_,_,_,_,_ ), 0 , 5 , 0 , 9196 , 6 , 4 ), // #414
+ INST(Minss , ExtRm , O(F30F00,5D,_,_,_,_,_,_ ), 0 , 6 , 0 , 7152 , 7 , 5 ), // #415
INST(Monitor , X86Op , O(000F01,C8,_,_,_,_,_,_ ), 0 , 21 , 0 , 3232 , 115, 79 ), // #416
INST(Monitorx , X86Op , O(000F01,FA,_,_,_,_,_,_ ), 0 , 21 , 0 , 1948 , 115, 80 ), // #417
INST(Mov , X86Mov , 0 , 0 , 0 , 0 , 138 , 116, 0 ), // #418
INST(Movabs , X86Movabs , 0 , 0 , 0 , 0 , 1957 , 117, 0 ), // #419
- INST(Movapd , ExtMov , O(660F00,28,_,_,_,_,_,_ ), O(660F00,29,_,_,_,_,_,_ ), 3 , 45 , 6235 , 118, 4 ), // #420
- INST(Movaps , ExtMov , O(000F00,28,_,_,_,_,_,_ ), O(000F00,29,_,_,_,_,_,_ ), 4 , 46 , 6243 , 118, 5 ), // #421
- INST(Movbe , ExtMovbe , O(000F38,F0,_,_,x,_,_,_ ), O(000F38,F1,_,_,x,_,_,_ ), 84 , 47 , 656 , 119, 81 ), // #422
- INST(Movd , ExtMovd , O(000F00,6E,_,_,_,_,_,_ ), O(000F00,7E,_,_,_,_,_,_ ), 4 , 48 , 8131 , 120, 82 ), // #423
- INST(Movddup , ExtMov , O(F20F00,12,_,_,_,_,_,_ ), 0 , 5 , 0 , 6257 , 6 , 6 ), // #424
+ INST(Movapd , ExtMov , O(660F00,28,_,_,_,_,_,_ ), O(660F00,29,_,_,_,_,_,_ ), 3 , 45 , 7183 , 118, 4 ), // #420
+ INST(Movaps , ExtMov , O(000F00,28,_,_,_,_,_,_ ), O(000F00,29,_,_,_,_,_,_ ), 4 , 46 , 7191 , 118, 5 ), // #421
+ INST(Movbe , ExtMovbe , O(000F38,F0,_,_,x,_,_,_ ), O(000F38,F1,_,_,x,_,_,_ ), 83 , 47 , 656 , 119, 81 ), // #422
+ INST(Movd , ExtMovd , O(000F00,6E,_,_,_,_,_,_ ), O(000F00,7E,_,_,_,_,_,_ ), 4 , 48 , 9106 , 120, 82 ), // #423
+ INST(Movddup , ExtMov , O(F20F00,12,_,_,_,_,_,_ ), 0 , 5 , 0 , 7205 , 6 , 6 ), // #424
INST(Movdir64b , X86EnqcmdMovdir64b , O(660F38,F8,_,_,_,_,_,_ ), 0 , 2 , 0 , 1964 , 121, 83 ), // #425
- INST(Movdiri , X86MovntiMovdiri , O(000F38,F9,_,_,_,_,_,_ ), 0 , 84 , 0 , 1974 , 122, 84 ), // #426
+ INST(Movdiri , X86MovntiMovdiri , O(000F38,F9,_,_,_,_,_,_ ), 0 , 83 , 0 , 1974 , 122, 84 ), // #426
INST(Movdq2q , ExtMov , O(F20F00,D6,_,_,_,_,_,_ ), 0 , 5 , 0 , 1982 , 123, 4 ), // #427
- INST(Movdqa , ExtMov , O(660F00,6F,_,_,_,_,_,_ ), O(660F00,7F,_,_,_,_,_,_ ), 3 , 49 , 6266 , 118, 4 ), // #428
- INST(Movdqu , ExtMov , O(F30F00,6F,_,_,_,_,_,_ ), O(F30F00,7F,_,_,_,_,_,_ ), 6 , 50 , 6103 , 118, 4 ), // #429
- INST(Movhlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), 0 , 4 , 0 , 6341 , 124, 5 ), // #430
- INST(Movhpd , ExtMov , O(660F00,16,_,_,_,_,_,_ ), O(660F00,17,_,_,_,_,_,_ ), 3 , 51 , 6350 , 125, 4 ), // #431
- INST(Movhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), O(000F00,17,_,_,_,_,_,_ ), 4 , 52 , 6358 , 125, 5 ), // #432
- INST(Movlhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), 0 , 4 , 0 , 6366 , 124, 5 ), // #433
- INST(Movlpd , ExtMov , O(660F00,12,_,_,_,_,_,_ ), O(660F00,13,_,_,_,_,_,_ ), 3 , 53 , 6375 , 125, 4 ), // #434
- INST(Movlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), O(000F00,13,_,_,_,_,_,_ ), 4 , 54 , 6383 , 125, 5 ), // #435
- INST(Movmskpd , ExtMov , O(660F00,50,_,_,_,_,_,_ ), 0 , 3 , 0 , 6391 , 126, 4 ), // #436
- INST(Movmskps , ExtMov , O(000F00,50,_,_,_,_,_,_ ), 0 , 4 , 0 , 6401 , 126, 5 ), // #437
- INST(Movntdq , ExtMov , 0 , O(660F00,E7,_,_,_,_,_,_ ), 0 , 55 , 6411 , 127, 4 ), // #438
- INST(Movntdqa , ExtMov , O(660F38,2A,_,_,_,_,_,_ ), 0 , 2 , 0 , 6420 , 100, 12 ), // #439
+ INST(Movdqa , ExtMov , O(660F00,6F,_,_,_,_,_,_ ), O(660F00,7F,_,_,_,_,_,_ ), 3 , 49 , 7214 , 118, 4 ), // #428
+ INST(Movdqu , ExtMov , O(F30F00,6F,_,_,_,_,_,_ ), O(F30F00,7F,_,_,_,_,_,_ ), 6 , 50 , 7023 , 118, 4 ), // #429
+ INST(Movhlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), 0 , 4 , 0 , 7289 , 124, 5 ), // #430
+ INST(Movhpd , ExtMov , O(660F00,16,_,_,_,_,_,_ ), O(660F00,17,_,_,_,_,_,_ ), 3 , 51 , 7298 , 125, 4 ), // #431
+ INST(Movhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), O(000F00,17,_,_,_,_,_,_ ), 4 , 52 , 7306 , 125, 5 ), // #432
+ INST(Movlhps , ExtMov , O(000F00,16,_,_,_,_,_,_ ), 0 , 4 , 0 , 7314 , 124, 5 ), // #433
+ INST(Movlpd , ExtMov , O(660F00,12,_,_,_,_,_,_ ), O(660F00,13,_,_,_,_,_,_ ), 3 , 53 , 7323 , 125, 4 ), // #434
+ INST(Movlps , ExtMov , O(000F00,12,_,_,_,_,_,_ ), O(000F00,13,_,_,_,_,_,_ ), 4 , 54 , 7331 , 125, 5 ), // #435
+ INST(Movmskpd , ExtMov , O(660F00,50,_,_,_,_,_,_ ), 0 , 3 , 0 , 7339 , 126, 4 ), // #436
+ INST(Movmskps , ExtMov , O(000F00,50,_,_,_,_,_,_ ), 0 , 4 , 0 , 7349 , 126, 5 ), // #437
+ INST(Movntdq , ExtMov , 0 , O(660F00,E7,_,_,_,_,_,_ ), 0 , 55 , 7359 , 127, 4 ), // #438
+ INST(Movntdqa , ExtMov , O(660F38,2A,_,_,_,_,_,_ ), 0 , 2 , 0 , 7368 , 100, 12 ), // #439
INST(Movnti , X86MovntiMovdiri , O(000F00,C3,_,_,x,_,_,_ ), 0 , 4 , 0 , 1990 , 122, 4 ), // #440
- INST(Movntpd , ExtMov , 0 , O(660F00,2B,_,_,_,_,_,_ ), 0 , 56 , 6430 , 127, 4 ), // #441
- INST(Movntps , ExtMov , 0 , O(000F00,2B,_,_,_,_,_,_ ), 0 , 57 , 6439 , 127, 5 ), // #442
+ INST(Movntpd , ExtMov , 0 , O(660F00,2B,_,_,_,_,_,_ ), 0 , 56 , 7378 , 127, 4 ), // #441
+ INST(Movntps , ExtMov , 0 , O(000F00,2B,_,_,_,_,_,_ ), 0 , 57 , 7387 , 127, 5 ), // #442
INST(Movntq , ExtMov , 0 , O(000F00,E7,_,_,_,_,_,_ ), 0 , 58 , 1997 , 128, 77 ), // #443
INST(Movntsd , ExtMov , 0 , O(F20F00,2B,_,_,_,_,_,_ ), 0 , 59 , 2004 , 129, 49 ), // #444
INST(Movntss , ExtMov , 0 , O(F30F00,2B,_,_,_,_,_,_ ), 0 , 60 , 2012 , 130, 49 ), // #445
- INST(Movq , ExtMovq , O(000F00,6E,_,_,x,_,_,_ ), O(000F00,7E,_,_,x,_,_,_ ), 4 , 61 , 8142 , 131, 82 ), // #446
+ INST(Movq , ExtMovq , O(000F00,6E,_,_,x,_,_,_ ), O(000F00,7E,_,_,x,_,_,_ ), 4 , 48 , 9117 , 131, 82 ), // #446
INST(Movq2dq , ExtRm , O(F30F00,D6,_,_,_,_,_,_ ), 0 , 6 , 0 , 2020 , 132, 4 ), // #447
INST(Movs , X86StrMm , O(000000,A4,_,_,_,_,_,_ ), 0 , 0 , 0 , 439 , 133, 75 ), // #448
- INST(Movsd , ExtMov , O(F20F00,10,_,_,_,_,_,_ ), O(F20F00,11,_,_,_,_,_,_ ), 5 , 62 , 6454 , 134, 4 ), // #449
- INST(Movshdup , ExtRm , O(F30F00,16,_,_,_,_,_,_ ), 0 , 6 , 0 , 6461 , 5 , 6 ), // #450
- INST(Movsldup , ExtRm , O(F30F00,12,_,_,_,_,_,_ ), 0 , 6 , 0 , 6471 , 5 , 6 ), // #451
- INST(Movss , ExtMov , O(F30F00,10,_,_,_,_,_,_ ), O(F30F00,11,_,_,_,_,_,_ ), 6 , 63 , 6481 , 135, 5 ), // #452
+ INST(Movsd , ExtMov , O(F20F00,10,_,_,_,_,_,_ ), O(F20F00,11,_,_,_,_,_,_ ), 5 , 61 , 7402 , 134, 4 ), // #449
+ INST(Movshdup , ExtRm , O(F30F00,16,_,_,_,_,_,_ ), 0 , 6 , 0 , 7416 , 5 , 6 ), // #450
+ INST(Movsldup , ExtRm , O(F30F00,12,_,_,_,_,_,_ ), 0 , 6 , 0 , 7426 , 5 , 6 ), // #451
+ INST(Movss , ExtMov , O(F30F00,10,_,_,_,_,_,_ ), O(F30F00,11,_,_,_,_,_,_ ), 6 , 62 , 7436 , 135, 5 ), // #452
INST(Movsx , X86MovsxMovzx , O(000F00,BE,_,_,x,_,_,_ ), 0 , 4 , 0 , 2028 , 136, 0 ), // #453
INST(Movsxd , X86Rm , O(000000,63,_,_,x,_,_,_ ), 0 , 0 , 0 , 2034 , 137, 0 ), // #454
- INST(Movupd , ExtMov , O(660F00,10,_,_,_,_,_,_ ), O(660F00,11,_,_,_,_,_,_ ), 3 , 64 , 6488 , 118, 4 ), // #455
- INST(Movups , ExtMov , O(000F00,10,_,_,_,_,_,_ ), O(000F00,11,_,_,_,_,_,_ ), 4 , 65 , 6496 , 118, 5 ), // #456
+ INST(Movupd , ExtMov , O(660F00,10,_,_,_,_,_,_ ), O(660F00,11,_,_,_,_,_,_ ), 3 , 63 , 7443 , 118, 4 ), // #455
+ INST(Movups , ExtMov , O(000F00,10,_,_,_,_,_,_ ), O(000F00,11,_,_,_,_,_,_ ), 4 , 64 , 7451 , 118, 5 ), // #456
INST(Movzx , X86MovsxMovzx , O(000F00,B6,_,_,x,_,_,_ ), 0 , 4 , 0 , 2041 , 136, 0 ), // #457
- INST(Mpsadbw , ExtRmi , O(660F3A,42,_,_,_,_,_,_ ), 0 , 8 , 0 , 6504 , 8 , 12 ), // #458
+ INST(Mpsadbw , ExtRmi , O(660F3A,42,_,_,_,_,_,_ ), 0 , 8 , 0 , 7465 , 8 , 12 ), // #458
INST(Mul , X86M_GPB_MulDiv , O(000000,F6,4,_,x,_,_,_ ), 0 , 9 , 0 , 828 , 54 , 1 ), // #459
- INST(Mulpd , ExtRm , O(660F00,59,_,_,_,_,_,_ ), 0 , 3 , 0 , 6558 , 5 , 4 ), // #460
- INST(Mulps , ExtRm , O(000F00,59,_,_,_,_,_,_ ), 0 , 4 , 0 , 6565 , 5 , 5 ), // #461
- INST(Mulsd , ExtRm , O(F20F00,59,_,_,_,_,_,_ ), 0 , 5 , 0 , 6572 , 6 , 4 ), // #462
- INST(Mulss , ExtRm , O(F30F00,59,_,_,_,_,_,_ ), 0 , 6 , 0 , 6579 , 7 , 5 ), // #463
- INST(Mulx , VexRvm_ZDX_Wx , V(F20F38,F6,_,0,x,_,_,_ ), 0 , 85 , 0 , 2047 , 138, 85 ), // #464
+ INST(Mulpd , ExtRm , O(660F00,59,_,_,_,_,_,_ ), 0 , 3 , 0 , 7519 , 5 , 4 ), // #460
+ INST(Mulps , ExtRm , O(000F00,59,_,_,_,_,_,_ ), 0 , 4 , 0 , 7533 , 5 , 5 ), // #461
+ INST(Mulsd , ExtRm , O(F20F00,59,_,_,_,_,_,_ ), 0 , 5 , 0 , 7540 , 6 , 4 ), // #462
+ INST(Mulss , ExtRm , O(F30F00,59,_,_,_,_,_,_ ), 0 , 6 , 0 , 7554 , 7 , 5 ), // #463
+ INST(Mulx , VexRvm_ZDX_Wx , V(F20F38,F6,_,0,x,_,_,_ ), 0 , 84 , 0 , 2047 , 138, 85 ), // #464
INST(Mwait , X86Op , O(000F01,C9,_,_,_,_,_,_ ), 0 , 21 , 0 , 3241 , 139, 79 ), // #465
INST(Mwaitx , X86Op , O(000F01,FB,_,_,_,_,_,_ ), 0 , 21 , 0 , 2052 , 140, 80 ), // #466
- INST(Neg , X86M_GPB , O(000000,F6,3,_,x,_,_,_ ), 0 , 76 , 0 , 2059 , 141, 1 ), // #467
+ INST(Neg , X86M_GPB , O(000000,F6,3,_,x,_,_,_ ), 0 , 75 , 0 , 2059 , 141, 1 ), // #467
INST(Nop , X86M_Nop , O(000000,90,_,_,_,_,_,_ ), 0 , 0 , 0 , 959 , 142, 0 ), // #468
INST(Not , X86M_GPB , O(000000,F6,2,_,x,_,_,_ ), 0 , 1 , 0 , 2063 , 141, 0 ), // #469
INST(Or , X86Arith , O(000000,08,1,_,x,_,_,_ ), 0 , 31 , 0 , 3237 , 143, 1 ), // #470
- INST(Orpd , ExtRm , O(660F00,56,_,_,_,_,_,_ ), 0 , 3 , 0 , 10348, 11 , 4 ), // #471
- INST(Orps , ExtRm , O(000F00,56,_,_,_,_,_,_ ), 0 , 4 , 0 , 10355, 11 , 5 ), // #472
- INST(Out , X86Out , O(000000,EE,_,_,_,_,_,_ ), O(000000,E6,_,_,_,_,_,_ ), 0 , 66 , 2067 , 144, 0 ), // #473
+ INST(Orpd , ExtRm , O(660F00,56,_,_,_,_,_,_ ), 0 , 3 , 0 , 11458, 11 , 4 ), // #471
+ INST(Orps , ExtRm , O(000F00,56,_,_,_,_,_,_ ), 0 , 4 , 0 , 11465, 11 , 5 ), // #472
+ INST(Out , X86Out , O(000000,EE,_,_,_,_,_,_ ), O(000000,E6,_,_,_,_,_,_ ), 0 , 65 , 2067 , 144, 0 ), // #473
INST(Outs , X86Outs , O(000000,6E,_,_,_,_,_,_ ), 0 , 0 , 0 , 2071 , 145, 0 ), // #474
- INST(Pabsb , ExtRm_P , O(000F38,1C,_,_,_,_,_,_ ), 0 , 84 , 0 , 6661 , 146, 86 ), // #475
- INST(Pabsd , ExtRm_P , O(000F38,1E,_,_,_,_,_,_ ), 0 , 84 , 0 , 6668 , 146, 86 ), // #476
- INST(Pabsw , ExtRm_P , O(000F38,1D,_,_,_,_,_,_ ), 0 , 84 , 0 , 6682 , 146, 86 ), // #477
- INST(Packssdw , ExtRm_P , O(000F00,6B,_,_,_,_,_,_ ), 0 , 4 , 0 , 6689 , 146, 82 ), // #478
- INST(Packsswb , ExtRm_P , O(000F00,63,_,_,_,_,_,_ ), 0 , 4 , 0 , 6699 , 146, 82 ), // #479
- INST(Packusdw , ExtRm , O(660F38,2B,_,_,_,_,_,_ ), 0 , 2 , 0 , 6709 , 5 , 12 ), // #480
- INST(Packuswb , ExtRm_P , O(000F00,67,_,_,_,_,_,_ ), 0 , 4 , 0 , 6719 , 146, 82 ), // #481
- INST(Paddb , ExtRm_P , O(000F00,FC,_,_,_,_,_,_ ), 0 , 4 , 0 , 6729 , 146, 82 ), // #482
- INST(Paddd , ExtRm_P , O(000F00,FE,_,_,_,_,_,_ ), 0 , 4 , 0 , 6736 , 146, 82 ), // #483
- INST(Paddq , ExtRm_P , O(000F00,D4,_,_,_,_,_,_ ), 0 , 4 , 0 , 6743 , 146, 4 ), // #484
- INST(Paddsb , ExtRm_P , O(000F00,EC,_,_,_,_,_,_ ), 0 , 4 , 0 , 6750 , 146, 82 ), // #485
- INST(Paddsw , ExtRm_P , O(000F00,ED,_,_,_,_,_,_ ), 0 , 4 , 0 , 6758 , 146, 82 ), // #486
- INST(Paddusb , ExtRm_P , O(000F00,DC,_,_,_,_,_,_ ), 0 , 4 , 0 , 6766 , 146, 82 ), // #487
- INST(Paddusw , ExtRm_P , O(000F00,DD,_,_,_,_,_,_ ), 0 , 4 , 0 , 6775 , 146, 82 ), // #488
- INST(Paddw , ExtRm_P , O(000F00,FD,_,_,_,_,_,_ ), 0 , 4 , 0 , 6784 , 146, 82 ), // #489
- INST(Palignr , ExtRmi_P , O(000F3A,0F,_,_,_,_,_,_ ), 0 , 86 , 0 , 6791 , 147, 6 ), // #490
- INST(Pand , ExtRm_P , O(000F00,DB,_,_,_,_,_,_ ), 0 , 4 , 0 , 6800 , 148, 82 ), // #491
- INST(Pandn , ExtRm_P , O(000F00,DF,_,_,_,_,_,_ ), 0 , 4 , 0 , 6813 , 149, 82 ), // #492
- INST(Pause , X86Op , O(F30000,90,_,_,_,_,_,_ ), 0 , 87 , 0 , 3195 , 30 , 0 ), // #493
- INST(Pavgb , ExtRm_P , O(000F00,E0,_,_,_,_,_,_ ), 0 , 4 , 0 , 6843 , 146, 87 ), // #494
- INST(Pavgusb , Ext3dNow , O(000F0F,BF,_,_,_,_,_,_ ), 0 , 88 , 0 , 2076 , 150, 51 ), // #495
- INST(Pavgw , ExtRm_P , O(000F00,E3,_,_,_,_,_,_ ), 0 , 4 , 0 , 6850 , 146, 87 ), // #496
- INST(Pblendvb , ExtRm_XMM0 , O(660F38,10,_,_,_,_,_,_ ), 0 , 2 , 0 , 6906 , 15 , 12 ), // #497
- INST(Pblendw , ExtRmi , O(660F3A,0E,_,_,_,_,_,_ ), 0 , 8 , 0 , 6916 , 8 , 12 ), // #498
- INST(Pclmulqdq , ExtRmi , O(660F3A,44,_,_,_,_,_,_ ), 0 , 8 , 0 , 7009 , 8 , 88 ), // #499
- INST(Pcmpeqb , ExtRm_P , O(000F00,74,_,_,_,_,_,_ ), 0 , 4 , 0 , 7041 , 149, 82 ), // #500
- INST(Pcmpeqd , ExtRm_P , O(000F00,76,_,_,_,_,_,_ ), 0 , 4 , 0 , 7050 , 149, 82 ), // #501
- INST(Pcmpeqq , ExtRm , O(660F38,29,_,_,_,_,_,_ ), 0 , 2 , 0 , 7059 , 151, 12 ), // #502
- INST(Pcmpeqw , ExtRm_P , O(000F00,75,_,_,_,_,_,_ ), 0 , 4 , 0 , 7068 , 149, 82 ), // #503
- INST(Pcmpestri , ExtRmi , O(660F3A,61,_,_,_,_,_,_ ), 0 , 8 , 0 , 7077 , 152, 89 ), // #504
- INST(Pcmpestrm , ExtRmi , O(660F3A,60,_,_,_,_,_,_ ), 0 , 8 , 0 , 7088 , 153, 89 ), // #505
- INST(Pcmpgtb , ExtRm_P , O(000F00,64,_,_,_,_,_,_ ), 0 , 4 , 0 , 7099 , 149, 82 ), // #506
- INST(Pcmpgtd , ExtRm_P , O(000F00,66,_,_,_,_,_,_ ), 0 , 4 , 0 , 7108 , 149, 82 ), // #507
- INST(Pcmpgtq , ExtRm , O(660F38,37,_,_,_,_,_,_ ), 0 , 2 , 0 , 7117 , 151, 44 ), // #508
- INST(Pcmpgtw , ExtRm_P , O(000F00,65,_,_,_,_,_,_ ), 0 , 4 , 0 , 7126 , 149, 82 ), // #509
- INST(Pcmpistri , ExtRmi , O(660F3A,63,_,_,_,_,_,_ ), 0 , 8 , 0 , 7135 , 154, 89 ), // #510
- INST(Pcmpistrm , ExtRmi , O(660F3A,62,_,_,_,_,_,_ ), 0 , 8 , 0 , 7146 , 155, 89 ), // #511
+ INST(Pabsb , ExtRm_P , O(000F38,1C,_,_,_,_,_,_ ), 0 , 83 , 0 , 7636 , 146, 86 ), // #475
+ INST(Pabsd , ExtRm_P , O(000F38,1E,_,_,_,_,_,_ ), 0 , 83 , 0 , 7643 , 146, 86 ), // #476
+ INST(Pabsw , ExtRm_P , O(000F38,1D,_,_,_,_,_,_ ), 0 , 83 , 0 , 7657 , 146, 86 ), // #477
+ INST(Packssdw , ExtRm_P , O(000F00,6B,_,_,_,_,_,_ ), 0 , 4 , 0 , 7664 , 146, 82 ), // #478
+ INST(Packsswb , ExtRm_P , O(000F00,63,_,_,_,_,_,_ ), 0 , 4 , 0 , 7674 , 146, 82 ), // #479
+ INST(Packusdw , ExtRm , O(660F38,2B,_,_,_,_,_,_ ), 0 , 2 , 0 , 7684 , 5 , 12 ), // #480
+ INST(Packuswb , ExtRm_P , O(000F00,67,_,_,_,_,_,_ ), 0 , 4 , 0 , 7694 , 146, 82 ), // #481
+ INST(Paddb , ExtRm_P , O(000F00,FC,_,_,_,_,_,_ ), 0 , 4 , 0 , 7704 , 146, 82 ), // #482
+ INST(Paddd , ExtRm_P , O(000F00,FE,_,_,_,_,_,_ ), 0 , 4 , 0 , 7711 , 146, 82 ), // #483
+ INST(Paddq , ExtRm_P , O(000F00,D4,_,_,_,_,_,_ ), 0 , 4 , 0 , 7718 , 146, 4 ), // #484
+ INST(Paddsb , ExtRm_P , O(000F00,EC,_,_,_,_,_,_ ), 0 , 4 , 0 , 7725 , 146, 82 ), // #485
+ INST(Paddsw , ExtRm_P , O(000F00,ED,_,_,_,_,_,_ ), 0 , 4 , 0 , 7733 , 146, 82 ), // #486
+ INST(Paddusb , ExtRm_P , O(000F00,DC,_,_,_,_,_,_ ), 0 , 4 , 0 , 7741 , 146, 82 ), // #487
+ INST(Paddusw , ExtRm_P , O(000F00,DD,_,_,_,_,_,_ ), 0 , 4 , 0 , 7750 , 146, 82 ), // #488
+ INST(Paddw , ExtRm_P , O(000F00,FD,_,_,_,_,_,_ ), 0 , 4 , 0 , 7759 , 146, 82 ), // #489
+ INST(Palignr , ExtRmi_P , O(000F3A,0F,_,_,_,_,_,_ ), 0 , 85 , 0 , 7766 , 147, 6 ), // #490
+ INST(Pand , ExtRm_P , O(000F00,DB,_,_,_,_,_,_ ), 0 , 4 , 0 , 7775 , 148, 82 ), // #491
+ INST(Pandn , ExtRm_P , O(000F00,DF,_,_,_,_,_,_ ), 0 , 4 , 0 , 7788 , 149, 82 ), // #492
+ INST(Pause , X86Op , O(F30000,90,_,_,_,_,_,_ ), 0 , 86 , 0 , 3195 , 30 , 0 ), // #493
+ INST(Pavgb , ExtRm_P , O(000F00,E0,_,_,_,_,_,_ ), 0 , 4 , 0 , 7818 , 146, 87 ), // #494
+ INST(Pavgusb , Ext3dNow , O(000F0F,BF,_,_,_,_,_,_ ), 0 , 87 , 0 , 2076 , 150, 51 ), // #495
+ INST(Pavgw , ExtRm_P , O(000F00,E3,_,_,_,_,_,_ ), 0 , 4 , 0 , 7825 , 146, 87 ), // #496
+ INST(Pblendvb , ExtRm_XMM0 , O(660F38,10,_,_,_,_,_,_ ), 0 , 2 , 0 , 7881 , 15 , 12 ), // #497
+ INST(Pblendw , ExtRmi , O(660F3A,0E,_,_,_,_,_,_ ), 0 , 8 , 0 , 7891 , 8 , 12 ), // #498
+ INST(Pclmulqdq , ExtRmi , O(660F3A,44,_,_,_,_,_,_ ), 0 , 8 , 0 , 7984 , 8 , 88 ), // #499
+ INST(Pcmpeqb , ExtRm_P , O(000F00,74,_,_,_,_,_,_ ), 0 , 4 , 0 , 8016 , 149, 82 ), // #500
+ INST(Pcmpeqd , ExtRm_P , O(000F00,76,_,_,_,_,_,_ ), 0 , 4 , 0 , 8025 , 149, 82 ), // #501
+ INST(Pcmpeqq , ExtRm , O(660F38,29,_,_,_,_,_,_ ), 0 , 2 , 0 , 8034 , 151, 12 ), // #502
+ INST(Pcmpeqw , ExtRm_P , O(000F00,75,_,_,_,_,_,_ ), 0 , 4 , 0 , 8043 , 149, 82 ), // #503
+ INST(Pcmpestri , ExtRmi , O(660F3A,61,_,_,_,_,_,_ ), 0 , 8 , 0 , 8052 , 152, 89 ), // #504
+ INST(Pcmpestrm , ExtRmi , O(660F3A,60,_,_,_,_,_,_ ), 0 , 8 , 0 , 8063 , 153, 89 ), // #505
+ INST(Pcmpgtb , ExtRm_P , O(000F00,64,_,_,_,_,_,_ ), 0 , 4 , 0 , 8074 , 149, 82 ), // #506
+ INST(Pcmpgtd , ExtRm_P , O(000F00,66,_,_,_,_,_,_ ), 0 , 4 , 0 , 8083 , 149, 82 ), // #507
+ INST(Pcmpgtq , ExtRm , O(660F38,37,_,_,_,_,_,_ ), 0 , 2 , 0 , 8092 , 151, 44 ), // #508
+ INST(Pcmpgtw , ExtRm_P , O(000F00,65,_,_,_,_,_,_ ), 0 , 4 , 0 , 8101 , 149, 82 ), // #509
+ INST(Pcmpistri , ExtRmi , O(660F3A,63,_,_,_,_,_,_ ), 0 , 8 , 0 , 8110 , 154, 89 ), // #510
+ INST(Pcmpistrm , ExtRmi , O(660F3A,62,_,_,_,_,_,_ ), 0 , 8 , 0 , 8121 , 155, 89 ), // #511
INST(Pconfig , X86Op , O(000F01,C5,_,_,_,_,_,_ ), 0 , 21 , 0 , 2084 , 30 , 90 ), // #512
- INST(Pdep , VexRvm_Wx , V(F20F38,F5,_,0,x,_,_,_ ), 0 , 85 , 0 , 2092 , 10 , 85 ), // #513
- INST(Pext , VexRvm_Wx , V(F30F38,F5,_,0,x,_,_,_ ), 0 , 89 , 0 , 2097 , 10 , 85 ), // #514
- INST(Pextrb , ExtExtract , O(000F3A,14,_,_,_,_,_,_ ), 0 , 86 , 0 , 7633 , 156, 12 ), // #515
- INST(Pextrd , ExtExtract , O(000F3A,16,_,_,_,_,_,_ ), 0 , 86 , 0 , 7641 , 58 , 12 ), // #516
- INST(Pextrq , ExtExtract , O(000F3A,16,_,_,1,_,_,_ ), 0 , 90 , 0 , 7649 , 157, 12 ), // #517
- INST(Pextrw , ExtPextrw , O(000F00,C5,_,_,_,_,_,_ ), O(000F3A,15,_,_,_,_,_,_ ), 4 , 67 , 7657 , 158, 91 ), // #518
- INST(Pf2id , Ext3dNow , O(000F0F,1D,_,_,_,_,_,_ ), 0 , 88 , 0 , 2102 , 150, 51 ), // #519
- INST(Pf2iw , Ext3dNow , O(000F0F,1C,_,_,_,_,_,_ ), 0 , 88 , 0 , 2108 , 150, 92 ), // #520
- INST(Pfacc , Ext3dNow , O(000F0F,AE,_,_,_,_,_,_ ), 0 , 88 , 0 , 2114 , 150, 51 ), // #521
- INST(Pfadd , Ext3dNow , O(000F0F,9E,_,_,_,_,_,_ ), 0 , 88 , 0 , 2120 , 150, 51 ), // #522
- INST(Pfcmpeq , Ext3dNow , O(000F0F,B0,_,_,_,_,_,_ ), 0 , 88 , 0 , 2126 , 150, 51 ), // #523
- INST(Pfcmpge , Ext3dNow , O(000F0F,90,_,_,_,_,_,_ ), 0 , 88 , 0 , 2134 , 150, 51 ), // #524
- INST(Pfcmpgt , Ext3dNow , O(000F0F,A0,_,_,_,_,_,_ ), 0 , 88 , 0 , 2142 , 150, 51 ), // #525
- INST(Pfmax , Ext3dNow , O(000F0F,A4,_,_,_,_,_,_ ), 0 , 88 , 0 , 2150 , 150, 51 ), // #526
- INST(Pfmin , Ext3dNow , O(000F0F,94,_,_,_,_,_,_ ), 0 , 88 , 0 , 2156 , 150, 51 ), // #527
- INST(Pfmul , Ext3dNow , O(000F0F,B4,_,_,_,_,_,_ ), 0 , 88 , 0 , 2162 , 150, 51 ), // #528
- INST(Pfnacc , Ext3dNow , O(000F0F,8A,_,_,_,_,_,_ ), 0 , 88 , 0 , 2168 , 150, 92 ), // #529
- INST(Pfpnacc , Ext3dNow , O(000F0F,8E,_,_,_,_,_,_ ), 0 , 88 , 0 , 2175 , 150, 92 ), // #530
- INST(Pfrcp , Ext3dNow , O(000F0F,96,_,_,_,_,_,_ ), 0 , 88 , 0 , 2183 , 150, 51 ), // #531
- INST(Pfrcpit1 , Ext3dNow , O(000F0F,A6,_,_,_,_,_,_ ), 0 , 88 , 0 , 2189 , 150, 51 ), // #532
- INST(Pfrcpit2 , Ext3dNow , O(000F0F,B6,_,_,_,_,_,_ ), 0 , 88 , 0 , 2198 , 150, 51 ), // #533
- INST(Pfrcpv , Ext3dNow , O(000F0F,86,_,_,_,_,_,_ ), 0 , 88 , 0 , 2207 , 150, 93 ), // #534
- INST(Pfrsqit1 , Ext3dNow , O(000F0F,A7,_,_,_,_,_,_ ), 0 , 88 , 0 , 2214 , 150, 51 ), // #535
- INST(Pfrsqrt , Ext3dNow , O(000F0F,97,_,_,_,_,_,_ ), 0 , 88 , 0 , 2223 , 150, 51 ), // #536
- INST(Pfrsqrtv , Ext3dNow , O(000F0F,87,_,_,_,_,_,_ ), 0 , 88 , 0 , 2231 , 150, 93 ), // #537
- INST(Pfsub , Ext3dNow , O(000F0F,9A,_,_,_,_,_,_ ), 0 , 88 , 0 , 2240 , 150, 51 ), // #538
- INST(Pfsubr , Ext3dNow , O(000F0F,AA,_,_,_,_,_,_ ), 0 , 88 , 0 , 2246 , 150, 51 ), // #539
- INST(Phaddd , ExtRm_P , O(000F38,02,_,_,_,_,_,_ ), 0 , 84 , 0 , 7736 , 146, 86 ), // #540
- INST(Phaddsw , ExtRm_P , O(000F38,03,_,_,_,_,_,_ ), 0 , 84 , 0 , 7753 , 146, 86 ), // #541
- INST(Phaddw , ExtRm_P , O(000F38,01,_,_,_,_,_,_ ), 0 , 84 , 0 , 7822 , 146, 86 ), // #542
- INST(Phminposuw , ExtRm , O(660F38,41,_,_,_,_,_,_ ), 0 , 2 , 0 , 7848 , 5 , 12 ), // #543
- INST(Phsubd , ExtRm_P , O(000F38,06,_,_,_,_,_,_ ), 0 , 84 , 0 , 7869 , 146, 86 ), // #544
- INST(Phsubsw , ExtRm_P , O(000F38,07,_,_,_,_,_,_ ), 0 , 84 , 0 , 7886 , 146, 86 ), // #545
- INST(Phsubw , ExtRm_P , O(000F38,05,_,_,_,_,_,_ ), 0 , 84 , 0 , 7895 , 146, 86 ), // #546
- INST(Pi2fd , Ext3dNow , O(000F0F,0D,_,_,_,_,_,_ ), 0 , 88 , 0 , 2253 , 150, 51 ), // #547
- INST(Pi2fw , Ext3dNow , O(000F0F,0C,_,_,_,_,_,_ ), 0 , 88 , 0 , 2259 , 150, 92 ), // #548
- INST(Pinsrb , ExtRmi , O(660F3A,20,_,_,_,_,_,_ ), 0 , 8 , 0 , 7912 , 159, 12 ), // #549
- INST(Pinsrd , ExtRmi , O(660F3A,22,_,_,_,_,_,_ ), 0 , 8 , 0 , 7920 , 160, 12 ), // #550
- INST(Pinsrq , ExtRmi , O(660F3A,22,_,_,1,_,_,_ ), 0 , 91 , 0 , 7928 , 161, 12 ), // #551
- INST(Pinsrw , ExtRmi_P , O(000F00,C4,_,_,_,_,_,_ ), 0 , 4 , 0 , 7936 , 162, 87 ), // #552
- INST(Pmaddubsw , ExtRm_P , O(000F38,04,_,_,_,_,_,_ ), 0 , 84 , 0 , 8106 , 146, 86 ), // #553
- INST(Pmaddwd , ExtRm_P , O(000F00,F5,_,_,_,_,_,_ ), 0 , 4 , 0 , 8117 , 146, 82 ), // #554
- INST(Pmaxsb , ExtRm , O(660F38,3C,_,_,_,_,_,_ ), 0 , 2 , 0 , 8148 , 11 , 12 ), // #555
- INST(Pmaxsd , ExtRm , O(660F38,3D,_,_,_,_,_,_ ), 0 , 2 , 0 , 8156 , 11 , 12 ), // #556
- INST(Pmaxsw , ExtRm_P , O(000F00,EE,_,_,_,_,_,_ ), 0 , 4 , 0 , 8172 , 148, 87 ), // #557
- INST(Pmaxub , ExtRm_P , O(000F00,DE,_,_,_,_,_,_ ), 0 , 4 , 0 , 8180 , 148, 87 ), // #558
- INST(Pmaxud , ExtRm , O(660F38,3F,_,_,_,_,_,_ ), 0 , 2 , 0 , 8188 , 11 , 12 ), // #559
- INST(Pmaxuw , ExtRm , O(660F38,3E,_,_,_,_,_,_ ), 0 , 2 , 0 , 8204 , 11 , 12 ), // #560
- INST(Pminsb , ExtRm , O(660F38,38,_,_,_,_,_,_ ), 0 , 2 , 0 , 8212 , 11 , 12 ), // #561
- INST(Pminsd , ExtRm , O(660F38,39,_,_,_,_,_,_ ), 0 , 2 , 0 , 8220 , 11 , 12 ), // #562
- INST(Pminsw , ExtRm_P , O(000F00,EA,_,_,_,_,_,_ ), 0 , 4 , 0 , 8236 , 148, 87 ), // #563
- INST(Pminub , ExtRm_P , O(000F00,DA,_,_,_,_,_,_ ), 0 , 4 , 0 , 8244 , 148, 87 ), // #564
- INST(Pminud , ExtRm , O(660F38,3B,_,_,_,_,_,_ ), 0 , 2 , 0 , 8252 , 11 , 12 ), // #565
- INST(Pminuw , ExtRm , O(660F38,3A,_,_,_,_,_,_ ), 0 , 2 , 0 , 8268 , 11 , 12 ), // #566
- INST(Pmovmskb , ExtRm_P , O(000F00,D7,_,_,_,_,_,_ ), 0 , 4 , 0 , 8346 , 163, 87 ), // #567
- INST(Pmovsxbd , ExtRm , O(660F38,21,_,_,_,_,_,_ ), 0 , 2 , 0 , 8443 , 7 , 12 ), // #568
- INST(Pmovsxbq , ExtRm , O(660F38,22,_,_,_,_,_,_ ), 0 , 2 , 0 , 8453 , 164, 12 ), // #569
- INST(Pmovsxbw , ExtRm , O(660F38,20,_,_,_,_,_,_ ), 0 , 2 , 0 , 8463 , 6 , 12 ), // #570
- INST(Pmovsxdq , ExtRm , O(660F38,25,_,_,_,_,_,_ ), 0 , 2 , 0 , 8473 , 6 , 12 ), // #571
- INST(Pmovsxwd , ExtRm , O(660F38,23,_,_,_,_,_,_ ), 0 , 2 , 0 , 8483 , 6 , 12 ), // #572
- INST(Pmovsxwq , ExtRm , O(660F38,24,_,_,_,_,_,_ ), 0 , 2 , 0 , 8493 , 7 , 12 ), // #573
- INST(Pmovzxbd , ExtRm , O(660F38,31,_,_,_,_,_,_ ), 0 , 2 , 0 , 8580 , 7 , 12 ), // #574
- INST(Pmovzxbq , ExtRm , O(660F38,32,_,_,_,_,_,_ ), 0 , 2 , 0 , 8590 , 164, 12 ), // #575
- INST(Pmovzxbw , ExtRm , O(660F38,30,_,_,_,_,_,_ ), 0 , 2 , 0 , 8600 , 6 , 12 ), // #576
- INST(Pmovzxdq , ExtRm , O(660F38,35,_,_,_,_,_,_ ), 0 , 2 , 0 , 8610 , 6 , 12 ), // #577
- INST(Pmovzxwd , ExtRm , O(660F38,33,_,_,_,_,_,_ ), 0 , 2 , 0 , 8620 , 6 , 12 ), // #578
- INST(Pmovzxwq , ExtRm , O(660F38,34,_,_,_,_,_,_ ), 0 , 2 , 0 , 8630 , 7 , 12 ), // #579
- INST(Pmuldq , ExtRm , O(660F38,28,_,_,_,_,_,_ ), 0 , 2 , 0 , 8640 , 5 , 12 ), // #580
- INST(Pmulhrsw , ExtRm_P , O(000F38,0B,_,_,_,_,_,_ ), 0 , 84 , 0 , 8648 , 146, 86 ), // #581
- INST(Pmulhrw , Ext3dNow , O(000F0F,B7,_,_,_,_,_,_ ), 0 , 88 , 0 , 2265 , 150, 51 ), // #582
- INST(Pmulhuw , ExtRm_P , O(000F00,E4,_,_,_,_,_,_ ), 0 , 4 , 0 , 8658 , 146, 87 ), // #583
- INST(Pmulhw , ExtRm_P , O(000F00,E5,_,_,_,_,_,_ ), 0 , 4 , 0 , 8667 , 146, 82 ), // #584
- INST(Pmulld , ExtRm , O(660F38,40,_,_,_,_,_,_ ), 0 , 2 , 0 , 8675 , 5 , 12 ), // #585
- INST(Pmullw , ExtRm_P , O(000F00,D5,_,_,_,_,_,_ ), 0 , 4 , 0 , 8691 , 146, 82 ), // #586
- INST(Pmuludq , ExtRm_P , O(000F00,F4,_,_,_,_,_,_ ), 0 , 4 , 0 , 8714 , 146, 4 ), // #587
- INST(Pop , X86Pop , O(000000,8F,0,_,_,_,_,_ ), O(000000,58,_,_,_,_,_,_ ), 0 , 68 , 2273 , 165, 0 ), // #588
+ INST(Pdep , VexRvm_Wx , V(F20F38,F5,_,0,x,_,_,_ ), 0 , 84 , 0 , 2092 , 10 , 85 ), // #513
+ INST(Pext , VexRvm_Wx , V(F30F38,F5,_,0,x,_,_,_ ), 0 , 88 , 0 , 2097 , 10 , 85 ), // #514
+ INST(Pextrb , ExtExtract , O(000F3A,14,_,_,_,_,_,_ ), 0 , 85 , 0 , 8608 , 156, 12 ), // #515
+ INST(Pextrd , ExtExtract , O(000F3A,16,_,_,_,_,_,_ ), 0 , 85 , 0 , 8616 , 58 , 12 ), // #516
+ INST(Pextrq , ExtExtract , O(000F3A,16,_,_,1,_,_,_ ), 0 , 89 , 0 , 8624 , 157, 12 ), // #517
+ INST(Pextrw , ExtPextrw , O(000F00,C5,_,_,_,_,_,_ ), O(000F3A,15,_,_,_,_,_,_ ), 4 , 66 , 8632 , 158, 91 ), // #518
+ INST(Pf2id , Ext3dNow , O(000F0F,1D,_,_,_,_,_,_ ), 0 , 87 , 0 , 2102 , 150, 51 ), // #519
+ INST(Pf2iw , Ext3dNow , O(000F0F,1C,_,_,_,_,_,_ ), 0 , 87 , 0 , 2108 , 150, 92 ), // #520
+ INST(Pfacc , Ext3dNow , O(000F0F,AE,_,_,_,_,_,_ ), 0 , 87 , 0 , 2114 , 150, 51 ), // #521
+ INST(Pfadd , Ext3dNow , O(000F0F,9E,_,_,_,_,_,_ ), 0 , 87 , 0 , 2120 , 150, 51 ), // #522
+ INST(Pfcmpeq , Ext3dNow , O(000F0F,B0,_,_,_,_,_,_ ), 0 , 87 , 0 , 2126 , 150, 51 ), // #523
+ INST(Pfcmpge , Ext3dNow , O(000F0F,90,_,_,_,_,_,_ ), 0 , 87 , 0 , 2134 , 150, 51 ), // #524
+ INST(Pfcmpgt , Ext3dNow , O(000F0F,A0,_,_,_,_,_,_ ), 0 , 87 , 0 , 2142 , 150, 51 ), // #525
+ INST(Pfmax , Ext3dNow , O(000F0F,A4,_,_,_,_,_,_ ), 0 , 87 , 0 , 2150 , 150, 51 ), // #526
+ INST(Pfmin , Ext3dNow , O(000F0F,94,_,_,_,_,_,_ ), 0 , 87 , 0 , 2156 , 150, 51 ), // #527
+ INST(Pfmul , Ext3dNow , O(000F0F,B4,_,_,_,_,_,_ ), 0 , 87 , 0 , 2162 , 150, 51 ), // #528
+ INST(Pfnacc , Ext3dNow , O(000F0F,8A,_,_,_,_,_,_ ), 0 , 87 , 0 , 2168 , 150, 92 ), // #529
+ INST(Pfpnacc , Ext3dNow , O(000F0F,8E,_,_,_,_,_,_ ), 0 , 87 , 0 , 2175 , 150, 92 ), // #530
+ INST(Pfrcp , Ext3dNow , O(000F0F,96,_,_,_,_,_,_ ), 0 , 87 , 0 , 2183 , 150, 51 ), // #531
+ INST(Pfrcpit1 , Ext3dNow , O(000F0F,A6,_,_,_,_,_,_ ), 0 , 87 , 0 , 2189 , 150, 51 ), // #532
+ INST(Pfrcpit2 , Ext3dNow , O(000F0F,B6,_,_,_,_,_,_ ), 0 , 87 , 0 , 2198 , 150, 51 ), // #533
+ INST(Pfrcpv , Ext3dNow , O(000F0F,86,_,_,_,_,_,_ ), 0 , 87 , 0 , 2207 , 150, 93 ), // #534
+ INST(Pfrsqit1 , Ext3dNow , O(000F0F,A7,_,_,_,_,_,_ ), 0 , 87 , 0 , 2214 , 150, 51 ), // #535
+ INST(Pfrsqrt , Ext3dNow , O(000F0F,97,_,_,_,_,_,_ ), 0 , 87 , 0 , 2223 , 150, 51 ), // #536
+ INST(Pfrsqrtv , Ext3dNow , O(000F0F,87,_,_,_,_,_,_ ), 0 , 87 , 0 , 2231 , 150, 93 ), // #537
+ INST(Pfsub , Ext3dNow , O(000F0F,9A,_,_,_,_,_,_ ), 0 , 87 , 0 , 2240 , 150, 51 ), // #538
+ INST(Pfsubr , Ext3dNow , O(000F0F,AA,_,_,_,_,_,_ ), 0 , 87 , 0 , 2246 , 150, 51 ), // #539
+ INST(Phaddd , ExtRm_P , O(000F38,02,_,_,_,_,_,_ ), 0 , 83 , 0 , 8711 , 146, 86 ), // #540
+ INST(Phaddsw , ExtRm_P , O(000F38,03,_,_,_,_,_,_ ), 0 , 83 , 0 , 8728 , 146, 86 ), // #541
+ INST(Phaddw , ExtRm_P , O(000F38,01,_,_,_,_,_,_ ), 0 , 83 , 0 , 8797 , 146, 86 ), // #542
+ INST(Phminposuw , ExtRm , O(660F38,41,_,_,_,_,_,_ ), 0 , 2 , 0 , 8823 , 5 , 12 ), // #543
+ INST(Phsubd , ExtRm_P , O(000F38,06,_,_,_,_,_,_ ), 0 , 83 , 0 , 8844 , 146, 86 ), // #544
+ INST(Phsubsw , ExtRm_P , O(000F38,07,_,_,_,_,_,_ ), 0 , 83 , 0 , 8861 , 146, 86 ), // #545
+ INST(Phsubw , ExtRm_P , O(000F38,05,_,_,_,_,_,_ ), 0 , 83 , 0 , 8870 , 146, 86 ), // #546
+ INST(Pi2fd , Ext3dNow , O(000F0F,0D,_,_,_,_,_,_ ), 0 , 87 , 0 , 2253 , 150, 51 ), // #547
+ INST(Pi2fw , Ext3dNow , O(000F0F,0C,_,_,_,_,_,_ ), 0 , 87 , 0 , 2259 , 150, 92 ), // #548
+ INST(Pinsrb , ExtRmi , O(660F3A,20,_,_,_,_,_,_ ), 0 , 8 , 0 , 8887 , 159, 12 ), // #549
+ INST(Pinsrd , ExtRmi , O(660F3A,22,_,_,_,_,_,_ ), 0 , 8 , 0 , 8895 , 160, 12 ), // #550
+ INST(Pinsrq , ExtRmi , O(660F3A,22,_,_,1,_,_,_ ), 0 , 90 , 0 , 8903 , 161, 12 ), // #551
+ INST(Pinsrw , ExtRmi_P , O(000F00,C4,_,_,_,_,_,_ ), 0 , 4 , 0 , 8911 , 162, 87 ), // #552
+ INST(Pmaddubsw , ExtRm_P , O(000F38,04,_,_,_,_,_,_ ), 0 , 83 , 0 , 9081 , 146, 86 ), // #553
+ INST(Pmaddwd , ExtRm_P , O(000F00,F5,_,_,_,_,_,_ ), 0 , 4 , 0 , 9092 , 146, 82 ), // #554
+ INST(Pmaxsb , ExtRm , O(660F38,3C,_,_,_,_,_,_ ), 0 , 2 , 0 , 9123 , 11 , 12 ), // #555
+ INST(Pmaxsd , ExtRm , O(660F38,3D,_,_,_,_,_,_ ), 0 , 2 , 0 , 9131 , 11 , 12 ), // #556
+ INST(Pmaxsw , ExtRm_P , O(000F00,EE,_,_,_,_,_,_ ), 0 , 4 , 0 , 9147 , 148, 87 ), // #557
+ INST(Pmaxub , ExtRm_P , O(000F00,DE,_,_,_,_,_,_ ), 0 , 4 , 0 , 9155 , 148, 87 ), // #558
+ INST(Pmaxud , ExtRm , O(660F38,3F,_,_,_,_,_,_ ), 0 , 2 , 0 , 9163 , 11 , 12 ), // #559
+ INST(Pmaxuw , ExtRm , O(660F38,3E,_,_,_,_,_,_ ), 0 , 2 , 0 , 9179 , 11 , 12 ), // #560
+ INST(Pminsb , ExtRm , O(660F38,38,_,_,_,_,_,_ ), 0 , 2 , 0 , 9187 , 11 , 12 ), // #561
+ INST(Pminsd , ExtRm , O(660F38,39,_,_,_,_,_,_ ), 0 , 2 , 0 , 9195 , 11 , 12 ), // #562
+ INST(Pminsw , ExtRm_P , O(000F00,EA,_,_,_,_,_,_ ), 0 , 4 , 0 , 9211 , 148, 87 ), // #563
+ INST(Pminub , ExtRm_P , O(000F00,DA,_,_,_,_,_,_ ), 0 , 4 , 0 , 9219 , 148, 87 ), // #564
+ INST(Pminud , ExtRm , O(660F38,3B,_,_,_,_,_,_ ), 0 , 2 , 0 , 9227 , 11 , 12 ), // #565
+ INST(Pminuw , ExtRm , O(660F38,3A,_,_,_,_,_,_ ), 0 , 2 , 0 , 9243 , 11 , 12 ), // #566
+ INST(Pmovmskb , ExtRm_P , O(000F00,D7,_,_,_,_,_,_ ), 0 , 4 , 0 , 9321 , 163, 87 ), // #567
+ INST(Pmovsxbd , ExtRm , O(660F38,21,_,_,_,_,_,_ ), 0 , 2 , 0 , 9418 , 7 , 12 ), // #568
+ INST(Pmovsxbq , ExtRm , O(660F38,22,_,_,_,_,_,_ ), 0 , 2 , 0 , 9428 , 164, 12 ), // #569
+ INST(Pmovsxbw , ExtRm , O(660F38,20,_,_,_,_,_,_ ), 0 , 2 , 0 , 9438 , 6 , 12 ), // #570
+ INST(Pmovsxdq , ExtRm , O(660F38,25,_,_,_,_,_,_ ), 0 , 2 , 0 , 9448 , 6 , 12 ), // #571
+ INST(Pmovsxwd , ExtRm , O(660F38,23,_,_,_,_,_,_ ), 0 , 2 , 0 , 9458 , 6 , 12 ), // #572
+ INST(Pmovsxwq , ExtRm , O(660F38,24,_,_,_,_,_,_ ), 0 , 2 , 0 , 9468 , 7 , 12 ), // #573
+ INST(Pmovzxbd , ExtRm , O(660F38,31,_,_,_,_,_,_ ), 0 , 2 , 0 , 9555 , 7 , 12 ), // #574
+ INST(Pmovzxbq , ExtRm , O(660F38,32,_,_,_,_,_,_ ), 0 , 2 , 0 , 9565 , 164, 12 ), // #575
+ INST(Pmovzxbw , ExtRm , O(660F38,30,_,_,_,_,_,_ ), 0 , 2 , 0 , 9575 , 6 , 12 ), // #576
+ INST(Pmovzxdq , ExtRm , O(660F38,35,_,_,_,_,_,_ ), 0 , 2 , 0 , 9585 , 6 , 12 ), // #577
+ INST(Pmovzxwd , ExtRm , O(660F38,33,_,_,_,_,_,_ ), 0 , 2 , 0 , 9595 , 6 , 12 ), // #578
+ INST(Pmovzxwq , ExtRm , O(660F38,34,_,_,_,_,_,_ ), 0 , 2 , 0 , 9605 , 7 , 12 ), // #579
+ INST(Pmuldq , ExtRm , O(660F38,28,_,_,_,_,_,_ ), 0 , 2 , 0 , 9615 , 5 , 12 ), // #580
+ INST(Pmulhrsw , ExtRm_P , O(000F38,0B,_,_,_,_,_,_ ), 0 , 83 , 0 , 9623 , 146, 86 ), // #581
+ INST(Pmulhrw , Ext3dNow , O(000F0F,B7,_,_,_,_,_,_ ), 0 , 87 , 0 , 2265 , 150, 51 ), // #582
+ INST(Pmulhuw , ExtRm_P , O(000F00,E4,_,_,_,_,_,_ ), 0 , 4 , 0 , 9633 , 146, 87 ), // #583
+ INST(Pmulhw , ExtRm_P , O(000F00,E5,_,_,_,_,_,_ ), 0 , 4 , 0 , 9642 , 146, 82 ), // #584
+ INST(Pmulld , ExtRm , O(660F38,40,_,_,_,_,_,_ ), 0 , 2 , 0 , 9650 , 5 , 12 ), // #585
+ INST(Pmullw , ExtRm_P , O(000F00,D5,_,_,_,_,_,_ ), 0 , 4 , 0 , 9666 , 146, 82 ), // #586
+ INST(Pmuludq , ExtRm_P , O(000F00,F4,_,_,_,_,_,_ ), 0 , 4 , 0 , 9689 , 146, 4 ), // #587
+ INST(Pop , X86Pop , O(000000,8F,0,_,_,_,_,_ ), O(000000,58,_,_,_,_,_,_ ), 0 , 67 , 2273 , 165, 0 ), // #588
INST(Popa , X86Op , O(660000,61,_,_,_,_,_,_ ), 0 , 19 , 0 , 2277 , 81 , 0 ), // #589
INST(Popad , X86Op , O(000000,61,_,_,_,_,_,_ ), 0 , 0 , 0 , 2282 , 81 , 0 ), // #590
INST(Popcnt , X86Rm_Raw66H , O(F30F00,B8,_,_,x,_,_,_ ), 0 , 6 , 0 , 2288 , 22 , 94 ), // #591
INST(Popf , X86Op , O(660000,9D,_,_,_,_,_,_ ), 0 , 19 , 0 , 2295 , 30 , 95 ), // #592
INST(Popfd , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 2300 , 81 , 95 ), // #593
INST(Popfq , X86Op , O(000000,9D,_,_,_,_,_,_ ), 0 , 0 , 0 , 2306 , 33 , 95 ), // #594
- INST(Por , ExtRm_P , O(000F00,EB,_,_,_,_,_,_ ), 0 , 4 , 0 , 8759 , 148, 82 ), // #595
+ INST(Por , ExtRm_P , O(000F00,EB,_,_,_,_,_,_ ), 0 , 4 , 0 , 9734 , 148, 82 ), // #595
INST(Prefetch , X86M_Only , O(000F00,0D,0,_,_,_,_,_ ), 0 , 4 , 0 , 2312 , 31 , 51 ), // #596
INST(Prefetchnta , X86M_Only , O(000F00,18,0,_,_,_,_,_ ), 0 , 4 , 0 , 2321 , 31 , 77 ), // #597
INST(Prefetcht0 , X86M_Only , O(000F00,18,1,_,_,_,_,_ ), 0 , 29 , 0 , 2333 , 31 , 77 ), // #598
- INST(Prefetcht1 , X86M_Only , O(000F00,18,2,_,_,_,_,_ ), 0 , 77 , 0 , 2344 , 31 , 77 ), // #599
- INST(Prefetcht2 , X86M_Only , O(000F00,18,3,_,_,_,_,_ ), 0 , 79 , 0 , 2355 , 31 , 77 ), // #600
+ INST(Prefetcht1 , X86M_Only , O(000F00,18,2,_,_,_,_,_ ), 0 , 76 , 0 , 2344 , 31 , 77 ), // #599
+ INST(Prefetcht2 , X86M_Only , O(000F00,18,3,_,_,_,_,_ ), 0 , 78 , 0 , 2355 , 31 , 77 ), // #600
INST(Prefetchw , X86M_Only , O(000F00,0D,1,_,_,_,_,_ ), 0 , 29 , 0 , 2366 , 31 , 96 ), // #601
- INST(Prefetchwt1 , X86M_Only , O(000F00,0D,2,_,_,_,_,_ ), 0 , 77 , 0 , 2376 , 31 , 97 ), // #602
- INST(Psadbw , ExtRm_P , O(000F00,F6,_,_,_,_,_,_ ), 0 , 4 , 0 , 4272 , 146, 87 ), // #603
- INST(Pshufb , ExtRm_P , O(000F38,00,_,_,_,_,_,_ ), 0 , 84 , 0 , 9085 , 146, 86 ), // #604
- INST(Pshufd , ExtRmi , O(660F00,70,_,_,_,_,_,_ ), 0 , 3 , 0 , 9106 , 8 , 4 ), // #605
- INST(Pshufhw , ExtRmi , O(F30F00,70,_,_,_,_,_,_ ), 0 , 6 , 0 , 9114 , 8 , 4 ), // #606
- INST(Pshuflw , ExtRmi , O(F20F00,70,_,_,_,_,_,_ ), 0 , 5 , 0 , 9123 , 8 , 4 ), // #607
+ INST(Prefetchwt1 , X86M_Only , O(000F00,0D,2,_,_,_,_,_ ), 0 , 76 , 0 , 2376 , 31 , 97 ), // #602
+ INST(Psadbw , ExtRm_P , O(000F00,F6,_,_,_,_,_,_ ), 0 , 4 , 0 , 4644 , 146, 87 ), // #603
+ INST(Pshufb , ExtRm_P , O(000F38,00,_,_,_,_,_,_ ), 0 , 83 , 0 , 10060, 146, 86 ), // #604
+ INST(Pshufd , ExtRmi , O(660F00,70,_,_,_,_,_,_ ), 0 , 3 , 0 , 10081, 8 , 4 ), // #605
+ INST(Pshufhw , ExtRmi , O(F30F00,70,_,_,_,_,_,_ ), 0 , 6 , 0 , 10089, 8 , 4 ), // #606
+ INST(Pshuflw , ExtRmi , O(F20F00,70,_,_,_,_,_,_ ), 0 , 5 , 0 , 10098, 8 , 4 ), // #607
INST(Pshufw , ExtRmi_P , O(000F00,70,_,_,_,_,_,_ ), 0 , 4 , 0 , 2388 , 166, 77 ), // #608
- INST(Psignb , ExtRm_P , O(000F38,08,_,_,_,_,_,_ ), 0 , 84 , 0 , 9132 , 146, 86 ), // #609
- INST(Psignd , ExtRm_P , O(000F38,0A,_,_,_,_,_,_ ), 0 , 84 , 0 , 9140 , 146, 86 ), // #610
- INST(Psignw , ExtRm_P , O(000F38,09,_,_,_,_,_,_ ), 0 , 84 , 0 , 9148 , 146, 86 ), // #611
- INST(Pslld , ExtRmRi_P , O(000F00,F2,_,_,_,_,_,_ ), O(000F00,72,6,_,_,_,_,_ ), 4 , 69 , 9156 , 167, 82 ), // #612
- INST(Pslldq , ExtRmRi , 0 , O(660F00,73,7,_,_,_,_,_ ), 0 , 70 , 9163 , 168, 4 ), // #613
- INST(Psllq , ExtRmRi_P , O(000F00,F3,_,_,_,_,_,_ ), O(000F00,73,6,_,_,_,_,_ ), 4 , 71 , 9171 , 167, 82 ), // #614
- INST(Psllw , ExtRmRi_P , O(000F00,F1,_,_,_,_,_,_ ), O(000F00,71,6,_,_,_,_,_ ), 4 , 72 , 9202 , 167, 82 ), // #615
+ INST(Psignb , ExtRm_P , O(000F38,08,_,_,_,_,_,_ ), 0 , 83 , 0 , 10107, 146, 86 ), // #609
+ INST(Psignd , ExtRm_P , O(000F38,0A,_,_,_,_,_,_ ), 0 , 83 , 0 , 10115, 146, 86 ), // #610
+ INST(Psignw , ExtRm_P , O(000F38,09,_,_,_,_,_,_ ), 0 , 83 , 0 , 10123, 146, 86 ), // #611
+ INST(Pslld , ExtRmRi_P , O(000F00,F2,_,_,_,_,_,_ ), O(000F00,72,6,_,_,_,_,_ ), 4 , 68 , 10131, 167, 82 ), // #612
+ INST(Pslldq , ExtRmRi , 0 , O(660F00,73,7,_,_,_,_,_ ), 0 , 69 , 10138, 168, 4 ), // #613
+ INST(Psllq , ExtRmRi_P , O(000F00,F3,_,_,_,_,_,_ ), O(000F00,73,6,_,_,_,_,_ ), 4 , 70 , 10146, 167, 82 ), // #614
+ INST(Psllw , ExtRmRi_P , O(000F00,F1,_,_,_,_,_,_ ), O(000F00,71,6,_,_,_,_,_ ), 4 , 71 , 10177, 167, 82 ), // #615
INST(Psmash , X86Op , O(F30F01,FF,_,_,_,_,_,_ ), 0 , 25 , 0 , 2395 , 33 , 98 ), // #616
- INST(Psrad , ExtRmRi_P , O(000F00,E2,_,_,_,_,_,_ ), O(000F00,72,4,_,_,_,_,_ ), 4 , 73 , 9209 , 167, 82 ), // #617
- INST(Psraw , ExtRmRi_P , O(000F00,E1,_,_,_,_,_,_ ), O(000F00,71,4,_,_,_,_,_ ), 4 , 74 , 9247 , 167, 82 ), // #618
- INST(Psrld , ExtRmRi_P , O(000F00,D2,_,_,_,_,_,_ ), O(000F00,72,2,_,_,_,_,_ ), 4 , 75 , 9254 , 167, 82 ), // #619
- INST(Psrldq , ExtRmRi , 0 , O(660F00,73,3,_,_,_,_,_ ), 0 , 76 , 9261 , 168, 4 ), // #620
- INST(Psrlq , ExtRmRi_P , O(000F00,D3,_,_,_,_,_,_ ), O(000F00,73,2,_,_,_,_,_ ), 4 , 77 , 9269 , 167, 82 ), // #621
- INST(Psrlw , ExtRmRi_P , O(000F00,D1,_,_,_,_,_,_ ), O(000F00,71,2,_,_,_,_,_ ), 4 , 78 , 9300 , 167, 82 ), // #622
- INST(Psubb , ExtRm_P , O(000F00,F8,_,_,_,_,_,_ ), 0 , 4 , 0 , 9307 , 149, 82 ), // #623
- INST(Psubd , ExtRm_P , O(000F00,FA,_,_,_,_,_,_ ), 0 , 4 , 0 , 9314 , 149, 82 ), // #624
- INST(Psubq , ExtRm_P , O(000F00,FB,_,_,_,_,_,_ ), 0 , 4 , 0 , 9321 , 149, 4 ), // #625
- INST(Psubsb , ExtRm_P , O(000F00,E8,_,_,_,_,_,_ ), 0 , 4 , 0 , 9328 , 149, 82 ), // #626
- INST(Psubsw , ExtRm_P , O(000F00,E9,_,_,_,_,_,_ ), 0 , 4 , 0 , 9336 , 149, 82 ), // #627
- INST(Psubusb , ExtRm_P , O(000F00,D8,_,_,_,_,_,_ ), 0 , 4 , 0 , 9344 , 149, 82 ), // #628
- INST(Psubusw , ExtRm_P , O(000F00,D9,_,_,_,_,_,_ ), 0 , 4 , 0 , 9353 , 149, 82 ), // #629
- INST(Psubw , ExtRm_P , O(000F00,F9,_,_,_,_,_,_ ), 0 , 4 , 0 , 9362 , 149, 82 ), // #630
- INST(Pswapd , Ext3dNow , O(000F0F,BB,_,_,_,_,_,_ ), 0 , 88 , 0 , 2402 , 150, 92 ), // #631
- INST(Ptest , ExtRm , O(660F38,17,_,_,_,_,_,_ ), 0 , 2 , 0 , 9391 , 5 , 99 ), // #632
- INST(Ptwrite , X86M , O(F30F00,AE,4,_,_,_,_,_ ), 0 , 92 , 0 , 2409 , 169, 100), // #633
- INST(Punpckhbw , ExtRm_P , O(000F00,68,_,_,_,_,_,_ ), 0 , 4 , 0 , 9474 , 146, 82 ), // #634
- INST(Punpckhdq , ExtRm_P , O(000F00,6A,_,_,_,_,_,_ ), 0 , 4 , 0 , 9485 , 146, 82 ), // #635
- INST(Punpckhqdq , ExtRm , O(660F00,6D,_,_,_,_,_,_ ), 0 , 3 , 0 , 9496 , 5 , 4 ), // #636
- INST(Punpckhwd , ExtRm_P , O(000F00,69,_,_,_,_,_,_ ), 0 , 4 , 0 , 9508 , 146, 82 ), // #637
- INST(Punpcklbw , ExtRm_P , O(000F00,60,_,_,_,_,_,_ ), 0 , 4 , 0 , 9519 , 170, 82 ), // #638
- INST(Punpckldq , ExtRm_P , O(000F00,62,_,_,_,_,_,_ ), 0 , 4 , 0 , 9530 , 170, 82 ), // #639
- INST(Punpcklqdq , ExtRm , O(660F00,6C,_,_,_,_,_,_ ), 0 , 3 , 0 , 9541 , 5 , 4 ), // #640
- INST(Punpcklwd , ExtRm_P , O(000F00,61,_,_,_,_,_,_ ), 0 , 4 , 0 , 9553 , 170, 82 ), // #641
- INST(Push , X86Push , O(000000,FF,6,_,_,_,_,_ ), O(000000,50,_,_,_,_,_,_ ), 32 , 79 , 2417 , 171, 0 ), // #642
+ INST(Psrad , ExtRmRi_P , O(000F00,E2,_,_,_,_,_,_ ), O(000F00,72,4,_,_,_,_,_ ), 4 , 72 , 10184, 167, 82 ), // #617
+ INST(Psraw , ExtRmRi_P , O(000F00,E1,_,_,_,_,_,_ ), O(000F00,71,4,_,_,_,_,_ ), 4 , 73 , 10222, 167, 82 ), // #618
+ INST(Psrld , ExtRmRi_P , O(000F00,D2,_,_,_,_,_,_ ), O(000F00,72,2,_,_,_,_,_ ), 4 , 74 , 10229, 167, 82 ), // #619
+ INST(Psrldq , ExtRmRi , 0 , O(660F00,73,3,_,_,_,_,_ ), 0 , 75 , 10236, 168, 4 ), // #620
+ INST(Psrlq , ExtRmRi_P , O(000F00,D3,_,_,_,_,_,_ ), O(000F00,73,2,_,_,_,_,_ ), 4 , 76 , 10244, 167, 82 ), // #621
+ INST(Psrlw , ExtRmRi_P , O(000F00,D1,_,_,_,_,_,_ ), O(000F00,71,2,_,_,_,_,_ ), 4 , 77 , 10275, 167, 82 ), // #622
+ INST(Psubb , ExtRm_P , O(000F00,F8,_,_,_,_,_,_ ), 0 , 4 , 0 , 10282, 149, 82 ), // #623
+ INST(Psubd , ExtRm_P , O(000F00,FA,_,_,_,_,_,_ ), 0 , 4 , 0 , 10289, 149, 82 ), // #624
+ INST(Psubq , ExtRm_P , O(000F00,FB,_,_,_,_,_,_ ), 0 , 4 , 0 , 10296, 149, 4 ), // #625
+ INST(Psubsb , ExtRm_P , O(000F00,E8,_,_,_,_,_,_ ), 0 , 4 , 0 , 10303, 149, 82 ), // #626
+ INST(Psubsw , ExtRm_P , O(000F00,E9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10311, 149, 82 ), // #627
+ INST(Psubusb , ExtRm_P , O(000F00,D8,_,_,_,_,_,_ ), 0 , 4 , 0 , 10319, 149, 82 ), // #628
+ INST(Psubusw , ExtRm_P , O(000F00,D9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10328, 149, 82 ), // #629
+ INST(Psubw , ExtRm_P , O(000F00,F9,_,_,_,_,_,_ ), 0 , 4 , 0 , 10337, 149, 82 ), // #630
+ INST(Pswapd , Ext3dNow , O(000F0F,BB,_,_,_,_,_,_ ), 0 , 87 , 0 , 2402 , 150, 92 ), // #631
+ INST(Ptest , ExtRm , O(660F38,17,_,_,_,_,_,_ ), 0 , 2 , 0 , 10366, 5 , 99 ), // #632
+ INST(Ptwrite , X86M , O(F30F00,AE,4,_,_,_,_,_ ), 0 , 91 , 0 , 2409 , 169, 100), // #633
+ INST(Punpckhbw , ExtRm_P , O(000F00,68,_,_,_,_,_,_ ), 0 , 4 , 0 , 10449, 146, 82 ), // #634
+ INST(Punpckhdq , ExtRm_P , O(000F00,6A,_,_,_,_,_,_ ), 0 , 4 , 0 , 10460, 146, 82 ), // #635
+ INST(Punpckhqdq , ExtRm , O(660F00,6D,_,_,_,_,_,_ ), 0 , 3 , 0 , 10471, 5 , 4 ), // #636
+ INST(Punpckhwd , ExtRm_P , O(000F00,69,_,_,_,_,_,_ ), 0 , 4 , 0 , 10483, 146, 82 ), // #637
+ INST(Punpcklbw , ExtRm_P , O(000F00,60,_,_,_,_,_,_ ), 0 , 4 , 0 , 10494, 170, 82 ), // #638
+ INST(Punpckldq , ExtRm_P , O(000F00,62,_,_,_,_,_,_ ), 0 , 4 , 0 , 10505, 170, 82 ), // #639
+ INST(Punpcklqdq , ExtRm , O(660F00,6C,_,_,_,_,_,_ ), 0 , 3 , 0 , 10516, 5 , 4 ), // #640
+ INST(Punpcklwd , ExtRm_P , O(000F00,61,_,_,_,_,_,_ ), 0 , 4 , 0 , 10528, 170, 82 ), // #641
+ INST(Push , X86Push , O(000000,FF,6,_,_,_,_,_ ), O(000000,50,_,_,_,_,_,_ ), 32 , 78 , 2417 , 171, 0 ), // #642
INST(Pusha , X86Op , O(660000,60,_,_,_,_,_,_ ), 0 , 19 , 0 , 2422 , 81 , 0 ), // #643
INST(Pushad , X86Op , O(000000,60,_,_,_,_,_,_ ), 0 , 0 , 0 , 2428 , 81 , 0 ), // #644
INST(Pushf , X86Op , O(660000,9C,_,_,_,_,_,_ ), 0 , 19 , 0 , 2435 , 30 , 101), // #645
INST(Pushfd , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 2441 , 81 , 101), // #646
INST(Pushfq , X86Op , O(000000,9C,_,_,_,_,_,_ ), 0 , 0 , 0 , 2448 , 33 , 101), // #647
- INST(Pvalidate , X86Op , O(F20F01,FF,_,_,_,_,_,_ ), 0 , 93 , 0 , 2455 , 30 , 102), // #648
- INST(Pxor , ExtRm_P , O(000F00,EF,_,_,_,_,_,_ ), 0 , 4 , 0 , 9564 , 149, 82 ), // #649
+ INST(Pvalidate , X86Op , O(F20F01,FF,_,_,_,_,_,_ ), 0 , 92 , 0 , 2455 , 30 , 102), // #648
+ INST(Pxor , ExtRm_P , O(000F00,EF,_,_,_,_,_,_ ), 0 , 4 , 0 , 10539, 149, 82 ), // #649
INST(Rcl , X86Rot , O(000000,D0,2,_,x,_,_,_ ), 0 , 1 , 0 , 2465 , 172, 103), // #650
- INST(Rcpps , ExtRm , O(000F00,53,_,_,_,_,_,_ ), 0 , 4 , 0 , 9692 , 5 , 5 ), // #651
- INST(Rcpss , ExtRm , O(F30F00,53,_,_,_,_,_,_ ), 0 , 6 , 0 , 9699 , 7 , 5 ), // #652
- INST(Rcr , X86Rot , O(000000,D0,3,_,x,_,_,_ ), 0 , 76 , 0 , 2469 , 172, 103), // #653
+ INST(Rcpps , ExtRm , O(000F00,53,_,_,_,_,_,_ ), 0 , 4 , 0 , 10674, 5 , 5 ), // #651
+ INST(Rcpss , ExtRm , O(F30F00,53,_,_,_,_,_,_ ), 0 , 6 , 0 , 10688, 7 , 5 ), // #652
+ INST(Rcr , X86Rot , O(000000,D0,3,_,x,_,_,_ ), 0 , 75 , 0 , 2469 , 172, 103), // #653
INST(Rdfsbase , X86M , O(F30F00,AE,0,_,x,_,_,_ ), 0 , 6 , 0 , 2473 , 173, 104), // #654
- INST(Rdgsbase , X86M , O(F30F00,AE,1,_,x,_,_,_ ), 0 , 94 , 0 , 2482 , 173, 104), // #655
+ INST(Rdgsbase , X86M , O(F30F00,AE,1,_,x,_,_,_ ), 0 , 93 , 0 , 2482 , 173, 104), // #655
INST(Rdmsr , X86Op , O(000F00,32,_,_,_,_,_,_ ), 0 , 4 , 0 , 2491 , 174, 105), // #656
- INST(Rdpid , X86R_Native , O(F30F00,C7,7,_,_,_,_,_ ), 0 , 95 , 0 , 2497 , 175, 106), // #657
+ INST(Rdpid , X86R_Native , O(F30F00,C7,7,_,_,_,_,_ ), 0 , 94 , 0 , 2497 , 175, 106), // #657
INST(Rdpkru , X86Op , O(000F01,EE,_,_,_,_,_,_ ), 0 , 21 , 0 , 2503 , 174, 107), // #658
INST(Rdpmc , X86Op , O(000F00,33,_,_,_,_,_,_ ), 0 , 4 , 0 , 2510 , 174, 0 ), // #659
INST(Rdpru , X86Op , O(000F01,FD,_,_,_,_,_,_ ), 0 , 21 , 0 , 2516 , 174, 108), // #660
- INST(Rdrand , X86M , O(000F00,C7,6,_,x,_,_,_ ), 0 , 81 , 0 , 2522 , 23 , 109), // #661
+ INST(Rdrand , X86M , O(000F00,C7,6,_,x,_,_,_ ), 0 , 80 , 0 , 2522 , 23 , 109), // #661
INST(Rdseed , X86M , O(000F00,C7,7,_,x,_,_,_ ), 0 , 22 , 0 , 2529 , 23 , 110), // #662
- INST(Rdsspd , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 94 , 0 , 2536 , 76 , 56 ), // #663
- INST(Rdsspq , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 94 , 0 , 2543 , 77 , 56 ), // #664
+ INST(Rdsspd , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 93 , 0 , 2536 , 76 , 56 ), // #663
+ INST(Rdsspq , X86M , O(F30F00,1E,1,_,_,_,_,_ ), 0 , 93 , 0 , 2543 , 77 , 56 ), // #664
INST(Rdtsc , X86Op , O(000F00,31,_,_,_,_,_,_ ), 0 , 4 , 0 , 2550 , 28 , 111), // #665
INST(Rdtscp , X86Op , O(000F01,F9,_,_,_,_,_,_ ), 0 , 21 , 0 , 2556 , 174, 112), // #666
INST(Ret , X86Ret , O(000000,C2,_,_,_,_,_,_ ), 0 , 0 , 0 , 3072 , 176, 0 ), // #667
INST(Retf , X86Ret , O(000000,CA,_,_,x,_,_,_ ), 0 , 0 , 0 , 2563 , 177, 0 ), // #668
INST(Rmpadjust , X86Op , O(F30F01,FE,_,_,_,_,_,_ ), 0 , 25 , 0 , 2568 , 33 , 98 ), // #669
- INST(Rmpupdate , X86Op , O(F20F01,FE,_,_,_,_,_,_ ), 0 , 93 , 0 , 2578 , 33 , 98 ), // #670
+ INST(Rmpupdate , X86Op , O(F20F01,FE,_,_,_,_,_,_ ), 0 , 92 , 0 , 2578 , 33 , 98 ), // #670
INST(Rol , X86Rot , O(000000,D0,0,_,x,_,_,_ ), 0 , 0 , 0 , 2588 , 172, 113), // #671
INST(Ror , X86Rot , O(000000,D0,1,_,x,_,_,_ ), 0 , 31 , 0 , 2592 , 172, 113), // #672
- INST(Rorx , VexRmi_Wx , V(F20F3A,F0,_,0,x,_,_,_ ), 0 , 96 , 0 , 2596 , 178, 85 ), // #673
- INST(Roundpd , ExtRmi , O(660F3A,09,_,_,_,_,_,_ ), 0 , 8 , 0 , 9794 , 8 , 12 ), // #674
- INST(Roundps , ExtRmi , O(660F3A,08,_,_,_,_,_,_ ), 0 , 8 , 0 , 9803 , 8 , 12 ), // #675
- INST(Roundsd , ExtRmi , O(660F3A,0B,_,_,_,_,_,_ ), 0 , 8 , 0 , 9812 , 37 , 12 ), // #676
- INST(Roundss , ExtRmi , O(660F3A,0A,_,_,_,_,_,_ ), 0 , 8 , 0 , 9821 , 38 , 12 ), // #677
+ INST(Rorx , VexRmi_Wx , V(F20F3A,F0,_,0,x,_,_,_ ), 0 , 95 , 0 , 2596 , 178, 85 ), // #673
+ INST(Roundpd , ExtRmi , O(660F3A,09,_,_,_,_,_,_ ), 0 , 8 , 0 , 10827, 8 , 12 ), // #674
+ INST(Roundps , ExtRmi , O(660F3A,08,_,_,_,_,_,_ ), 0 , 8 , 0 , 10836, 8 , 12 ), // #675
+ INST(Roundsd , ExtRmi , O(660F3A,0B,_,_,_,_,_,_ ), 0 , 8 , 0 , 10845, 37 , 12 ), // #676
+ INST(Roundss , ExtRmi , O(660F3A,0A,_,_,_,_,_,_ ), 0 , 8 , 0 , 10854, 38 , 12 ), // #677
INST(Rsm , X86Op , O(000F00,AA,_,_,_,_,_,_ ), 0 , 4 , 0 , 2601 , 81 , 1 ), // #678
- INST(Rsqrtps , ExtRm , O(000F00,52,_,_,_,_,_,_ ), 0 , 4 , 0 , 9918 , 5 , 5 ), // #679
- INST(Rsqrtss , ExtRm , O(F30F00,52,_,_,_,_,_,_ ), 0 , 6 , 0 , 9927 , 7 , 5 ), // #680
- INST(Rstorssp , X86M_Only , O(F30F00,01,5,_,_,_,_,_ ), 0 , 64 , 0 , 2605 , 32 , 24 ), // #681
+ INST(Rsqrtps , ExtRm , O(000F00,52,_,_,_,_,_,_ ), 0 , 4 , 0 , 10960, 5 , 5 ), // #679
+ INST(Rsqrtss , ExtRm , O(F30F00,52,_,_,_,_,_,_ ), 0 , 6 , 0 , 10978, 7 , 5 ), // #680
+ INST(Rstorssp , X86M_Only , O(F30F00,01,5,_,_,_,_,_ ), 0 , 63 , 0 , 2605 , 32 , 24 ), // #681
INST(Sahf , X86Op , O(000000,9E,_,_,_,_,_,_ ), 0 , 0 , 0 , 2614 , 97 , 114), // #682
INST(Sal , X86Rot , O(000000,D0,4,_,x,_,_,_ ), 0 , 9 , 0 , 2619 , 172, 1 ), // #683
INST(Sar , X86Rot , O(000000,D0,7,_,x,_,_,_ ), 0 , 27 , 0 , 2623 , 172, 1 ), // #684
- INST(Sarx , VexRmv_Wx , V(F30F38,F7,_,0,x,_,_,_ ), 0 , 89 , 0 , 2627 , 13 , 85 ), // #685
+ INST(Sarx , VexRmv_Wx , V(F30F38,F7,_,0,x,_,_,_ ), 0 , 88 , 0 , 2627 , 13 , 85 ), // #685
INST(Saveprevssp , X86Op , O(F30F01,EA,_,_,_,_,_,_ ), 0 , 25 , 0 , 2632 , 30 , 24 ), // #686
- INST(Sbb , X86Arith , O(000000,18,3,_,x,_,_,_ ), 0 , 76 , 0 , 2644 , 179, 2 ), // #687
+ INST(Sbb , X86Arith , O(000000,18,3,_,x,_,_,_ ), 0 , 75 , 0 , 2644 , 179, 2 ), // #687
INST(Scas , X86StrRm , O(000000,AE,_,_,_,_,_,_ ), 0 , 0 , 0 , 2648 , 180, 37 ), // #688
INST(Senduipi , X86M_NoSize , O(F30F00,C7,6,_,_,_,_,_ ), 0 , 24 , 0 , 2653 , 77 , 25 ), // #689
INST(Serialize , X86Op , O(000F01,E8,_,_,_,_,_,_ ), 0 , 21 , 0 , 2662 , 30 , 115), // #690
@@ -818,1086 +796,1199 @@ const InstDB::InstInfo InstDB::_instInfoTable[] = {
INST(Setz , X86Set , O(000F00,94,_,_,_,_,_,_ ), 0 , 4 , 0 , 2850 , 181, 61 ), // #721
INST(Sfence , X86Fence , O(000F00,AE,7,_,_,_,_,_ ), 0 , 22 , 0 , 2855 , 30 , 77 ), // #722
INST(Sgdt , X86M_Only , O(000F00,01,0,_,_,_,_,_ ), 0 , 4 , 0 , 2862 , 69 , 0 ), // #723
- INST(Sha1msg1 , ExtRm , O(000F38,C9,_,_,_,_,_,_ ), 0 , 84 , 0 , 2867 , 5 , 116), // #724
- INST(Sha1msg2 , ExtRm , O(000F38,CA,_,_,_,_,_,_ ), 0 , 84 , 0 , 2876 , 5 , 116), // #725
- INST(Sha1nexte , ExtRm , O(000F38,C8,_,_,_,_,_,_ ), 0 , 84 , 0 , 2885 , 5 , 116), // #726
- INST(Sha1rnds4 , ExtRmi , O(000F3A,CC,_,_,_,_,_,_ ), 0 , 86 , 0 , 2895 , 8 , 116), // #727
- INST(Sha256msg1 , ExtRm , O(000F38,CC,_,_,_,_,_,_ ), 0 , 84 , 0 , 2905 , 5 , 116), // #728
- INST(Sha256msg2 , ExtRm , O(000F38,CD,_,_,_,_,_,_ ), 0 , 84 , 0 , 2916 , 5 , 116), // #729
- INST(Sha256rnds2 , ExtRm_XMM0 , O(000F38,CB,_,_,_,_,_,_ ), 0 , 84 , 0 , 2927 , 15 , 116), // #730
+ INST(Sha1msg1 , ExtRm , O(000F38,C9,_,_,_,_,_,_ ), 0 , 83 , 0 , 2867 , 5 , 116), // #724
+ INST(Sha1msg2 , ExtRm , O(000F38,CA,_,_,_,_,_,_ ), 0 , 83 , 0 , 2876 , 5 , 116), // #725
+ INST(Sha1nexte , ExtRm , O(000F38,C8,_,_,_,_,_,_ ), 0 , 83 , 0 , 2885 , 5 , 116), // #726
+ INST(Sha1rnds4 , ExtRmi , O(000F3A,CC,_,_,_,_,_,_ ), 0 , 85 , 0 , 2895 , 8 , 116), // #727
+ INST(Sha256msg1 , ExtRm , O(000F38,CC,_,_,_,_,_,_ ), 0 , 83 , 0 , 2905 , 5 , 116), // #728
+ INST(Sha256msg2 , ExtRm , O(000F38,CD,_,_,_,_,_,_ ), 0 , 83 , 0 , 2916 , 5 , 116), // #729
+ INST(Sha256rnds2 , ExtRm_XMM0 , O(000F38,CB,_,_,_,_,_,_ ), 0 , 83 , 0 , 2927 , 15 , 116), // #730
INST(Shl , X86Rot , O(000000,D0,4,_,x,_,_,_ ), 0 , 9 , 0 , 2939 , 172, 1 ), // #731
- INST(Shld , X86ShldShrd , O(000F00,A4,_,_,x,_,_,_ ), 0 , 4 , 0 , 8963 , 182, 1 ), // #732
- INST(Shlx , VexRmv_Wx , V(660F38,F7,_,0,x,_,_,_ ), 0 , 97 , 0 , 2943 , 13 , 85 ), // #733
- INST(Shr , X86Rot , O(000000,D0,5,_,x,_,_,_ ), 0 , 63 , 0 , 2948 , 172, 1 ), // #734
+ INST(Shld , X86ShldShrd , O(000F00,A4,_,_,x,_,_,_ ), 0 , 4 , 0 , 9938 , 182, 1 ), // #732
+ INST(Shlx , VexRmv_Wx , V(660F38,F7,_,0,x,_,_,_ ), 0 , 96 , 0 , 2943 , 13 , 85 ), // #733
+ INST(Shr , X86Rot , O(000000,D0,5,_,x,_,_,_ ), 0 , 62 , 0 , 2948 , 172, 1 ), // #734
INST(Shrd , X86ShldShrd , O(000F00,AC,_,_,x,_,_,_ ), 0 , 4 , 0 , 2952 , 182, 1 ), // #735
- INST(Shrx , VexRmv_Wx , V(F20F38,F7,_,0,x,_,_,_ ), 0 , 85 , 0 , 2957 , 13 , 85 ), // #736
- INST(Shufpd , ExtRmi , O(660F00,C6,_,_,_,_,_,_ ), 0 , 3 , 0 , 10188, 8 , 4 ), // #737
- INST(Shufps , ExtRmi , O(000F00,C6,_,_,_,_,_,_ ), 0 , 4 , 0 , 10196, 8 , 5 ), // #738
+ INST(Shrx , VexRmv_Wx , V(F20F38,F7,_,0,x,_,_,_ ), 0 , 84 , 0 , 2957 , 13 , 85 ), // #736
+ INST(Shufpd , ExtRmi , O(660F00,C6,_,_,_,_,_,_ ), 0 , 3 , 0 , 11259, 8 , 4 ), // #737
+ INST(Shufps , ExtRmi , O(000F00,C6,_,_,_,_,_,_ ), 0 , 4 , 0 , 11267, 8 , 5 ), // #738
INST(Sidt , X86M_Only , O(000F00,01,1,_,_,_,_,_ ), 0 , 29 , 0 , 2962 , 69 , 0 ), // #739
INST(Skinit , X86Op_xAX , O(000F01,DE,_,_,_,_,_,_ ), 0 , 21 , 0 , 2967 , 52 , 117), // #740
INST(Sldt , X86M_NoMemSize , O(000F00,00,0,_,_,_,_,_ ), 0 , 4 , 0 , 2974 , 183, 0 ), // #741
INST(Slwpcb , VexR_Wx , V(XOP_M9,12,1,0,x,_,_,_ ), 0 , 11 , 0 , 2979 , 108, 74 ), // #742
- INST(Smsw , X86M_NoMemSize , O(000F00,01,4,_,_,_,_,_ ), 0 , 98 , 0 , 2986 , 183, 0 ), // #743
- INST(Sqrtpd , ExtRm , O(660F00,51,_,_,_,_,_,_ ), 0 , 3 , 0 , 10204, 5 , 4 ), // #744
- INST(Sqrtps , ExtRm , O(000F00,51,_,_,_,_,_,_ ), 0 , 4 , 0 , 9919 , 5 , 5 ), // #745
- INST(Sqrtsd , ExtRm , O(F20F00,51,_,_,_,_,_,_ ), 0 , 5 , 0 , 10220, 6 , 4 ), // #746
- INST(Sqrtss , ExtRm , O(F30F00,51,_,_,_,_,_,_ ), 0 , 6 , 0 , 9928 , 7 , 5 ), // #747
+ INST(Smsw , X86M_NoMemSize , O(000F00,01,4,_,_,_,_,_ ), 0 , 97 , 0 , 2986 , 183, 0 ), // #743
+ INST(Sqrtpd , ExtRm , O(660F00,51,_,_,_,_,_,_ ), 0 , 3 , 0 , 11275, 5 , 4 ), // #744
+ INST(Sqrtps , ExtRm , O(000F00,51,_,_,_,_,_,_ ), 0 , 4 , 0 , 10961, 5 , 5 ), // #745
+ INST(Sqrtsd , ExtRm , O(F20F00,51,_,_,_,_,_,_ ), 0 , 5 , 0 , 11299, 6 , 4 ), // #746
+ INST(Sqrtss , ExtRm , O(F30F00,51,_,_,_,_,_,_ ), 0 , 6 , 0 , 10979, 7 , 5 ), // #747
INST(Stac , X86Op , O(000F01,CB,_,_,_,_,_,_ ), 0 , 21 , 0 , 2991 , 30 , 16 ), // #748
INST(Stc , X86Op , O(000000,F9,_,_,_,_,_,_ ), 0 , 0 , 0 , 2996 , 30 , 17 ), // #749
- INST(Std , X86Op , O(000000,FD,_,_,_,_,_,_ ), 0 , 0 , 0 , 6946 , 30 , 18 ), // #750
+ INST(Std , X86Op , O(000000,FD,_,_,_,_,_,_ ), 0 , 0 , 0 , 7921 , 30 , 18 ), // #750
INST(Stgi , X86Op , O(000F01,DC,_,_,_,_,_,_ ), 0 , 21 , 0 , 3000 , 30 , 117), // #751
INST(Sti , X86Op , O(000000,FB,_,_,_,_,_,_ ), 0 , 0 , 0 , 3005 , 30 , 23 ), // #752
- INST(Stmxcsr , X86M_Only , O(000F00,AE,3,_,_,_,_,_ ), 0 , 79 , 0 , 10236, 101, 5 ), // #753
+ INST(Stmxcsr , X86M_Only , O(000F00,AE,3,_,_,_,_,_ ), 0 , 78 , 0 , 11323, 101, 5 ), // #753
INST(Stos , X86StrMr , O(000000,AA,_,_,_,_,_,_ ), 0 , 0 , 0 , 3009 , 184, 75 ), // #754
INST(Str , X86M_NoMemSize , O(000F00,00,1,_,_,_,_,_ ), 0 , 29 , 0 , 3014 , 183, 0 ), // #755
- INST(Sttilecfg , AmxCfg , V(660F38,49,_,0,0,_,_,_ ), 0 , 97 , 0 , 3018 , 103, 73 ), // #756
+ INST(Sttilecfg , AmxCfg , V(660F38,49,_,0,0,_,_,_ ), 0 , 96 , 0 , 3018 , 103, 73 ), // #756
INST(Stui , X86Op , O(F30F01,EF,_,_,_,_,_,_ ), 0 , 25 , 0 , 3135 , 33 , 25 ), // #757
- INST(Sub , X86Arith , O(000000,28,5,_,x,_,_,_ ), 0 , 63 , 0 , 866 , 179, 1 ), // #758
- INST(Subpd , ExtRm , O(660F00,5C,_,_,_,_,_,_ ), 0 , 3 , 0 , 4848 , 5 , 4 ), // #759
- INST(Subps , ExtRm , O(000F00,5C,_,_,_,_,_,_ ), 0 , 4 , 0 , 4860 , 5 , 5 ), // #760
- INST(Subsd , ExtRm , O(F20F00,5C,_,_,_,_,_,_ ), 0 , 5 , 0 , 5536 , 6 , 4 ), // #761
- INST(Subss , ExtRm , O(F30F00,5C,_,_,_,_,_,_ ), 0 , 6 , 0 , 5546 , 7 , 5 ), // #762
+ INST(Sub , X86Arith , O(000000,28,5,_,x,_,_,_ ), 0 , 62 , 0 , 866 , 179, 1 ), // #758
+ INST(Subpd , ExtRm , O(660F00,5C,_,_,_,_,_,_ ), 0 , 3 , 0 , 5413 , 5 , 4 ), // #759
+ INST(Subps , ExtRm , O(000F00,5C,_,_,_,_,_,_ ), 0 , 4 , 0 , 5425 , 5 , 5 ), // #760
+ INST(Subsd , ExtRm , O(F20F00,5C,_,_,_,_,_,_ ), 0 , 5 , 0 , 6392 , 6 , 4 ), // #761
+ INST(Subss , ExtRm , O(F30F00,5C,_,_,_,_,_,_ ), 0 , 6 , 0 , 6402 , 7 , 5 ), // #762
INST(Swapgs , X86Op , O(000F01,F8,_,_,_,_,_,_ ), 0 , 21 , 0 , 3028 , 33 , 0 ), // #763
INST(Syscall , X86Op , O(000F00,05,_,_,_,_,_,_ ), 0 , 4 , 0 , 3035 , 33 , 0 ), // #764
INST(Sysenter , X86Op , O(000F00,34,_,_,_,_,_,_ ), 0 , 4 , 0 , 3043 , 30 , 0 ), // #765
INST(Sysexit , X86Op , O(000F00,35,_,_,_,_,_,_ ), 0 , 4 , 0 , 3052 , 30 , 0 ), // #766
- INST(Sysexitq , X86Op , O(000F00,35,_,_,1,_,_,_ ), 0 , 61 , 0 , 3060 , 30 , 0 ), // #767
+ INST(Sysexitq , X86Op , O(000F00,35,_,_,1,_,_,_ ), 0 , 60 , 0 , 3060 , 30 , 0 ), // #767
INST(Sysret , X86Op , O(000F00,07,_,_,_,_,_,_ ), 0 , 4 , 0 , 3069 , 33 , 0 ), // #768
- INST(Sysretq , X86Op , O(000F00,07,_,_,1,_,_,_ ), 0 , 61 , 0 , 3076 , 33 , 0 ), // #769
- INST(T1mskc , VexVm_Wx , V(XOP_M9,01,7,0,x,_,_,_ ), 0 , 99 , 0 , 3084 , 14 , 11 ), // #770
- INST(Tdpbf16ps , AmxRmv , V(F30F38,5C,_,0,0,_,_,_ ), 0 , 89 , 0 , 3091 , 185, 118), // #771
- INST(Tdpbssd , AmxRmv , V(F20F38,5E,_,0,0,_,_,_ ), 0 , 85 , 0 , 3101 , 185, 119), // #772
- INST(Tdpbsud , AmxRmv , V(F30F38,5E,_,0,0,_,_,_ ), 0 , 89 , 0 , 3109 , 185, 119), // #773
- INST(Tdpbusd , AmxRmv , V(660F38,5E,_,0,0,_,_,_ ), 0 , 97 , 0 , 3117 , 185, 119), // #774
+ INST(Sysretq , X86Op , O(000F00,07,_,_,1,_,_,_ ), 0 , 60 , 0 , 3076 , 33 , 0 ), // #769
+ INST(T1mskc , VexVm_Wx , V(XOP_M9,01,7,0,x,_,_,_ ), 0 , 98 , 0 , 3084 , 14 , 11 ), // #770
+ INST(Tdpbf16ps , AmxRmv , V(F30F38,5C,_,0,0,_,_,_ ), 0 , 88 , 0 , 3091 , 185, 118), // #771
+ INST(Tdpbssd , AmxRmv , V(F20F38,5E,_,0,0,_,_,_ ), 0 , 84 , 0 , 3101 , 185, 119), // #772
+ INST(Tdpbsud , AmxRmv , V(F30F38,5E,_,0,0,_,_,_ ), 0 , 88 , 0 , 3109 , 185, 119), // #773
+ INST(Tdpbusd , AmxRmv , V(660F38,5E,_,0,0,_,_,_ ), 0 , 96 , 0 , 3117 , 185, 119), // #774
INST(Tdpbuud , AmxRmv , V(000F38,5E,_,0,0,_,_,_ ), 0 , 10 , 0 , 3125 , 185, 119), // #775
- INST(Test , X86Test , O(000000,84,_,_,x,_,_,_ ), O(000000,F6,_,_,x,_,_,_ ), 0 , 80 , 9392 , 186, 1 ), // #776
+ INST(Test , X86Test , O(000000,84,_,_,x,_,_,_ ), O(000000,F6,_,_,x,_,_,_ ), 0 , 79 , 10367, 186, 1 ), // #776
INST(Testui , X86Op , O(F30F01,ED,_,_,_,_,_,_ ), 0 , 25 , 0 , 3133 , 33 , 120), // #777
- INST(Tileloadd , AmxRm , V(F20F38,4B,_,0,0,_,_,_ ), 0 , 85 , 0 , 3140 , 187, 73 ), // #778
- INST(Tileloaddt1 , AmxRm , V(660F38,4B,_,0,0,_,_,_ ), 0 , 97 , 0 , 3150 , 187, 73 ), // #779
+ INST(Tileloadd , AmxRm , V(F20F38,4B,_,0,0,_,_,_ ), 0 , 84 , 0 , 3140 , 187, 73 ), // #778
+ INST(Tileloaddt1 , AmxRm , V(660F38,4B,_,0,0,_,_,_ ), 0 , 96 , 0 , 3150 , 187, 73 ), // #779
INST(Tilerelease , VexOpMod , V(000F38,49,0,0,0,_,_,_ ), 0 , 10 , 0 , 3162 , 188, 73 ), // #780
- INST(Tilestored , AmxMr , V(F30F38,4B,_,0,0,_,_,_ ), 0 , 89 , 0 , 3174 , 189, 73 ), // #781
- INST(Tilezero , AmxR , V(F20F38,49,_,0,0,_,_,_ ), 0 , 85 , 0 , 3185 , 190, 73 ), // #782
+ INST(Tilestored , AmxMr , V(F30F38,4B,_,0,0,_,_,_ ), 0 , 88 , 0 , 3174 , 189, 73 ), // #781
+ INST(Tilezero , AmxR , V(F20F38,49,_,0,0,_,_,_ ), 0 , 84 , 0 , 3185 , 190, 73 ), // #782
INST(Tpause , X86R32_EDX_EAX , O(660F00,AE,6,_,_,_,_,_ ), 0 , 26 , 0 , 3194 , 191, 121), // #783
INST(Tzcnt , X86Rm_Raw66H , O(F30F00,BC,_,_,x,_,_,_ ), 0 , 6 , 0 , 3201 , 22 , 9 ), // #784
- INST(Tzmsk , VexVm_Wx , V(XOP_M9,01,4,0,x,_,_,_ ), 0 , 100, 0 , 3207 , 14 , 11 ), // #785
- INST(Ucomisd , ExtRm , O(660F00,2E,_,_,_,_,_,_ ), 0 , 3 , 0 , 10289, 6 , 41 ), // #786
- INST(Ucomiss , ExtRm , O(000F00,2E,_,_,_,_,_,_ ), 0 , 4 , 0 , 10298, 7 , 42 ), // #787
+ INST(Tzmsk , VexVm_Wx , V(XOP_M9,01,4,0,x,_,_,_ ), 0 , 99 , 0 , 3207 , 14 , 11 ), // #785
+ INST(Ucomisd , ExtRm , O(660F00,2E,_,_,_,_,_,_ ), 0 , 3 , 0 , 11390, 6 , 41 ), // #786
+ INST(Ucomiss , ExtRm , O(000F00,2E,_,_,_,_,_,_ ), 0 , 4 , 0 , 11408, 7 , 42 ), // #787
INST(Ud0 , X86Rm , O(000F00,FF,_,_,_,_,_,_ ), 0 , 4 , 0 , 3213 , 192, 0 ), // #788
INST(Ud1 , X86Rm , O(000F00,B9,_,_,_,_,_,_ ), 0 , 4 , 0 , 3217 , 192, 0 ), // #789
INST(Ud2 , X86Op , O(000F00,0B,_,_,_,_,_,_ ), 0 , 4 , 0 , 3221 , 30 , 0 ), // #790
INST(Uiret , X86Op , O(F30F01,EC,_,_,_,_,_,_ ), 0 , 25 , 0 , 3225 , 33 , 25 ), // #791
INST(Umonitor , X86R_FromM , O(F30F00,AE,6,_,_,_,_,_ ), 0 , 24 , 0 , 3231 , 193, 122), // #792
- INST(Umwait , X86R32_EDX_EAX , O(F20F00,AE,6,_,_,_,_,_ ), 0 , 101, 0 , 3240 , 191, 121), // #793
- INST(Unpckhpd , ExtRm , O(660F00,15,_,_,_,_,_,_ ), 0 , 3 , 0 , 10307, 5 , 4 ), // #794
- INST(Unpckhps , ExtRm , O(000F00,15,_,_,_,_,_,_ ), 0 , 4 , 0 , 10317, 5 , 5 ), // #795
- INST(Unpcklpd , ExtRm , O(660F00,14,_,_,_,_,_,_ ), 0 , 3 , 0 , 10327, 5 , 4 ), // #796
- INST(Unpcklps , ExtRm , O(000F00,14,_,_,_,_,_,_ ), 0 , 4 , 0 , 10337, 5 , 5 ), // #797
- INST(V4fmaddps , VexRm_T1_4X , E(F20F38,9A,_,2,_,0,4,T4X), 0 , 102, 0 , 3247 , 194, 123), // #798
- INST(V4fmaddss , VexRm_T1_4X , E(F20F38,9B,_,0,_,0,4,T4X), 0 , 103, 0 , 3257 , 195, 123), // #799
- INST(V4fnmaddps , VexRm_T1_4X , E(F20F38,AA,_,2,_,0,4,T4X), 0 , 102, 0 , 3267 , 194, 123), // #800
- INST(V4fnmaddss , VexRm_T1_4X , E(F20F38,AB,_,0,_,0,4,T4X), 0 , 103, 0 , 3278 , 195, 123), // #801
- INST(Vaddpd , VexRvm_Lx , V(660F00,58,_,x,I,1,4,FV ), 0 , 104, 0 , 3289 , 196, 124), // #802
- INST(Vaddps , VexRvm_Lx , V(000F00,58,_,x,I,0,4,FV ), 0 , 105, 0 , 3296 , 197, 124), // #803
- INST(Vaddsd , VexRvm , V(F20F00,58,_,I,I,1,3,T1S), 0 , 106, 0 , 3303 , 198, 125), // #804
- INST(Vaddss , VexRvm , V(F30F00,58,_,I,I,0,2,T1S), 0 , 107, 0 , 3310 , 199, 125), // #805
- INST(Vaddsubpd , VexRvm_Lx , V(660F00,D0,_,x,I,_,_,_ ), 0 , 70 , 0 , 3317 , 200, 126), // #806
- INST(Vaddsubps , VexRvm_Lx , V(F20F00,D0,_,x,I,_,_,_ ), 0 , 108, 0 , 3327 , 200, 126), // #807
- INST(Vaesdec , VexRvm_Lx , V(660F38,DE,_,x,I,_,4,FVM), 0 , 109, 0 , 3337 , 201, 127), // #808
- INST(Vaesdeclast , VexRvm_Lx , V(660F38,DF,_,x,I,_,4,FVM), 0 , 109, 0 , 3345 , 201, 127), // #809
- INST(Vaesenc , VexRvm_Lx , V(660F38,DC,_,x,I,_,4,FVM), 0 , 109, 0 , 3357 , 201, 127), // #810
- INST(Vaesenclast , VexRvm_Lx , V(660F38,DD,_,x,I,_,4,FVM), 0 , 109, 0 , 3365 , 201, 127), // #811
- INST(Vaesimc , VexRm , V(660F38,DB,_,0,I,_,_,_ ), 0 , 97 , 0 , 3377 , 202, 128), // #812
- INST(Vaeskeygenassist , VexRmi , V(660F3A,DF,_,0,I,_,_,_ ), 0 , 74 , 0 , 3385 , 203, 128), // #813
- INST(Valignd , VexRvmi_Lx , E(660F3A,03,_,x,_,0,4,FV ), 0 , 110, 0 , 3402 , 204, 129), // #814
- INST(Valignq , VexRvmi_Lx , E(660F3A,03,_,x,_,1,4,FV ), 0 , 111, 0 , 3410 , 205, 129), // #815
- INST(Vandnpd , VexRvm_Lx , V(660F00,55,_,x,I,1,4,FV ), 0 , 104, 0 , 3418 , 206, 130), // #816
- INST(Vandnps , VexRvm_Lx , V(000F00,55,_,x,I,0,4,FV ), 0 , 105, 0 , 3426 , 207, 130), // #817
- INST(Vandpd , VexRvm_Lx , V(660F00,54,_,x,I,1,4,FV ), 0 , 104, 0 , 3434 , 208, 130), // #818
- INST(Vandps , VexRvm_Lx , V(000F00,54,_,x,I,0,4,FV ), 0 , 105, 0 , 3441 , 209, 130), // #819
- INST(Vblendmpd , VexRvm_Lx , E(660F38,65,_,x,_,1,4,FV ), 0 , 112, 0 , 3448 , 210, 129), // #820
- INST(Vblendmps , VexRvm_Lx , E(660F38,65,_,x,_,0,4,FV ), 0 , 113, 0 , 3458 , 211, 129), // #821
- INST(Vblendpd , VexRvmi_Lx , V(660F3A,0D,_,x,I,_,_,_ ), 0 , 74 , 0 , 3468 , 212, 126), // #822
- INST(Vblendps , VexRvmi_Lx , V(660F3A,0C,_,x,I,_,_,_ ), 0 , 74 , 0 , 3477 , 212, 126), // #823
- INST(Vblendvpd , VexRvmr_Lx , V(660F3A,4B,_,x,0,_,_,_ ), 0 , 74 , 0 , 3486 , 213, 126), // #824
- INST(Vblendvps , VexRvmr_Lx , V(660F3A,4A,_,x,0,_,_,_ ), 0 , 74 , 0 , 3496 , 213, 126), // #825
- INST(Vbroadcastf128 , VexRm , V(660F38,1A,_,1,0,_,_,_ ), 0 , 114, 0 , 3506 , 214, 126), // #826
- INST(Vbroadcastf32x2 , VexRm_Lx , E(660F38,19,_,x,_,0,3,T2 ), 0 , 115, 0 , 3521 , 215, 131), // #827
- INST(Vbroadcastf32x4 , VexRm_Lx , E(660F38,1A,_,x,_,0,4,T4 ), 0 , 116, 0 , 3537 , 216, 68 ), // #828
- INST(Vbroadcastf32x8 , VexRm , E(660F38,1B,_,2,_,0,5,T8 ), 0 , 117, 0 , 3553 , 217, 66 ), // #829
- INST(Vbroadcastf64x2 , VexRm_Lx , E(660F38,1A,_,x,_,1,4,T2 ), 0 , 118, 0 , 3569 , 216, 131), // #830
- INST(Vbroadcastf64x4 , VexRm , E(660F38,1B,_,2,_,1,5,T4 ), 0 , 119, 0 , 3585 , 217, 68 ), // #831
- INST(Vbroadcasti128 , VexRm , V(660F38,5A,_,1,0,_,_,_ ), 0 , 114, 0 , 3601 , 214, 132), // #832
- INST(Vbroadcasti32x2 , VexRm_Lx , E(660F38,59,_,x,_,0,3,T2 ), 0 , 115, 0 , 3616 , 218, 131), // #833
- INST(Vbroadcasti32x4 , VexRm_Lx , E(660F38,5A,_,x,_,0,4,T4 ), 0 , 116, 0 , 3632 , 216, 129), // #834
- INST(Vbroadcasti32x8 , VexRm , E(660F38,5B,_,2,_,0,5,T8 ), 0 , 117, 0 , 3648 , 217, 66 ), // #835
- INST(Vbroadcasti64x2 , VexRm_Lx , E(660F38,5A,_,x,_,1,4,T2 ), 0 , 118, 0 , 3664 , 216, 131), // #836
- INST(Vbroadcasti64x4 , VexRm , E(660F38,5B,_,2,_,1,5,T4 ), 0 , 119, 0 , 3680 , 217, 68 ), // #837
- INST(Vbroadcastsd , VexRm_Lx , V(660F38,19,_,x,0,1,3,T1S), 0 , 120, 0 , 3696 , 219, 133), // #838
- INST(Vbroadcastss , VexRm_Lx , V(660F38,18,_,x,0,0,2,T1S), 0 , 121, 0 , 3709 , 220, 133), // #839
- INST(Vcmppd , VexRvmi_Lx_KEvex , V(660F00,C2,_,x,I,1,4,FV ), 0 , 104, 0 , 3722 , 221, 124), // #840
- INST(Vcmpps , VexRvmi_Lx_KEvex , V(000F00,C2,_,x,I,0,4,FV ), 0 , 105, 0 , 3729 , 222, 124), // #841
- INST(Vcmpsd , VexRvmi_KEvex , V(F20F00,C2,_,I,I,1,3,T1S), 0 , 106, 0 , 3736 , 223, 125), // #842
- INST(Vcmpss , VexRvmi_KEvex , V(F30F00,C2,_,I,I,0,2,T1S), 0 , 107, 0 , 3743 , 224, 125), // #843
- INST(Vcomisd , VexRm , V(660F00,2F,_,I,I,1,3,T1S), 0 , 122, 0 , 3750 , 225, 134), // #844
- INST(Vcomiss , VexRm , V(000F00,2F,_,I,I,0,2,T1S), 0 , 123, 0 , 3758 , 226, 134), // #845
- INST(Vcompresspd , VexMr_Lx , E(660F38,8A,_,x,_,1,3,T1S), 0 , 124, 0 , 3766 , 227, 129), // #846
- INST(Vcompressps , VexMr_Lx , E(660F38,8A,_,x,_,0,2,T1S), 0 , 125, 0 , 3778 , 227, 129), // #847
- INST(Vcvtdq2pd , VexRm_Lx , V(F30F00,E6,_,x,I,0,3,HV ), 0 , 126, 0 , 3790 , 228, 124), // #848
- INST(Vcvtdq2ps , VexRm_Lx , V(000F00,5B,_,x,I,0,4,FV ), 0 , 105, 0 , 3800 , 229, 124), // #849
- INST(Vcvtne2ps2bf16 , VexRvm_Lx , E(F20F38,72,_,_,_,0,4,FV ), 0 , 127, 0 , 3810 , 211, 135), // #850
- INST(Vcvtneps2bf16 , VexRm_Lx_Narrow , E(F30F38,72,_,_,_,0,4,FV ), 0 , 128, 0 , 3825 , 230, 135), // #851
- INST(Vcvtpd2dq , VexRm_Lx_Narrow , V(F20F00,E6,_,x,I,1,4,FV ), 0 , 129, 0 , 3839 , 231, 124), // #852
- INST(Vcvtpd2ps , VexRm_Lx_Narrow , V(660F00,5A,_,x,I,1,4,FV ), 0 , 104, 0 , 3849 , 231, 124), // #853
- INST(Vcvtpd2qq , VexRm_Lx , E(660F00,7B,_,x,_,1,4,FV ), 0 , 130, 0 , 3859 , 232, 131), // #854
- INST(Vcvtpd2udq , VexRm_Lx_Narrow , E(000F00,79,_,x,_,1,4,FV ), 0 , 131, 0 , 3869 , 233, 129), // #855
- INST(Vcvtpd2uqq , VexRm_Lx , E(660F00,79,_,x,_,1,4,FV ), 0 , 130, 0 , 3880 , 232, 131), // #856
- INST(Vcvtph2ps , VexRm_Lx , V(660F38,13,_,x,0,0,3,HVM), 0 , 132, 0 , 3891 , 234, 136), // #857
- INST(Vcvtps2dq , VexRm_Lx , V(660F00,5B,_,x,I,0,4,FV ), 0 , 133, 0 , 3901 , 229, 124), // #858
- INST(Vcvtps2pd , VexRm_Lx , V(000F00,5A,_,x,I,0,3,HV ), 0 , 134, 0 , 3911 , 235, 124), // #859
- INST(Vcvtps2ph , VexMri_Lx , V(660F3A,1D,_,x,0,0,3,HVM), 0 , 135, 0 , 3921 , 236, 136), // #860
- INST(Vcvtps2qq , VexRm_Lx , E(660F00,7B,_,x,_,0,3,HV ), 0 , 136, 0 , 3931 , 237, 131), // #861
- INST(Vcvtps2udq , VexRm_Lx , E(000F00,79,_,x,_,0,4,FV ), 0 , 137, 0 , 3941 , 238, 129), // #862
- INST(Vcvtps2uqq , VexRm_Lx , E(660F00,79,_,x,_,0,3,HV ), 0 , 136, 0 , 3952 , 237, 131), // #863
- INST(Vcvtqq2pd , VexRm_Lx , E(F30F00,E6,_,x,_,1,4,FV ), 0 , 138, 0 , 3963 , 232, 131), // #864
- INST(Vcvtqq2ps , VexRm_Lx_Narrow , E(000F00,5B,_,x,_,1,4,FV ), 0 , 131, 0 , 3973 , 233, 131), // #865
- INST(Vcvtsd2si , VexRm_Wx , V(F20F00,2D,_,I,x,x,3,T1F), 0 , 139, 0 , 3983 , 239, 125), // #866
- INST(Vcvtsd2ss , VexRvm , V(F20F00,5A,_,I,I,1,3,T1S), 0 , 106, 0 , 3993 , 198, 125), // #867
- INST(Vcvtsd2usi , VexRm_Wx , E(F20F00,79,_,I,_,x,3,T1F), 0 , 140, 0 , 4003 , 240, 68 ), // #868
- INST(Vcvtsi2sd , VexRvm_Wx , V(F20F00,2A,_,I,x,x,2,T1W), 0 , 141, 0 , 4014 , 241, 125), // #869
- INST(Vcvtsi2ss , VexRvm_Wx , V(F30F00,2A,_,I,x,x,2,T1W), 0 , 142, 0 , 4024 , 241, 125), // #870
- INST(Vcvtss2sd , VexRvm , V(F30F00,5A,_,I,I,0,2,T1S), 0 , 107, 0 , 4034 , 242, 125), // #871
- INST(Vcvtss2si , VexRm_Wx , V(F30F00,2D,_,I,x,x,2,T1F), 0 , 143, 0 , 4044 , 243, 125), // #872
- INST(Vcvtss2usi , VexRm_Wx , E(F30F00,79,_,I,_,x,2,T1F), 0 , 144, 0 , 4054 , 244, 68 ), // #873
- INST(Vcvttpd2dq , VexRm_Lx_Narrow , V(660F00,E6,_,x,I,1,4,FV ), 0 , 104, 0 , 4065 , 245, 124), // #874
- INST(Vcvttpd2qq , VexRm_Lx , E(660F00,7A,_,x,_,1,4,FV ), 0 , 130, 0 , 4076 , 246, 129), // #875
- INST(Vcvttpd2udq , VexRm_Lx_Narrow , E(000F00,78,_,x,_,1,4,FV ), 0 , 131, 0 , 4087 , 247, 129), // #876
- INST(Vcvttpd2uqq , VexRm_Lx , E(660F00,78,_,x,_,1,4,FV ), 0 , 130, 0 , 4099 , 246, 131), // #877
- INST(Vcvttps2dq , VexRm_Lx , V(F30F00,5B,_,x,I,0,4,FV ), 0 , 145, 0 , 4111 , 248, 124), // #878
- INST(Vcvttps2qq , VexRm_Lx , E(660F00,7A,_,x,_,0,3,HV ), 0 , 136, 0 , 4122 , 249, 131), // #879
- INST(Vcvttps2udq , VexRm_Lx , E(000F00,78,_,x,_,0,4,FV ), 0 , 137, 0 , 4133 , 250, 129), // #880
- INST(Vcvttps2uqq , VexRm_Lx , E(660F00,78,_,x,_,0,3,HV ), 0 , 136, 0 , 4145 , 249, 131), // #881
- INST(Vcvttsd2si , VexRm_Wx , V(F20F00,2C,_,I,x,x,3,T1F), 0 , 139, 0 , 4157 , 251, 125), // #882
- INST(Vcvttsd2usi , VexRm_Wx , E(F20F00,78,_,I,_,x,3,T1F), 0 , 140, 0 , 4168 , 252, 68 ), // #883
- INST(Vcvttss2si , VexRm_Wx , V(F30F00,2C,_,I,x,x,2,T1F), 0 , 143, 0 , 4180 , 253, 125), // #884
- INST(Vcvttss2usi , VexRm_Wx , E(F30F00,78,_,I,_,x,2,T1F), 0 , 144, 0 , 4191 , 254, 68 ), // #885
- INST(Vcvtudq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,0,3,HV ), 0 , 146, 0 , 4203 , 255, 129), // #886
- INST(Vcvtudq2ps , VexRm_Lx , E(F20F00,7A,_,x,_,0,4,FV ), 0 , 147, 0 , 4214 , 238, 129), // #887
- INST(Vcvtuqq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,1,4,FV ), 0 , 138, 0 , 4225 , 232, 131), // #888
- INST(Vcvtuqq2ps , VexRm_Lx_Narrow , E(F20F00,7A,_,x,_,1,4,FV ), 0 , 148, 0 , 4236 , 233, 131), // #889
- INST(Vcvtusi2sd , VexRvm_Wx , E(F20F00,7B,_,I,_,x,2,T1W), 0 , 149, 0 , 4247 , 256, 68 ), // #890
- INST(Vcvtusi2ss , VexRvm_Wx , E(F30F00,7B,_,I,_,x,2,T1W), 0 , 150, 0 , 4258 , 256, 68 ), // #891
- INST(Vdbpsadbw , VexRvmi_Lx , E(660F3A,42,_,x,_,0,4,FVM), 0 , 151, 0 , 4269 , 257, 137), // #892
- INST(Vdivpd , VexRvm_Lx , V(660F00,5E,_,x,I,1,4,FV ), 0 , 104, 0 , 4279 , 196, 124), // #893
- INST(Vdivps , VexRvm_Lx , V(000F00,5E,_,x,I,0,4,FV ), 0 , 105, 0 , 4286 , 197, 124), // #894
- INST(Vdivsd , VexRvm , V(F20F00,5E,_,I,I,1,3,T1S), 0 , 106, 0 , 4293 , 198, 125), // #895
- INST(Vdivss , VexRvm , V(F30F00,5E,_,I,I,0,2,T1S), 0 , 107, 0 , 4300 , 199, 125), // #896
- INST(Vdpbf16ps , VexRvm_Lx , E(F30F38,52,_,_,_,0,4,FV ), 0 , 128, 0 , 4307 , 211, 135), // #897
- INST(Vdppd , VexRvmi_Lx , V(660F3A,41,_,x,I,_,_,_ ), 0 , 74 , 0 , 4317 , 258, 126), // #898
- INST(Vdpps , VexRvmi_Lx , V(660F3A,40,_,x,I,_,_,_ ), 0 , 74 , 0 , 4323 , 212, 126), // #899
- INST(Verr , X86M_NoSize , O(000F00,00,4,_,_,_,_,_ ), 0 , 98 , 0 , 4329 , 107, 10 ), // #900
- INST(Verw , X86M_NoSize , O(000F00,00,5,_,_,_,_,_ ), 0 , 78 , 0 , 4334 , 107, 10 ), // #901
- INST(Vexp2pd , VexRm , E(660F38,C8,_,2,_,1,4,FV ), 0 , 152, 0 , 4339 , 259, 138), // #902
- INST(Vexp2ps , VexRm , E(660F38,C8,_,2,_,0,4,FV ), 0 , 153, 0 , 4347 , 260, 138), // #903
- INST(Vexpandpd , VexRm_Lx , E(660F38,88,_,x,_,1,3,T1S), 0 , 124, 0 , 4355 , 261, 129), // #904
- INST(Vexpandps , VexRm_Lx , E(660F38,88,_,x,_,0,2,T1S), 0 , 125, 0 , 4365 , 261, 129), // #905
- INST(Vextractf128 , VexMri , V(660F3A,19,_,1,0,_,_,_ ), 0 , 154, 0 , 4375 , 262, 126), // #906
- INST(Vextractf32x4 , VexMri_Lx , E(660F3A,19,_,x,_,0,4,T4 ), 0 , 155, 0 , 4388 , 263, 129), // #907
- INST(Vextractf32x8 , VexMri , E(660F3A,1B,_,2,_,0,5,T8 ), 0 , 156, 0 , 4402 , 264, 66 ), // #908
- INST(Vextractf64x2 , VexMri_Lx , E(660F3A,19,_,x,_,1,4,T2 ), 0 , 157, 0 , 4416 , 263, 131), // #909
- INST(Vextractf64x4 , VexMri , E(660F3A,1B,_,2,_,1,5,T4 ), 0 , 158, 0 , 4430 , 264, 68 ), // #910
- INST(Vextracti128 , VexMri , V(660F3A,39,_,1,0,_,_,_ ), 0 , 154, 0 , 4444 , 262, 132), // #911
- INST(Vextracti32x4 , VexMri_Lx , E(660F3A,39,_,x,_,0,4,T4 ), 0 , 155, 0 , 4457 , 263, 129), // #912
- INST(Vextracti32x8 , VexMri , E(660F3A,3B,_,2,_,0,5,T8 ), 0 , 156, 0 , 4471 , 264, 66 ), // #913
- INST(Vextracti64x2 , VexMri_Lx , E(660F3A,39,_,x,_,1,4,T2 ), 0 , 157, 0 , 4485 , 263, 131), // #914
- INST(Vextracti64x4 , VexMri , E(660F3A,3B,_,2,_,1,5,T4 ), 0 , 158, 0 , 4499 , 264, 68 ), // #915
- INST(Vextractps , VexMri , V(660F3A,17,_,0,I,I,2,T1S), 0 , 159, 0 , 4513 , 265, 125), // #916
- INST(Vfixupimmpd , VexRvmi_Lx , E(660F3A,54,_,x,_,1,4,FV ), 0 , 111, 0 , 4524 , 266, 129), // #917
- INST(Vfixupimmps , VexRvmi_Lx , E(660F3A,54,_,x,_,0,4,FV ), 0 , 110, 0 , 4536 , 267, 129), // #918
- INST(Vfixupimmsd , VexRvmi , E(660F3A,55,_,I,_,1,3,T1S), 0 , 160, 0 , 4548 , 268, 68 ), // #919
- INST(Vfixupimmss , VexRvmi , E(660F3A,55,_,I,_,0,2,T1S), 0 , 161, 0 , 4560 , 269, 68 ), // #920
- INST(Vfmadd132pd , VexRvm_Lx , V(660F38,98,_,x,1,1,4,FV ), 0 , 162, 0 , 4572 , 196, 139), // #921
- INST(Vfmadd132ps , VexRvm_Lx , V(660F38,98,_,x,0,0,4,FV ), 0 , 163, 0 , 4584 , 197, 139), // #922
- INST(Vfmadd132sd , VexRvm , V(660F38,99,_,I,1,1,3,T1S), 0 , 164, 0 , 4596 , 198, 140), // #923
- INST(Vfmadd132ss , VexRvm , V(660F38,99,_,I,0,0,2,T1S), 0 , 121, 0 , 4608 , 199, 140), // #924
- INST(Vfmadd213pd , VexRvm_Lx , V(660F38,A8,_,x,1,1,4,FV ), 0 , 162, 0 , 4620 , 196, 139), // #925
- INST(Vfmadd213ps , VexRvm_Lx , V(660F38,A8,_,x,0,0,4,FV ), 0 , 163, 0 , 4632 , 197, 139), // #926
- INST(Vfmadd213sd , VexRvm , V(660F38,A9,_,I,1,1,3,T1S), 0 , 164, 0 , 4644 , 198, 140), // #927
- INST(Vfmadd213ss , VexRvm , V(660F38,A9,_,I,0,0,2,T1S), 0 , 121, 0 , 4656 , 199, 140), // #928
- INST(Vfmadd231pd , VexRvm_Lx , V(660F38,B8,_,x,1,1,4,FV ), 0 , 162, 0 , 4668 , 196, 139), // #929
- INST(Vfmadd231ps , VexRvm_Lx , V(660F38,B8,_,x,0,0,4,FV ), 0 , 163, 0 , 4680 , 197, 139), // #930
- INST(Vfmadd231sd , VexRvm , V(660F38,B9,_,I,1,1,3,T1S), 0 , 164, 0 , 4692 , 198, 140), // #931
- INST(Vfmadd231ss , VexRvm , V(660F38,B9,_,I,0,0,2,T1S), 0 , 121, 0 , 4704 , 199, 140), // #932
- INST(Vfmaddpd , Fma4_Lx , V(660F3A,69,_,x,x,_,_,_ ), 0 , 74 , 0 , 4716 , 270, 141), // #933
- INST(Vfmaddps , Fma4_Lx , V(660F3A,68,_,x,x,_,_,_ ), 0 , 74 , 0 , 4725 , 270, 141), // #934
- INST(Vfmaddsd , Fma4 , V(660F3A,6B,_,0,x,_,_,_ ), 0 , 74 , 0 , 4734 , 271, 141), // #935
- INST(Vfmaddss , Fma4 , V(660F3A,6A,_,0,x,_,_,_ ), 0 , 74 , 0 , 4743 , 272, 141), // #936
- INST(Vfmaddsub132pd , VexRvm_Lx , V(660F38,96,_,x,1,1,4,FV ), 0 , 162, 0 , 4752 , 196, 139), // #937
- INST(Vfmaddsub132ps , VexRvm_Lx , V(660F38,96,_,x,0,0,4,FV ), 0 , 163, 0 , 4767 , 197, 139), // #938
- INST(Vfmaddsub213pd , VexRvm_Lx , V(660F38,A6,_,x,1,1,4,FV ), 0 , 162, 0 , 4782 , 196, 139), // #939
- INST(Vfmaddsub213ps , VexRvm_Lx , V(660F38,A6,_,x,0,0,4,FV ), 0 , 163, 0 , 4797 , 197, 139), // #940
- INST(Vfmaddsub231pd , VexRvm_Lx , V(660F38,B6,_,x,1,1,4,FV ), 0 , 162, 0 , 4812 , 196, 139), // #941
- INST(Vfmaddsub231ps , VexRvm_Lx , V(660F38,B6,_,x,0,0,4,FV ), 0 , 163, 0 , 4827 , 197, 139), // #942
- INST(Vfmaddsubpd , Fma4_Lx , V(660F3A,5D,_,x,x,_,_,_ ), 0 , 74 , 0 , 4842 , 270, 141), // #943
- INST(Vfmaddsubps , Fma4_Lx , V(660F3A,5C,_,x,x,_,_,_ ), 0 , 74 , 0 , 4854 , 270, 141), // #944
- INST(Vfmsub132pd , VexRvm_Lx , V(660F38,9A,_,x,1,1,4,FV ), 0 , 162, 0 , 4866 , 196, 139), // #945
- INST(Vfmsub132ps , VexRvm_Lx , V(660F38,9A,_,x,0,0,4,FV ), 0 , 163, 0 , 4878 , 197, 139), // #946
- INST(Vfmsub132sd , VexRvm , V(660F38,9B,_,I,1,1,3,T1S), 0 , 164, 0 , 4890 , 198, 140), // #947
- INST(Vfmsub132ss , VexRvm , V(660F38,9B,_,I,0,0,2,T1S), 0 , 121, 0 , 4902 , 199, 140), // #948
- INST(Vfmsub213pd , VexRvm_Lx , V(660F38,AA,_,x,1,1,4,FV ), 0 , 162, 0 , 4914 , 196, 139), // #949
- INST(Vfmsub213ps , VexRvm_Lx , V(660F38,AA,_,x,0,0,4,FV ), 0 , 163, 0 , 4926 , 197, 139), // #950
- INST(Vfmsub213sd , VexRvm , V(660F38,AB,_,I,1,1,3,T1S), 0 , 164, 0 , 4938 , 198, 140), // #951
- INST(Vfmsub213ss , VexRvm , V(660F38,AB,_,I,0,0,2,T1S), 0 , 121, 0 , 4950 , 199, 140), // #952
- INST(Vfmsub231pd , VexRvm_Lx , V(660F38,BA,_,x,1,1,4,FV ), 0 , 162, 0 , 4962 , 196, 139), // #953
- INST(Vfmsub231ps , VexRvm_Lx , V(660F38,BA,_,x,0,0,4,FV ), 0 , 163, 0 , 4974 , 197, 139), // #954
- INST(Vfmsub231sd , VexRvm , V(660F38,BB,_,I,1,1,3,T1S), 0 , 164, 0 , 4986 , 198, 140), // #955
- INST(Vfmsub231ss , VexRvm , V(660F38,BB,_,I,0,0,2,T1S), 0 , 121, 0 , 4998 , 199, 140), // #956
- INST(Vfmsubadd132pd , VexRvm_Lx , V(660F38,97,_,x,1,1,4,FV ), 0 , 162, 0 , 5010 , 196, 139), // #957
- INST(Vfmsubadd132ps , VexRvm_Lx , V(660F38,97,_,x,0,0,4,FV ), 0 , 163, 0 , 5025 , 197, 139), // #958
- INST(Vfmsubadd213pd , VexRvm_Lx , V(660F38,A7,_,x,1,1,4,FV ), 0 , 162, 0 , 5040 , 196, 139), // #959
- INST(Vfmsubadd213ps , VexRvm_Lx , V(660F38,A7,_,x,0,0,4,FV ), 0 , 163, 0 , 5055 , 197, 139), // #960
- INST(Vfmsubadd231pd , VexRvm_Lx , V(660F38,B7,_,x,1,1,4,FV ), 0 , 162, 0 , 5070 , 196, 139), // #961
- INST(Vfmsubadd231ps , VexRvm_Lx , V(660F38,B7,_,x,0,0,4,FV ), 0 , 163, 0 , 5085 , 197, 139), // #962
- INST(Vfmsubaddpd , Fma4_Lx , V(660F3A,5F,_,x,x,_,_,_ ), 0 , 74 , 0 , 5100 , 270, 141), // #963
- INST(Vfmsubaddps , Fma4_Lx , V(660F3A,5E,_,x,x,_,_,_ ), 0 , 74 , 0 , 5112 , 270, 141), // #964
- INST(Vfmsubpd , Fma4_Lx , V(660F3A,6D,_,x,x,_,_,_ ), 0 , 74 , 0 , 5124 , 270, 141), // #965
- INST(Vfmsubps , Fma4_Lx , V(660F3A,6C,_,x,x,_,_,_ ), 0 , 74 , 0 , 5133 , 270, 141), // #966
- INST(Vfmsubsd , Fma4 , V(660F3A,6F,_,0,x,_,_,_ ), 0 , 74 , 0 , 5142 , 271, 141), // #967
- INST(Vfmsubss , Fma4 , V(660F3A,6E,_,0,x,_,_,_ ), 0 , 74 , 0 , 5151 , 272, 141), // #968
- INST(Vfnmadd132pd , VexRvm_Lx , V(660F38,9C,_,x,1,1,4,FV ), 0 , 162, 0 , 5160 , 196, 139), // #969
- INST(Vfnmadd132ps , VexRvm_Lx , V(660F38,9C,_,x,0,0,4,FV ), 0 , 163, 0 , 5173 , 197, 139), // #970
- INST(Vfnmadd132sd , VexRvm , V(660F38,9D,_,I,1,1,3,T1S), 0 , 164, 0 , 5186 , 198, 140), // #971
- INST(Vfnmadd132ss , VexRvm , V(660F38,9D,_,I,0,0,2,T1S), 0 , 121, 0 , 5199 , 199, 140), // #972
- INST(Vfnmadd213pd , VexRvm_Lx , V(660F38,AC,_,x,1,1,4,FV ), 0 , 162, 0 , 5212 , 196, 139), // #973
- INST(Vfnmadd213ps , VexRvm_Lx , V(660F38,AC,_,x,0,0,4,FV ), 0 , 163, 0 , 5225 , 197, 139), // #974
- INST(Vfnmadd213sd , VexRvm , V(660F38,AD,_,I,1,1,3,T1S), 0 , 164, 0 , 5238 , 198, 140), // #975
- INST(Vfnmadd213ss , VexRvm , V(660F38,AD,_,I,0,0,2,T1S), 0 , 121, 0 , 5251 , 199, 140), // #976
- INST(Vfnmadd231pd , VexRvm_Lx , V(660F38,BC,_,x,1,1,4,FV ), 0 , 162, 0 , 5264 , 196, 139), // #977
- INST(Vfnmadd231ps , VexRvm_Lx , V(660F38,BC,_,x,0,0,4,FV ), 0 , 163, 0 , 5277 , 197, 139), // #978
- INST(Vfnmadd231sd , VexRvm , V(660F38,BD,_,I,1,1,3,T1S), 0 , 164, 0 , 5290 , 198, 140), // #979
- INST(Vfnmadd231ss , VexRvm , V(660F38,BD,_,I,0,0,2,T1S), 0 , 121, 0 , 5303 , 199, 140), // #980
- INST(Vfnmaddpd , Fma4_Lx , V(660F3A,79,_,x,x,_,_,_ ), 0 , 74 , 0 , 5316 , 270, 141), // #981
- INST(Vfnmaddps , Fma4_Lx , V(660F3A,78,_,x,x,_,_,_ ), 0 , 74 , 0 , 5326 , 270, 141), // #982
- INST(Vfnmaddsd , Fma4 , V(660F3A,7B,_,0,x,_,_,_ ), 0 , 74 , 0 , 5336 , 271, 141), // #983
- INST(Vfnmaddss , Fma4 , V(660F3A,7A,_,0,x,_,_,_ ), 0 , 74 , 0 , 5346 , 272, 141), // #984
- INST(Vfnmsub132pd , VexRvm_Lx , V(660F38,9E,_,x,1,1,4,FV ), 0 , 162, 0 , 5356 , 196, 139), // #985
- INST(Vfnmsub132ps , VexRvm_Lx , V(660F38,9E,_,x,0,0,4,FV ), 0 , 163, 0 , 5369 , 197, 139), // #986
- INST(Vfnmsub132sd , VexRvm , V(660F38,9F,_,I,1,1,3,T1S), 0 , 164, 0 , 5382 , 198, 140), // #987
- INST(Vfnmsub132ss , VexRvm , V(660F38,9F,_,I,0,0,2,T1S), 0 , 121, 0 , 5395 , 199, 140), // #988
- INST(Vfnmsub213pd , VexRvm_Lx , V(660F38,AE,_,x,1,1,4,FV ), 0 , 162, 0 , 5408 , 196, 139), // #989
- INST(Vfnmsub213ps , VexRvm_Lx , V(660F38,AE,_,x,0,0,4,FV ), 0 , 163, 0 , 5421 , 197, 139), // #990
- INST(Vfnmsub213sd , VexRvm , V(660F38,AF,_,I,1,1,3,T1S), 0 , 164, 0 , 5434 , 198, 140), // #991
- INST(Vfnmsub213ss , VexRvm , V(660F38,AF,_,I,0,0,2,T1S), 0 , 121, 0 , 5447 , 199, 140), // #992
- INST(Vfnmsub231pd , VexRvm_Lx , V(660F38,BE,_,x,1,1,4,FV ), 0 , 162, 0 , 5460 , 196, 139), // #993
- INST(Vfnmsub231ps , VexRvm_Lx , V(660F38,BE,_,x,0,0,4,FV ), 0 , 163, 0 , 5473 , 197, 139), // #994
- INST(Vfnmsub231sd , VexRvm , V(660F38,BF,_,I,1,1,3,T1S), 0 , 164, 0 , 5486 , 198, 140), // #995
- INST(Vfnmsub231ss , VexRvm , V(660F38,BF,_,I,0,0,2,T1S), 0 , 121, 0 , 5499 , 199, 140), // #996
- INST(Vfnmsubpd , Fma4_Lx , V(660F3A,7D,_,x,x,_,_,_ ), 0 , 74 , 0 , 5512 , 270, 141), // #997
- INST(Vfnmsubps , Fma4_Lx , V(660F3A,7C,_,x,x,_,_,_ ), 0 , 74 , 0 , 5522 , 270, 141), // #998
- INST(Vfnmsubsd , Fma4 , V(660F3A,7F,_,0,x,_,_,_ ), 0 , 74 , 0 , 5532 , 271, 141), // #999
- INST(Vfnmsubss , Fma4 , V(660F3A,7E,_,0,x,_,_,_ ), 0 , 74 , 0 , 5542 , 272, 141), // #1000
- INST(Vfpclasspd , VexRmi_Lx , E(660F3A,66,_,x,_,1,4,FV ), 0 , 111, 0 , 5552 , 273, 131), // #1001
- INST(Vfpclassps , VexRmi_Lx , E(660F3A,66,_,x,_,0,4,FV ), 0 , 110, 0 , 5563 , 274, 131), // #1002
- INST(Vfpclasssd , VexRmi_Lx , E(660F3A,67,_,I,_,1,3,T1S), 0 , 160, 0 , 5574 , 275, 66 ), // #1003
- INST(Vfpclassss , VexRmi_Lx , E(660F3A,67,_,I,_,0,2,T1S), 0 , 161, 0 , 5585 , 276, 66 ), // #1004
- INST(Vfrczpd , VexRm_Lx , V(XOP_M9,81,_,x,0,_,_,_ ), 0 , 80 , 0 , 5596 , 277, 142), // #1005
- INST(Vfrczps , VexRm_Lx , V(XOP_M9,80,_,x,0,_,_,_ ), 0 , 80 , 0 , 5604 , 277, 142), // #1006
- INST(Vfrczsd , VexRm , V(XOP_M9,83,_,0,0,_,_,_ ), 0 , 80 , 0 , 5612 , 278, 142), // #1007
- INST(Vfrczss , VexRm , V(XOP_M9,82,_,0,0,_,_,_ ), 0 , 80 , 0 , 5620 , 279, 142), // #1008
- INST(Vgatherdpd , VexRmvRm_VM , V(660F38,92,_,x,1,_,_,_ ), E(660F38,92,_,x,_,1,3,T1S), 165, 81 , 5628 , 280, 143), // #1009
- INST(Vgatherdps , VexRmvRm_VM , V(660F38,92,_,x,0,_,_,_ ), E(660F38,92,_,x,_,0,2,T1S), 97 , 82 , 5639 , 281, 143), // #1010
- INST(Vgatherpf0dpd , VexM_VM , E(660F38,C6,1,2,_,1,3,T1S), 0 , 166, 0 , 5650 , 282, 144), // #1011
- INST(Vgatherpf0dps , VexM_VM , E(660F38,C6,1,2,_,0,2,T1S), 0 , 167, 0 , 5664 , 283, 144), // #1012
- INST(Vgatherpf0qpd , VexM_VM , E(660F38,C7,1,2,_,1,3,T1S), 0 , 166, 0 , 5678 , 284, 144), // #1013
- INST(Vgatherpf0qps , VexM_VM , E(660F38,C7,1,2,_,0,2,T1S), 0 , 167, 0 , 5692 , 284, 144), // #1014
- INST(Vgatherpf1dpd , VexM_VM , E(660F38,C6,2,2,_,1,3,T1S), 0 , 168, 0 , 5706 , 282, 144), // #1015
- INST(Vgatherpf1dps , VexM_VM , E(660F38,C6,2,2,_,0,2,T1S), 0 , 169, 0 , 5720 , 283, 144), // #1016
- INST(Vgatherpf1qpd , VexM_VM , E(660F38,C7,2,2,_,1,3,T1S), 0 , 168, 0 , 5734 , 284, 144), // #1017
- INST(Vgatherpf1qps , VexM_VM , E(660F38,C7,2,2,_,0,2,T1S), 0 , 169, 0 , 5748 , 284, 144), // #1018
- INST(Vgatherqpd , VexRmvRm_VM , V(660F38,93,_,x,1,_,_,_ ), E(660F38,93,_,x,_,1,3,T1S), 165, 83 , 5762 , 285, 143), // #1019
- INST(Vgatherqps , VexRmvRm_VM , V(660F38,93,_,x,0,_,_,_ ), E(660F38,93,_,x,_,0,2,T1S), 97 , 84 , 5773 , 286, 143), // #1020
- INST(Vgetexppd , VexRm_Lx , E(660F38,42,_,x,_,1,4,FV ), 0 , 112, 0 , 5784 , 246, 129), // #1021
- INST(Vgetexpps , VexRm_Lx , E(660F38,42,_,x,_,0,4,FV ), 0 , 113, 0 , 5794 , 250, 129), // #1022
- INST(Vgetexpsd , VexRvm , E(660F38,43,_,I,_,1,3,T1S), 0 , 124, 0 , 5804 , 287, 68 ), // #1023
- INST(Vgetexpss , VexRvm , E(660F38,43,_,I,_,0,2,T1S), 0 , 125, 0 , 5814 , 288, 68 ), // #1024
- INST(Vgetmantpd , VexRmi_Lx , E(660F3A,26,_,x,_,1,4,FV ), 0 , 111, 0 , 5824 , 289, 129), // #1025
- INST(Vgetmantps , VexRmi_Lx , E(660F3A,26,_,x,_,0,4,FV ), 0 , 110, 0 , 5835 , 290, 129), // #1026
- INST(Vgetmantsd , VexRvmi , E(660F3A,27,_,I,_,1,3,T1S), 0 , 160, 0 , 5846 , 268, 68 ), // #1027
- INST(Vgetmantss , VexRvmi , E(660F3A,27,_,I,_,0,2,T1S), 0 , 161, 0 , 5857 , 269, 68 ), // #1028
- INST(Vgf2p8affineinvqb, VexRvmi_Lx , V(660F3A,CF,_,x,1,1,4,FV ), 0 , 170, 0 , 5868 , 291, 145), // #1029
- INST(Vgf2p8affineqb , VexRvmi_Lx , V(660F3A,CE,_,x,1,1,4,FV ), 0 , 170, 0 , 5886 , 291, 145), // #1030
- INST(Vgf2p8mulb , VexRvm_Lx , V(660F38,CF,_,x,0,0,4,FV ), 0 , 163, 0 , 5901 , 292, 145), // #1031
- INST(Vhaddpd , VexRvm_Lx , V(660F00,7C,_,x,I,_,_,_ ), 0 , 70 , 0 , 5912 , 200, 126), // #1032
- INST(Vhaddps , VexRvm_Lx , V(F20F00,7C,_,x,I,_,_,_ ), 0 , 108, 0 , 5920 , 200, 126), // #1033
- INST(Vhsubpd , VexRvm_Lx , V(660F00,7D,_,x,I,_,_,_ ), 0 , 70 , 0 , 5928 , 200, 126), // #1034
- INST(Vhsubps , VexRvm_Lx , V(F20F00,7D,_,x,I,_,_,_ ), 0 , 108, 0 , 5936 , 200, 126), // #1035
- INST(Vinsertf128 , VexRvmi , V(660F3A,18,_,1,0,_,_,_ ), 0 , 154, 0 , 5944 , 293, 126), // #1036
- INST(Vinsertf32x4 , VexRvmi_Lx , E(660F3A,18,_,x,_,0,4,T4 ), 0 , 155, 0 , 5956 , 294, 129), // #1037
- INST(Vinsertf32x8 , VexRvmi , E(660F3A,1A,_,2,_,0,5,T8 ), 0 , 156, 0 , 5969 , 295, 66 ), // #1038
- INST(Vinsertf64x2 , VexRvmi_Lx , E(660F3A,18,_,x,_,1,4,T2 ), 0 , 157, 0 , 5982 , 294, 131), // #1039
- INST(Vinsertf64x4 , VexRvmi , E(660F3A,1A,_,2,_,1,5,T4 ), 0 , 158, 0 , 5995 , 295, 68 ), // #1040
- INST(Vinserti128 , VexRvmi , V(660F3A,38,_,1,0,_,_,_ ), 0 , 154, 0 , 6008 , 293, 132), // #1041
- INST(Vinserti32x4 , VexRvmi_Lx , E(660F3A,38,_,x,_,0,4,T4 ), 0 , 155, 0 , 6020 , 294, 129), // #1042
- INST(Vinserti32x8 , VexRvmi , E(660F3A,3A,_,2,_,0,5,T8 ), 0 , 156, 0 , 6033 , 295, 66 ), // #1043
- INST(Vinserti64x2 , VexRvmi_Lx , E(660F3A,38,_,x,_,1,4,T2 ), 0 , 157, 0 , 6046 , 294, 131), // #1044
- INST(Vinserti64x4 , VexRvmi , E(660F3A,3A,_,2,_,1,5,T4 ), 0 , 158, 0 , 6059 , 295, 68 ), // #1045
- INST(Vinsertps , VexRvmi , V(660F3A,21,_,0,I,0,2,T1S), 0 , 159, 0 , 6072 , 296, 125), // #1046
- INST(Vlddqu , VexRm_Lx , V(F20F00,F0,_,x,I,_,_,_ ), 0 , 108, 0 , 6082 , 297, 126), // #1047
- INST(Vldmxcsr , VexM , V(000F00,AE,2,0,I,_,_,_ ), 0 , 171, 0 , 6089 , 298, 126), // #1048
- INST(Vmaskmovdqu , VexRm_ZDI , V(660F00,F7,_,0,I,_,_,_ ), 0 , 70 , 0 , 6098 , 299, 126), // #1049
- INST(Vmaskmovpd , VexRvmMvr_Lx , V(660F38,2D,_,x,0,_,_,_ ), V(660F38,2F,_,x,0,_,_,_ ), 97 , 85 , 6110 , 300, 126), // #1050
- INST(Vmaskmovps , VexRvmMvr_Lx , V(660F38,2C,_,x,0,_,_,_ ), V(660F38,2E,_,x,0,_,_,_ ), 97 , 86 , 6121 , 300, 126), // #1051
- INST(Vmaxpd , VexRvm_Lx , V(660F00,5F,_,x,I,1,4,FV ), 0 , 104, 0 , 6132 , 301, 124), // #1052
- INST(Vmaxps , VexRvm_Lx , V(000F00,5F,_,x,I,0,4,FV ), 0 , 105, 0 , 6139 , 302, 124), // #1053
- INST(Vmaxsd , VexRvm , V(F20F00,5F,_,I,I,1,3,T1S), 0 , 106, 0 , 6146 , 303, 124), // #1054
- INST(Vmaxss , VexRvm , V(F30F00,5F,_,I,I,0,2,T1S), 0 , 107, 0 , 6153 , 242, 124), // #1055
- INST(Vmcall , X86Op , O(000F01,C1,_,_,_,_,_,_ ), 0 , 21 , 0 , 6160 , 30 , 58 ), // #1056
- INST(Vmclear , X86M_Only , O(660F00,C7,6,_,_,_,_,_ ), 0 , 26 , 0 , 6167 , 32 , 58 ), // #1057
- INST(Vmfunc , X86Op , O(000F01,D4,_,_,_,_,_,_ ), 0 , 21 , 0 , 6175 , 30 , 58 ), // #1058
- INST(Vminpd , VexRvm_Lx , V(660F00,5D,_,x,I,1,4,FV ), 0 , 104, 0 , 6182 , 301, 124), // #1059
- INST(Vminps , VexRvm_Lx , V(000F00,5D,_,x,I,0,4,FV ), 0 , 105, 0 , 6189 , 302, 124), // #1060
- INST(Vminsd , VexRvm , V(F20F00,5D,_,I,I,1,3,T1S), 0 , 106, 0 , 6196 , 303, 124), // #1061
- INST(Vminss , VexRvm , V(F30F00,5D,_,I,I,0,2,T1S), 0 , 107, 0 , 6203 , 242, 124), // #1062
- INST(Vmlaunch , X86Op , O(000F01,C2,_,_,_,_,_,_ ), 0 , 21 , 0 , 6210 , 30 , 58 ), // #1063
- INST(Vmload , X86Op_xAX , O(000F01,DA,_,_,_,_,_,_ ), 0 , 21 , 0 , 6219 , 304, 22 ), // #1064
- INST(Vmmcall , X86Op , O(000F01,D9,_,_,_,_,_,_ ), 0 , 21 , 0 , 6226 , 30 , 22 ), // #1065
- INST(Vmovapd , VexRmMr_Lx , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 172, 87 , 6234 , 305, 124), // #1066
- INST(Vmovaps , VexRmMr_Lx , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 173, 88 , 6242 , 305, 124), // #1067
- INST(Vmovd , VexMovdMovq , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 174, 89 , 6250 , 306, 125), // #1068
- INST(Vmovddup , VexRm_Lx , V(F20F00,12,_,x,I,1,3,DUP), 0 , 175, 0 , 6256 , 307, 124), // #1069
- INST(Vmovdqa , VexRmMr_Lx , V(660F00,6F,_,x,I,_,_,_ ), V(660F00,7F,_,x,I,_,_,_ ), 70 , 90 , 6265 , 308, 126), // #1070
- INST(Vmovdqa32 , VexRmMr_Lx , E(660F00,6F,_,x,_,0,4,FVM), E(660F00,7F,_,x,_,0,4,FVM), 176, 91 , 6273 , 309, 129), // #1071
- INST(Vmovdqa64 , VexRmMr_Lx , E(660F00,6F,_,x,_,1,4,FVM), E(660F00,7F,_,x,_,1,4,FVM), 177, 92 , 6283 , 309, 129), // #1072
- INST(Vmovdqu , VexRmMr_Lx , V(F30F00,6F,_,x,I,_,_,_ ), V(F30F00,7F,_,x,I,_,_,_ ), 178, 93 , 6293 , 308, 126), // #1073
- INST(Vmovdqu16 , VexRmMr_Lx , E(F20F00,6F,_,x,_,1,4,FVM), E(F20F00,7F,_,x,_,1,4,FVM), 179, 94 , 6301 , 309, 137), // #1074
- INST(Vmovdqu32 , VexRmMr_Lx , E(F30F00,6F,_,x,_,0,4,FVM), E(F30F00,7F,_,x,_,0,4,FVM), 180, 95 , 6311 , 309, 129), // #1075
- INST(Vmovdqu64 , VexRmMr_Lx , E(F30F00,6F,_,x,_,1,4,FVM), E(F30F00,7F,_,x,_,1,4,FVM), 181, 96 , 6321 , 309, 129), // #1076
- INST(Vmovdqu8 , VexRmMr_Lx , E(F20F00,6F,_,x,_,0,4,FVM), E(F20F00,7F,_,x,_,0,4,FVM), 182, 97 , 6331 , 309, 137), // #1077
- INST(Vmovhlps , VexRvm , V(000F00,12,_,0,I,0,_,_ ), 0 , 73 , 0 , 6340 , 310, 125), // #1078
- INST(Vmovhpd , VexRvmMr , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 122, 98 , 6349 , 311, 125), // #1079
- INST(Vmovhps , VexRvmMr , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 183, 99 , 6357 , 311, 125), // #1080
- INST(Vmovlhps , VexRvm , V(000F00,16,_,0,I,0,_,_ ), 0 , 73 , 0 , 6365 , 310, 125), // #1081
- INST(Vmovlpd , VexRvmMr , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 122, 100, 6374 , 311, 125), // #1082
- INST(Vmovlps , VexRvmMr , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 183, 101, 6382 , 311, 125), // #1083
- INST(Vmovmskpd , VexRm_Lx , V(660F00,50,_,x,I,_,_,_ ), 0 , 70 , 0 , 6390 , 312, 126), // #1084
- INST(Vmovmskps , VexRm_Lx , V(000F00,50,_,x,I,_,_,_ ), 0 , 73 , 0 , 6400 , 312, 126), // #1085
- INST(Vmovntdq , VexMr_Lx , V(660F00,E7,_,x,I,0,4,FVM), 0 , 184, 0 , 6410 , 313, 124), // #1086
- INST(Vmovntdqa , VexRm_Lx , V(660F38,2A,_,x,I,0,4,FVM), 0 , 109, 0 , 6419 , 314, 133), // #1087
- INST(Vmovntpd , VexMr_Lx , V(660F00,2B,_,x,I,1,4,FVM), 0 , 172, 0 , 6429 , 313, 124), // #1088
- INST(Vmovntps , VexMr_Lx , V(000F00,2B,_,x,I,0,4,FVM), 0 , 173, 0 , 6438 , 313, 124), // #1089
- INST(Vmovq , VexMovdMovq , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 122, 102, 6447 , 315, 125), // #1090
- INST(Vmovsd , VexMovssMovsd , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 106, 103, 6453 , 316, 125), // #1091
- INST(Vmovshdup , VexRm_Lx , V(F30F00,16,_,x,I,0,4,FVM), 0 , 185, 0 , 6460 , 317, 124), // #1092
- INST(Vmovsldup , VexRm_Lx , V(F30F00,12,_,x,I,0,4,FVM), 0 , 185, 0 , 6470 , 317, 124), // #1093
- INST(Vmovss , VexMovssMovsd , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 107, 104, 6480 , 318, 125), // #1094
- INST(Vmovupd , VexRmMr_Lx , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 172, 105, 6487 , 305, 124), // #1095
- INST(Vmovups , VexRmMr_Lx , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 173, 106, 6495 , 305, 124), // #1096
- INST(Vmpsadbw , VexRvmi_Lx , V(660F3A,42,_,x,I,_,_,_ ), 0 , 74 , 0 , 6503 , 212, 146), // #1097
- INST(Vmptrld , X86M_Only , O(000F00,C7,6,_,_,_,_,_ ), 0 , 81 , 0 , 6512 , 32 , 58 ), // #1098
- INST(Vmptrst , X86M_Only , O(000F00,C7,7,_,_,_,_,_ ), 0 , 22 , 0 , 6520 , 32 , 58 ), // #1099
- INST(Vmread , X86Mr_NoSize , O(000F00,78,_,_,_,_,_,_ ), 0 , 4 , 0 , 6528 , 319, 58 ), // #1100
- INST(Vmresume , X86Op , O(000F01,C3,_,_,_,_,_,_ ), 0 , 21 , 0 , 6535 , 30 , 58 ), // #1101
- INST(Vmrun , X86Op_xAX , O(000F01,D8,_,_,_,_,_,_ ), 0 , 21 , 0 , 6544 , 304, 22 ), // #1102
- INST(Vmsave , X86Op_xAX , O(000F01,DB,_,_,_,_,_,_ ), 0 , 21 , 0 , 6550 , 304, 22 ), // #1103
- INST(Vmulpd , VexRvm_Lx , V(660F00,59,_,x,I,1,4,FV ), 0 , 104, 0 , 6557 , 196, 124), // #1104
- INST(Vmulps , VexRvm_Lx , V(000F00,59,_,x,I,0,4,FV ), 0 , 105, 0 , 6564 , 197, 124), // #1105
- INST(Vmulsd , VexRvm_Lx , V(F20F00,59,_,I,I,1,3,T1S), 0 , 106, 0 , 6571 , 198, 125), // #1106
- INST(Vmulss , VexRvm_Lx , V(F30F00,59,_,I,I,0,2,T1S), 0 , 107, 0 , 6578 , 199, 125), // #1107
- INST(Vmwrite , X86Rm_NoSize , O(000F00,79,_,_,_,_,_,_ ), 0 , 4 , 0 , 6585 , 320, 58 ), // #1108
- INST(Vmxon , X86M_Only , O(F30F00,C7,6,_,_,_,_,_ ), 0 , 24 , 0 , 6593 , 32 , 58 ), // #1109
- INST(Vorpd , VexRvm_Lx , V(660F00,56,_,x,I,1,4,FV ), 0 , 104, 0 , 6599 , 208, 130), // #1110
- INST(Vorps , VexRvm_Lx , V(000F00,56,_,x,I,0,4,FV ), 0 , 105, 0 , 6605 , 209, 130), // #1111
- INST(Vp2intersectd , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,0,4,FV ), 0 , 127, 0 , 6611 , 321, 147), // #1112
- INST(Vp2intersectq , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,1,4,FV ), 0 , 186, 0 , 6625 , 322, 147), // #1113
- INST(Vp4dpwssd , VexRm_T1_4X , E(F20F38,52,_,2,_,0,4,T4X), 0 , 102, 0 , 6639 , 194, 148), // #1114
- INST(Vp4dpwssds , VexRm_T1_4X , E(F20F38,53,_,2,_,0,4,T4X), 0 , 102, 0 , 6649 , 194, 148), // #1115
- INST(Vpabsb , VexRm_Lx , V(660F38,1C,_,x,I,_,4,FVM), 0 , 109, 0 , 6660 , 317, 149), // #1116
- INST(Vpabsd , VexRm_Lx , V(660F38,1E,_,x,I,0,4,FV ), 0 , 163, 0 , 6667 , 317, 133), // #1117
- INST(Vpabsq , VexRm_Lx , E(660F38,1F,_,x,_,1,4,FV ), 0 , 112, 0 , 6674 , 261, 129), // #1118
- INST(Vpabsw , VexRm_Lx , V(660F38,1D,_,x,I,_,4,FVM), 0 , 109, 0 , 6681 , 317, 149), // #1119
- INST(Vpackssdw , VexRvm_Lx , V(660F00,6B,_,x,I,0,4,FV ), 0 , 133, 0 , 6688 , 207, 149), // #1120
- INST(Vpacksswb , VexRvm_Lx , V(660F00,63,_,x,I,I,4,FVM), 0 , 184, 0 , 6698 , 292, 149), // #1121
- INST(Vpackusdw , VexRvm_Lx , V(660F38,2B,_,x,I,0,4,FV ), 0 , 163, 0 , 6708 , 207, 149), // #1122
- INST(Vpackuswb , VexRvm_Lx , V(660F00,67,_,x,I,I,4,FVM), 0 , 184, 0 , 6718 , 292, 149), // #1123
- INST(Vpaddb , VexRvm_Lx , V(660F00,FC,_,x,I,I,4,FVM), 0 , 184, 0 , 6728 , 292, 149), // #1124
- INST(Vpaddd , VexRvm_Lx , V(660F00,FE,_,x,I,0,4,FV ), 0 , 133, 0 , 6735 , 207, 133), // #1125
- INST(Vpaddq , VexRvm_Lx , V(660F00,D4,_,x,I,1,4,FV ), 0 , 104, 0 , 6742 , 206, 133), // #1126
- INST(Vpaddsb , VexRvm_Lx , V(660F00,EC,_,x,I,I,4,FVM), 0 , 184, 0 , 6749 , 292, 149), // #1127
- INST(Vpaddsw , VexRvm_Lx , V(660F00,ED,_,x,I,I,4,FVM), 0 , 184, 0 , 6757 , 292, 149), // #1128
- INST(Vpaddusb , VexRvm_Lx , V(660F00,DC,_,x,I,I,4,FVM), 0 , 184, 0 , 6765 , 292, 149), // #1129
- INST(Vpaddusw , VexRvm_Lx , V(660F00,DD,_,x,I,I,4,FVM), 0 , 184, 0 , 6774 , 292, 149), // #1130
- INST(Vpaddw , VexRvm_Lx , V(660F00,FD,_,x,I,I,4,FVM), 0 , 184, 0 , 6783 , 292, 149), // #1131
- INST(Vpalignr , VexRvmi_Lx , V(660F3A,0F,_,x,I,I,4,FVM), 0 , 187, 0 , 6790 , 291, 149), // #1132
- INST(Vpand , VexRvm_Lx , V(660F00,DB,_,x,I,_,_,_ ), 0 , 70 , 0 , 6799 , 323, 146), // #1133
- INST(Vpandd , VexRvm_Lx , E(660F00,DB,_,x,_,0,4,FV ), 0 , 188, 0 , 6805 , 324, 129), // #1134
- INST(Vpandn , VexRvm_Lx , V(660F00,DF,_,x,I,_,_,_ ), 0 , 70 , 0 , 6812 , 325, 146), // #1135
- INST(Vpandnd , VexRvm_Lx , E(660F00,DF,_,x,_,0,4,FV ), 0 , 188, 0 , 6819 , 326, 129), // #1136
- INST(Vpandnq , VexRvm_Lx , E(660F00,DF,_,x,_,1,4,FV ), 0 , 130, 0 , 6827 , 327, 129), // #1137
- INST(Vpandq , VexRvm_Lx , E(660F00,DB,_,x,_,1,4,FV ), 0 , 130, 0 , 6835 , 328, 129), // #1138
- INST(Vpavgb , VexRvm_Lx , V(660F00,E0,_,x,I,I,4,FVM), 0 , 184, 0 , 6842 , 292, 149), // #1139
- INST(Vpavgw , VexRvm_Lx , V(660F00,E3,_,x,I,I,4,FVM), 0 , 184, 0 , 6849 , 292, 149), // #1140
- INST(Vpblendd , VexRvmi_Lx , V(660F3A,02,_,x,0,_,_,_ ), 0 , 74 , 0 , 6856 , 212, 132), // #1141
- INST(Vpblendmb , VexRvm_Lx , E(660F38,66,_,x,_,0,4,FVM), 0 , 189, 0 , 6865 , 329, 137), // #1142
- INST(Vpblendmd , VexRvm_Lx , E(660F38,64,_,x,_,0,4,FV ), 0 , 113, 0 , 6875 , 211, 129), // #1143
- INST(Vpblendmq , VexRvm_Lx , E(660F38,64,_,x,_,1,4,FV ), 0 , 112, 0 , 6885 , 210, 129), // #1144
- INST(Vpblendmw , VexRvm_Lx , E(660F38,66,_,x,_,1,4,FVM), 0 , 190, 0 , 6895 , 329, 137), // #1145
- INST(Vpblendvb , VexRvmr_Lx , V(660F3A,4C,_,x,0,_,_,_ ), 0 , 74 , 0 , 6905 , 213, 146), // #1146
- INST(Vpblendw , VexRvmi_Lx , V(660F3A,0E,_,x,I,_,_,_ ), 0 , 74 , 0 , 6915 , 212, 146), // #1147
- INST(Vpbroadcastb , VexRm_Lx_Bcst , V(660F38,78,_,x,0,0,0,T1S), E(660F38,7A,_,x,0,0,0,T1S), 191, 107, 6924 , 330, 150), // #1148
- INST(Vpbroadcastd , VexRm_Lx_Bcst , V(660F38,58,_,x,0,0,2,T1S), E(660F38,7C,_,x,0,0,0,T1S), 121, 108, 6937 , 331, 143), // #1149
- INST(Vpbroadcastmb2q , VexRm_Lx , E(F30F38,2A,_,x,_,1,_,_ ), 0 , 192, 0 , 6950 , 332, 151), // #1150
- INST(Vpbroadcastmw2d , VexRm_Lx , E(F30F38,3A,_,x,_,0,_,_ ), 0 , 193, 0 , 6966 , 332, 151), // #1151
- INST(Vpbroadcastq , VexRm_Lx_Bcst , V(660F38,59,_,x,0,1,3,T1S), E(660F38,7C,_,x,0,1,0,T1S), 120, 109, 6982 , 333, 143), // #1152
- INST(Vpbroadcastw , VexRm_Lx_Bcst , V(660F38,79,_,x,0,0,1,T1S), E(660F38,7B,_,x,0,0,0,T1S), 194, 110, 6995 , 334, 150), // #1153
- INST(Vpclmulqdq , VexRvmi_Lx , V(660F3A,44,_,x,I,_,4,FVM), 0 , 187, 0 , 7008 , 335, 152), // #1154
- INST(Vpcmov , VexRvrmRvmr_Lx , V(XOP_M8,A2,_,x,x,_,_,_ ), 0 , 195, 0 , 7019 , 270, 142), // #1155
- INST(Vpcmpb , VexRvmi_Lx , E(660F3A,3F,_,x,_,0,4,FVM), 0 , 151, 0 , 7026 , 336, 137), // #1156
- INST(Vpcmpd , VexRvmi_Lx , E(660F3A,1F,_,x,_,0,4,FV ), 0 , 110, 0 , 7033 , 337, 129), // #1157
- INST(Vpcmpeqb , VexRvm_Lx_KEvex , V(660F00,74,_,x,I,I,4,FV ), 0 , 133, 0 , 7040 , 338, 149), // #1158
- INST(Vpcmpeqd , VexRvm_Lx_KEvex , V(660F00,76,_,x,I,0,4,FVM), 0 , 184, 0 , 7049 , 339, 133), // #1159
- INST(Vpcmpeqq , VexRvm_Lx_KEvex , V(660F38,29,_,x,I,1,4,FVM), 0 , 196, 0 , 7058 , 340, 133), // #1160
- INST(Vpcmpeqw , VexRvm_Lx_KEvex , V(660F00,75,_,x,I,I,4,FV ), 0 , 133, 0 , 7067 , 338, 149), // #1161
- INST(Vpcmpestri , VexRmi , V(660F3A,61,_,0,I,_,_,_ ), 0 , 74 , 0 , 7076 , 341, 153), // #1162
- INST(Vpcmpestrm , VexRmi , V(660F3A,60,_,0,I,_,_,_ ), 0 , 74 , 0 , 7087 , 342, 153), // #1163
- INST(Vpcmpgtb , VexRvm_Lx_KEvex , V(660F00,64,_,x,I,I,4,FV ), 0 , 133, 0 , 7098 , 338, 149), // #1164
- INST(Vpcmpgtd , VexRvm_Lx_KEvex , V(660F00,66,_,x,I,0,4,FVM), 0 , 184, 0 , 7107 , 339, 133), // #1165
- INST(Vpcmpgtq , VexRvm_Lx_KEvex , V(660F38,37,_,x,I,1,4,FVM), 0 , 196, 0 , 7116 , 340, 133), // #1166
- INST(Vpcmpgtw , VexRvm_Lx_KEvex , V(660F00,65,_,x,I,I,4,FV ), 0 , 133, 0 , 7125 , 338, 149), // #1167
- INST(Vpcmpistri , VexRmi , V(660F3A,63,_,0,I,_,_,_ ), 0 , 74 , 0 , 7134 , 343, 153), // #1168
- INST(Vpcmpistrm , VexRmi , V(660F3A,62,_,0,I,_,_,_ ), 0 , 74 , 0 , 7145 , 344, 153), // #1169
- INST(Vpcmpq , VexRvmi_Lx , E(660F3A,1F,_,x,_,1,4,FV ), 0 , 111, 0 , 7156 , 345, 129), // #1170
- INST(Vpcmpub , VexRvmi_Lx , E(660F3A,3E,_,x,_,0,4,FVM), 0 , 151, 0 , 7163 , 336, 137), // #1171
- INST(Vpcmpud , VexRvmi_Lx , E(660F3A,1E,_,x,_,0,4,FV ), 0 , 110, 0 , 7171 , 337, 129), // #1172
- INST(Vpcmpuq , VexRvmi_Lx , E(660F3A,1E,_,x,_,1,4,FV ), 0 , 111, 0 , 7179 , 345, 129), // #1173
- INST(Vpcmpuw , VexRvmi_Lx , E(660F3A,3E,_,x,_,1,4,FVM), 0 , 197, 0 , 7187 , 345, 137), // #1174
- INST(Vpcmpw , VexRvmi_Lx , E(660F3A,3F,_,x,_,1,4,FVM), 0 , 197, 0 , 7195 , 345, 137), // #1175
- INST(Vpcomb , VexRvmi , V(XOP_M8,CC,_,0,0,_,_,_ ), 0 , 195, 0 , 7202 , 258, 142), // #1176
- INST(Vpcomd , VexRvmi , V(XOP_M8,CE,_,0,0,_,_,_ ), 0 , 195, 0 , 7209 , 258, 142), // #1177
- INST(Vpcompressb , VexMr_Lx , E(660F38,63,_,x,_,0,0,T1S), 0 , 198, 0 , 7216 , 227, 154), // #1178
- INST(Vpcompressd , VexMr_Lx , E(660F38,8B,_,x,_,0,2,T1S), 0 , 125, 0 , 7228 , 227, 129), // #1179
- INST(Vpcompressq , VexMr_Lx , E(660F38,8B,_,x,_,1,3,T1S), 0 , 124, 0 , 7240 , 227, 129), // #1180
- INST(Vpcompressw , VexMr_Lx , E(660F38,63,_,x,_,1,1,T1S), 0 , 199, 0 , 7252 , 227, 154), // #1181
- INST(Vpcomq , VexRvmi , V(XOP_M8,CF,_,0,0,_,_,_ ), 0 , 195, 0 , 7264 , 258, 142), // #1182
- INST(Vpcomub , VexRvmi , V(XOP_M8,EC,_,0,0,_,_,_ ), 0 , 195, 0 , 7271 , 258, 142), // #1183
- INST(Vpcomud , VexRvmi , V(XOP_M8,EE,_,0,0,_,_,_ ), 0 , 195, 0 , 7279 , 258, 142), // #1184
- INST(Vpcomuq , VexRvmi , V(XOP_M8,EF,_,0,0,_,_,_ ), 0 , 195, 0 , 7287 , 258, 142), // #1185
- INST(Vpcomuw , VexRvmi , V(XOP_M8,ED,_,0,0,_,_,_ ), 0 , 195, 0 , 7295 , 258, 142), // #1186
- INST(Vpcomw , VexRvmi , V(XOP_M8,CD,_,0,0,_,_,_ ), 0 , 195, 0 , 7303 , 258, 142), // #1187
- INST(Vpconflictd , VexRm_Lx , E(660F38,C4,_,x,_,0,4,FV ), 0 , 113, 0 , 7310 , 346, 151), // #1188
- INST(Vpconflictq , VexRm_Lx , E(660F38,C4,_,x,_,1,4,FV ), 0 , 112, 0 , 7322 , 346, 151), // #1189
- INST(Vpdpbusd , VexRvm_Lx , V(660F38,50,_,x,_,0,4,FV ), 0 , 163, 0 , 7334 , 347, 155), // #1190
- INST(Vpdpbusds , VexRvm_Lx , V(660F38,51,_,x,_,0,4,FV ), 0 , 163, 0 , 7343 , 347, 155), // #1191
- INST(Vpdpwssd , VexRvm_Lx , V(660F38,52,_,x,_,0,4,FV ), 0 , 163, 0 , 7353 , 347, 155), // #1192
- INST(Vpdpwssds , VexRvm_Lx , V(660F38,53,_,x,_,0,4,FV ), 0 , 163, 0 , 7362 , 347, 155), // #1193
- INST(Vperm2f128 , VexRvmi , V(660F3A,06,_,1,0,_,_,_ ), 0 , 154, 0 , 7372 , 348, 126), // #1194
- INST(Vperm2i128 , VexRvmi , V(660F3A,46,_,1,0,_,_,_ ), 0 , 154, 0 , 7383 , 348, 132), // #1195
- INST(Vpermb , VexRvm_Lx , E(660F38,8D,_,x,_,0,4,FVM), 0 , 189, 0 , 7394 , 329, 156), // #1196
- INST(Vpermd , VexRvm_Lx , V(660F38,36,_,x,0,0,4,FV ), 0 , 163, 0 , 7401 , 349, 143), // #1197
- INST(Vpermi2b , VexRvm_Lx , E(660F38,75,_,x,_,0,4,FVM), 0 , 189, 0 , 7408 , 329, 156), // #1198
- INST(Vpermi2d , VexRvm_Lx , E(660F38,76,_,x,_,0,4,FV ), 0 , 113, 0 , 7417 , 211, 129), // #1199
- INST(Vpermi2pd , VexRvm_Lx , E(660F38,77,_,x,_,1,4,FV ), 0 , 112, 0 , 7426 , 210, 129), // #1200
- INST(Vpermi2ps , VexRvm_Lx , E(660F38,77,_,x,_,0,4,FV ), 0 , 113, 0 , 7436 , 211, 129), // #1201
- INST(Vpermi2q , VexRvm_Lx , E(660F38,76,_,x,_,1,4,FV ), 0 , 112, 0 , 7446 , 210, 129), // #1202
- INST(Vpermi2w , VexRvm_Lx , E(660F38,75,_,x,_,1,4,FVM), 0 , 190, 0 , 7455 , 329, 137), // #1203
- INST(Vpermil2pd , VexRvrmiRvmri_Lx , V(660F3A,49,_,x,x,_,_,_ ), 0 , 74 , 0 , 7464 , 350, 142), // #1204
- INST(Vpermil2ps , VexRvrmiRvmri_Lx , V(660F3A,48,_,x,x,_,_,_ ), 0 , 74 , 0 , 7475 , 350, 142), // #1205
- INST(Vpermilpd , VexRvmRmi_Lx , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 200, 111, 7486 , 351, 124), // #1206
- INST(Vpermilps , VexRvmRmi_Lx , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 163, 112, 7496 , 351, 124), // #1207
- INST(Vpermpd , VexRvmRmi_Lx , E(660F38,16,_,x,1,1,4,FV ), V(660F3A,01,_,x,1,1,4,FV ), 201, 113, 7506 , 352, 143), // #1208
- INST(Vpermps , VexRvm_Lx , V(660F38,16,_,x,0,0,4,FV ), 0 , 163, 0 , 7514 , 349, 143), // #1209
- INST(Vpermq , VexRvmRmi_Lx , E(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 112, 114, 7522 , 352, 143), // #1210
- INST(Vpermt2b , VexRvm_Lx , E(660F38,7D,_,x,_,0,4,FVM), 0 , 189, 0 , 7529 , 329, 156), // #1211
- INST(Vpermt2d , VexRvm_Lx , E(660F38,7E,_,x,_,0,4,FV ), 0 , 113, 0 , 7538 , 211, 129), // #1212
- INST(Vpermt2pd , VexRvm_Lx , E(660F38,7F,_,x,_,1,4,FV ), 0 , 112, 0 , 7547 , 210, 129), // #1213
- INST(Vpermt2ps , VexRvm_Lx , E(660F38,7F,_,x,_,0,4,FV ), 0 , 113, 0 , 7557 , 211, 129), // #1214
- INST(Vpermt2q , VexRvm_Lx , E(660F38,7E,_,x,_,1,4,FV ), 0 , 112, 0 , 7567 , 210, 129), // #1215
- INST(Vpermt2w , VexRvm_Lx , E(660F38,7D,_,x,_,1,4,FVM), 0 , 190, 0 , 7576 , 329, 137), // #1216
- INST(Vpermw , VexRvm_Lx , E(660F38,8D,_,x,_,1,4,FVM), 0 , 190, 0 , 7585 , 329, 137), // #1217
- INST(Vpexpandb , VexRm_Lx , E(660F38,62,_,x,_,0,0,T1S), 0 , 198, 0 , 7592 , 261, 154), // #1218
- INST(Vpexpandd , VexRm_Lx , E(660F38,89,_,x,_,0,2,T1S), 0 , 125, 0 , 7602 , 261, 129), // #1219
- INST(Vpexpandq , VexRm_Lx , E(660F38,89,_,x,_,1,3,T1S), 0 , 124, 0 , 7612 , 261, 129), // #1220
- INST(Vpexpandw , VexRm_Lx , E(660F38,62,_,x,_,1,1,T1S), 0 , 199, 0 , 7622 , 261, 154), // #1221
- INST(Vpextrb , VexMri , V(660F3A,14,_,0,0,I,0,T1S), 0 , 202, 0 , 7632 , 353, 157), // #1222
- INST(Vpextrd , VexMri , V(660F3A,16,_,0,0,0,2,T1S), 0 , 159, 0 , 7640 , 265, 158), // #1223
- INST(Vpextrq , VexMri , V(660F3A,16,_,0,1,1,3,T1S), 0 , 203, 0 , 7648 , 354, 158), // #1224
- INST(Vpextrw , VexMri_Vpextrw , V(660F3A,15,_,0,0,I,1,T1S), 0 , 204, 0 , 7656 , 355, 157), // #1225
- INST(Vpgatherdd , VexRmvRm_VM , V(660F38,90,_,x,0,_,_,_ ), E(660F38,90,_,x,_,0,2,T1S), 97 , 115, 7664 , 281, 143), // #1226
- INST(Vpgatherdq , VexRmvRm_VM , V(660F38,90,_,x,1,_,_,_ ), E(660F38,90,_,x,_,1,3,T1S), 165, 116, 7675 , 280, 143), // #1227
- INST(Vpgatherqd , VexRmvRm_VM , V(660F38,91,_,x,0,_,_,_ ), E(660F38,91,_,x,_,0,2,T1S), 97 , 117, 7686 , 286, 143), // #1228
- INST(Vpgatherqq , VexRmvRm_VM , V(660F38,91,_,x,1,_,_,_ ), E(660F38,91,_,x,_,1,3,T1S), 165, 118, 7697 , 285, 143), // #1229
- INST(Vphaddbd , VexRm , V(XOP_M9,C2,_,0,0,_,_,_ ), 0 , 80 , 0 , 7708 , 202, 142), // #1230
- INST(Vphaddbq , VexRm , V(XOP_M9,C3,_,0,0,_,_,_ ), 0 , 80 , 0 , 7717 , 202, 142), // #1231
- INST(Vphaddbw , VexRm , V(XOP_M9,C1,_,0,0,_,_,_ ), 0 , 80 , 0 , 7726 , 202, 142), // #1232
- INST(Vphaddd , VexRvm_Lx , V(660F38,02,_,x,I,_,_,_ ), 0 , 97 , 0 , 7735 , 200, 146), // #1233
- INST(Vphadddq , VexRm , V(XOP_M9,CB,_,0,0,_,_,_ ), 0 , 80 , 0 , 7743 , 202, 142), // #1234
- INST(Vphaddsw , VexRvm_Lx , V(660F38,03,_,x,I,_,_,_ ), 0 , 97 , 0 , 7752 , 200, 146), // #1235
- INST(Vphaddubd , VexRm , V(XOP_M9,D2,_,0,0,_,_,_ ), 0 , 80 , 0 , 7761 , 202, 142), // #1236
- INST(Vphaddubq , VexRm , V(XOP_M9,D3,_,0,0,_,_,_ ), 0 , 80 , 0 , 7771 , 202, 142), // #1237
- INST(Vphaddubw , VexRm , V(XOP_M9,D1,_,0,0,_,_,_ ), 0 , 80 , 0 , 7781 , 202, 142), // #1238
- INST(Vphaddudq , VexRm , V(XOP_M9,DB,_,0,0,_,_,_ ), 0 , 80 , 0 , 7791 , 202, 142), // #1239
- INST(Vphadduwd , VexRm , V(XOP_M9,D6,_,0,0,_,_,_ ), 0 , 80 , 0 , 7801 , 202, 142), // #1240
- INST(Vphadduwq , VexRm , V(XOP_M9,D7,_,0,0,_,_,_ ), 0 , 80 , 0 , 7811 , 202, 142), // #1241
- INST(Vphaddw , VexRvm_Lx , V(660F38,01,_,x,I,_,_,_ ), 0 , 97 , 0 , 7821 , 200, 146), // #1242
- INST(Vphaddwd , VexRm , V(XOP_M9,C6,_,0,0,_,_,_ ), 0 , 80 , 0 , 7829 , 202, 142), // #1243
- INST(Vphaddwq , VexRm , V(XOP_M9,C7,_,0,0,_,_,_ ), 0 , 80 , 0 , 7838 , 202, 142), // #1244
- INST(Vphminposuw , VexRm , V(660F38,41,_,0,I,_,_,_ ), 0 , 97 , 0 , 7847 , 202, 126), // #1245
- INST(Vphsubbw , VexRm , V(XOP_M9,E1,_,0,0,_,_,_ ), 0 , 80 , 0 , 7859 , 202, 142), // #1246
- INST(Vphsubd , VexRvm_Lx , V(660F38,06,_,x,I,_,_,_ ), 0 , 97 , 0 , 7868 , 200, 146), // #1247
- INST(Vphsubdq , VexRm , V(XOP_M9,E3,_,0,0,_,_,_ ), 0 , 80 , 0 , 7876 , 202, 142), // #1248
- INST(Vphsubsw , VexRvm_Lx , V(660F38,07,_,x,I,_,_,_ ), 0 , 97 , 0 , 7885 , 200, 146), // #1249
- INST(Vphsubw , VexRvm_Lx , V(660F38,05,_,x,I,_,_,_ ), 0 , 97 , 0 , 7894 , 200, 146), // #1250
- INST(Vphsubwd , VexRm , V(XOP_M9,E2,_,0,0,_,_,_ ), 0 , 80 , 0 , 7902 , 202, 142), // #1251
- INST(Vpinsrb , VexRvmi , V(660F3A,20,_,0,0,I,0,T1S), 0 , 202, 0 , 7911 , 356, 157), // #1252
- INST(Vpinsrd , VexRvmi , V(660F3A,22,_,0,0,0,2,T1S), 0 , 159, 0 , 7919 , 357, 158), // #1253
- INST(Vpinsrq , VexRvmi , V(660F3A,22,_,0,1,1,3,T1S), 0 , 203, 0 , 7927 , 358, 158), // #1254
- INST(Vpinsrw , VexRvmi , V(660F00,C4,_,0,0,I,1,T1S), 0 , 205, 0 , 7935 , 359, 157), // #1255
- INST(Vplzcntd , VexRm_Lx , E(660F38,44,_,x,_,0,4,FV ), 0 , 113, 0 , 7943 , 346, 151), // #1256
- INST(Vplzcntq , VexRm_Lx , E(660F38,44,_,x,_,1,4,FV ), 0 , 112, 0 , 7952 , 360, 151), // #1257
- INST(Vpmacsdd , VexRvmr , V(XOP_M8,9E,_,0,0,_,_,_ ), 0 , 195, 0 , 7961 , 361, 142), // #1258
- INST(Vpmacsdqh , VexRvmr , V(XOP_M8,9F,_,0,0,_,_,_ ), 0 , 195, 0 , 7970 , 361, 142), // #1259
- INST(Vpmacsdql , VexRvmr , V(XOP_M8,97,_,0,0,_,_,_ ), 0 , 195, 0 , 7980 , 361, 142), // #1260
- INST(Vpmacssdd , VexRvmr , V(XOP_M8,8E,_,0,0,_,_,_ ), 0 , 195, 0 , 7990 , 361, 142), // #1261
- INST(Vpmacssdqh , VexRvmr , V(XOP_M8,8F,_,0,0,_,_,_ ), 0 , 195, 0 , 8000 , 361, 142), // #1262
- INST(Vpmacssdql , VexRvmr , V(XOP_M8,87,_,0,0,_,_,_ ), 0 , 195, 0 , 8011 , 361, 142), // #1263
- INST(Vpmacsswd , VexRvmr , V(XOP_M8,86,_,0,0,_,_,_ ), 0 , 195, 0 , 8022 , 361, 142), // #1264
- INST(Vpmacssww , VexRvmr , V(XOP_M8,85,_,0,0,_,_,_ ), 0 , 195, 0 , 8032 , 361, 142), // #1265
- INST(Vpmacswd , VexRvmr , V(XOP_M8,96,_,0,0,_,_,_ ), 0 , 195, 0 , 8042 , 361, 142), // #1266
- INST(Vpmacsww , VexRvmr , V(XOP_M8,95,_,0,0,_,_,_ ), 0 , 195, 0 , 8051 , 361, 142), // #1267
- INST(Vpmadcsswd , VexRvmr , V(XOP_M8,A6,_,0,0,_,_,_ ), 0 , 195, 0 , 8060 , 361, 142), // #1268
- INST(Vpmadcswd , VexRvmr , V(XOP_M8,B6,_,0,0,_,_,_ ), 0 , 195, 0 , 8071 , 361, 142), // #1269
- INST(Vpmadd52huq , VexRvm_Lx , E(660F38,B5,_,x,_,1,4,FV ), 0 , 112, 0 , 8081 , 210, 159), // #1270
- INST(Vpmadd52luq , VexRvm_Lx , E(660F38,B4,_,x,_,1,4,FV ), 0 , 112, 0 , 8093 , 210, 159), // #1271
- INST(Vpmaddubsw , VexRvm_Lx , V(660F38,04,_,x,I,I,4,FVM), 0 , 109, 0 , 8105 , 292, 149), // #1272
- INST(Vpmaddwd , VexRvm_Lx , V(660F00,F5,_,x,I,I,4,FVM), 0 , 184, 0 , 8116 , 292, 149), // #1273
- INST(Vpmaskmovd , VexRvmMvr_Lx , V(660F38,8C,_,x,0,_,_,_ ), V(660F38,8E,_,x,0,_,_,_ ), 97 , 119, 8125 , 300, 132), // #1274
- INST(Vpmaskmovq , VexRvmMvr_Lx , V(660F38,8C,_,x,1,_,_,_ ), V(660F38,8E,_,x,1,_,_,_ ), 165, 120, 8136 , 300, 132), // #1275
- INST(Vpmaxsb , VexRvm_Lx , V(660F38,3C,_,x,I,I,4,FVM), 0 , 109, 0 , 8147 , 362, 149), // #1276
- INST(Vpmaxsd , VexRvm_Lx , V(660F38,3D,_,x,I,0,4,FV ), 0 , 163, 0 , 8155 , 209, 133), // #1277
- INST(Vpmaxsq , VexRvm_Lx , E(660F38,3D,_,x,_,1,4,FV ), 0 , 112, 0 , 8163 , 210, 129), // #1278
- INST(Vpmaxsw , VexRvm_Lx , V(660F00,EE,_,x,I,I,4,FVM), 0 , 184, 0 , 8171 , 362, 149), // #1279
- INST(Vpmaxub , VexRvm_Lx , V(660F00,DE,_,x,I,I,4,FVM), 0 , 184, 0 , 8179 , 362, 149), // #1280
- INST(Vpmaxud , VexRvm_Lx , V(660F38,3F,_,x,I,0,4,FV ), 0 , 163, 0 , 8187 , 209, 133), // #1281
- INST(Vpmaxuq , VexRvm_Lx , E(660F38,3F,_,x,_,1,4,FV ), 0 , 112, 0 , 8195 , 210, 129), // #1282
- INST(Vpmaxuw , VexRvm_Lx , V(660F38,3E,_,x,I,I,4,FVM), 0 , 109, 0 , 8203 , 362, 149), // #1283
- INST(Vpminsb , VexRvm_Lx , V(660F38,38,_,x,I,I,4,FVM), 0 , 109, 0 , 8211 , 362, 149), // #1284
- INST(Vpminsd , VexRvm_Lx , V(660F38,39,_,x,I,0,4,FV ), 0 , 163, 0 , 8219 , 209, 133), // #1285
- INST(Vpminsq , VexRvm_Lx , E(660F38,39,_,x,_,1,4,FV ), 0 , 112, 0 , 8227 , 210, 129), // #1286
- INST(Vpminsw , VexRvm_Lx , V(660F00,EA,_,x,I,I,4,FVM), 0 , 184, 0 , 8235 , 362, 149), // #1287
- INST(Vpminub , VexRvm_Lx , V(660F00,DA,_,x,I,_,4,FVM), 0 , 184, 0 , 8243 , 362, 149), // #1288
- INST(Vpminud , VexRvm_Lx , V(660F38,3B,_,x,I,0,4,FV ), 0 , 163, 0 , 8251 , 209, 133), // #1289
- INST(Vpminuq , VexRvm_Lx , E(660F38,3B,_,x,_,1,4,FV ), 0 , 112, 0 , 8259 , 210, 129), // #1290
- INST(Vpminuw , VexRvm_Lx , V(660F38,3A,_,x,I,_,4,FVM), 0 , 109, 0 , 8267 , 362, 149), // #1291
- INST(Vpmovb2m , VexRm_Lx , E(F30F38,29,_,x,_,0,_,_ ), 0 , 193, 0 , 8275 , 363, 137), // #1292
- INST(Vpmovd2m , VexRm_Lx , E(F30F38,39,_,x,_,0,_,_ ), 0 , 193, 0 , 8284 , 363, 131), // #1293
- INST(Vpmovdb , VexMr_Lx , E(F30F38,31,_,x,_,0,2,QVM), 0 , 206, 0 , 8293 , 364, 129), // #1294
- INST(Vpmovdw , VexMr_Lx , E(F30F38,33,_,x,_,0,3,HVM), 0 , 207, 0 , 8301 , 365, 129), // #1295
- INST(Vpmovm2b , VexRm_Lx , E(F30F38,28,_,x,_,0,_,_ ), 0 , 193, 0 , 8309 , 332, 137), // #1296
- INST(Vpmovm2d , VexRm_Lx , E(F30F38,38,_,x,_,0,_,_ ), 0 , 193, 0 , 8318 , 332, 131), // #1297
- INST(Vpmovm2q , VexRm_Lx , E(F30F38,38,_,x,_,1,_,_ ), 0 , 192, 0 , 8327 , 332, 131), // #1298
- INST(Vpmovm2w , VexRm_Lx , E(F30F38,28,_,x,_,1,_,_ ), 0 , 192, 0 , 8336 , 332, 137), // #1299
- INST(Vpmovmskb , VexRm_Lx , V(660F00,D7,_,x,I,_,_,_ ), 0 , 70 , 0 , 8345 , 312, 146), // #1300
- INST(Vpmovq2m , VexRm_Lx , E(F30F38,39,_,x,_,1,_,_ ), 0 , 192, 0 , 8355 , 363, 131), // #1301
- INST(Vpmovqb , VexMr_Lx , E(F30F38,32,_,x,_,0,1,OVM), 0 , 208, 0 , 8364 , 366, 129), // #1302
- INST(Vpmovqd , VexMr_Lx , E(F30F38,35,_,x,_,0,3,HVM), 0 , 207, 0 , 8372 , 365, 129), // #1303
- INST(Vpmovqw , VexMr_Lx , E(F30F38,34,_,x,_,0,2,QVM), 0 , 206, 0 , 8380 , 364, 129), // #1304
- INST(Vpmovsdb , VexMr_Lx , E(F30F38,21,_,x,_,0,2,QVM), 0 , 206, 0 , 8388 , 364, 129), // #1305
- INST(Vpmovsdw , VexMr_Lx , E(F30F38,23,_,x,_,0,3,HVM), 0 , 207, 0 , 8397 , 365, 129), // #1306
- INST(Vpmovsqb , VexMr_Lx , E(F30F38,22,_,x,_,0,1,OVM), 0 , 208, 0 , 8406 , 366, 129), // #1307
- INST(Vpmovsqd , VexMr_Lx , E(F30F38,25,_,x,_,0,3,HVM), 0 , 207, 0 , 8415 , 365, 129), // #1308
- INST(Vpmovsqw , VexMr_Lx , E(F30F38,24,_,x,_,0,2,QVM), 0 , 206, 0 , 8424 , 364, 129), // #1309
- INST(Vpmovswb , VexMr_Lx , E(F30F38,20,_,x,_,0,3,HVM), 0 , 207, 0 , 8433 , 365, 137), // #1310
- INST(Vpmovsxbd , VexRm_Lx , V(660F38,21,_,x,I,I,2,QVM), 0 , 209, 0 , 8442 , 367, 133), // #1311
- INST(Vpmovsxbq , VexRm_Lx , V(660F38,22,_,x,I,I,1,OVM), 0 , 210, 0 , 8452 , 368, 133), // #1312
- INST(Vpmovsxbw , VexRm_Lx , V(660F38,20,_,x,I,I,3,HVM), 0 , 132, 0 , 8462 , 369, 149), // #1313
- INST(Vpmovsxdq , VexRm_Lx , V(660F38,25,_,x,I,0,3,HVM), 0 , 132, 0 , 8472 , 369, 133), // #1314
- INST(Vpmovsxwd , VexRm_Lx , V(660F38,23,_,x,I,I,3,HVM), 0 , 132, 0 , 8482 , 369, 133), // #1315
- INST(Vpmovsxwq , VexRm_Lx , V(660F38,24,_,x,I,I,2,QVM), 0 , 209, 0 , 8492 , 367, 133), // #1316
- INST(Vpmovusdb , VexMr_Lx , E(F30F38,11,_,x,_,0,2,QVM), 0 , 206, 0 , 8502 , 364, 129), // #1317
- INST(Vpmovusdw , VexMr_Lx , E(F30F38,13,_,x,_,0,3,HVM), 0 , 207, 0 , 8512 , 365, 129), // #1318
- INST(Vpmovusqb , VexMr_Lx , E(F30F38,12,_,x,_,0,1,OVM), 0 , 208, 0 , 8522 , 366, 129), // #1319
- INST(Vpmovusqd , VexMr_Lx , E(F30F38,15,_,x,_,0,3,HVM), 0 , 207, 0 , 8532 , 365, 129), // #1320
- INST(Vpmovusqw , VexMr_Lx , E(F30F38,14,_,x,_,0,2,QVM), 0 , 206, 0 , 8542 , 364, 129), // #1321
- INST(Vpmovuswb , VexMr_Lx , E(F30F38,10,_,x,_,0,3,HVM), 0 , 207, 0 , 8552 , 365, 137), // #1322
- INST(Vpmovw2m , VexRm_Lx , E(F30F38,29,_,x,_,1,_,_ ), 0 , 192, 0 , 8562 , 363, 137), // #1323
- INST(Vpmovwb , VexMr_Lx , E(F30F38,30,_,x,_,0,3,HVM), 0 , 207, 0 , 8571 , 365, 137), // #1324
- INST(Vpmovzxbd , VexRm_Lx , V(660F38,31,_,x,I,I,2,QVM), 0 , 209, 0 , 8579 , 367, 133), // #1325
- INST(Vpmovzxbq , VexRm_Lx , V(660F38,32,_,x,I,I,1,OVM), 0 , 210, 0 , 8589 , 368, 133), // #1326
- INST(Vpmovzxbw , VexRm_Lx , V(660F38,30,_,x,I,I,3,HVM), 0 , 132, 0 , 8599 , 369, 149), // #1327
- INST(Vpmovzxdq , VexRm_Lx , V(660F38,35,_,x,I,0,3,HVM), 0 , 132, 0 , 8609 , 369, 133), // #1328
- INST(Vpmovzxwd , VexRm_Lx , V(660F38,33,_,x,I,I,3,HVM), 0 , 132, 0 , 8619 , 369, 133), // #1329
- INST(Vpmovzxwq , VexRm_Lx , V(660F38,34,_,x,I,I,2,QVM), 0 , 209, 0 , 8629 , 367, 133), // #1330
- INST(Vpmuldq , VexRvm_Lx , V(660F38,28,_,x,I,1,4,FV ), 0 , 200, 0 , 8639 , 206, 133), // #1331
- INST(Vpmulhrsw , VexRvm_Lx , V(660F38,0B,_,x,I,I,4,FVM), 0 , 109, 0 , 8647 , 292, 149), // #1332
- INST(Vpmulhuw , VexRvm_Lx , V(660F00,E4,_,x,I,I,4,FVM), 0 , 184, 0 , 8657 , 292, 149), // #1333
- INST(Vpmulhw , VexRvm_Lx , V(660F00,E5,_,x,I,I,4,FVM), 0 , 184, 0 , 8666 , 292, 149), // #1334
- INST(Vpmulld , VexRvm_Lx , V(660F38,40,_,x,I,0,4,FV ), 0 , 163, 0 , 8674 , 207, 133), // #1335
- INST(Vpmullq , VexRvm_Lx , E(660F38,40,_,x,_,1,4,FV ), 0 , 112, 0 , 8682 , 210, 131), // #1336
- INST(Vpmullw , VexRvm_Lx , V(660F00,D5,_,x,I,I,4,FVM), 0 , 184, 0 , 8690 , 292, 149), // #1337
- INST(Vpmultishiftqb , VexRvm_Lx , E(660F38,83,_,x,_,1,4,FV ), 0 , 112, 0 , 8698 , 210, 156), // #1338
- INST(Vpmuludq , VexRvm_Lx , V(660F00,F4,_,x,I,1,4,FV ), 0 , 104, 0 , 8713 , 206, 133), // #1339
- INST(Vpopcntb , VexRm_Lx , E(660F38,54,_,x,_,0,4,FV ), 0 , 113, 0 , 8722 , 261, 160), // #1340
- INST(Vpopcntd , VexRm_Lx , E(660F38,55,_,x,_,0,4,FVM), 0 , 189, 0 , 8731 , 346, 161), // #1341
- INST(Vpopcntq , VexRm_Lx , E(660F38,55,_,x,_,1,4,FVM), 0 , 190, 0 , 8740 , 360, 161), // #1342
- INST(Vpopcntw , VexRm_Lx , E(660F38,54,_,x,_,1,4,FV ), 0 , 112, 0 , 8749 , 261, 160), // #1343
- INST(Vpor , VexRvm_Lx , V(660F00,EB,_,x,I,_,_,_ ), 0 , 70 , 0 , 8758 , 323, 146), // #1344
- INST(Vpord , VexRvm_Lx , E(660F00,EB,_,x,_,0,4,FV ), 0 , 188, 0 , 8763 , 324, 129), // #1345
- INST(Vporq , VexRvm_Lx , E(660F00,EB,_,x,_,1,4,FV ), 0 , 130, 0 , 8769 , 328, 129), // #1346
- INST(Vpperm , VexRvrmRvmr , V(XOP_M8,A3,_,0,x,_,_,_ ), 0 , 195, 0 , 8775 , 370, 142), // #1347
- INST(Vprold , VexVmi_Lx , E(660F00,72,1,x,_,0,4,FV ), 0 , 211, 0 , 8782 , 371, 129), // #1348
- INST(Vprolq , VexVmi_Lx , E(660F00,72,1,x,_,1,4,FV ), 0 , 212, 0 , 8789 , 372, 129), // #1349
- INST(Vprolvd , VexRvm_Lx , E(660F38,15,_,x,_,0,4,FV ), 0 , 113, 0 , 8796 , 211, 129), // #1350
- INST(Vprolvq , VexRvm_Lx , E(660F38,15,_,x,_,1,4,FV ), 0 , 112, 0 , 8804 , 210, 129), // #1351
- INST(Vprord , VexVmi_Lx , E(660F00,72,0,x,_,0,4,FV ), 0 , 188, 0 , 8812 , 371, 129), // #1352
- INST(Vprorq , VexVmi_Lx , E(660F00,72,0,x,_,1,4,FV ), 0 , 130, 0 , 8819 , 372, 129), // #1353
- INST(Vprorvd , VexRvm_Lx , E(660F38,14,_,x,_,0,4,FV ), 0 , 113, 0 , 8826 , 211, 129), // #1354
- INST(Vprorvq , VexRvm_Lx , E(660F38,14,_,x,_,1,4,FV ), 0 , 112, 0 , 8834 , 210, 129), // #1355
- INST(Vprotb , VexRvmRmvRmi , V(XOP_M9,90,_,0,x,_,_,_ ), V(XOP_M8,C0,_,0,x,_,_,_ ), 80 , 121, 8842 , 373, 142), // #1356
- INST(Vprotd , VexRvmRmvRmi , V(XOP_M9,92,_,0,x,_,_,_ ), V(XOP_M8,C2,_,0,x,_,_,_ ), 80 , 122, 8849 , 373, 142), // #1357
- INST(Vprotq , VexRvmRmvRmi , V(XOP_M9,93,_,0,x,_,_,_ ), V(XOP_M8,C3,_,0,x,_,_,_ ), 80 , 123, 8856 , 373, 142), // #1358
- INST(Vprotw , VexRvmRmvRmi , V(XOP_M9,91,_,0,x,_,_,_ ), V(XOP_M8,C1,_,0,x,_,_,_ ), 80 , 124, 8863 , 373, 142), // #1359
- INST(Vpsadbw , VexRvm_Lx , V(660F00,F6,_,x,I,I,4,FVM), 0 , 184, 0 , 8870 , 201, 149), // #1360
- INST(Vpscatterdd , VexMr_VM , E(660F38,A0,_,x,_,0,2,T1S), 0 , 125, 0 , 8878 , 374, 129), // #1361
- INST(Vpscatterdq , VexMr_VM , E(660F38,A0,_,x,_,1,3,T1S), 0 , 124, 0 , 8890 , 375, 129), // #1362
- INST(Vpscatterqd , VexMr_VM , E(660F38,A1,_,x,_,0,2,T1S), 0 , 125, 0 , 8902 , 376, 129), // #1363
- INST(Vpscatterqq , VexMr_VM , E(660F38,A1,_,x,_,1,3,T1S), 0 , 124, 0 , 8914 , 377, 129), // #1364
- INST(Vpshab , VexRvmRmv , V(XOP_M9,98,_,0,x,_,_,_ ), 0 , 80 , 0 , 8926 , 378, 142), // #1365
- INST(Vpshad , VexRvmRmv , V(XOP_M9,9A,_,0,x,_,_,_ ), 0 , 80 , 0 , 8933 , 378, 142), // #1366
- INST(Vpshaq , VexRvmRmv , V(XOP_M9,9B,_,0,x,_,_,_ ), 0 , 80 , 0 , 8940 , 378, 142), // #1367
- INST(Vpshaw , VexRvmRmv , V(XOP_M9,99,_,0,x,_,_,_ ), 0 , 80 , 0 , 8947 , 378, 142), // #1368
- INST(Vpshlb , VexRvmRmv , V(XOP_M9,94,_,0,x,_,_,_ ), 0 , 80 , 0 , 8954 , 378, 142), // #1369
- INST(Vpshld , VexRvmRmv , V(XOP_M9,96,_,0,x,_,_,_ ), 0 , 80 , 0 , 8961 , 378, 142), // #1370
- INST(Vpshldd , VexRvmi_Lx , E(660F3A,71,_,x,_,0,4,FV ), 0 , 110, 0 , 8968 , 204, 154), // #1371
- INST(Vpshldq , VexRvmi_Lx , E(660F3A,71,_,x,_,1,4,FV ), 0 , 111, 0 , 8976 , 205, 154), // #1372
- INST(Vpshldvd , VexRvm_Lx , E(660F38,71,_,x,_,0,4,FV ), 0 , 113, 0 , 8984 , 211, 154), // #1373
- INST(Vpshldvq , VexRvm_Lx , E(660F38,71,_,x,_,1,4,FV ), 0 , 112, 0 , 8993 , 210, 154), // #1374
- INST(Vpshldvw , VexRvm_Lx , E(660F38,70,_,x,_,1,4,FVM), 0 , 190, 0 , 9002 , 329, 154), // #1375
- INST(Vpshldw , VexRvmi_Lx , E(660F3A,70,_,x,_,1,4,FVM), 0 , 197, 0 , 9011 , 257, 154), // #1376
- INST(Vpshlq , VexRvmRmv , V(XOP_M9,97,_,0,x,_,_,_ ), 0 , 80 , 0 , 9019 , 378, 142), // #1377
- INST(Vpshlw , VexRvmRmv , V(XOP_M9,95,_,0,x,_,_,_ ), 0 , 80 , 0 , 9026 , 378, 142), // #1378
- INST(Vpshrdd , VexRvmi_Lx , E(660F3A,73,_,x,_,0,4,FV ), 0 , 110, 0 , 9033 , 204, 154), // #1379
- INST(Vpshrdq , VexRvmi_Lx , E(660F3A,73,_,x,_,1,4,FV ), 0 , 111, 0 , 9041 , 205, 154), // #1380
- INST(Vpshrdvd , VexRvm_Lx , E(660F38,73,_,x,_,0,4,FV ), 0 , 113, 0 , 9049 , 211, 154), // #1381
- INST(Vpshrdvq , VexRvm_Lx , E(660F38,73,_,x,_,1,4,FV ), 0 , 112, 0 , 9058 , 210, 154), // #1382
- INST(Vpshrdvw , VexRvm_Lx , E(660F38,72,_,x,_,1,4,FVM), 0 , 190, 0 , 9067 , 329, 154), // #1383
- INST(Vpshrdw , VexRvmi_Lx , E(660F3A,72,_,x,_,1,4,FVM), 0 , 197, 0 , 9076 , 257, 154), // #1384
- INST(Vpshufb , VexRvm_Lx , V(660F38,00,_,x,I,I,4,FVM), 0 , 109, 0 , 9084 , 292, 149), // #1385
- INST(Vpshufbitqmb , VexRvm_Lx , E(660F38,8F,_,x,0,0,4,FVM), 0 , 189, 0 , 9092 , 379, 160), // #1386
- INST(Vpshufd , VexRmi_Lx , V(660F00,70,_,x,I,0,4,FV ), 0 , 133, 0 , 9105 , 380, 133), // #1387
- INST(Vpshufhw , VexRmi_Lx , V(F30F00,70,_,x,I,I,4,FVM), 0 , 185, 0 , 9113 , 381, 149), // #1388
- INST(Vpshuflw , VexRmi_Lx , V(F20F00,70,_,x,I,I,4,FVM), 0 , 213, 0 , 9122 , 381, 149), // #1389
- INST(Vpsignb , VexRvm_Lx , V(660F38,08,_,x,I,_,_,_ ), 0 , 97 , 0 , 9131 , 200, 146), // #1390
- INST(Vpsignd , VexRvm_Lx , V(660F38,0A,_,x,I,_,_,_ ), 0 , 97 , 0 , 9139 , 200, 146), // #1391
- INST(Vpsignw , VexRvm_Lx , V(660F38,09,_,x,I,_,_,_ ), 0 , 97 , 0 , 9147 , 200, 146), // #1392
- INST(Vpslld , VexRvmVmi_Lx_MEvex , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 214, 125, 9155 , 382, 133), // #1393
- INST(Vpslldq , VexVmi_Lx_MEvex , V(660F00,73,7,x,I,I,4,FVM), 0 , 215, 0 , 9162 , 383, 149), // #1394
- INST(Vpsllq , VexRvmVmi_Lx_MEvex , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 216, 126, 9170 , 384, 133), // #1395
- INST(Vpsllvd , VexRvm_Lx , V(660F38,47,_,x,0,0,4,FV ), 0 , 163, 0 , 9177 , 207, 143), // #1396
- INST(Vpsllvq , VexRvm_Lx , V(660F38,47,_,x,1,1,4,FV ), 0 , 162, 0 , 9185 , 206, 143), // #1397
- INST(Vpsllvw , VexRvm_Lx , E(660F38,12,_,x,_,1,4,FVM), 0 , 190, 0 , 9193 , 329, 137), // #1398
- INST(Vpsllw , VexRvmVmi_Lx_MEvex , V(660F00,F1,_,x,I,I,4,128), V(660F00,71,6,x,I,I,4,FVM), 214, 127, 9201 , 385, 149), // #1399
- INST(Vpsrad , VexRvmVmi_Lx_MEvex , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 214, 128, 9208 , 382, 133), // #1400
- INST(Vpsraq , VexRvmVmi_Lx_MEvex , E(660F00,E2,_,x,_,1,4,128), E(660F00,72,4,x,_,1,4,FV ), 217, 129, 9215 , 386, 129), // #1401
- INST(Vpsravd , VexRvm_Lx , V(660F38,46,_,x,0,0,4,FV ), 0 , 163, 0 , 9222 , 207, 143), // #1402
- INST(Vpsravq , VexRvm_Lx , E(660F38,46,_,x,_,1,4,FV ), 0 , 112, 0 , 9230 , 210, 129), // #1403
- INST(Vpsravw , VexRvm_Lx , E(660F38,11,_,x,_,1,4,FVM), 0 , 190, 0 , 9238 , 329, 137), // #1404
- INST(Vpsraw , VexRvmVmi_Lx_MEvex , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 214, 130, 9246 , 385, 149), // #1405
- INST(Vpsrld , VexRvmVmi_Lx_MEvex , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 214, 131, 9253 , 382, 133), // #1406
- INST(Vpsrldq , VexVmi_Lx_MEvex , V(660F00,73,3,x,I,I,4,FVM), 0 , 218, 0 , 9260 , 383, 149), // #1407
- INST(Vpsrlq , VexRvmVmi_Lx_MEvex , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 216, 132, 9268 , 384, 133), // #1408
- INST(Vpsrlvd , VexRvm_Lx , V(660F38,45,_,x,0,0,4,FV ), 0 , 163, 0 , 9275 , 207, 143), // #1409
- INST(Vpsrlvq , VexRvm_Lx , V(660F38,45,_,x,1,1,4,FV ), 0 , 162, 0 , 9283 , 206, 143), // #1410
- INST(Vpsrlvw , VexRvm_Lx , E(660F38,10,_,x,_,1,4,FVM), 0 , 190, 0 , 9291 , 329, 137), // #1411
- INST(Vpsrlw , VexRvmVmi_Lx_MEvex , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 214, 133, 9299 , 385, 149), // #1412
- INST(Vpsubb , VexRvm_Lx , V(660F00,F8,_,x,I,I,4,FVM), 0 , 184, 0 , 9306 , 387, 149), // #1413
- INST(Vpsubd , VexRvm_Lx , V(660F00,FA,_,x,I,0,4,FV ), 0 , 133, 0 , 9313 , 388, 133), // #1414
- INST(Vpsubq , VexRvm_Lx , V(660F00,FB,_,x,I,1,4,FV ), 0 , 104, 0 , 9320 , 389, 133), // #1415
- INST(Vpsubsb , VexRvm_Lx , V(660F00,E8,_,x,I,I,4,FVM), 0 , 184, 0 , 9327 , 387, 149), // #1416
- INST(Vpsubsw , VexRvm_Lx , V(660F00,E9,_,x,I,I,4,FVM), 0 , 184, 0 , 9335 , 387, 149), // #1417
- INST(Vpsubusb , VexRvm_Lx , V(660F00,D8,_,x,I,I,4,FVM), 0 , 184, 0 , 9343 , 387, 149), // #1418
- INST(Vpsubusw , VexRvm_Lx , V(660F00,D9,_,x,I,I,4,FVM), 0 , 184, 0 , 9352 , 387, 149), // #1419
- INST(Vpsubw , VexRvm_Lx , V(660F00,F9,_,x,I,I,4,FVM), 0 , 184, 0 , 9361 , 387, 149), // #1420
- INST(Vpternlogd , VexRvmi_Lx , E(660F3A,25,_,x,_,0,4,FV ), 0 , 110, 0 , 9368 , 204, 129), // #1421
- INST(Vpternlogq , VexRvmi_Lx , E(660F3A,25,_,x,_,1,4,FV ), 0 , 111, 0 , 9379 , 205, 129), // #1422
- INST(Vptest , VexRm_Lx , V(660F38,17,_,x,I,_,_,_ ), 0 , 97 , 0 , 9390 , 277, 153), // #1423
- INST(Vptestmb , VexRvm_Lx , E(660F38,26,_,x,_,0,4,FVM), 0 , 189, 0 , 9397 , 379, 137), // #1424
- INST(Vptestmd , VexRvm_Lx , E(660F38,27,_,x,_,0,4,FV ), 0 , 113, 0 , 9406 , 390, 129), // #1425
- INST(Vptestmq , VexRvm_Lx , E(660F38,27,_,x,_,1,4,FV ), 0 , 112, 0 , 9415 , 391, 129), // #1426
- INST(Vptestmw , VexRvm_Lx , E(660F38,26,_,x,_,1,4,FVM), 0 , 190, 0 , 9424 , 379, 137), // #1427
- INST(Vptestnmb , VexRvm_Lx , E(F30F38,26,_,x,_,0,4,FVM), 0 , 219, 0 , 9433 , 379, 137), // #1428
- INST(Vptestnmd , VexRvm_Lx , E(F30F38,27,_,x,_,0,4,FV ), 0 , 128, 0 , 9443 , 390, 129), // #1429
- INST(Vptestnmq , VexRvm_Lx , E(F30F38,27,_,x,_,1,4,FV ), 0 , 220, 0 , 9453 , 391, 129), // #1430
- INST(Vptestnmw , VexRvm_Lx , E(F30F38,26,_,x,_,1,4,FVM), 0 , 221, 0 , 9463 , 379, 137), // #1431
- INST(Vpunpckhbw , VexRvm_Lx , V(660F00,68,_,x,I,I,4,FVM), 0 , 184, 0 , 9473 , 292, 149), // #1432
- INST(Vpunpckhdq , VexRvm_Lx , V(660F00,6A,_,x,I,0,4,FV ), 0 , 133, 0 , 9484 , 207, 133), // #1433
- INST(Vpunpckhqdq , VexRvm_Lx , V(660F00,6D,_,x,I,1,4,FV ), 0 , 104, 0 , 9495 , 206, 133), // #1434
- INST(Vpunpckhwd , VexRvm_Lx , V(660F00,69,_,x,I,I,4,FVM), 0 , 184, 0 , 9507 , 292, 149), // #1435
- INST(Vpunpcklbw , VexRvm_Lx , V(660F00,60,_,x,I,I,4,FVM), 0 , 184, 0 , 9518 , 292, 149), // #1436
- INST(Vpunpckldq , VexRvm_Lx , V(660F00,62,_,x,I,0,4,FV ), 0 , 133, 0 , 9529 , 207, 133), // #1437
- INST(Vpunpcklqdq , VexRvm_Lx , V(660F00,6C,_,x,I,1,4,FV ), 0 , 104, 0 , 9540 , 206, 133), // #1438
- INST(Vpunpcklwd , VexRvm_Lx , V(660F00,61,_,x,I,I,4,FVM), 0 , 184, 0 , 9552 , 292, 149), // #1439
- INST(Vpxor , VexRvm_Lx , V(660F00,EF,_,x,I,_,_,_ ), 0 , 70 , 0 , 9563 , 325, 146), // #1440
- INST(Vpxord , VexRvm_Lx , E(660F00,EF,_,x,_,0,4,FV ), 0 , 188, 0 , 9569 , 326, 129), // #1441
- INST(Vpxorq , VexRvm_Lx , E(660F00,EF,_,x,_,1,4,FV ), 0 , 130, 0 , 9576 , 327, 129), // #1442
- INST(Vrangepd , VexRvmi_Lx , E(660F3A,50,_,x,_,1,4,FV ), 0 , 111, 0 , 9583 , 266, 131), // #1443
- INST(Vrangeps , VexRvmi_Lx , E(660F3A,50,_,x,_,0,4,FV ), 0 , 110, 0 , 9592 , 267, 131), // #1444
- INST(Vrangesd , VexRvmi , E(660F3A,51,_,I,_,1,3,T1S), 0 , 160, 0 , 9601 , 268, 66 ), // #1445
- INST(Vrangess , VexRvmi , E(660F3A,51,_,I,_,0,2,T1S), 0 , 161, 0 , 9610 , 269, 66 ), // #1446
- INST(Vrcp14pd , VexRm_Lx , E(660F38,4C,_,x,_,1,4,FV ), 0 , 112, 0 , 9619 , 360, 129), // #1447
- INST(Vrcp14ps , VexRm_Lx , E(660F38,4C,_,x,_,0,4,FV ), 0 , 113, 0 , 9628 , 346, 129), // #1448
- INST(Vrcp14sd , VexRvm , E(660F38,4D,_,I,_,1,3,T1S), 0 , 124, 0 , 9637 , 392, 68 ), // #1449
- INST(Vrcp14ss , VexRvm , E(660F38,4D,_,I,_,0,2,T1S), 0 , 125, 0 , 9646 , 393, 68 ), // #1450
- INST(Vrcp28pd , VexRm , E(660F38,CA,_,2,_,1,4,FV ), 0 , 152, 0 , 9655 , 259, 138), // #1451
- INST(Vrcp28ps , VexRm , E(660F38,CA,_,2,_,0,4,FV ), 0 , 153, 0 , 9664 , 260, 138), // #1452
- INST(Vrcp28sd , VexRvm , E(660F38,CB,_,I,_,1,3,T1S), 0 , 124, 0 , 9673 , 287, 138), // #1453
- INST(Vrcp28ss , VexRvm , E(660F38,CB,_,I,_,0,2,T1S), 0 , 125, 0 , 9682 , 288, 138), // #1454
- INST(Vrcpps , VexRm_Lx , V(000F00,53,_,x,I,_,_,_ ), 0 , 73 , 0 , 9691 , 277, 126), // #1455
- INST(Vrcpss , VexRvm , V(F30F00,53,_,I,I,_,_,_ ), 0 , 178, 0 , 9698 , 394, 126), // #1456
- INST(Vreducepd , VexRmi_Lx , E(660F3A,56,_,x,_,1,4,FV ), 0 , 111, 0 , 9705 , 372, 131), // #1457
- INST(Vreduceps , VexRmi_Lx , E(660F3A,56,_,x,_,0,4,FV ), 0 , 110, 0 , 9715 , 371, 131), // #1458
- INST(Vreducesd , VexRvmi , E(660F3A,57,_,I,_,1,3,T1S), 0 , 160, 0 , 9725 , 395, 66 ), // #1459
- INST(Vreducess , VexRvmi , E(660F3A,57,_,I,_,0,2,T1S), 0 , 161, 0 , 9735 , 396, 66 ), // #1460
- INST(Vrndscalepd , VexRmi_Lx , E(660F3A,09,_,x,_,1,4,FV ), 0 , 111, 0 , 9745 , 289, 129), // #1461
- INST(Vrndscaleps , VexRmi_Lx , E(660F3A,08,_,x,_,0,4,FV ), 0 , 110, 0 , 9757 , 290, 129), // #1462
- INST(Vrndscalesd , VexRvmi , E(660F3A,0B,_,I,_,1,3,T1S), 0 , 160, 0 , 9769 , 268, 68 ), // #1463
- INST(Vrndscaless , VexRvmi , E(660F3A,0A,_,I,_,0,2,T1S), 0 , 161, 0 , 9781 , 269, 68 ), // #1464
- INST(Vroundpd , VexRmi_Lx , V(660F3A,09,_,x,I,_,_,_ ), 0 , 74 , 0 , 9793 , 397, 126), // #1465
- INST(Vroundps , VexRmi_Lx , V(660F3A,08,_,x,I,_,_,_ ), 0 , 74 , 0 , 9802 , 397, 126), // #1466
- INST(Vroundsd , VexRvmi , V(660F3A,0B,_,I,I,_,_,_ ), 0 , 74 , 0 , 9811 , 398, 126), // #1467
- INST(Vroundss , VexRvmi , V(660F3A,0A,_,I,I,_,_,_ ), 0 , 74 , 0 , 9820 , 399, 126), // #1468
- INST(Vrsqrt14pd , VexRm_Lx , E(660F38,4E,_,x,_,1,4,FV ), 0 , 112, 0 , 9829 , 360, 129), // #1469
- INST(Vrsqrt14ps , VexRm_Lx , E(660F38,4E,_,x,_,0,4,FV ), 0 , 113, 0 , 9840 , 346, 129), // #1470
- INST(Vrsqrt14sd , VexRvm , E(660F38,4F,_,I,_,1,3,T1S), 0 , 124, 0 , 9851 , 392, 68 ), // #1471
- INST(Vrsqrt14ss , VexRvm , E(660F38,4F,_,I,_,0,2,T1S), 0 , 125, 0 , 9862 , 393, 68 ), // #1472
- INST(Vrsqrt28pd , VexRm , E(660F38,CC,_,2,_,1,4,FV ), 0 , 152, 0 , 9873 , 259, 138), // #1473
- INST(Vrsqrt28ps , VexRm , E(660F38,CC,_,2,_,0,4,FV ), 0 , 153, 0 , 9884 , 260, 138), // #1474
- INST(Vrsqrt28sd , VexRvm , E(660F38,CD,_,I,_,1,3,T1S), 0 , 124, 0 , 9895 , 287, 138), // #1475
- INST(Vrsqrt28ss , VexRvm , E(660F38,CD,_,I,_,0,2,T1S), 0 , 125, 0 , 9906 , 288, 138), // #1476
- INST(Vrsqrtps , VexRm_Lx , V(000F00,52,_,x,I,_,_,_ ), 0 , 73 , 0 , 9917 , 277, 126), // #1477
- INST(Vrsqrtss , VexRvm , V(F30F00,52,_,I,I,_,_,_ ), 0 , 178, 0 , 9926 , 394, 126), // #1478
- INST(Vscalefpd , VexRvm_Lx , E(660F38,2C,_,x,_,1,4,FV ), 0 , 112, 0 , 9935 , 400, 129), // #1479
- INST(Vscalefps , VexRvm_Lx , E(660F38,2C,_,x,_,0,4,FV ), 0 , 113, 0 , 9945 , 401, 129), // #1480
- INST(Vscalefsd , VexRvm , E(660F38,2D,_,I,_,1,3,T1S), 0 , 124, 0 , 9955 , 402, 68 ), // #1481
- INST(Vscalefss , VexRvm , E(660F38,2D,_,I,_,0,2,T1S), 0 , 125, 0 , 9965 , 403, 68 ), // #1482
- INST(Vscatterdpd , VexMr_VM , E(660F38,A2,_,x,_,1,3,T1S), 0 , 124, 0 , 9975 , 375, 129), // #1483
- INST(Vscatterdps , VexMr_VM , E(660F38,A2,_,x,_,0,2,T1S), 0 , 125, 0 , 9987 , 374, 129), // #1484
- INST(Vscatterpf0dpd , VexM_VM , E(660F38,C6,5,2,_,1,3,T1S), 0 , 222, 0 , 9999 , 282, 144), // #1485
- INST(Vscatterpf0dps , VexM_VM , E(660F38,C6,5,2,_,0,2,T1S), 0 , 223, 0 , 10014, 283, 144), // #1486
- INST(Vscatterpf0qpd , VexM_VM , E(660F38,C7,5,2,_,1,3,T1S), 0 , 222, 0 , 10029, 284, 144), // #1487
- INST(Vscatterpf0qps , VexM_VM , E(660F38,C7,5,2,_,0,2,T1S), 0 , 223, 0 , 10044, 284, 144), // #1488
- INST(Vscatterpf1dpd , VexM_VM , E(660F38,C6,6,2,_,1,3,T1S), 0 , 224, 0 , 10059, 282, 144), // #1489
- INST(Vscatterpf1dps , VexM_VM , E(660F38,C6,6,2,_,0,2,T1S), 0 , 225, 0 , 10074, 283, 144), // #1490
- INST(Vscatterpf1qpd , VexM_VM , E(660F38,C7,6,2,_,1,3,T1S), 0 , 224, 0 , 10089, 284, 144), // #1491
- INST(Vscatterpf1qps , VexM_VM , E(660F38,C7,6,2,_,0,2,T1S), 0 , 225, 0 , 10104, 284, 144), // #1492
- INST(Vscatterqpd , VexMr_VM , E(660F38,A3,_,x,_,1,3,T1S), 0 , 124, 0 , 10119, 377, 129), // #1493
- INST(Vscatterqps , VexMr_VM , E(660F38,A3,_,x,_,0,2,T1S), 0 , 125, 0 , 10131, 376, 129), // #1494
- INST(Vshuff32x4 , VexRvmi_Lx , E(660F3A,23,_,x,_,0,4,FV ), 0 , 110, 0 , 10143, 404, 129), // #1495
- INST(Vshuff64x2 , VexRvmi_Lx , E(660F3A,23,_,x,_,1,4,FV ), 0 , 111, 0 , 10154, 405, 129), // #1496
- INST(Vshufi32x4 , VexRvmi_Lx , E(660F3A,43,_,x,_,0,4,FV ), 0 , 110, 0 , 10165, 404, 129), // #1497
- INST(Vshufi64x2 , VexRvmi_Lx , E(660F3A,43,_,x,_,1,4,FV ), 0 , 111, 0 , 10176, 405, 129), // #1498
- INST(Vshufpd , VexRvmi_Lx , V(660F00,C6,_,x,I,1,4,FV ), 0 , 104, 0 , 10187, 406, 124), // #1499
- INST(Vshufps , VexRvmi_Lx , V(000F00,C6,_,x,I,0,4,FV ), 0 , 105, 0 , 10195, 407, 124), // #1500
- INST(Vsqrtpd , VexRm_Lx , V(660F00,51,_,x,I,1,4,FV ), 0 , 104, 0 , 10203, 408, 124), // #1501
- INST(Vsqrtps , VexRm_Lx , V(000F00,51,_,x,I,0,4,FV ), 0 , 105, 0 , 10211, 229, 124), // #1502
- INST(Vsqrtsd , VexRvm , V(F20F00,51,_,I,I,1,3,T1S), 0 , 106, 0 , 10219, 198, 125), // #1503
- INST(Vsqrtss , VexRvm , V(F30F00,51,_,I,I,0,2,T1S), 0 , 107, 0 , 10227, 199, 125), // #1504
- INST(Vstmxcsr , VexM , V(000F00,AE,3,0,I,_,_,_ ), 0 , 226, 0 , 10235, 298, 126), // #1505
- INST(Vsubpd , VexRvm_Lx , V(660F00,5C,_,x,I,1,4,FV ), 0 , 104, 0 , 10244, 196, 124), // #1506
- INST(Vsubps , VexRvm_Lx , V(000F00,5C,_,x,I,0,4,FV ), 0 , 105, 0 , 10251, 197, 124), // #1507
- INST(Vsubsd , VexRvm , V(F20F00,5C,_,I,I,1,3,T1S), 0 , 106, 0 , 10258, 198, 125), // #1508
- INST(Vsubss , VexRvm , V(F30F00,5C,_,I,I,0,2,T1S), 0 , 107, 0 , 10265, 199, 125), // #1509
- INST(Vtestpd , VexRm_Lx , V(660F38,0F,_,x,0,_,_,_ ), 0 , 97 , 0 , 10272, 277, 153), // #1510
- INST(Vtestps , VexRm_Lx , V(660F38,0E,_,x,0,_,_,_ ), 0 , 97 , 0 , 10280, 277, 153), // #1511
- INST(Vucomisd , VexRm , V(660F00,2E,_,I,I,1,3,T1S), 0 , 122, 0 , 10288, 225, 134), // #1512
- INST(Vucomiss , VexRm , V(000F00,2E,_,I,I,0,2,T1S), 0 , 123, 0 , 10297, 226, 134), // #1513
- INST(Vunpckhpd , VexRvm_Lx , V(660F00,15,_,x,I,1,4,FV ), 0 , 104, 0 , 10306, 206, 124), // #1514
- INST(Vunpckhps , VexRvm_Lx , V(000F00,15,_,x,I,0,4,FV ), 0 , 105, 0 , 10316, 207, 124), // #1515
- INST(Vunpcklpd , VexRvm_Lx , V(660F00,14,_,x,I,1,4,FV ), 0 , 104, 0 , 10326, 206, 124), // #1516
- INST(Vunpcklps , VexRvm_Lx , V(000F00,14,_,x,I,0,4,FV ), 0 , 105, 0 , 10336, 207, 124), // #1517
- INST(Vxorpd , VexRvm_Lx , V(660F00,57,_,x,I,1,4,FV ), 0 , 104, 0 , 10346, 389, 130), // #1518
- INST(Vxorps , VexRvm_Lx , V(000F00,57,_,x,I,0,4,FV ), 0 , 105, 0 , 10353, 388, 130), // #1519
- INST(Vzeroall , VexOp , V(000F00,77,_,1,I,_,_,_ ), 0 , 69 , 0 , 10360, 409, 126), // #1520
- INST(Vzeroupper , VexOp , V(000F00,77,_,0,I,_,_,_ ), 0 , 73 , 0 , 10369, 409, 126), // #1521
- INST(Wbinvd , X86Op , O(000F00,09,_,_,_,_,_,_ ), 0 , 4 , 0 , 10380, 30 , 0 ), // #1522
- INST(Wbnoinvd , X86Op , O(F30F00,09,_,_,_,_,_,_ ), 0 , 6 , 0 , 10387, 30 , 162), // #1523
- INST(Wrfsbase , X86M , O(F30F00,AE,2,_,x,_,_,_ ), 0 , 227, 0 , 10396, 173, 104), // #1524
- INST(Wrgsbase , X86M , O(F30F00,AE,3,_,x,_,_,_ ), 0 , 228, 0 , 10405, 173, 104), // #1525
- INST(Wrmsr , X86Op , O(000F00,30,_,_,_,_,_,_ ), 0 , 4 , 0 , 10414, 174, 105), // #1526
- INST(Wrssd , X86Mr , O(000F38,F6,_,_,_,_,_,_ ), 0 , 84 , 0 , 10420, 410, 56 ), // #1527
- INST(Wrssq , X86Mr , O(000F38,F6,_,_,1,_,_,_ ), 0 , 229, 0 , 10426, 411, 56 ), // #1528
- INST(Wrussd , X86Mr , O(660F38,F5,_,_,_,_,_,_ ), 0 , 2 , 0 , 10432, 410, 56 ), // #1529
- INST(Wrussq , X86Mr , O(660F38,F5,_,_,1,_,_,_ ), 0 , 230, 0 , 10439, 411, 56 ), // #1530
- INST(Xabort , X86Op_Mod11RM_I8 , O(000000,C6,7,_,_,_,_,_ ), 0 , 27 , 0 , 10446, 80 , 163), // #1531
- INST(Xadd , X86Xadd , O(000F00,C0,_,_,x,_,_,_ ), 0 , 4 , 0 , 10453, 412, 38 ), // #1532
- INST(Xbegin , X86JmpRel , O(000000,C7,7,_,_,_,_,_ ), 0 , 27 , 0 , 10458, 413, 163), // #1533
- INST(Xchg , X86Xchg , O(000000,86,_,_,x,_,_,_ ), 0 , 0 , 0 , 462 , 414, 0 ), // #1534
- INST(Xend , X86Op , O(000F01,D5,_,_,_,_,_,_ ), 0 , 21 , 0 , 10465, 30 , 163), // #1535
- INST(Xgetbv , X86Op , O(000F01,D0,_,_,_,_,_,_ ), 0 , 21 , 0 , 10470, 174, 164), // #1536
- INST(Xlatb , X86Op , O(000000,D7,_,_,_,_,_,_ ), 0 , 0 , 0 , 10477, 30 , 0 ), // #1537
- INST(Xor , X86Arith , O(000000,30,6,_,x,_,_,_ ), 0 , 32 , 0 , 9565 , 179, 1 ), // #1538
- INST(Xorpd , ExtRm , O(660F00,57,_,_,_,_,_,_ ), 0 , 3 , 0 , 10347, 151, 4 ), // #1539
- INST(Xorps , ExtRm , O(000F00,57,_,_,_,_,_,_ ), 0 , 4 , 0 , 10354, 151, 5 ), // #1540
- INST(Xresldtrk , X86Op , O(F20F01,E9,_,_,_,_,_,_ ), 0 , 93 , 0 , 10483, 30 , 165), // #1541
- INST(Xrstor , X86M_Only_EDX_EAX , O(000F00,AE,5,_,_,_,_,_ ), 0 , 78 , 0 , 1164 , 415, 164), // #1542
- INST(Xrstor64 , X86M_Only_EDX_EAX , O(000F00,AE,5,_,1,_,_,_ ), 0 , 231, 0 , 1172 , 416, 164), // #1543
- INST(Xrstors , X86M_Only_EDX_EAX , O(000F00,C7,3,_,_,_,_,_ ), 0 , 79 , 0 , 10493, 415, 166), // #1544
- INST(Xrstors64 , X86M_Only_EDX_EAX , O(000F00,C7,3,_,1,_,_,_ ), 0 , 232, 0 , 10501, 416, 166), // #1545
- INST(Xsave , X86M_Only_EDX_EAX , O(000F00,AE,4,_,_,_,_,_ ), 0 , 98 , 0 , 1182 , 415, 164), // #1546
- INST(Xsave64 , X86M_Only_EDX_EAX , O(000F00,AE,4,_,1,_,_,_ ), 0 , 233, 0 , 1189 , 416, 164), // #1547
- INST(Xsavec , X86M_Only_EDX_EAX , O(000F00,C7,4,_,_,_,_,_ ), 0 , 98 , 0 , 10511, 415, 167), // #1548
- INST(Xsavec64 , X86M_Only_EDX_EAX , O(000F00,C7,4,_,1,_,_,_ ), 0 , 233, 0 , 10518, 416, 167), // #1549
- INST(Xsaveopt , X86M_Only_EDX_EAX , O(000F00,AE,6,_,_,_,_,_ ), 0 , 81 , 0 , 10527, 415, 168), // #1550
- INST(Xsaveopt64 , X86M_Only_EDX_EAX , O(000F00,AE,6,_,1,_,_,_ ), 0 , 234, 0 , 10536, 416, 168), // #1551
- INST(Xsaves , X86M_Only_EDX_EAX , O(000F00,C7,5,_,_,_,_,_ ), 0 , 78 , 0 , 10547, 415, 166), // #1552
- INST(Xsaves64 , X86M_Only_EDX_EAX , O(000F00,C7,5,_,1,_,_,_ ), 0 , 231, 0 , 10554, 416, 166), // #1553
- INST(Xsetbv , X86Op , O(000F01,D1,_,_,_,_,_,_ ), 0 , 21 , 0 , 10563, 174, 164), // #1554
- INST(Xsusldtrk , X86Op , O(F20F01,E8,_,_,_,_,_,_ ), 0 , 93 , 0 , 10570, 30 , 165), // #1555
- INST(Xtest , X86Op , O(000F01,D6,_,_,_,_,_,_ ), 0 , 21 , 0 , 10580, 30 , 169) // #1556
+ INST(Umwait , X86R32_EDX_EAX , O(F20F00,AE,6,_,_,_,_,_ ), 0 , 100, 0 , 3240 , 191, 121), // #793
+ INST(Unpckhpd , ExtRm , O(660F00,15,_,_,_,_,_,_ ), 0 , 3 , 0 , 11417, 5 , 4 ), // #794
+ INST(Unpckhps , ExtRm , O(000F00,15,_,_,_,_,_,_ ), 0 , 4 , 0 , 11427, 5 , 5 ), // #795
+ INST(Unpcklpd , ExtRm , O(660F00,14,_,_,_,_,_,_ ), 0 , 3 , 0 , 11437, 5 , 4 ), // #796
+ INST(Unpcklps , ExtRm , O(000F00,14,_,_,_,_,_,_ ), 0 , 4 , 0 , 11447, 5 , 5 ), // #797
+ INST(V4fmaddps , VexRm_T1_4X , E(F20F38,9A,_,2,_,0,4,T4X), 0 , 101, 0 , 3247 , 194, 123), // #798
+ INST(V4fmaddss , VexRm_T1_4X , E(F20F38,9B,_,0,_,0,4,T4X), 0 , 102, 0 , 3257 , 195, 123), // #799
+ INST(V4fnmaddps , VexRm_T1_4X , E(F20F38,AA,_,2,_,0,4,T4X), 0 , 101, 0 , 3267 , 194, 123), // #800
+ INST(V4fnmaddss , VexRm_T1_4X , E(F20F38,AB,_,0,_,0,4,T4X), 0 , 102, 0 , 3278 , 195, 123), // #801
+ INST(Vaddpd , VexRvm_Lx , V(660F00,58,_,x,I,1,4,FV ), 0 , 103, 0 , 3289 , 196, 124), // #802
+ INST(Vaddph , VexRvm_Lx , E(00MAP5,58,_,_,_,0,4,FV ), 0 , 104, 0 , 3296 , 197, 125), // #803
+ INST(Vaddps , VexRvm_Lx , V(000F00,58,_,x,I,0,4,FV ), 0 , 105, 0 , 3303 , 198, 124), // #804
+ INST(Vaddsd , VexRvm , V(F20F00,58,_,I,I,1,3,T1S), 0 , 106, 0 , 3310 , 199, 126), // #805
+ INST(Vaddsh , VexRvm , E(F3MAP5,58,_,_,_,0,1,T1S), 0 , 107, 0 , 3317 , 200, 127), // #806
+ INST(Vaddss , VexRvm , V(F30F00,58,_,I,I,0,2,T1S), 0 , 108, 0 , 3324 , 201, 126), // #807
+ INST(Vaddsubpd , VexRvm_Lx , V(660F00,D0,_,x,I,_,_,_ ), 0 , 69 , 0 , 3331 , 202, 128), // #808
+ INST(Vaddsubps , VexRvm_Lx , V(F20F00,D0,_,x,I,_,_,_ ), 0 , 109, 0 , 3341 , 202, 128), // #809
+ INST(Vaesdec , VexRvm_Lx , V(660F38,DE,_,x,I,_,4,FVM), 0 , 110, 0 , 3351 , 203, 129), // #810
+ INST(Vaesdeclast , VexRvm_Lx , V(660F38,DF,_,x,I,_,4,FVM), 0 , 110, 0 , 3359 , 203, 129), // #811
+ INST(Vaesenc , VexRvm_Lx , V(660F38,DC,_,x,I,_,4,FVM), 0 , 110, 0 , 3371 , 203, 129), // #812
+ INST(Vaesenclast , VexRvm_Lx , V(660F38,DD,_,x,I,_,4,FVM), 0 , 110, 0 , 3379 , 203, 129), // #813
+ INST(Vaesimc , VexRm , V(660F38,DB,_,0,I,_,_,_ ), 0 , 96 , 0 , 3391 , 204, 130), // #814
+ INST(Vaeskeygenassist , VexRmi , V(660F3A,DF,_,0,I,_,_,_ ), 0 , 73 , 0 , 3399 , 205, 130), // #815
+ INST(Valignd , VexRvmi_Lx , E(660F3A,03,_,x,_,0,4,FV ), 0 , 111, 0 , 3416 , 206, 131), // #816
+ INST(Valignq , VexRvmi_Lx , E(660F3A,03,_,x,_,1,4,FV ), 0 , 112, 0 , 3424 , 207, 131), // #817
+ INST(Vandnpd , VexRvm_Lx , V(660F00,55,_,x,I,1,4,FV ), 0 , 103, 0 , 3432 , 208, 132), // #818
+ INST(Vandnps , VexRvm_Lx , V(000F00,55,_,x,I,0,4,FV ), 0 , 105, 0 , 3440 , 209, 132), // #819
+ INST(Vandpd , VexRvm_Lx , V(660F00,54,_,x,I,1,4,FV ), 0 , 103, 0 , 3448 , 210, 132), // #820
+ INST(Vandps , VexRvm_Lx , V(000F00,54,_,x,I,0,4,FV ), 0 , 105, 0 , 3455 , 211, 132), // #821
+ INST(Vblendmpd , VexRvm_Lx , E(660F38,65,_,x,_,1,4,FV ), 0 , 113, 0 , 3462 , 212, 131), // #822
+ INST(Vblendmps , VexRvm_Lx , E(660F38,65,_,x,_,0,4,FV ), 0 , 114, 0 , 3472 , 213, 131), // #823
+ INST(Vblendpd , VexRvmi_Lx , V(660F3A,0D,_,x,I,_,_,_ ), 0 , 73 , 0 , 3482 , 214, 128), // #824
+ INST(Vblendps , VexRvmi_Lx , V(660F3A,0C,_,x,I,_,_,_ ), 0 , 73 , 0 , 3491 , 214, 128), // #825
+ INST(Vblendvpd , VexRvmr_Lx , V(660F3A,4B,_,x,0,_,_,_ ), 0 , 73 , 0 , 3500 , 215, 128), // #826
+ INST(Vblendvps , VexRvmr_Lx , V(660F3A,4A,_,x,0,_,_,_ ), 0 , 73 , 0 , 3510 , 215, 128), // #827
+ INST(Vbroadcastf128 , VexRm , V(660F38,1A,_,1,0,_,_,_ ), 0 , 115, 0 , 3520 , 216, 128), // #828
+ INST(Vbroadcastf32x2 , VexRm_Lx , E(660F38,19,_,x,_,0,3,T2 ), 0 , 116, 0 , 3535 , 217, 133), // #829
+ INST(Vbroadcastf32x4 , VexRm_Lx , E(660F38,1A,_,x,_,0,4,T4 ), 0 , 117, 0 , 3551 , 218, 68 ), // #830
+ INST(Vbroadcastf32x8 , VexRm , E(660F38,1B,_,2,_,0,5,T8 ), 0 , 118, 0 , 3567 , 219, 66 ), // #831
+ INST(Vbroadcastf64x2 , VexRm_Lx , E(660F38,1A,_,x,_,1,4,T2 ), 0 , 119, 0 , 3583 , 218, 133), // #832
+ INST(Vbroadcastf64x4 , VexRm , E(660F38,1B,_,2,_,1,5,T4 ), 0 , 120, 0 , 3599 , 219, 68 ), // #833
+ INST(Vbroadcasti128 , VexRm , V(660F38,5A,_,1,0,_,_,_ ), 0 , 115, 0 , 3615 , 216, 134), // #834
+ INST(Vbroadcasti32x2 , VexRm_Lx , E(660F38,59,_,x,_,0,3,T2 ), 0 , 116, 0 , 3630 , 220, 133), // #835
+ INST(Vbroadcasti32x4 , VexRm_Lx , E(660F38,5A,_,x,_,0,4,T4 ), 0 , 117, 0 , 3646 , 218, 131), // #836
+ INST(Vbroadcasti32x8 , VexRm , E(660F38,5B,_,2,_,0,5,T8 ), 0 , 118, 0 , 3662 , 219, 66 ), // #837
+ INST(Vbroadcasti64x2 , VexRm_Lx , E(660F38,5A,_,x,_,1,4,T2 ), 0 , 119, 0 , 3678 , 218, 133), // #838
+ INST(Vbroadcasti64x4 , VexRm , E(660F38,5B,_,2,_,1,5,T4 ), 0 , 120, 0 , 3694 , 219, 68 ), // #839
+ INST(Vbroadcastsd , VexRm_Lx , V(660F38,19,_,x,0,1,3,T1S), 0 , 121, 0 , 3710 , 221, 135), // #840
+ INST(Vbroadcastss , VexRm_Lx , V(660F38,18,_,x,0,0,2,T1S), 0 , 122, 0 , 3723 , 222, 135), // #841
+ INST(Vcmppd , VexRvmi_Lx_KEvex , V(660F00,C2,_,x,I,1,4,FV ), 0 , 103, 0 , 3736 , 223, 124), // #842
+ INST(Vcmpph , VexRvmi_Lx_KEvex , E(000F3A,C2,_,_,_,0,4,FV ), 0 , 123, 0 , 3743 , 224, 125), // #843
+ INST(Vcmpps , VexRvmi_Lx_KEvex , V(000F00,C2,_,x,I,0,4,FV ), 0 , 105, 0 , 3750 , 225, 124), // #844
+ INST(Vcmpsd , VexRvmi_KEvex , V(F20F00,C2,_,I,I,1,3,T1S), 0 , 106, 0 , 3757 , 226, 126), // #845
+ INST(Vcmpsh , VexRvmi_KEvex , E(F30F3A,C2,_,_,_,0,1,T1S), 0 , 124, 0 , 3764 , 227, 127), // #846
+ INST(Vcmpss , VexRvmi_KEvex , V(F30F00,C2,_,I,I,0,2,T1S), 0 , 108, 0 , 3771 , 228, 126), // #847
+ INST(Vcomisd , VexRm , V(660F00,2F,_,I,I,1,3,T1S), 0 , 125, 0 , 3778 , 229, 136), // #848
+ INST(Vcomish , VexRm , E(00MAP5,2F,_,_,_,0,1,T1S), 0 , 126, 0 , 3786 , 230, 127), // #849
+ INST(Vcomiss , VexRm , V(000F00,2F,_,I,I,0,2,T1S), 0 , 127, 0 , 3794 , 231, 136), // #850
+ INST(Vcompresspd , VexMr_Lx , E(660F38,8A,_,x,_,1,3,T1S), 0 , 128, 0 , 3802 , 232, 131), // #851
+ INST(Vcompressps , VexMr_Lx , E(660F38,8A,_,x,_,0,2,T1S), 0 , 129, 0 , 3814 , 232, 131), // #852
+ INST(Vcvtdq2pd , VexRm_Lx , V(F30F00,E6,_,x,I,0,3,HV ), 0 , 130, 0 , 3826 , 233, 124), // #853
+ INST(Vcvtdq2ph , VexRm_Lx , E(00MAP5,5B,_,_,_,0,4,FV ), 0 , 104, 0 , 3836 , 234, 125), // #854
+ INST(Vcvtdq2ps , VexRm_Lx , V(000F00,5B,_,x,I,0,4,FV ), 0 , 105, 0 , 3846 , 235, 124), // #855
+ INST(Vcvtne2ps2bf16 , VexRvm_Lx , E(F20F38,72,_,_,_,0,4,FV ), 0 , 131, 0 , 3856 , 213, 137), // #856
+ INST(Vcvtneps2bf16 , VexRm_Lx_Narrow , E(F30F38,72,_,_,_,0,4,FV ), 0 , 132, 0 , 3871 , 236, 137), // #857
+ INST(Vcvtpd2dq , VexRm_Lx_Narrow , V(F20F00,E6,_,x,I,1,4,FV ), 0 , 133, 0 , 3885 , 237, 124), // #858
+ INST(Vcvtpd2ph , VexRm_Lx , E(66MAP5,5A,_,_,_,1,4,FV ), 0 , 134, 0 , 3895 , 238, 125), // #859
+ INST(Vcvtpd2ps , VexRm_Lx_Narrow , V(660F00,5A,_,x,I,1,4,FV ), 0 , 103, 0 , 3905 , 237, 124), // #860
+ INST(Vcvtpd2qq , VexRm_Lx , E(660F00,7B,_,x,_,1,4,FV ), 0 , 135, 0 , 3915 , 239, 133), // #861
+ INST(Vcvtpd2udq , VexRm_Lx_Narrow , E(000F00,79,_,x,_,1,4,FV ), 0 , 136, 0 , 3925 , 240, 131), // #862
+ INST(Vcvtpd2uqq , VexRm_Lx , E(660F00,79,_,x,_,1,4,FV ), 0 , 135, 0 , 3936 , 239, 133), // #863
+ INST(Vcvtph2dq , VexRm_Lx , E(66MAP5,5B,_,_,_,0,3,HV ), 0 , 137, 0 , 3947 , 241, 125), // #864
+ INST(Vcvtph2pd , VexRm_Lx , E(00MAP5,5A,_,_,_,0,2,QV ), 0 , 138, 0 , 3957 , 242, 125), // #865
+ INST(Vcvtph2ps , VexRm_Lx , V(660F38,13,_,x,0,0,3,HVM), 0 , 139, 0 , 3967 , 243, 138), // #866
+ INST(Vcvtph2psx , VexRm_Lx , E(66MAP6,13,_,_,_,0,3,HV ), 0 , 140, 0 , 3977 , 244, 125), // #867
+ INST(Vcvtph2qq , VexRm_Lx , E(66MAP5,7B,_,_,_,0,2,QV ), 0 , 141, 0 , 3988 , 245, 125), // #868
+ INST(Vcvtph2udq , VexRm_Lx , E(00MAP5,79,_,_,_,0,3,HV ), 0 , 142, 0 , 3998 , 241, 125), // #869
+ INST(Vcvtph2uqq , VexRm_Lx , E(66MAP5,79,_,_,_,0,2,QV ), 0 , 141, 0 , 4009 , 245, 125), // #870
+ INST(Vcvtph2uw , VexRm_Lx , E(00MAP5,7D,_,_,_,0,4,FV ), 0 , 104, 0 , 4020 , 246, 125), // #871
+ INST(Vcvtph2w , VexRm_Lx , E(66MAP5,7D,_,_,_,0,4,FV ), 0 , 143, 0 , 4030 , 246, 125), // #872
+ INST(Vcvtps2dq , VexRm_Lx , V(660F00,5B,_,x,I,0,4,FV ), 0 , 144, 0 , 4039 , 235, 124), // #873
+ INST(Vcvtps2pd , VexRm_Lx , V(000F00,5A,_,x,I,0,3,HV ), 0 , 145, 0 , 4049 , 247, 124), // #874
+ INST(Vcvtps2ph , VexMri_Lx , V(660F3A,1D,_,x,0,0,3,HVM), 0 , 146, 0 , 4059 , 248, 138), // #875
+ INST(Vcvtps2phx , VexRm_Lx , E(66MAP5,1D,_,_,_,0,4,FV ), 0 , 143, 0 , 4069 , 234, 125), // #876
+ INST(Vcvtps2qq , VexRm_Lx , E(660F00,7B,_,x,_,0,3,HV ), 0 , 147, 0 , 4080 , 249, 133), // #877
+ INST(Vcvtps2udq , VexRm_Lx , E(000F00,79,_,x,_,0,4,FV ), 0 , 148, 0 , 4090 , 250, 131), // #878
+ INST(Vcvtps2uqq , VexRm_Lx , E(660F00,79,_,x,_,0,3,HV ), 0 , 147, 0 , 4101 , 249, 133), // #879
+ INST(Vcvtqq2pd , VexRm_Lx , E(F30F00,E6,_,x,_,1,4,FV ), 0 , 149, 0 , 4112 , 239, 133), // #880
+ INST(Vcvtqq2ph , VexRm_Lx , E(00MAP5,5B,_,_,_,1,4,FV ), 0 , 150, 0 , 4122 , 238, 125), // #881
+ INST(Vcvtqq2ps , VexRm_Lx_Narrow , E(000F00,5B,_,x,_,1,4,FV ), 0 , 136, 0 , 4132 , 240, 133), // #882
+ INST(Vcvtsd2sh , VexRvm , E(F2MAP5,5A,_,_,_,1,3,T1S), 0 , 151, 0 , 4142 , 251, 127), // #883
+ INST(Vcvtsd2si , VexRm_Wx , V(F20F00,2D,_,I,x,x,3,T1F), 0 , 152, 0 , 4152 , 252, 126), // #884
+ INST(Vcvtsd2ss , VexRvm , V(F20F00,5A,_,I,I,1,3,T1S), 0 , 106, 0 , 4162 , 199, 126), // #885
+ INST(Vcvtsd2usi , VexRm_Wx , E(F20F00,79,_,I,_,x,3,T1F), 0 , 153, 0 , 4172 , 253, 68 ), // #886
+ INST(Vcvtsh2sd , VexRvm , E(F3MAP5,5A,_,_,_,0,1,T1S), 0 , 107, 0 , 4183 , 254, 127), // #887
+ INST(Vcvtsh2si , VexRm_Wx , E(F3MAP5,2D,_,_,_,x,1,T1S), 0 , 107, 0 , 4193 , 255, 127), // #888
+ INST(Vcvtsh2ss , VexRvm , E(00MAP6,13,_,_,_,0,1,T1S), 0 , 154, 0 , 4203 , 254, 127), // #889
+ INST(Vcvtsh2usi , VexRm_Wx , E(F3MAP5,79,_,_,_,x,1,T1S), 0 , 107, 0 , 4213 , 255, 127), // #890
+ INST(Vcvtsi2sd , VexRvm_Wx , V(F20F00,2A,_,I,x,x,2,T1W), 0 , 155, 0 , 4224 , 256, 126), // #891
+ INST(Vcvtsi2sh , VexRvm_Wx , E(F3MAP5,2A,_,_,_,x,2,T1W), 0 , 156, 0 , 4234 , 257, 127), // #892
+ INST(Vcvtsi2ss , VexRvm_Wx , V(F30F00,2A,_,I,x,x,2,T1W), 0 , 157, 0 , 4244 , 256, 126), // #893
+ INST(Vcvtss2sd , VexRvm , V(F30F00,5A,_,I,I,0,2,T1S), 0 , 108, 0 , 4254 , 258, 126), // #894
+ INST(Vcvtss2sh , VexRvm , E(00MAP5,1D,_,_,_,0,2,T1S), 0 , 158, 0 , 4264 , 259, 127), // #895
+ INST(Vcvtss2si , VexRm_Wx , V(F30F00,2D,_,I,x,x,2,T1F), 0 , 108, 0 , 4274 , 260, 126), // #896
+ INST(Vcvtss2usi , VexRm_Wx , E(F30F00,79,_,I,_,x,2,T1F), 0 , 159, 0 , 4284 , 261, 68 ), // #897
+ INST(Vcvttpd2dq , VexRm_Lx_Narrow , V(660F00,E6,_,x,I,1,4,FV ), 0 , 103, 0 , 4295 , 262, 124), // #898
+ INST(Vcvttpd2qq , VexRm_Lx , E(660F00,7A,_,x,_,1,4,FV ), 0 , 135, 0 , 4306 , 263, 131), // #899
+ INST(Vcvttpd2udq , VexRm_Lx_Narrow , E(000F00,78,_,x,_,1,4,FV ), 0 , 136, 0 , 4317 , 264, 131), // #900
+ INST(Vcvttpd2uqq , VexRm_Lx , E(660F00,78,_,x,_,1,4,FV ), 0 , 135, 0 , 4329 , 263, 133), // #901
+ INST(Vcvttph2dq , VexRm_Lx , E(F3MAP5,5B,_,_,_,0,3,HV ), 0 , 160, 0 , 4341 , 244, 125), // #902
+ INST(Vcvttph2qq , VexRm_Lx , E(66MAP5,7A,_,_,_,0,2,QV ), 0 , 141, 0 , 4352 , 242, 125), // #903
+ INST(Vcvttph2udq , VexRm_Lx , E(00MAP5,78,_,_,_,0,3,HV ), 0 , 142, 0 , 4363 , 244, 125), // #904
+ INST(Vcvttph2uqq , VexRm_Lx , E(66MAP5,78,_,_,_,0,2,QV ), 0 , 141, 0 , 4375 , 242, 125), // #905
+ INST(Vcvttph2uw , VexRm_Lx , E(00MAP5,7C,_,_,_,0,4,FV ), 0 , 104, 0 , 4387 , 265, 125), // #906
+ INST(Vcvttph2w , VexRm_Lx , E(66MAP5,7C,_,_,_,0,4,FV ), 0 , 143, 0 , 4398 , 265, 125), // #907
+ INST(Vcvttps2dq , VexRm_Lx , V(F30F00,5B,_,x,I,0,4,FV ), 0 , 161, 0 , 4408 , 266, 124), // #908
+ INST(Vcvttps2qq , VexRm_Lx , E(660F00,7A,_,x,_,0,3,HV ), 0 , 147, 0 , 4419 , 267, 133), // #909
+ INST(Vcvttps2udq , VexRm_Lx , E(000F00,78,_,x,_,0,4,FV ), 0 , 148, 0 , 4430 , 268, 131), // #910
+ INST(Vcvttps2uqq , VexRm_Lx , E(660F00,78,_,x,_,0,3,HV ), 0 , 147, 0 , 4442 , 267, 133), // #911
+ INST(Vcvttsd2si , VexRm_Wx , V(F20F00,2C,_,I,x,x,3,T1F), 0 , 152, 0 , 4454 , 269, 126), // #912
+ INST(Vcvttsd2usi , VexRm_Wx , E(F20F00,78,_,I,_,x,3,T1F), 0 , 153, 0 , 4465 , 270, 68 ), // #913
+ INST(Vcvttsh2si , VexRm_Wx , E(F3MAP5,2C,_,_,_,x,1,T1S), 0 , 107, 0 , 4477 , 271, 127), // #914
+ INST(Vcvttsh2usi , VexRm_Wx , E(F3MAP5,78,_,_,_,x,1,T1S), 0 , 107, 0 , 4488 , 271, 127), // #915
+ INST(Vcvttss2si , VexRm_Wx , V(F30F00,2C,_,I,x,x,2,T1F), 0 , 108, 0 , 4500 , 272, 126), // #916
+ INST(Vcvttss2usi , VexRm_Wx , E(F30F00,78,_,I,_,x,2,T1F), 0 , 159, 0 , 4511 , 273, 68 ), // #917
+ INST(Vcvtudq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,0,3,HV ), 0 , 162, 0 , 4523 , 274, 131), // #918
+ INST(Vcvtudq2ph , VexRm_Lx , E(F2MAP5,7A,_,_,_,0,4,FV ), 0 , 163, 0 , 4534 , 234, 125), // #919
+ INST(Vcvtudq2ps , VexRm_Lx , E(F20F00,7A,_,x,_,0,4,FV ), 0 , 164, 0 , 4545 , 250, 131), // #920
+ INST(Vcvtuqq2pd , VexRm_Lx , E(F30F00,7A,_,x,_,1,4,FV ), 0 , 149, 0 , 4556 , 239, 133), // #921
+ INST(Vcvtuqq2ph , VexRm_Lx , E(F2MAP5,7A,_,_,_,1,4,FV ), 0 , 165, 0 , 4567 , 238, 125), // #922
+ INST(Vcvtuqq2ps , VexRm_Lx_Narrow , E(F20F00,7A,_,x,_,1,4,FV ), 0 , 166, 0 , 4578 , 240, 133), // #923
+ INST(Vcvtusi2sd , VexRvm_Wx , E(F20F00,7B,_,I,_,x,2,T1W), 0 , 167, 0 , 4589 , 257, 68 ), // #924
+ INST(Vcvtusi2sh , VexRvm_Wx , E(F3MAP5,7B,_,_,_,x,2,T1W), 0 , 156, 0 , 4600 , 257, 127), // #925
+ INST(Vcvtusi2ss , VexRvm_Wx , E(F30F00,7B,_,I,_,x,2,T1W), 0 , 168, 0 , 4611 , 257, 68 ), // #926
+ INST(Vcvtuw2ph , VexRm_Lx , E(F2MAP5,7D,_,_,_,0,4,FV ), 0 , 163, 0 , 4622 , 246, 125), // #927
+ INST(Vcvtw2ph , VexRm_Lx , E(F3MAP5,7D,_,_,_,0,4,FV ), 0 , 169, 0 , 4632 , 246, 125), // #928
+ INST(Vdbpsadbw , VexRvmi_Lx , E(660F3A,42,_,x,_,0,4,FVM), 0 , 111, 0 , 4641 , 275, 139), // #929
+ INST(Vdivpd , VexRvm_Lx , V(660F00,5E,_,x,I,1,4,FV ), 0 , 103, 0 , 4651 , 196, 124), // #930
+ INST(Vdivph , VexRvm_Lx , E(00MAP5,5E,_,_,_,0,4,FV ), 0 , 104, 0 , 4658 , 197, 125), // #931
+ INST(Vdivps , VexRvm_Lx , V(000F00,5E,_,x,I,0,4,FV ), 0 , 105, 0 , 4665 , 198, 124), // #932
+ INST(Vdivsd , VexRvm , V(F20F00,5E,_,I,I,1,3,T1S), 0 , 106, 0 , 4672 , 199, 126), // #933
+ INST(Vdivsh , VexRvm , E(F3MAP5,5E,_,_,_,0,1,T1S), 0 , 107, 0 , 4679 , 200, 127), // #934
+ INST(Vdivss , VexRvm , V(F30F00,5E,_,I,I,0,2,T1S), 0 , 108, 0 , 4686 , 201, 126), // #935
+ INST(Vdpbf16ps , VexRvm_Lx , E(F30F38,52,_,_,_,0,4,FV ), 0 , 132, 0 , 4693 , 213, 137), // #936
+ INST(Vdppd , VexRvmi_Lx , V(660F3A,41,_,x,I,_,_,_ ), 0 , 73 , 0 , 4703 , 276, 128), // #937
+ INST(Vdpps , VexRvmi_Lx , V(660F3A,40,_,x,I,_,_,_ ), 0 , 73 , 0 , 4709 , 214, 128), // #938
+ INST(Verr , X86M_NoSize , O(000F00,00,4,_,_,_,_,_ ), 0 , 97 , 0 , 4715 , 107, 10 ), // #939
+ INST(Verw , X86M_NoSize , O(000F00,00,5,_,_,_,_,_ ), 0 , 77 , 0 , 4720 , 107, 10 ), // #940
+ INST(Vexp2pd , VexRm , E(660F38,C8,_,2,_,1,4,FV ), 0 , 170, 0 , 4725 , 277, 140), // #941
+ INST(Vexp2ps , VexRm , E(660F38,C8,_,2,_,0,4,FV ), 0 , 171, 0 , 4733 , 278, 140), // #942
+ INST(Vexpandpd , VexRm_Lx , E(660F38,88,_,x,_,1,3,T1S), 0 , 128, 0 , 4741 , 279, 131), // #943
+ INST(Vexpandps , VexRm_Lx , E(660F38,88,_,x,_,0,2,T1S), 0 , 129, 0 , 4751 , 279, 131), // #944
+ INST(Vextractf128 , VexMri , V(660F3A,19,_,1,0,_,_,_ ), 0 , 172, 0 , 4761 , 280, 128), // #945
+ INST(Vextractf32x4 , VexMri_Lx , E(660F3A,19,_,x,_,0,4,T4 ), 0 , 173, 0 , 4774 , 281, 131), // #946
+ INST(Vextractf32x8 , VexMri , E(660F3A,1B,_,2,_,0,5,T8 ), 0 , 174, 0 , 4788 , 282, 66 ), // #947
+ INST(Vextractf64x2 , VexMri_Lx , E(660F3A,19,_,x,_,1,4,T2 ), 0 , 175, 0 , 4802 , 281, 133), // #948
+ INST(Vextractf64x4 , VexMri , E(660F3A,1B,_,2,_,1,5,T4 ), 0 , 176, 0 , 4816 , 282, 68 ), // #949
+ INST(Vextracti128 , VexMri , V(660F3A,39,_,1,0,_,_,_ ), 0 , 172, 0 , 4830 , 280, 134), // #950
+ INST(Vextracti32x4 , VexMri_Lx , E(660F3A,39,_,x,_,0,4,T4 ), 0 , 173, 0 , 4843 , 281, 131), // #951
+ INST(Vextracti32x8 , VexMri , E(660F3A,3B,_,2,_,0,5,T8 ), 0 , 174, 0 , 4857 , 282, 66 ), // #952
+ INST(Vextracti64x2 , VexMri_Lx , E(660F3A,39,_,x,_,1,4,T2 ), 0 , 175, 0 , 4871 , 281, 133), // #953
+ INST(Vextracti64x4 , VexMri , E(660F3A,3B,_,2,_,1,5,T4 ), 0 , 176, 0 , 4885 , 282, 68 ), // #954
+ INST(Vextractps , VexMri , V(660F3A,17,_,0,I,I,2,T1S), 0 , 177, 0 , 4899 , 283, 126), // #955
+ INST(Vfcmaddcph , VexRvm_Lx , E(F2MAP6,56,_,_,_,0,4,FV ), 0 , 178, 0 , 4910 , 284, 125), // #956
+ INST(Vfcmaddcsh , VexRvm , E(F2MAP6,57,_,_,_,0,2,T1S), 0 , 179, 0 , 4921 , 259, 125), // #957
+ INST(Vfcmulcph , VexRvm_Lx , E(F2MAP6,D6,_,_,_,0,4,FV ), 0 , 178, 0 , 4932 , 284, 125), // #958
+ INST(Vfcmulcsh , VexRvm , E(F2MAP6,D7,_,_,_,0,2,T1S), 0 , 179, 0 , 4942 , 259, 125), // #959
+ INST(Vfixupimmpd , VexRvmi_Lx , E(660F3A,54,_,x,_,1,4,FV ), 0 , 112, 0 , 4952 , 285, 131), // #960
+ INST(Vfixupimmps , VexRvmi_Lx , E(660F3A,54,_,x,_,0,4,FV ), 0 , 111, 0 , 4964 , 286, 131), // #961
+ INST(Vfixupimmsd , VexRvmi , E(660F3A,55,_,I,_,1,3,T1S), 0 , 180, 0 , 4976 , 287, 68 ), // #962
+ INST(Vfixupimmss , VexRvmi , E(660F3A,55,_,I,_,0,2,T1S), 0 , 181, 0 , 4988 , 288, 68 ), // #963
+ INST(Vfmadd132pd , VexRvm_Lx , V(660F38,98,_,x,1,1,4,FV ), 0 , 182, 0 , 5000 , 196, 141), // #964
+ INST(Vfmadd132ph , VexRvm_Lx , E(66MAP6,98,_,_,_,0,4,FV ), 0 , 183, 0 , 5012 , 197, 125), // #965
+ INST(Vfmadd132ps , VexRvm_Lx , V(660F38,98,_,x,0,0,4,FV ), 0 , 110, 0 , 5024 , 198, 141), // #966
+ INST(Vfmadd132sd , VexRvm , V(660F38,99,_,I,1,1,3,T1S), 0 , 184, 0 , 5036 , 199, 142), // #967
+ INST(Vfmadd132sh , VexRvm , E(66MAP6,99,_,_,_,0,1,T1S), 0 , 185, 0 , 5048 , 200, 127), // #968
+ INST(Vfmadd132ss , VexRvm , V(660F38,99,_,I,0,0,2,T1S), 0 , 122, 0 , 5060 , 201, 142), // #969
+ INST(Vfmadd213pd , VexRvm_Lx , V(660F38,A8,_,x,1,1,4,FV ), 0 , 182, 0 , 5072 , 196, 141), // #970
+ INST(Vfmadd213ph , VexRvm_Lx , E(66MAP6,A8,_,_,_,0,4,FV ), 0 , 183, 0 , 5084 , 197, 125), // #971
+ INST(Vfmadd213ps , VexRvm_Lx , V(660F38,A8,_,x,0,0,4,FV ), 0 , 110, 0 , 5096 , 198, 141), // #972
+ INST(Vfmadd213sd , VexRvm , V(660F38,A9,_,I,1,1,3,T1S), 0 , 184, 0 , 5108 , 199, 142), // #973
+ INST(Vfmadd213sh , VexRvm , E(66MAP6,A9,_,_,_,0,1,T1S), 0 , 185, 0 , 5120 , 200, 127), // #974
+ INST(Vfmadd213ss , VexRvm , V(660F38,A9,_,I,0,0,2,T1S), 0 , 122, 0 , 5132 , 201, 142), // #975
+ INST(Vfmadd231pd , VexRvm_Lx , V(660F38,B8,_,x,1,1,4,FV ), 0 , 182, 0 , 5144 , 196, 141), // #976
+ INST(Vfmadd231ph , VexRvm_Lx , E(66MAP6,B8,_,_,_,0,4,FV ), 0 , 183, 0 , 5156 , 197, 125), // #977
+ INST(Vfmadd231ps , VexRvm_Lx , V(660F38,B8,_,x,0,0,4,FV ), 0 , 110, 0 , 5168 , 198, 141), // #978
+ INST(Vfmadd231sd , VexRvm , V(660F38,B9,_,I,1,1,3,T1S), 0 , 184, 0 , 5180 , 199, 142), // #979
+ INST(Vfmadd231sh , VexRvm , E(66MAP6,B9,_,_,_,0,1,T1S), 0 , 185, 0 , 5192 , 200, 127), // #980
+ INST(Vfmadd231ss , VexRvm , V(660F38,B9,_,I,0,0,2,T1S), 0 , 122, 0 , 5204 , 201, 142), // #981
+ INST(Vfmaddcph , VexRvm_Lx , E(F3MAP6,56,_,_,_,0,4,FV ), 0 , 186, 0 , 5216 , 284, 125), // #982
+ INST(Vfmaddcsh , VexRvm , E(F3MAP6,57,_,_,_,0,2,T1S), 0 , 187, 0 , 5226 , 259, 125), // #983
+ INST(Vfmaddpd , Fma4_Lx , V(660F3A,69,_,x,x,_,_,_ ), 0 , 73 , 0 , 5236 , 289, 143), // #984
+ INST(Vfmaddps , Fma4_Lx , V(660F3A,68,_,x,x,_,_,_ ), 0 , 73 , 0 , 5245 , 289, 143), // #985
+ INST(Vfmaddsd , Fma4 , V(660F3A,6B,_,0,x,_,_,_ ), 0 , 73 , 0 , 5254 , 290, 143), // #986
+ INST(Vfmaddss , Fma4 , V(660F3A,6A,_,0,x,_,_,_ ), 0 , 73 , 0 , 5263 , 291, 143), // #987
+ INST(Vfmaddsub132pd , VexRvm_Lx , V(660F38,96,_,x,1,1,4,FV ), 0 , 182, 0 , 5272 , 196, 141), // #988
+ INST(Vfmaddsub132ph , VexRvm_Lx , E(66MAP6,96,_,_,_,0,4,FV ), 0 , 183, 0 , 5287 , 197, 125), // #989
+ INST(Vfmaddsub132ps , VexRvm_Lx , V(660F38,96,_,x,0,0,4,FV ), 0 , 110, 0 , 5302 , 198, 141), // #990
+ INST(Vfmaddsub213pd , VexRvm_Lx , V(660F38,A6,_,x,1,1,4,FV ), 0 , 182, 0 , 5317 , 196, 141), // #991
+ INST(Vfmaddsub213ph , VexRvm_Lx , E(66MAP6,A6,_,_,_,0,4,FV ), 0 , 183, 0 , 5332 , 197, 125), // #992
+ INST(Vfmaddsub213ps , VexRvm_Lx , V(660F38,A6,_,x,0,0,4,FV ), 0 , 110, 0 , 5347 , 198, 141), // #993
+ INST(Vfmaddsub231pd , VexRvm_Lx , V(660F38,B6,_,x,1,1,4,FV ), 0 , 182, 0 , 5362 , 196, 141), // #994
+ INST(Vfmaddsub231ph , VexRvm_Lx , E(66MAP6,B6,_,_,_,0,4,FV ), 0 , 183, 0 , 5377 , 197, 125), // #995
+ INST(Vfmaddsub231ps , VexRvm_Lx , V(660F38,B6,_,x,0,0,4,FV ), 0 , 110, 0 , 5392 , 198, 141), // #996
+ INST(Vfmaddsubpd , Fma4_Lx , V(660F3A,5D,_,x,x,_,_,_ ), 0 , 73 , 0 , 5407 , 289, 143), // #997
+ INST(Vfmaddsubps , Fma4_Lx , V(660F3A,5C,_,x,x,_,_,_ ), 0 , 73 , 0 , 5419 , 289, 143), // #998
+ INST(Vfmsub132pd , VexRvm_Lx , V(660F38,9A,_,x,1,1,4,FV ), 0 , 182, 0 , 5431 , 196, 141), // #999
+ INST(Vfmsub132ph , VexRvm_Lx , E(66MAP6,9A,_,_,_,0,4,FV ), 0 , 183, 0 , 5443 , 197, 125), // #1000
+ INST(Vfmsub132ps , VexRvm_Lx , V(660F38,9A,_,x,0,0,4,FV ), 0 , 110, 0 , 5455 , 198, 141), // #1001
+ INST(Vfmsub132sd , VexRvm , V(660F38,9B,_,I,1,1,3,T1S), 0 , 184, 0 , 5467 , 199, 142), // #1002
+ INST(Vfmsub132sh , VexRvm , E(66MAP6,9B,_,_,_,0,1,T1S), 0 , 185, 0 , 5479 , 200, 127), // #1003
+ INST(Vfmsub132ss , VexRvm , V(660F38,9B,_,I,0,0,2,T1S), 0 , 122, 0 , 5491 , 201, 142), // #1004
+ INST(Vfmsub213pd , VexRvm_Lx , V(660F38,AA,_,x,1,1,4,FV ), 0 , 182, 0 , 5503 , 196, 141), // #1005
+ INST(Vfmsub213ph , VexRvm_Lx , E(66MAP6,AA,_,_,_,0,4,FV ), 0 , 183, 0 , 5515 , 197, 125), // #1006
+ INST(Vfmsub213ps , VexRvm_Lx , V(660F38,AA,_,x,0,0,4,FV ), 0 , 110, 0 , 5527 , 198, 141), // #1007
+ INST(Vfmsub213sd , VexRvm , V(660F38,AB,_,I,1,1,3,T1S), 0 , 184, 0 , 5539 , 199, 142), // #1008
+ INST(Vfmsub213sh , VexRvm , E(66MAP6,AB,_,_,_,0,1,T1S), 0 , 185, 0 , 5551 , 200, 127), // #1009
+ INST(Vfmsub213ss , VexRvm , V(660F38,AB,_,I,0,0,2,T1S), 0 , 122, 0 , 5563 , 201, 142), // #1010
+ INST(Vfmsub231pd , VexRvm_Lx , V(660F38,BA,_,x,1,1,4,FV ), 0 , 182, 0 , 5575 , 196, 141), // #1011
+ INST(Vfmsub231ph , VexRvm_Lx , E(66MAP6,BA,_,_,_,0,4,FV ), 0 , 183, 0 , 5587 , 197, 125), // #1012
+ INST(Vfmsub231ps , VexRvm_Lx , V(660F38,BA,_,x,0,0,4,FV ), 0 , 110, 0 , 5599 , 198, 141), // #1013
+ INST(Vfmsub231sd , VexRvm , V(660F38,BB,_,I,1,1,3,T1S), 0 , 184, 0 , 5611 , 199, 142), // #1014
+ INST(Vfmsub231sh , VexRvm , E(66MAP6,BB,_,_,_,0,1,T1S), 0 , 185, 0 , 5623 , 200, 127), // #1015
+ INST(Vfmsub231ss , VexRvm , V(660F38,BB,_,I,0,0,2,T1S), 0 , 122, 0 , 5635 , 201, 142), // #1016
+ INST(Vfmsubadd132pd , VexRvm_Lx , V(660F38,97,_,x,1,1,4,FV ), 0 , 182, 0 , 5647 , 196, 141), // #1017
+ INST(Vfmsubadd132ph , VexRvm_Lx , E(66MAP6,97,_,_,_,0,4,FV ), 0 , 183, 0 , 5662 , 197, 125), // #1018
+ INST(Vfmsubadd132ps , VexRvm_Lx , V(660F38,97,_,x,0,0,4,FV ), 0 , 110, 0 , 5677 , 198, 141), // #1019
+ INST(Vfmsubadd213pd , VexRvm_Lx , V(660F38,A7,_,x,1,1,4,FV ), 0 , 182, 0 , 5692 , 196, 141), // #1020
+ INST(Vfmsubadd213ph , VexRvm_Lx , E(66MAP6,A7,_,_,_,0,4,FV ), 0 , 183, 0 , 5707 , 197, 125), // #1021
+ INST(Vfmsubadd213ps , VexRvm_Lx , V(660F38,A7,_,x,0,0,4,FV ), 0 , 110, 0 , 5722 , 198, 141), // #1022
+ INST(Vfmsubadd231pd , VexRvm_Lx , V(660F38,B7,_,x,1,1,4,FV ), 0 , 182, 0 , 5737 , 196, 141), // #1023
+ INST(Vfmsubadd231ph , VexRvm_Lx , E(66MAP6,B7,_,_,_,0,4,FV ), 0 , 183, 0 , 5752 , 197, 125), // #1024
+ INST(Vfmsubadd231ps , VexRvm_Lx , V(660F38,B7,_,x,0,0,4,FV ), 0 , 110, 0 , 5767 , 198, 141), // #1025
+ INST(Vfmsubaddpd , Fma4_Lx , V(660F3A,5F,_,x,x,_,_,_ ), 0 , 73 , 0 , 5782 , 289, 143), // #1026
+ INST(Vfmsubaddps , Fma4_Lx , V(660F3A,5E,_,x,x,_,_,_ ), 0 , 73 , 0 , 5794 , 289, 143), // #1027
+ INST(Vfmsubpd , Fma4_Lx , V(660F3A,6D,_,x,x,_,_,_ ), 0 , 73 , 0 , 5806 , 289, 143), // #1028
+ INST(Vfmsubps , Fma4_Lx , V(660F3A,6C,_,x,x,_,_,_ ), 0 , 73 , 0 , 5815 , 289, 143), // #1029
+ INST(Vfmsubsd , Fma4 , V(660F3A,6F,_,0,x,_,_,_ ), 0 , 73 , 0 , 5824 , 290, 143), // #1030
+ INST(Vfmsubss , Fma4 , V(660F3A,6E,_,0,x,_,_,_ ), 0 , 73 , 0 , 5833 , 291, 143), // #1031
+ INST(Vfmulcph , VexRvm_Lx , E(F3MAP6,D6,_,_,_,0,4,FV ), 0 , 186, 0 , 5842 , 284, 125), // #1032
+ INST(Vfmulcsh , VexRvm , E(F3MAP6,D7,_,_,_,0,2,T1S), 0 , 187, 0 , 5851 , 259, 125), // #1033
+ INST(Vfnmadd132pd , VexRvm_Lx , V(660F38,9C,_,x,1,1,4,FV ), 0 , 182, 0 , 5860 , 196, 141), // #1034
+ INST(Vfnmadd132ph , VexRvm_Lx , E(66MAP6,9C,_,_,_,0,4,FV ), 0 , 183, 0 , 5873 , 197, 125), // #1035
+ INST(Vfnmadd132ps , VexRvm_Lx , V(660F38,9C,_,x,0,0,4,FV ), 0 , 110, 0 , 5886 , 198, 141), // #1036
+ INST(Vfnmadd132sd , VexRvm , V(660F38,9D,_,I,1,1,3,T1S), 0 , 184, 0 , 5899 , 199, 142), // #1037
+ INST(Vfnmadd132sh , VexRvm , E(66MAP6,9D,_,_,_,0,1,T1S), 0 , 185, 0 , 5912 , 200, 127), // #1038
+ INST(Vfnmadd132ss , VexRvm , V(660F38,9D,_,I,0,0,2,T1S), 0 , 122, 0 , 5925 , 201, 142), // #1039
+ INST(Vfnmadd213pd , VexRvm_Lx , V(660F38,AC,_,x,1,1,4,FV ), 0 , 182, 0 , 5938 , 196, 141), // #1040
+ INST(Vfnmadd213ph , VexRvm_Lx , E(66MAP6,AC,_,_,_,0,4,FV ), 0 , 183, 0 , 5951 , 197, 125), // #1041
+ INST(Vfnmadd213ps , VexRvm_Lx , V(660F38,AC,_,x,0,0,4,FV ), 0 , 110, 0 , 5964 , 198, 141), // #1042
+ INST(Vfnmadd213sd , VexRvm , V(660F38,AD,_,I,1,1,3,T1S), 0 , 184, 0 , 5977 , 199, 142), // #1043
+ INST(Vfnmadd213sh , VexRvm , E(66MAP6,AD,_,_,_,0,1,T1S), 0 , 185, 0 , 5990 , 200, 127), // #1044
+ INST(Vfnmadd213ss , VexRvm , V(660F38,AD,_,I,0,0,2,T1S), 0 , 122, 0 , 6003 , 201, 142), // #1045
+ INST(Vfnmadd231pd , VexRvm_Lx , V(660F38,BC,_,x,1,1,4,FV ), 0 , 182, 0 , 6016 , 196, 141), // #1046
+ INST(Vfnmadd231ph , VexRvm_Lx , E(66MAP6,BC,_,_,_,0,4,FV ), 0 , 183, 0 , 6029 , 197, 125), // #1047
+ INST(Vfnmadd231ps , VexRvm_Lx , V(660F38,BC,_,x,0,0,4,FV ), 0 , 110, 0 , 6042 , 198, 141), // #1048
+ INST(Vfnmadd231sd , VexRvm , V(660F38,BD,_,I,1,1,3,T1S), 0 , 184, 0 , 6055 , 199, 142), // #1049
+ INST(Vfnmadd231sh , VexRvm , E(66MAP6,BD,_,_,_,0,1,T1S), 0 , 185, 0 , 6068 , 200, 127), // #1050
+ INST(Vfnmadd231ss , VexRvm , V(660F38,BD,_,I,0,0,2,T1S), 0 , 122, 0 , 6081 , 201, 142), // #1051
+ INST(Vfnmaddpd , Fma4_Lx , V(660F3A,79,_,x,x,_,_,_ ), 0 , 73 , 0 , 6094 , 289, 143), // #1052
+ INST(Vfnmaddps , Fma4_Lx , V(660F3A,78,_,x,x,_,_,_ ), 0 , 73 , 0 , 6104 , 289, 143), // #1053
+ INST(Vfnmaddsd , Fma4 , V(660F3A,7B,_,0,x,_,_,_ ), 0 , 73 , 0 , 6114 , 290, 143), // #1054
+ INST(Vfnmaddss , Fma4 , V(660F3A,7A,_,0,x,_,_,_ ), 0 , 73 , 0 , 6124 , 291, 143), // #1055
+ INST(Vfnmsub132pd , VexRvm_Lx , V(660F38,9E,_,x,1,1,4,FV ), 0 , 182, 0 , 6134 , 196, 141), // #1056
+ INST(Vfnmsub132ph , VexRvm_Lx , E(66MAP6,9E,_,_,_,0,4,FV ), 0 , 183, 0 , 6147 , 197, 125), // #1057
+ INST(Vfnmsub132ps , VexRvm_Lx , V(660F38,9E,_,x,0,0,4,FV ), 0 , 110, 0 , 6160 , 198, 141), // #1058
+ INST(Vfnmsub132sd , VexRvm , V(660F38,9F,_,I,1,1,3,T1S), 0 , 184, 0 , 6173 , 199, 142), // #1059
+ INST(Vfnmsub132sh , VexRvm , E(66MAP6,9F,_,_,_,0,1,T1S), 0 , 185, 0 , 6186 , 200, 127), // #1060
+ INST(Vfnmsub132ss , VexRvm , V(660F38,9F,_,I,0,0,2,T1S), 0 , 122, 0 , 6199 , 201, 142), // #1061
+ INST(Vfnmsub213pd , VexRvm_Lx , V(660F38,AE,_,x,1,1,4,FV ), 0 , 182, 0 , 6212 , 196, 141), // #1062
+ INST(Vfnmsub213ph , VexRvm_Lx , E(66MAP6,AE,_,_,_,0,4,FV ), 0 , 183, 0 , 6225 , 197, 125), // #1063
+ INST(Vfnmsub213ps , VexRvm_Lx , V(660F38,AE,_,x,0,0,4,FV ), 0 , 110, 0 , 6238 , 198, 141), // #1064
+ INST(Vfnmsub213sd , VexRvm , V(660F38,AF,_,I,1,1,3,T1S), 0 , 184, 0 , 6251 , 199, 142), // #1065
+ INST(Vfnmsub213sh , VexRvm , E(66MAP6,AF,_,_,_,0,1,T1S), 0 , 185, 0 , 6264 , 200, 127), // #1066
+ INST(Vfnmsub213ss , VexRvm , V(660F38,AF,_,I,0,0,2,T1S), 0 , 122, 0 , 6277 , 201, 142), // #1067
+ INST(Vfnmsub231pd , VexRvm_Lx , V(660F38,BE,_,x,1,1,4,FV ), 0 , 182, 0 , 6290 , 196, 141), // #1068
+ INST(Vfnmsub231ph , VexRvm_Lx , E(66MAP6,BE,_,_,_,0,4,FV ), 0 , 183, 0 , 6303 , 197, 125), // #1069
+ INST(Vfnmsub231ps , VexRvm_Lx , V(660F38,BE,_,x,0,0,4,FV ), 0 , 110, 0 , 6316 , 198, 141), // #1070
+ INST(Vfnmsub231sd , VexRvm , V(660F38,BF,_,I,1,1,3,T1S), 0 , 184, 0 , 6329 , 199, 142), // #1071
+ INST(Vfnmsub231sh , VexRvm , E(66MAP6,BF,_,_,_,0,1,T1S), 0 , 185, 0 , 6342 , 200, 127), // #1072
+ INST(Vfnmsub231ss , VexRvm , V(660F38,BF,_,I,0,0,2,T1S), 0 , 122, 0 , 6355 , 201, 142), // #1073
+ INST(Vfnmsubpd , Fma4_Lx , V(660F3A,7D,_,x,x,_,_,_ ), 0 , 73 , 0 , 6368 , 289, 143), // #1074
+ INST(Vfnmsubps , Fma4_Lx , V(660F3A,7C,_,x,x,_,_,_ ), 0 , 73 , 0 , 6378 , 289, 143), // #1075
+ INST(Vfnmsubsd , Fma4 , V(660F3A,7F,_,0,x,_,_,_ ), 0 , 73 , 0 , 6388 , 290, 143), // #1076
+ INST(Vfnmsubss , Fma4 , V(660F3A,7E,_,0,x,_,_,_ ), 0 , 73 , 0 , 6398 , 291, 143), // #1077
+ INST(Vfpclasspd , VexRmi_Lx , E(660F3A,66,_,x,_,1,4,FV ), 0 , 112, 0 , 6408 , 292, 133), // #1078
+ INST(Vfpclassph , VexRmi_Lx , E(000F3A,66,_,_,_,0,4,FV ), 0 , 123, 0 , 6419 , 293, 125), // #1079
+ INST(Vfpclassps , VexRmi_Lx , E(660F3A,66,_,x,_,0,4,FV ), 0 , 111, 0 , 6430 , 294, 133), // #1080
+ INST(Vfpclasssd , VexRmi , E(660F3A,67,_,I,_,1,3,T1S), 0 , 180, 0 , 6441 , 295, 66 ), // #1081
+ INST(Vfpclasssh , VexRmi , E(000F3A,67,_,_,_,0,1,T1S), 0 , 188, 0 , 6452 , 296, 127), // #1082
+ INST(Vfpclassss , VexRmi , E(660F3A,67,_,I,_,0,2,T1S), 0 , 181, 0 , 6463 , 297, 66 ), // #1083
+ INST(Vfrczpd , VexRm_Lx , V(XOP_M9,81,_,x,0,_,_,_ ), 0 , 79 , 0 , 6474 , 298, 144), // #1084
+ INST(Vfrczps , VexRm_Lx , V(XOP_M9,80,_,x,0,_,_,_ ), 0 , 79 , 0 , 6482 , 298, 144), // #1085
+ INST(Vfrczsd , VexRm , V(XOP_M9,83,_,0,0,_,_,_ ), 0 , 79 , 0 , 6490 , 299, 144), // #1086
+ INST(Vfrczss , VexRm , V(XOP_M9,82,_,0,0,_,_,_ ), 0 , 79 , 0 , 6498 , 300, 144), // #1087
+ INST(Vgatherdpd , VexRmvRm_VM , V(660F38,92,_,x,1,_,_,_ ), E(660F38,92,_,x,_,1,3,T1S), 189, 80 , 6506 , 301, 145), // #1088
+ INST(Vgatherdps , VexRmvRm_VM , V(660F38,92,_,x,0,_,_,_ ), E(660F38,92,_,x,_,0,2,T1S), 96 , 81 , 6517 , 302, 145), // #1089
+ INST(Vgatherpf0dpd , VexM_VM , E(660F38,C6,1,2,_,1,3,T1S), 0 , 190, 0 , 6528 , 303, 146), // #1090
+ INST(Vgatherpf0dps , VexM_VM , E(660F38,C6,1,2,_,0,2,T1S), 0 , 191, 0 , 6542 , 304, 146), // #1091
+ INST(Vgatherpf0qpd , VexM_VM , E(660F38,C7,1,2,_,1,3,T1S), 0 , 190, 0 , 6556 , 305, 146), // #1092
+ INST(Vgatherpf0qps , VexM_VM , E(660F38,C7,1,2,_,0,2,T1S), 0 , 191, 0 , 6570 , 305, 146), // #1093
+ INST(Vgatherpf1dpd , VexM_VM , E(660F38,C6,2,2,_,1,3,T1S), 0 , 192, 0 , 6584 , 303, 146), // #1094
+ INST(Vgatherpf1dps , VexM_VM , E(660F38,C6,2,2,_,0,2,T1S), 0 , 193, 0 , 6598 , 304, 146), // #1095
+ INST(Vgatherpf1qpd , VexM_VM , E(660F38,C7,2,2,_,1,3,T1S), 0 , 192, 0 , 6612 , 305, 146), // #1096
+ INST(Vgatherpf1qps , VexM_VM , E(660F38,C7,2,2,_,0,2,T1S), 0 , 193, 0 , 6626 , 305, 146), // #1097
+ INST(Vgatherqpd , VexRmvRm_VM , V(660F38,93,_,x,1,_,_,_ ), E(660F38,93,_,x,_,1,3,T1S), 189, 82 , 6640 , 306, 145), // #1098
+ INST(Vgatherqps , VexRmvRm_VM , V(660F38,93,_,x,0,_,_,_ ), E(660F38,93,_,x,_,0,2,T1S), 96 , 83 , 6651 , 307, 145), // #1099
+ INST(Vgetexppd , VexRm_Lx , E(660F38,42,_,x,_,1,4,FV ), 0 , 113, 0 , 6662 , 263, 131), // #1100
+ INST(Vgetexpph , VexRm_Lx , E(66MAP6,42,_,_,_,0,4,FV ), 0 , 183, 0 , 6672 , 265, 125), // #1101
+ INST(Vgetexpps , VexRm_Lx , E(660F38,42,_,x,_,0,4,FV ), 0 , 114, 0 , 6682 , 268, 131), // #1102
+ INST(Vgetexpsd , VexRvm , E(660F38,43,_,I,_,1,3,T1S), 0 , 128, 0 , 6692 , 308, 68 ), // #1103
+ INST(Vgetexpsh , VexRvm , E(66MAP6,43,_,_,_,0,1,T1S), 0 , 185, 0 , 6702 , 254, 127), // #1104
+ INST(Vgetexpss , VexRvm , E(660F38,43,_,I,_,0,2,T1S), 0 , 129, 0 , 6712 , 309, 68 ), // #1105
+ INST(Vgetmantpd , VexRmi_Lx , E(660F3A,26,_,x,_,1,4,FV ), 0 , 112, 0 , 6722 , 310, 131), // #1106
+ INST(Vgetmantph , VexRmi_Lx , E(000F3A,26,_,_,_,0,4,FV ), 0 , 123, 0 , 6733 , 311, 125), // #1107
+ INST(Vgetmantps , VexRmi_Lx , E(660F3A,26,_,x,_,0,4,FV ), 0 , 111, 0 , 6744 , 312, 131), // #1108
+ INST(Vgetmantsd , VexRvmi , E(660F3A,27,_,I,_,1,3,T1S), 0 , 180, 0 , 6755 , 287, 68 ), // #1109
+ INST(Vgetmantsh , VexRvmi , E(000F3A,27,_,_,_,0,1,T1S), 0 , 188, 0 , 6766 , 313, 127), // #1110
+ INST(Vgetmantss , VexRvmi , E(660F3A,27,_,I,_,0,2,T1S), 0 , 181, 0 , 6777 , 288, 68 ), // #1111
+ INST(Vgf2p8affineinvqb, VexRvmi_Lx , V(660F3A,CF,_,x,1,1,4,FV ), 0 , 194, 0 , 6788 , 314, 147), // #1112
+ INST(Vgf2p8affineqb , VexRvmi_Lx , V(660F3A,CE,_,x,1,1,4,FV ), 0 , 194, 0 , 6806 , 314, 147), // #1113
+ INST(Vgf2p8mulb , VexRvm_Lx , V(660F38,CF,_,x,0,0,4,FV ), 0 , 110, 0 , 6821 , 315, 147), // #1114
+ INST(Vhaddpd , VexRvm_Lx , V(660F00,7C,_,x,I,_,_,_ ), 0 , 69 , 0 , 6832 , 202, 128), // #1115
+ INST(Vhaddps , VexRvm_Lx , V(F20F00,7C,_,x,I,_,_,_ ), 0 , 109, 0 , 6840 , 202, 128), // #1116
+ INST(Vhsubpd , VexRvm_Lx , V(660F00,7D,_,x,I,_,_,_ ), 0 , 69 , 0 , 6848 , 202, 128), // #1117
+ INST(Vhsubps , VexRvm_Lx , V(F20F00,7D,_,x,I,_,_,_ ), 0 , 109, 0 , 6856 , 202, 128), // #1118
+ INST(Vinsertf128 , VexRvmi , V(660F3A,18,_,1,0,_,_,_ ), 0 , 172, 0 , 6864 , 316, 128), // #1119
+ INST(Vinsertf32x4 , VexRvmi_Lx , E(660F3A,18,_,x,_,0,4,T4 ), 0 , 173, 0 , 6876 , 317, 131), // #1120
+ INST(Vinsertf32x8 , VexRvmi , E(660F3A,1A,_,2,_,0,5,T8 ), 0 , 174, 0 , 6889 , 318, 66 ), // #1121
+ INST(Vinsertf64x2 , VexRvmi_Lx , E(660F3A,18,_,x,_,1,4,T2 ), 0 , 175, 0 , 6902 , 317, 133), // #1122
+ INST(Vinsertf64x4 , VexRvmi , E(660F3A,1A,_,2,_,1,5,T4 ), 0 , 176, 0 , 6915 , 318, 68 ), // #1123
+ INST(Vinserti128 , VexRvmi , V(660F3A,38,_,1,0,_,_,_ ), 0 , 172, 0 , 6928 , 316, 134), // #1124
+ INST(Vinserti32x4 , VexRvmi_Lx , E(660F3A,38,_,x,_,0,4,T4 ), 0 , 173, 0 , 6940 , 317, 131), // #1125
+ INST(Vinserti32x8 , VexRvmi , E(660F3A,3A,_,2,_,0,5,T8 ), 0 , 174, 0 , 6953 , 318, 66 ), // #1126
+ INST(Vinserti64x2 , VexRvmi_Lx , E(660F3A,38,_,x,_,1,4,T2 ), 0 , 175, 0 , 6966 , 317, 133), // #1127
+ INST(Vinserti64x4 , VexRvmi , E(660F3A,3A,_,2,_,1,5,T4 ), 0 , 176, 0 , 6979 , 318, 68 ), // #1128
+ INST(Vinsertps , VexRvmi , V(660F3A,21,_,0,I,0,2,T1S), 0 , 177, 0 , 6992 , 319, 126), // #1129
+ INST(Vlddqu , VexRm_Lx , V(F20F00,F0,_,x,I,_,_,_ ), 0 , 109, 0 , 7002 , 320, 128), // #1130
+ INST(Vldmxcsr , VexM , V(000F00,AE,2,0,I,_,_,_ ), 0 , 195, 0 , 7009 , 321, 128), // #1131
+ INST(Vmaskmovdqu , VexRm_ZDI , V(660F00,F7,_,0,I,_,_,_ ), 0 , 69 , 0 , 7018 , 322, 128), // #1132
+ INST(Vmaskmovpd , VexRvmMvr_Lx , V(660F38,2D,_,x,0,_,_,_ ), V(660F38,2F,_,x,0,_,_,_ ), 96 , 84 , 7030 , 323, 128), // #1133
+ INST(Vmaskmovps , VexRvmMvr_Lx , V(660F38,2C,_,x,0,_,_,_ ), V(660F38,2E,_,x,0,_,_,_ ), 96 , 85 , 7041 , 323, 128), // #1134
+ INST(Vmaxpd , VexRvm_Lx , V(660F00,5F,_,x,I,1,4,FV ), 0 , 103, 0 , 7052 , 324, 124), // #1135
+ INST(Vmaxph , VexRvm_Lx , E(00MAP5,5F,_,_,_,0,4,FV ), 0 , 104, 0 , 7059 , 325, 125), // #1136
+ INST(Vmaxps , VexRvm_Lx , V(000F00,5F,_,x,I,0,4,FV ), 0 , 105, 0 , 7066 , 326, 124), // #1137
+ INST(Vmaxsd , VexRvm , V(F20F00,5F,_,I,I,1,3,T1S), 0 , 106, 0 , 7073 , 327, 124), // #1138
+ INST(Vmaxsh , VexRvm , E(F3MAP5,5F,_,_,_,0,1,T1S), 0 , 107, 0 , 7080 , 254, 127), // #1139
+ INST(Vmaxss , VexRvm , V(F30F00,5F,_,I,I,0,2,T1S), 0 , 108, 0 , 7087 , 258, 124), // #1140
+ INST(Vmcall , X86Op , O(000F01,C1,_,_,_,_,_,_ ), 0 , 21 , 0 , 7094 , 30 , 58 ), // #1141
+ INST(Vmclear , X86M_Only , O(660F00,C7,6,_,_,_,_,_ ), 0 , 26 , 0 , 7101 , 32 , 58 ), // #1142
+ INST(Vmfunc , X86Op , O(000F01,D4,_,_,_,_,_,_ ), 0 , 21 , 0 , 7109 , 30 , 58 ), // #1143
+ INST(Vminpd , VexRvm_Lx , V(660F00,5D,_,x,I,1,4,FV ), 0 , 103, 0 , 7116 , 324, 124), // #1144
+ INST(Vminph , VexRvm_Lx , E(00MAP5,5D,_,_,_,0,4,FV ), 0 , 104, 0 , 7123 , 325, 125), // #1145
+ INST(Vminps , VexRvm_Lx , V(000F00,5D,_,x,I,0,4,FV ), 0 , 105, 0 , 7130 , 326, 124), // #1146
+ INST(Vminsd , VexRvm , V(F20F00,5D,_,I,I,1,3,T1S), 0 , 106, 0 , 7137 , 327, 124), // #1147
+ INST(Vminsh , VexRvm , E(F3MAP5,5D,_,_,_,0,1,T1S), 0 , 107, 0 , 7144 , 254, 127), // #1148
+ INST(Vminss , VexRvm , V(F30F00,5D,_,I,I,0,2,T1S), 0 , 108, 0 , 7151 , 258, 124), // #1149
+ INST(Vmlaunch , X86Op , O(000F01,C2,_,_,_,_,_,_ ), 0 , 21 , 0 , 7158 , 30 , 58 ), // #1150
+ INST(Vmload , X86Op_xAX , O(000F01,DA,_,_,_,_,_,_ ), 0 , 21 , 0 , 7167 , 328, 22 ), // #1151
+ INST(Vmmcall , X86Op , O(000F01,D9,_,_,_,_,_,_ ), 0 , 21 , 0 , 7174 , 30 , 22 ), // #1152
+ INST(Vmovapd , VexRmMr_Lx , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 103, 86 , 7182 , 329, 124), // #1153
+ INST(Vmovaps , VexRmMr_Lx , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 105, 87 , 7190 , 329, 124), // #1154
+ INST(Vmovd , VexMovdMovq , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 196, 88 , 7198 , 330, 126), // #1155
+ INST(Vmovddup , VexRm_Lx , V(F20F00,12,_,x,I,1,3,DUP), 0 , 197, 0 , 7204 , 331, 124), // #1156
+ INST(Vmovdqa , VexRmMr_Lx , V(660F00,6F,_,x,I,_,_,_ ), V(660F00,7F,_,x,I,_,_,_ ), 69 , 89 , 7213 , 332, 128), // #1157
+ INST(Vmovdqa32 , VexRmMr_Lx , E(660F00,6F,_,x,_,0,4,FVM), E(660F00,7F,_,x,_,0,4,FVM), 198, 90 , 7221 , 333, 131), // #1158
+ INST(Vmovdqa64 , VexRmMr_Lx , E(660F00,6F,_,x,_,1,4,FVM), E(660F00,7F,_,x,_,1,4,FVM), 135, 91 , 7231 , 333, 131), // #1159
+ INST(Vmovdqu , VexRmMr_Lx , V(F30F00,6F,_,x,I,_,_,_ ), V(F30F00,7F,_,x,I,_,_,_ ), 199, 92 , 7241 , 332, 128), // #1160
+ INST(Vmovdqu16 , VexRmMr_Lx , E(F20F00,6F,_,x,_,1,4,FVM), E(F20F00,7F,_,x,_,1,4,FVM), 166, 93 , 7249 , 333, 139), // #1161
+ INST(Vmovdqu32 , VexRmMr_Lx , E(F30F00,6F,_,x,_,0,4,FVM), E(F30F00,7F,_,x,_,0,4,FVM), 200, 94 , 7259 , 333, 131), // #1162
+ INST(Vmovdqu64 , VexRmMr_Lx , E(F30F00,6F,_,x,_,1,4,FVM), E(F30F00,7F,_,x,_,1,4,FVM), 149, 95 , 7269 , 333, 131), // #1163
+ INST(Vmovdqu8 , VexRmMr_Lx , E(F20F00,6F,_,x,_,0,4,FVM), E(F20F00,7F,_,x,_,0,4,FVM), 164, 96 , 7279 , 333, 139), // #1164
+ INST(Vmovhlps , VexRvm , V(000F00,12,_,0,I,0,_,_ ), 0 , 72 , 0 , 7288 , 334, 126), // #1165
+ INST(Vmovhpd , VexRvmMr , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 125, 97 , 7297 , 335, 126), // #1166
+ INST(Vmovhps , VexRvmMr , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 201, 98 , 7305 , 335, 126), // #1167
+ INST(Vmovlhps , VexRvm , V(000F00,16,_,0,I,0,_,_ ), 0 , 72 , 0 , 7313 , 334, 126), // #1168
+ INST(Vmovlpd , VexRvmMr , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 125, 99 , 7322 , 335, 126), // #1169
+ INST(Vmovlps , VexRvmMr , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 201, 100, 7330 , 335, 126), // #1170
+ INST(Vmovmskpd , VexRm_Lx , V(660F00,50,_,x,I,_,_,_ ), 0 , 69 , 0 , 7338 , 336, 128), // #1171
+ INST(Vmovmskps , VexRm_Lx , V(000F00,50,_,x,I,_,_,_ ), 0 , 72 , 0 , 7348 , 336, 128), // #1172
+ INST(Vmovntdq , VexMr_Lx , V(660F00,E7,_,x,I,0,4,FVM), 0 , 144, 0 , 7358 , 337, 124), // #1173
+ INST(Vmovntdqa , VexRm_Lx , V(660F38,2A,_,x,I,0,4,FVM), 0 , 110, 0 , 7367 , 338, 135), // #1174
+ INST(Vmovntpd , VexMr_Lx , V(660F00,2B,_,x,I,1,4,FVM), 0 , 103, 0 , 7377 , 337, 124), // #1175
+ INST(Vmovntps , VexMr_Lx , V(000F00,2B,_,x,I,0,4,FVM), 0 , 105, 0 , 7386 , 337, 124), // #1176
+ INST(Vmovq , VexMovdMovq , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 125, 101, 7395 , 339, 126), // #1177
+ INST(Vmovsd , VexMovssMovsd , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 106, 102, 7401 , 340, 126), // #1178
+ INST(Vmovsh , VexMovssMovsd , E(F3MAP5,10,_,I,_,0,1,T1S), E(F3MAP5,11,_,I,_,0,1,T1S), 107, 103, 7408 , 341, 127), // #1179
+ INST(Vmovshdup , VexRm_Lx , V(F30F00,16,_,x,I,0,4,FVM), 0 , 161, 0 , 7415 , 342, 124), // #1180
+ INST(Vmovsldup , VexRm_Lx , V(F30F00,12,_,x,I,0,4,FVM), 0 , 161, 0 , 7425 , 342, 124), // #1181
+ INST(Vmovss , VexMovssMovsd , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 108, 104, 7435 , 343, 126), // #1182
+ INST(Vmovupd , VexRmMr_Lx , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 103, 105, 7442 , 329, 124), // #1183
+ INST(Vmovups , VexRmMr_Lx , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 105, 106, 7450 , 329, 124), // #1184
+ INST(Vmovw , VexMovdMovq , E(66MAP5,6E,_,0,_,I,1,T1S), E(66MAP5,7E,_,0,_,I,1,T1S), 202, 107, 7458 , 344, 127), // #1185
+ INST(Vmpsadbw , VexRvmi_Lx , V(660F3A,42,_,x,I,_,_,_ ), 0 , 73 , 0 , 7464 , 214, 148), // #1186
+ INST(Vmptrld , X86M_Only , O(000F00,C7,6,_,_,_,_,_ ), 0 , 80 , 0 , 7473 , 32 , 58 ), // #1187
+ INST(Vmptrst , X86M_Only , O(000F00,C7,7,_,_,_,_,_ ), 0 , 22 , 0 , 7481 , 32 , 58 ), // #1188
+ INST(Vmread , X86Mr_NoSize , O(000F00,78,_,_,_,_,_,_ ), 0 , 4 , 0 , 7489 , 345, 58 ), // #1189
+ INST(Vmresume , X86Op , O(000F01,C3,_,_,_,_,_,_ ), 0 , 21 , 0 , 7496 , 30 , 58 ), // #1190
+ INST(Vmrun , X86Op_xAX , O(000F01,D8,_,_,_,_,_,_ ), 0 , 21 , 0 , 7505 , 328, 22 ), // #1191
+ INST(Vmsave , X86Op_xAX , O(000F01,DB,_,_,_,_,_,_ ), 0 , 21 , 0 , 7511 , 328, 22 ), // #1192
+ INST(Vmulpd , VexRvm_Lx , V(660F00,59,_,x,I,1,4,FV ), 0 , 103, 0 , 7518 , 196, 124), // #1193
+ INST(Vmulph , VexRvm_Lx , E(00MAP5,59,_,_,_,0,4,FV ), 0 , 104, 0 , 7525 , 197, 125), // #1194
+ INST(Vmulps , VexRvm_Lx , V(000F00,59,_,x,I,0,4,FV ), 0 , 105, 0 , 7532 , 198, 124), // #1195
+ INST(Vmulsd , VexRvm , V(F20F00,59,_,I,I,1,3,T1S), 0 , 106, 0 , 7539 , 199, 126), // #1196
+ INST(Vmulsh , VexRvm , E(F3MAP5,59,_,_,_,0,1,T1S), 0 , 107, 0 , 7546 , 200, 127), // #1197
+ INST(Vmulss , VexRvm , V(F30F00,59,_,I,I,0,2,T1S), 0 , 108, 0 , 7553 , 201, 126), // #1198
+ INST(Vmwrite , X86Rm_NoSize , O(000F00,79,_,_,_,_,_,_ ), 0 , 4 , 0 , 7560 , 346, 58 ), // #1199
+ INST(Vmxon , X86M_Only , O(F30F00,C7,6,_,_,_,_,_ ), 0 , 24 , 0 , 7568 , 32 , 58 ), // #1200
+ INST(Vorpd , VexRvm_Lx , V(660F00,56,_,x,I,1,4,FV ), 0 , 103, 0 , 7574 , 210, 132), // #1201
+ INST(Vorps , VexRvm_Lx , V(000F00,56,_,x,I,0,4,FV ), 0 , 105, 0 , 7580 , 211, 132), // #1202
+ INST(Vp2intersectd , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,0,4,FV ), 0 , 131, 0 , 7586 , 347, 149), // #1203
+ INST(Vp2intersectq , VexRvm_Lx_2xK , E(F20F38,68,_,_,_,1,4,FV ), 0 , 203, 0 , 7600 , 348, 149), // #1204
+ INST(Vp4dpwssd , VexRm_T1_4X , E(F20F38,52,_,2,_,0,4,T4X), 0 , 101, 0 , 7614 , 194, 150), // #1205
+ INST(Vp4dpwssds , VexRm_T1_4X , E(F20F38,53,_,2,_,0,4,T4X), 0 , 101, 0 , 7624 , 194, 150), // #1206
+ INST(Vpabsb , VexRm_Lx , V(660F38,1C,_,x,I,_,4,FVM), 0 , 110, 0 , 7635 , 342, 151), // #1207
+ INST(Vpabsd , VexRm_Lx , V(660F38,1E,_,x,I,0,4,FV ), 0 , 110, 0 , 7642 , 349, 135), // #1208
+ INST(Vpabsq , VexRm_Lx , E(660F38,1F,_,x,_,1,4,FV ), 0 , 113, 0 , 7649 , 350, 131), // #1209
+ INST(Vpabsw , VexRm_Lx , V(660F38,1D,_,x,I,_,4,FVM), 0 , 110, 0 , 7656 , 342, 151), // #1210
+ INST(Vpackssdw , VexRvm_Lx , V(660F00,6B,_,x,I,0,4,FV ), 0 , 144, 0 , 7663 , 209, 151), // #1211
+ INST(Vpacksswb , VexRvm_Lx , V(660F00,63,_,x,I,I,4,FVM), 0 , 144, 0 , 7673 , 315, 151), // #1212
+ INST(Vpackusdw , VexRvm_Lx , V(660F38,2B,_,x,I,0,4,FV ), 0 , 110, 0 , 7683 , 209, 151), // #1213
+ INST(Vpackuswb , VexRvm_Lx , V(660F00,67,_,x,I,I,4,FVM), 0 , 144, 0 , 7693 , 315, 151), // #1214
+ INST(Vpaddb , VexRvm_Lx , V(660F00,FC,_,x,I,I,4,FVM), 0 , 144, 0 , 7703 , 315, 151), // #1215
+ INST(Vpaddd , VexRvm_Lx , V(660F00,FE,_,x,I,0,4,FV ), 0 , 144, 0 , 7710 , 209, 135), // #1216
+ INST(Vpaddq , VexRvm_Lx , V(660F00,D4,_,x,I,1,4,FV ), 0 , 103, 0 , 7717 , 208, 135), // #1217
+ INST(Vpaddsb , VexRvm_Lx , V(660F00,EC,_,x,I,I,4,FVM), 0 , 144, 0 , 7724 , 315, 151), // #1218
+ INST(Vpaddsw , VexRvm_Lx , V(660F00,ED,_,x,I,I,4,FVM), 0 , 144, 0 , 7732 , 315, 151), // #1219
+ INST(Vpaddusb , VexRvm_Lx , V(660F00,DC,_,x,I,I,4,FVM), 0 , 144, 0 , 7740 , 315, 151), // #1220
+ INST(Vpaddusw , VexRvm_Lx , V(660F00,DD,_,x,I,I,4,FVM), 0 , 144, 0 , 7749 , 315, 151), // #1221
+ INST(Vpaddw , VexRvm_Lx , V(660F00,FD,_,x,I,I,4,FVM), 0 , 144, 0 , 7758 , 315, 151), // #1222
+ INST(Vpalignr , VexRvmi_Lx , V(660F3A,0F,_,x,I,I,4,FVM), 0 , 204, 0 , 7765 , 314, 151), // #1223
+ INST(Vpand , VexRvm_Lx , V(660F00,DB,_,x,I,_,_,_ ), 0 , 69 , 0 , 7774 , 351, 148), // #1224
+ INST(Vpandd , VexRvm_Lx , E(660F00,DB,_,x,_,0,4,FV ), 0 , 198, 0 , 7780 , 352, 131), // #1225
+ INST(Vpandn , VexRvm_Lx , V(660F00,DF,_,x,I,_,_,_ ), 0 , 69 , 0 , 7787 , 353, 148), // #1226
+ INST(Vpandnd , VexRvm_Lx , E(660F00,DF,_,x,_,0,4,FV ), 0 , 198, 0 , 7794 , 354, 131), // #1227
+ INST(Vpandnq , VexRvm_Lx , E(660F00,DF,_,x,_,1,4,FV ), 0 , 135, 0 , 7802 , 355, 131), // #1228
+ INST(Vpandq , VexRvm_Lx , E(660F00,DB,_,x,_,1,4,FV ), 0 , 135, 0 , 7810 , 356, 131), // #1229
+ INST(Vpavgb , VexRvm_Lx , V(660F00,E0,_,x,I,I,4,FVM), 0 , 144, 0 , 7817 , 315, 151), // #1230
+ INST(Vpavgw , VexRvm_Lx , V(660F00,E3,_,x,I,I,4,FVM), 0 , 144, 0 , 7824 , 315, 151), // #1231
+ INST(Vpblendd , VexRvmi_Lx , V(660F3A,02,_,x,0,_,_,_ ), 0 , 73 , 0 , 7831 , 214, 134), // #1232
+ INST(Vpblendmb , VexRvm_Lx , E(660F38,66,_,x,_,0,4,FVM), 0 , 114, 0 , 7840 , 357, 139), // #1233
+ INST(Vpblendmd , VexRvm_Lx , E(660F38,64,_,x,_,0,4,FV ), 0 , 114, 0 , 7850 , 213, 131), // #1234
+ INST(Vpblendmq , VexRvm_Lx , E(660F38,64,_,x,_,1,4,FV ), 0 , 113, 0 , 7860 , 212, 131), // #1235
+ INST(Vpblendmw , VexRvm_Lx , E(660F38,66,_,x,_,1,4,FVM), 0 , 113, 0 , 7870 , 357, 139), // #1236
+ INST(Vpblendvb , VexRvmr_Lx , V(660F3A,4C,_,x,0,_,_,_ ), 0 , 73 , 0 , 7880 , 215, 148), // #1237
+ INST(Vpblendw , VexRvmi_Lx , V(660F3A,0E,_,x,I,_,_,_ ), 0 , 73 , 0 , 7890 , 214, 148), // #1238
+ INST(Vpbroadcastb , VexRm_Lx_Bcst , V(660F38,78,_,x,0,0,0,T1S), E(660F38,7A,_,x,0,0,0,T1S), 96 , 108, 7899 , 358, 152), // #1239
+ INST(Vpbroadcastd , VexRm_Lx_Bcst , V(660F38,58,_,x,0,0,2,T1S), E(660F38,7C,_,x,0,0,0,T1S), 122, 109, 7912 , 359, 145), // #1240
+ INST(Vpbroadcastmb2q , VexRm_Lx , E(F30F38,2A,_,x,_,1,_,_ ), 0 , 205, 0 , 7925 , 360, 153), // #1241
+ INST(Vpbroadcastmw2d , VexRm_Lx , E(F30F38,3A,_,x,_,0,_,_ ), 0 , 206, 0 , 7941 , 360, 153), // #1242
+ INST(Vpbroadcastq , VexRm_Lx_Bcst , V(660F38,59,_,x,0,1,3,T1S), E(660F38,7C,_,x,0,1,0,T1S), 121, 110, 7957 , 361, 145), // #1243
+ INST(Vpbroadcastw , VexRm_Lx_Bcst , V(660F38,79,_,x,0,0,1,T1S), E(660F38,7B,_,x,0,0,0,T1S), 207, 111, 7970 , 362, 152), // #1244
+ INST(Vpclmulqdq , VexRvmi_Lx , V(660F3A,44,_,x,I,_,4,FVM), 0 , 204, 0 , 7983 , 363, 154), // #1245
+ INST(Vpcmov , VexRvrmRvmr_Lx , V(XOP_M8,A2,_,x,x,_,_,_ ), 0 , 208, 0 , 7994 , 289, 144), // #1246
+ INST(Vpcmpb , VexRvmi_Lx , E(660F3A,3F,_,x,_,0,4,FVM), 0 , 111, 0 , 8001 , 364, 139), // #1247
+ INST(Vpcmpd , VexRvmi_Lx , E(660F3A,1F,_,x,_,0,4,FV ), 0 , 111, 0 , 8008 , 365, 131), // #1248
+ INST(Vpcmpeqb , VexRvm_Lx_KEvex , V(660F00,74,_,x,I,I,4,FV ), 0 , 144, 0 , 8015 , 366, 151), // #1249
+ INST(Vpcmpeqd , VexRvm_Lx_KEvex , V(660F00,76,_,x,I,0,4,FVM), 0 , 144, 0 , 8024 , 367, 135), // #1250
+ INST(Vpcmpeqq , VexRvm_Lx_KEvex , V(660F38,29,_,x,I,1,4,FVM), 0 , 209, 0 , 8033 , 368, 135), // #1251
+ INST(Vpcmpeqw , VexRvm_Lx_KEvex , V(660F00,75,_,x,I,I,4,FV ), 0 , 144, 0 , 8042 , 366, 151), // #1252
+ INST(Vpcmpestri , VexRmi , V(660F3A,61,_,0,I,_,_,_ ), 0 , 73 , 0 , 8051 , 369, 155), // #1253
+ INST(Vpcmpestrm , VexRmi , V(660F3A,60,_,0,I,_,_,_ ), 0 , 73 , 0 , 8062 , 370, 155), // #1254
+ INST(Vpcmpgtb , VexRvm_Lx_KEvex , V(660F00,64,_,x,I,I,4,FV ), 0 , 144, 0 , 8073 , 366, 151), // #1255
+ INST(Vpcmpgtd , VexRvm_Lx_KEvex , V(660F00,66,_,x,I,0,4,FVM), 0 , 144, 0 , 8082 , 367, 135), // #1256
+ INST(Vpcmpgtq , VexRvm_Lx_KEvex , V(660F38,37,_,x,I,1,4,FVM), 0 , 209, 0 , 8091 , 368, 135), // #1257
+ INST(Vpcmpgtw , VexRvm_Lx_KEvex , V(660F00,65,_,x,I,I,4,FV ), 0 , 144, 0 , 8100 , 366, 151), // #1258
+ INST(Vpcmpistri , VexRmi , V(660F3A,63,_,0,I,_,_,_ ), 0 , 73 , 0 , 8109 , 371, 155), // #1259
+ INST(Vpcmpistrm , VexRmi , V(660F3A,62,_,0,I,_,_,_ ), 0 , 73 , 0 , 8120 , 372, 155), // #1260
+ INST(Vpcmpq , VexRvmi_Lx , E(660F3A,1F,_,x,_,1,4,FV ), 0 , 112, 0 , 8131 , 373, 131), // #1261
+ INST(Vpcmpub , VexRvmi_Lx , E(660F3A,3E,_,x,_,0,4,FVM), 0 , 111, 0 , 8138 , 364, 139), // #1262
+ INST(Vpcmpud , VexRvmi_Lx , E(660F3A,1E,_,x,_,0,4,FV ), 0 , 111, 0 , 8146 , 365, 131), // #1263
+ INST(Vpcmpuq , VexRvmi_Lx , E(660F3A,1E,_,x,_,1,4,FV ), 0 , 112, 0 , 8154 , 373, 131), // #1264
+ INST(Vpcmpuw , VexRvmi_Lx , E(660F3A,3E,_,x,_,1,4,FVM), 0 , 112, 0 , 8162 , 373, 139), // #1265
+ INST(Vpcmpw , VexRvmi_Lx , E(660F3A,3F,_,x,_,1,4,FVM), 0 , 112, 0 , 8170 , 373, 139), // #1266
+ INST(Vpcomb , VexRvmi , V(XOP_M8,CC,_,0,0,_,_,_ ), 0 , 208, 0 , 8177 , 276, 144), // #1267
+ INST(Vpcomd , VexRvmi , V(XOP_M8,CE,_,0,0,_,_,_ ), 0 , 208, 0 , 8184 , 276, 144), // #1268
+ INST(Vpcompressb , VexMr_Lx , E(660F38,63,_,x,_,0,0,T1S), 0 , 210, 0 , 8191 , 232, 156), // #1269
+ INST(Vpcompressd , VexMr_Lx , E(660F38,8B,_,x,_,0,2,T1S), 0 , 129, 0 , 8203 , 232, 131), // #1270
+ INST(Vpcompressq , VexMr_Lx , E(660F38,8B,_,x,_,1,3,T1S), 0 , 128, 0 , 8215 , 232, 131), // #1271
+ INST(Vpcompressw , VexMr_Lx , E(660F38,63,_,x,_,1,1,T1S), 0 , 211, 0 , 8227 , 232, 156), // #1272
+ INST(Vpcomq , VexRvmi , V(XOP_M8,CF,_,0,0,_,_,_ ), 0 , 208, 0 , 8239 , 276, 144), // #1273
+ INST(Vpcomub , VexRvmi , V(XOP_M8,EC,_,0,0,_,_,_ ), 0 , 208, 0 , 8246 , 276, 144), // #1274
+ INST(Vpcomud , VexRvmi , V(XOP_M8,EE,_,0,0,_,_,_ ), 0 , 208, 0 , 8254 , 276, 144), // #1275
+ INST(Vpcomuq , VexRvmi , V(XOP_M8,EF,_,0,0,_,_,_ ), 0 , 208, 0 , 8262 , 276, 144), // #1276
+ INST(Vpcomuw , VexRvmi , V(XOP_M8,ED,_,0,0,_,_,_ ), 0 , 208, 0 , 8270 , 276, 144), // #1277
+ INST(Vpcomw , VexRvmi , V(XOP_M8,CD,_,0,0,_,_,_ ), 0 , 208, 0 , 8278 , 276, 144), // #1278
+ INST(Vpconflictd , VexRm_Lx , E(660F38,C4,_,x,_,0,4,FV ), 0 , 114, 0 , 8285 , 374, 153), // #1279
+ INST(Vpconflictq , VexRm_Lx , E(660F38,C4,_,x,_,1,4,FV ), 0 , 113, 0 , 8297 , 374, 153), // #1280
+ INST(Vpdpbusd , VexRvm_Lx , V(660F38,50,_,x,_,0,4,FV ), 0 , 110, 0 , 8309 , 375, 157), // #1281
+ INST(Vpdpbusds , VexRvm_Lx , V(660F38,51,_,x,_,0,4,FV ), 0 , 110, 0 , 8318 , 375, 157), // #1282
+ INST(Vpdpwssd , VexRvm_Lx , V(660F38,52,_,x,_,0,4,FV ), 0 , 110, 0 , 8328 , 375, 157), // #1283
+ INST(Vpdpwssds , VexRvm_Lx , V(660F38,53,_,x,_,0,4,FV ), 0 , 110, 0 , 8337 , 375, 157), // #1284
+ INST(Vperm2f128 , VexRvmi , V(660F3A,06,_,1,0,_,_,_ ), 0 , 172, 0 , 8347 , 376, 128), // #1285
+ INST(Vperm2i128 , VexRvmi , V(660F3A,46,_,1,0,_,_,_ ), 0 , 172, 0 , 8358 , 376, 134), // #1286
+ INST(Vpermb , VexRvm_Lx , E(660F38,8D,_,x,_,0,4,FVM), 0 , 114, 0 , 8369 , 357, 158), // #1287
+ INST(Vpermd , VexRvm_Lx , V(660F38,36,_,x,0,0,4,FV ), 0 , 110, 0 , 8376 , 377, 145), // #1288
+ INST(Vpermi2b , VexRvm_Lx , E(660F38,75,_,x,_,0,4,FVM), 0 , 114, 0 , 8383 , 357, 158), // #1289
+ INST(Vpermi2d , VexRvm_Lx , E(660F38,76,_,x,_,0,4,FV ), 0 , 114, 0 , 8392 , 213, 131), // #1290
+ INST(Vpermi2pd , VexRvm_Lx , E(660F38,77,_,x,_,1,4,FV ), 0 , 113, 0 , 8401 , 212, 131), // #1291
+ INST(Vpermi2ps , VexRvm_Lx , E(660F38,77,_,x,_,0,4,FV ), 0 , 114, 0 , 8411 , 213, 131), // #1292
+ INST(Vpermi2q , VexRvm_Lx , E(660F38,76,_,x,_,1,4,FV ), 0 , 113, 0 , 8421 , 212, 131), // #1293
+ INST(Vpermi2w , VexRvm_Lx , E(660F38,75,_,x,_,1,4,FVM), 0 , 113, 0 , 8430 , 357, 139), // #1294
+ INST(Vpermil2pd , VexRvrmiRvmri_Lx , V(660F3A,49,_,x,x,_,_,_ ), 0 , 73 , 0 , 8439 , 378, 144), // #1295
+ INST(Vpermil2ps , VexRvrmiRvmri_Lx , V(660F3A,48,_,x,x,_,_,_ ), 0 , 73 , 0 , 8450 , 378, 144), // #1296
+ INST(Vpermilpd , VexRvmRmi_Lx , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 209, 112, 8461 , 379, 124), // #1297
+ INST(Vpermilps , VexRvmRmi_Lx , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 110, 113, 8471 , 380, 124), // #1298
+ INST(Vpermpd , VexRvmRmi_Lx , E(660F38,16,_,x,1,1,4,FV ), V(660F3A,01,_,x,1,1,4,FV ), 212, 114, 8481 , 381, 145), // #1299
+ INST(Vpermps , VexRvm_Lx , V(660F38,16,_,x,0,0,4,FV ), 0 , 110, 0 , 8489 , 377, 145), // #1300
+ INST(Vpermq , VexRvmRmi_Lx , E(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 113, 115, 8497 , 381, 145), // #1301
+ INST(Vpermt2b , VexRvm_Lx , E(660F38,7D,_,x,_,0,4,FVM), 0 , 114, 0 , 8504 , 357, 158), // #1302
+ INST(Vpermt2d , VexRvm_Lx , E(660F38,7E,_,x,_,0,4,FV ), 0 , 114, 0 , 8513 , 213, 131), // #1303
+ INST(Vpermt2pd , VexRvm_Lx , E(660F38,7F,_,x,_,1,4,FV ), 0 , 113, 0 , 8522 , 212, 131), // #1304
+ INST(Vpermt2ps , VexRvm_Lx , E(660F38,7F,_,x,_,0,4,FV ), 0 , 114, 0 , 8532 , 213, 131), // #1305
+ INST(Vpermt2q , VexRvm_Lx , E(660F38,7E,_,x,_,1,4,FV ), 0 , 113, 0 , 8542 , 212, 131), // #1306
+ INST(Vpermt2w , VexRvm_Lx , E(660F38,7D,_,x,_,1,4,FVM), 0 , 113, 0 , 8551 , 357, 139), // #1307
+ INST(Vpermw , VexRvm_Lx , E(660F38,8D,_,x,_,1,4,FVM), 0 , 113, 0 , 8560 , 357, 139), // #1308
+ INST(Vpexpandb , VexRm_Lx , E(660F38,62,_,x,_,0,0,T1S), 0 , 210, 0 , 8567 , 279, 156), // #1309
+ INST(Vpexpandd , VexRm_Lx , E(660F38,89,_,x,_,0,2,T1S), 0 , 129, 0 , 8577 , 279, 131), // #1310
+ INST(Vpexpandq , VexRm_Lx , E(660F38,89,_,x,_,1,3,T1S), 0 , 128, 0 , 8587 , 279, 131), // #1311
+ INST(Vpexpandw , VexRm_Lx , E(660F38,62,_,x,_,1,1,T1S), 0 , 211, 0 , 8597 , 279, 156), // #1312
+ INST(Vpextrb , VexMri , V(660F3A,14,_,0,0,I,0,T1S), 0 , 73 , 0 , 8607 , 382, 159), // #1313
+ INST(Vpextrd , VexMri , V(660F3A,16,_,0,0,0,2,T1S), 0 , 177, 0 , 8615 , 283, 160), // #1314
+ INST(Vpextrq , VexMri , V(660F3A,16,_,0,1,1,3,T1S), 0 , 213, 0 , 8623 , 383, 160), // #1315
+ INST(Vpextrw , VexMri_Vpextrw , V(660F3A,15,_,0,0,I,1,T1S), 0 , 214, 0 , 8631 , 384, 159), // #1316
+ INST(Vpgatherdd , VexRmvRm_VM , V(660F38,90,_,x,0,_,_,_ ), E(660F38,90,_,x,_,0,2,T1S), 96 , 116, 8639 , 302, 145), // #1317
+ INST(Vpgatherdq , VexRmvRm_VM , V(660F38,90,_,x,1,_,_,_ ), E(660F38,90,_,x,_,1,3,T1S), 189, 117, 8650 , 301, 145), // #1318
+ INST(Vpgatherqd , VexRmvRm_VM , V(660F38,91,_,x,0,_,_,_ ), E(660F38,91,_,x,_,0,2,T1S), 96 , 118, 8661 , 307, 145), // #1319
+ INST(Vpgatherqq , VexRmvRm_VM , V(660F38,91,_,x,1,_,_,_ ), E(660F38,91,_,x,_,1,3,T1S), 189, 119, 8672 , 306, 145), // #1320
+ INST(Vphaddbd , VexRm , V(XOP_M9,C2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8683 , 204, 144), // #1321
+ INST(Vphaddbq , VexRm , V(XOP_M9,C3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8692 , 204, 144), // #1322
+ INST(Vphaddbw , VexRm , V(XOP_M9,C1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8701 , 204, 144), // #1323
+ INST(Vphaddd , VexRvm_Lx , V(660F38,02,_,x,I,_,_,_ ), 0 , 96 , 0 , 8710 , 202, 148), // #1324
+ INST(Vphadddq , VexRm , V(XOP_M9,CB,_,0,0,_,_,_ ), 0 , 79 , 0 , 8718 , 204, 144), // #1325
+ INST(Vphaddsw , VexRvm_Lx , V(660F38,03,_,x,I,_,_,_ ), 0 , 96 , 0 , 8727 , 202, 148), // #1326
+ INST(Vphaddubd , VexRm , V(XOP_M9,D2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8736 , 204, 144), // #1327
+ INST(Vphaddubq , VexRm , V(XOP_M9,D3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8746 , 204, 144), // #1328
+ INST(Vphaddubw , VexRm , V(XOP_M9,D1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8756 , 204, 144), // #1329
+ INST(Vphaddudq , VexRm , V(XOP_M9,DB,_,0,0,_,_,_ ), 0 , 79 , 0 , 8766 , 204, 144), // #1330
+ INST(Vphadduwd , VexRm , V(XOP_M9,D6,_,0,0,_,_,_ ), 0 , 79 , 0 , 8776 , 204, 144), // #1331
+ INST(Vphadduwq , VexRm , V(XOP_M9,D7,_,0,0,_,_,_ ), 0 , 79 , 0 , 8786 , 204, 144), // #1332
+ INST(Vphaddw , VexRvm_Lx , V(660F38,01,_,x,I,_,_,_ ), 0 , 96 , 0 , 8796 , 202, 148), // #1333
+ INST(Vphaddwd , VexRm , V(XOP_M9,C6,_,0,0,_,_,_ ), 0 , 79 , 0 , 8804 , 204, 144), // #1334
+ INST(Vphaddwq , VexRm , V(XOP_M9,C7,_,0,0,_,_,_ ), 0 , 79 , 0 , 8813 , 204, 144), // #1335
+ INST(Vphminposuw , VexRm , V(660F38,41,_,0,I,_,_,_ ), 0 , 96 , 0 , 8822 , 204, 128), // #1336
+ INST(Vphsubbw , VexRm , V(XOP_M9,E1,_,0,0,_,_,_ ), 0 , 79 , 0 , 8834 , 204, 144), // #1337
+ INST(Vphsubd , VexRvm_Lx , V(660F38,06,_,x,I,_,_,_ ), 0 , 96 , 0 , 8843 , 202, 148), // #1338
+ INST(Vphsubdq , VexRm , V(XOP_M9,E3,_,0,0,_,_,_ ), 0 , 79 , 0 , 8851 , 204, 144), // #1339
+ INST(Vphsubsw , VexRvm_Lx , V(660F38,07,_,x,I,_,_,_ ), 0 , 96 , 0 , 8860 , 202, 148), // #1340
+ INST(Vphsubw , VexRvm_Lx , V(660F38,05,_,x,I,_,_,_ ), 0 , 96 , 0 , 8869 , 202, 148), // #1341
+ INST(Vphsubwd , VexRm , V(XOP_M9,E2,_,0,0,_,_,_ ), 0 , 79 , 0 , 8877 , 204, 144), // #1342
+ INST(Vpinsrb , VexRvmi , V(660F3A,20,_,0,0,I,0,T1S), 0 , 73 , 0 , 8886 , 385, 159), // #1343
+ INST(Vpinsrd , VexRvmi , V(660F3A,22,_,0,0,0,2,T1S), 0 , 177, 0 , 8894 , 386, 160), // #1344
+ INST(Vpinsrq , VexRvmi , V(660F3A,22,_,0,1,1,3,T1S), 0 , 213, 0 , 8902 , 387, 160), // #1345
+ INST(Vpinsrw , VexRvmi , V(660F00,C4,_,0,0,I,1,T1S), 0 , 215, 0 , 8910 , 388, 159), // #1346
+ INST(Vplzcntd , VexRm_Lx , E(660F38,44,_,x,_,0,4,FV ), 0 , 114, 0 , 8918 , 374, 153), // #1347
+ INST(Vplzcntq , VexRm_Lx , E(660F38,44,_,x,_,1,4,FV ), 0 , 113, 0 , 8927 , 350, 153), // #1348
+ INST(Vpmacsdd , VexRvmr , V(XOP_M8,9E,_,0,0,_,_,_ ), 0 , 208, 0 , 8936 , 389, 144), // #1349
+ INST(Vpmacsdqh , VexRvmr , V(XOP_M8,9F,_,0,0,_,_,_ ), 0 , 208, 0 , 8945 , 389, 144), // #1350
+ INST(Vpmacsdql , VexRvmr , V(XOP_M8,97,_,0,0,_,_,_ ), 0 , 208, 0 , 8955 , 389, 144), // #1351
+ INST(Vpmacssdd , VexRvmr , V(XOP_M8,8E,_,0,0,_,_,_ ), 0 , 208, 0 , 8965 , 389, 144), // #1352
+ INST(Vpmacssdqh , VexRvmr , V(XOP_M8,8F,_,0,0,_,_,_ ), 0 , 208, 0 , 8975 , 389, 144), // #1353
+ INST(Vpmacssdql , VexRvmr , V(XOP_M8,87,_,0,0,_,_,_ ), 0 , 208, 0 , 8986 , 389, 144), // #1354
+ INST(Vpmacsswd , VexRvmr , V(XOP_M8,86,_,0,0,_,_,_ ), 0 , 208, 0 , 8997 , 389, 144), // #1355
+ INST(Vpmacssww , VexRvmr , V(XOP_M8,85,_,0,0,_,_,_ ), 0 , 208, 0 , 9007 , 389, 144), // #1356
+ INST(Vpmacswd , VexRvmr , V(XOP_M8,96,_,0,0,_,_,_ ), 0 , 208, 0 , 9017 , 389, 144), // #1357
+ INST(Vpmacsww , VexRvmr , V(XOP_M8,95,_,0,0,_,_,_ ), 0 , 208, 0 , 9026 , 389, 144), // #1358
+ INST(Vpmadcsswd , VexRvmr , V(XOP_M8,A6,_,0,0,_,_,_ ), 0 , 208, 0 , 9035 , 389, 144), // #1359
+ INST(Vpmadcswd , VexRvmr , V(XOP_M8,B6,_,0,0,_,_,_ ), 0 , 208, 0 , 9046 , 389, 144), // #1360
+ INST(Vpmadd52huq , VexRvm_Lx , E(660F38,B5,_,x,_,1,4,FV ), 0 , 113, 0 , 9056 , 212, 161), // #1361
+ INST(Vpmadd52luq , VexRvm_Lx , E(660F38,B4,_,x,_,1,4,FV ), 0 , 113, 0 , 9068 , 212, 161), // #1362
+ INST(Vpmaddubsw , VexRvm_Lx , V(660F38,04,_,x,I,I,4,FVM), 0 , 110, 0 , 9080 , 315, 151), // #1363
+ INST(Vpmaddwd , VexRvm_Lx , V(660F00,F5,_,x,I,I,4,FVM), 0 , 144, 0 , 9091 , 315, 151), // #1364
+ INST(Vpmaskmovd , VexRvmMvr_Lx , V(660F38,8C,_,x,0,_,_,_ ), V(660F38,8E,_,x,0,_,_,_ ), 96 , 120, 9100 , 323, 134), // #1365
+ INST(Vpmaskmovq , VexRvmMvr_Lx , V(660F38,8C,_,x,1,_,_,_ ), V(660F38,8E,_,x,1,_,_,_ ), 189, 121, 9111 , 323, 134), // #1366
+ INST(Vpmaxsb , VexRvm_Lx , V(660F38,3C,_,x,I,I,4,FVM), 0 , 110, 0 , 9122 , 390, 151), // #1367
+ INST(Vpmaxsd , VexRvm_Lx , V(660F38,3D,_,x,I,0,4,FV ), 0 , 110, 0 , 9130 , 211, 135), // #1368
+ INST(Vpmaxsq , VexRvm_Lx , E(660F38,3D,_,x,_,1,4,FV ), 0 , 113, 0 , 9138 , 212, 131), // #1369
+ INST(Vpmaxsw , VexRvm_Lx , V(660F00,EE,_,x,I,I,4,FVM), 0 , 144, 0 , 9146 , 390, 151), // #1370
+ INST(Vpmaxub , VexRvm_Lx , V(660F00,DE,_,x,I,I,4,FVM), 0 , 144, 0 , 9154 , 390, 151), // #1371
+ INST(Vpmaxud , VexRvm_Lx , V(660F38,3F,_,x,I,0,4,FV ), 0 , 110, 0 , 9162 , 211, 135), // #1372
+ INST(Vpmaxuq , VexRvm_Lx , E(660F38,3F,_,x,_,1,4,FV ), 0 , 113, 0 , 9170 , 212, 131), // #1373
+ INST(Vpmaxuw , VexRvm_Lx , V(660F38,3E,_,x,I,I,4,FVM), 0 , 110, 0 , 9178 , 390, 151), // #1374
+ INST(Vpminsb , VexRvm_Lx , V(660F38,38,_,x,I,I,4,FVM), 0 , 110, 0 , 9186 , 390, 151), // #1375
+ INST(Vpminsd , VexRvm_Lx , V(660F38,39,_,x,I,0,4,FV ), 0 , 110, 0 , 9194 , 211, 135), // #1376
+ INST(Vpminsq , VexRvm_Lx , E(660F38,39,_,x,_,1,4,FV ), 0 , 113, 0 , 9202 , 212, 131), // #1377
+ INST(Vpminsw , VexRvm_Lx , V(660F00,EA,_,x,I,I,4,FVM), 0 , 144, 0 , 9210 , 390, 151), // #1378
+ INST(Vpminub , VexRvm_Lx , V(660F00,DA,_,x,I,_,4,FVM), 0 , 144, 0 , 9218 , 390, 151), // #1379
+ INST(Vpminud , VexRvm_Lx , V(660F38,3B,_,x,I,0,4,FV ), 0 , 110, 0 , 9226 , 211, 135), // #1380
+ INST(Vpminuq , VexRvm_Lx , E(660F38,3B,_,x,_,1,4,FV ), 0 , 113, 0 , 9234 , 212, 131), // #1381
+ INST(Vpminuw , VexRvm_Lx , V(660F38,3A,_,x,I,_,4,FVM), 0 , 110, 0 , 9242 , 390, 151), // #1382
+ INST(Vpmovb2m , VexRm_Lx , E(F30F38,29,_,x,_,0,_,_ ), 0 , 206, 0 , 9250 , 391, 139), // #1383
+ INST(Vpmovd2m , VexRm_Lx , E(F30F38,39,_,x,_,0,_,_ ), 0 , 206, 0 , 9259 , 391, 133), // #1384
+ INST(Vpmovdb , VexMr_Lx , E(F30F38,31,_,x,_,0,2,QVM), 0 , 216, 0 , 9268 , 392, 131), // #1385
+ INST(Vpmovdw , VexMr_Lx , E(F30F38,33,_,x,_,0,3,HVM), 0 , 217, 0 , 9276 , 393, 131), // #1386
+ INST(Vpmovm2b , VexRm_Lx , E(F30F38,28,_,x,_,0,_,_ ), 0 , 206, 0 , 9284 , 360, 139), // #1387
+ INST(Vpmovm2d , VexRm_Lx , E(F30F38,38,_,x,_,0,_,_ ), 0 , 206, 0 , 9293 , 360, 133), // #1388
+ INST(Vpmovm2q , VexRm_Lx , E(F30F38,38,_,x,_,1,_,_ ), 0 , 205, 0 , 9302 , 360, 133), // #1389
+ INST(Vpmovm2w , VexRm_Lx , E(F30F38,28,_,x,_,1,_,_ ), 0 , 205, 0 , 9311 , 360, 139), // #1390
+ INST(Vpmovmskb , VexRm_Lx , V(660F00,D7,_,x,I,_,_,_ ), 0 , 69 , 0 , 9320 , 336, 148), // #1391
+ INST(Vpmovq2m , VexRm_Lx , E(F30F38,39,_,x,_,1,_,_ ), 0 , 205, 0 , 9330 , 391, 133), // #1392
+ INST(Vpmovqb , VexMr_Lx , E(F30F38,32,_,x,_,0,1,OVM), 0 , 218, 0 , 9339 , 394, 131), // #1393
+ INST(Vpmovqd , VexMr_Lx , E(F30F38,35,_,x,_,0,3,HVM), 0 , 217, 0 , 9347 , 393, 131), // #1394
+ INST(Vpmovqw , VexMr_Lx , E(F30F38,34,_,x,_,0,2,QVM), 0 , 216, 0 , 9355 , 392, 131), // #1395
+ INST(Vpmovsdb , VexMr_Lx , E(F30F38,21,_,x,_,0,2,QVM), 0 , 216, 0 , 9363 , 392, 131), // #1396
+ INST(Vpmovsdw , VexMr_Lx , E(F30F38,23,_,x,_,0,3,HVM), 0 , 217, 0 , 9372 , 393, 131), // #1397
+ INST(Vpmovsqb , VexMr_Lx , E(F30F38,22,_,x,_,0,1,OVM), 0 , 218, 0 , 9381 , 394, 131), // #1398
+ INST(Vpmovsqd , VexMr_Lx , E(F30F38,25,_,x,_,0,3,HVM), 0 , 217, 0 , 9390 , 393, 131), // #1399
+ INST(Vpmovsqw , VexMr_Lx , E(F30F38,24,_,x,_,0,2,QVM), 0 , 216, 0 , 9399 , 392, 131), // #1400
+ INST(Vpmovswb , VexMr_Lx , E(F30F38,20,_,x,_,0,3,HVM), 0 , 217, 0 , 9408 , 393, 139), // #1401
+ INST(Vpmovsxbd , VexRm_Lx , V(660F38,21,_,x,I,I,2,QVM), 0 , 219, 0 , 9417 , 395, 135), // #1402
+ INST(Vpmovsxbq , VexRm_Lx , V(660F38,22,_,x,I,I,1,OVM), 0 , 220, 0 , 9427 , 396, 135), // #1403
+ INST(Vpmovsxbw , VexRm_Lx , V(660F38,20,_,x,I,I,3,HVM), 0 , 139, 0 , 9437 , 397, 151), // #1404
+ INST(Vpmovsxdq , VexRm_Lx , V(660F38,25,_,x,I,0,3,HVM), 0 , 139, 0 , 9447 , 397, 135), // #1405
+ INST(Vpmovsxwd , VexRm_Lx , V(660F38,23,_,x,I,I,3,HVM), 0 , 139, 0 , 9457 , 397, 135), // #1406
+ INST(Vpmovsxwq , VexRm_Lx , V(660F38,24,_,x,I,I,2,QVM), 0 , 219, 0 , 9467 , 395, 135), // #1407
+ INST(Vpmovusdb , VexMr_Lx , E(F30F38,11,_,x,_,0,2,QVM), 0 , 216, 0 , 9477 , 392, 131), // #1408
+ INST(Vpmovusdw , VexMr_Lx , E(F30F38,13,_,x,_,0,3,HVM), 0 , 217, 0 , 9487 , 393, 131), // #1409
+ INST(Vpmovusqb , VexMr_Lx , E(F30F38,12,_,x,_,0,1,OVM), 0 , 218, 0 , 9497 , 394, 131), // #1410
+ INST(Vpmovusqd , VexMr_Lx , E(F30F38,15,_,x,_,0,3,HVM), 0 , 217, 0 , 9507 , 393, 131), // #1411
+ INST(Vpmovusqw , VexMr_Lx , E(F30F38,14,_,x,_,0,2,QVM), 0 , 216, 0 , 9517 , 392, 131), // #1412
+ INST(Vpmovuswb , VexMr_Lx , E(F30F38,10,_,x,_,0,3,HVM), 0 , 217, 0 , 9527 , 393, 139), // #1413
+ INST(Vpmovw2m , VexRm_Lx , E(F30F38,29,_,x,_,1,_,_ ), 0 , 205, 0 , 9537 , 391, 139), // #1414
+ INST(Vpmovwb , VexMr_Lx , E(F30F38,30,_,x,_,0,3,HVM), 0 , 217, 0 , 9546 , 393, 139), // #1415
+ INST(Vpmovzxbd , VexRm_Lx , V(660F38,31,_,x,I,I,2,QVM), 0 , 219, 0 , 9554 , 395, 135), // #1416
+ INST(Vpmovzxbq , VexRm_Lx , V(660F38,32,_,x,I,I,1,OVM), 0 , 220, 0 , 9564 , 396, 135), // #1417
+ INST(Vpmovzxbw , VexRm_Lx , V(660F38,30,_,x,I,I,3,HVM), 0 , 139, 0 , 9574 , 397, 151), // #1418
+ INST(Vpmovzxdq , VexRm_Lx , V(660F38,35,_,x,I,0,3,HVM), 0 , 139, 0 , 9584 , 397, 135), // #1419
+ INST(Vpmovzxwd , VexRm_Lx , V(660F38,33,_,x,I,I,3,HVM), 0 , 139, 0 , 9594 , 397, 135), // #1420
+ INST(Vpmovzxwq , VexRm_Lx , V(660F38,34,_,x,I,I,2,QVM), 0 , 219, 0 , 9604 , 395, 135), // #1421
+ INST(Vpmuldq , VexRvm_Lx , V(660F38,28,_,x,I,1,4,FV ), 0 , 209, 0 , 9614 , 208, 135), // #1422
+ INST(Vpmulhrsw , VexRvm_Lx , V(660F38,0B,_,x,I,I,4,FVM), 0 , 110, 0 , 9622 , 315, 151), // #1423
+ INST(Vpmulhuw , VexRvm_Lx , V(660F00,E4,_,x,I,I,4,FVM), 0 , 144, 0 , 9632 , 315, 151), // #1424
+ INST(Vpmulhw , VexRvm_Lx , V(660F00,E5,_,x,I,I,4,FVM), 0 , 144, 0 , 9641 , 315, 151), // #1425
+ INST(Vpmulld , VexRvm_Lx , V(660F38,40,_,x,I,0,4,FV ), 0 , 110, 0 , 9649 , 209, 135), // #1426
+ INST(Vpmullq , VexRvm_Lx , E(660F38,40,_,x,_,1,4,FV ), 0 , 113, 0 , 9657 , 212, 133), // #1427
+ INST(Vpmullw , VexRvm_Lx , V(660F00,D5,_,x,I,I,4,FVM), 0 , 144, 0 , 9665 , 315, 151), // #1428
+ INST(Vpmultishiftqb , VexRvm_Lx , E(660F38,83,_,x,_,1,4,FV ), 0 , 113, 0 , 9673 , 212, 158), // #1429
+ INST(Vpmuludq , VexRvm_Lx , V(660F00,F4,_,x,I,1,4,FV ), 0 , 103, 0 , 9688 , 208, 135), // #1430
+ INST(Vpopcntb , VexRm_Lx , E(660F38,54,_,x,_,0,4,FV ), 0 , 114, 0 , 9697 , 279, 162), // #1431
+ INST(Vpopcntd , VexRm_Lx , E(660F38,55,_,x,_,0,4,FVM), 0 , 114, 0 , 9706 , 374, 163), // #1432
+ INST(Vpopcntq , VexRm_Lx , E(660F38,55,_,x,_,1,4,FVM), 0 , 113, 0 , 9715 , 350, 163), // #1433
+ INST(Vpopcntw , VexRm_Lx , E(660F38,54,_,x,_,1,4,FV ), 0 , 113, 0 , 9724 , 279, 162), // #1434
+ INST(Vpor , VexRvm_Lx , V(660F00,EB,_,x,I,_,_,_ ), 0 , 69 , 0 , 9733 , 351, 148), // #1435
+ INST(Vpord , VexRvm_Lx , E(660F00,EB,_,x,_,0,4,FV ), 0 , 198, 0 , 9738 , 352, 131), // #1436
+ INST(Vporq , VexRvm_Lx , E(660F00,EB,_,x,_,1,4,FV ), 0 , 135, 0 , 9744 , 356, 131), // #1437
+ INST(Vpperm , VexRvrmRvmr , V(XOP_M8,A3,_,0,x,_,_,_ ), 0 , 208, 0 , 9750 , 398, 144), // #1438
+ INST(Vprold , VexVmi_Lx , E(660F00,72,1,x,_,0,4,FV ), 0 , 221, 0 , 9757 , 399, 131), // #1439
+ INST(Vprolq , VexVmi_Lx , E(660F00,72,1,x,_,1,4,FV ), 0 , 222, 0 , 9764 , 400, 131), // #1440
+ INST(Vprolvd , VexRvm_Lx , E(660F38,15,_,x,_,0,4,FV ), 0 , 114, 0 , 9771 , 213, 131), // #1441
+ INST(Vprolvq , VexRvm_Lx , E(660F38,15,_,x,_,1,4,FV ), 0 , 113, 0 , 9779 , 212, 131), // #1442
+ INST(Vprord , VexVmi_Lx , E(660F00,72,0,x,_,0,4,FV ), 0 , 198, 0 , 9787 , 399, 131), // #1443
+ INST(Vprorq , VexVmi_Lx , E(660F00,72,0,x,_,1,4,FV ), 0 , 135, 0 , 9794 , 400, 131), // #1444
+ INST(Vprorvd , VexRvm_Lx , E(660F38,14,_,x,_,0,4,FV ), 0 , 114, 0 , 9801 , 213, 131), // #1445
+ INST(Vprorvq , VexRvm_Lx , E(660F38,14,_,x,_,1,4,FV ), 0 , 113, 0 , 9809 , 212, 131), // #1446
+ INST(Vprotb , VexRvmRmvRmi , V(XOP_M9,90,_,0,x,_,_,_ ), V(XOP_M8,C0,_,0,x,_,_,_ ), 79 , 122, 9817 , 401, 144), // #1447
+ INST(Vprotd , VexRvmRmvRmi , V(XOP_M9,92,_,0,x,_,_,_ ), V(XOP_M8,C2,_,0,x,_,_,_ ), 79 , 123, 9824 , 401, 144), // #1448
+ INST(Vprotq , VexRvmRmvRmi , V(XOP_M9,93,_,0,x,_,_,_ ), V(XOP_M8,C3,_,0,x,_,_,_ ), 79 , 124, 9831 , 401, 144), // #1449
+ INST(Vprotw , VexRvmRmvRmi , V(XOP_M9,91,_,0,x,_,_,_ ), V(XOP_M8,C1,_,0,x,_,_,_ ), 79 , 125, 9838 , 401, 144), // #1450
+ INST(Vpsadbw , VexRvm_Lx , V(660F00,F6,_,x,I,I,4,FVM), 0 , 144, 0 , 9845 , 203, 151), // #1451
+ INST(Vpscatterdd , VexMr_VM , E(660F38,A0,_,x,_,0,2,T1S), 0 , 129, 0 , 9853 , 402, 131), // #1452
+ INST(Vpscatterdq , VexMr_VM , E(660F38,A0,_,x,_,1,3,T1S), 0 , 128, 0 , 9865 , 403, 131), // #1453
+ INST(Vpscatterqd , VexMr_VM , E(660F38,A1,_,x,_,0,2,T1S), 0 , 129, 0 , 9877 , 404, 131), // #1454
+ INST(Vpscatterqq , VexMr_VM , E(660F38,A1,_,x,_,1,3,T1S), 0 , 128, 0 , 9889 , 405, 131), // #1455
+ INST(Vpshab , VexRvmRmv , V(XOP_M9,98,_,0,x,_,_,_ ), 0 , 79 , 0 , 9901 , 406, 144), // #1456
+ INST(Vpshad , VexRvmRmv , V(XOP_M9,9A,_,0,x,_,_,_ ), 0 , 79 , 0 , 9908 , 406, 144), // #1457
+ INST(Vpshaq , VexRvmRmv , V(XOP_M9,9B,_,0,x,_,_,_ ), 0 , 79 , 0 , 9915 , 406, 144), // #1458
+ INST(Vpshaw , VexRvmRmv , V(XOP_M9,99,_,0,x,_,_,_ ), 0 , 79 , 0 , 9922 , 406, 144), // #1459
+ INST(Vpshlb , VexRvmRmv , V(XOP_M9,94,_,0,x,_,_,_ ), 0 , 79 , 0 , 9929 , 406, 144), // #1460
+ INST(Vpshld , VexRvmRmv , V(XOP_M9,96,_,0,x,_,_,_ ), 0 , 79 , 0 , 9936 , 406, 144), // #1461
+ INST(Vpshldd , VexRvmi_Lx , E(660F3A,71,_,x,_,0,4,FV ), 0 , 111, 0 , 9943 , 206, 156), // #1462
+ INST(Vpshldq , VexRvmi_Lx , E(660F3A,71,_,x,_,1,4,FV ), 0 , 112, 0 , 9951 , 207, 156), // #1463
+ INST(Vpshldvd , VexRvm_Lx , E(660F38,71,_,x,_,0,4,FV ), 0 , 114, 0 , 9959 , 213, 156), // #1464
+ INST(Vpshldvq , VexRvm_Lx , E(660F38,71,_,x,_,1,4,FV ), 0 , 113, 0 , 9968 , 212, 156), // #1465
+ INST(Vpshldvw , VexRvm_Lx , E(660F38,70,_,x,_,1,4,FVM), 0 , 113, 0 , 9977 , 357, 156), // #1466
+ INST(Vpshldw , VexRvmi_Lx , E(660F3A,70,_,x,_,1,4,FVM), 0 , 112, 0 , 9986 , 275, 156), // #1467
+ INST(Vpshlq , VexRvmRmv , V(XOP_M9,97,_,0,x,_,_,_ ), 0 , 79 , 0 , 9994 , 406, 144), // #1468
+ INST(Vpshlw , VexRvmRmv , V(XOP_M9,95,_,0,x,_,_,_ ), 0 , 79 , 0 , 10001, 406, 144), // #1469
+ INST(Vpshrdd , VexRvmi_Lx , E(660F3A,73,_,x,_,0,4,FV ), 0 , 111, 0 , 10008, 206, 156), // #1470
+ INST(Vpshrdq , VexRvmi_Lx , E(660F3A,73,_,x,_,1,4,FV ), 0 , 112, 0 , 10016, 207, 156), // #1471
+ INST(Vpshrdvd , VexRvm_Lx , E(660F38,73,_,x,_,0,4,FV ), 0 , 114, 0 , 10024, 213, 156), // #1472
+ INST(Vpshrdvq , VexRvm_Lx , E(660F38,73,_,x,_,1,4,FV ), 0 , 113, 0 , 10033, 212, 156), // #1473
+ INST(Vpshrdvw , VexRvm_Lx , E(660F38,72,_,x,_,1,4,FVM), 0 , 113, 0 , 10042, 357, 156), // #1474
+ INST(Vpshrdw , VexRvmi_Lx , E(660F3A,72,_,x,_,1,4,FVM), 0 , 112, 0 , 10051, 275, 156), // #1475
+ INST(Vpshufb , VexRvm_Lx , V(660F38,00,_,x,I,I,4,FVM), 0 , 110, 0 , 10059, 315, 151), // #1476
+ INST(Vpshufbitqmb , VexRvm_Lx , E(660F38,8F,_,x,0,0,4,FVM), 0 , 114, 0 , 10067, 407, 162), // #1477
+ INST(Vpshufd , VexRmi_Lx , V(660F00,70,_,x,I,0,4,FV ), 0 , 144, 0 , 10080, 408, 135), // #1478
+ INST(Vpshufhw , VexRmi_Lx , V(F30F00,70,_,x,I,I,4,FVM), 0 , 161, 0 , 10088, 409, 151), // #1479
+ INST(Vpshuflw , VexRmi_Lx , V(F20F00,70,_,x,I,I,4,FVM), 0 , 223, 0 , 10097, 409, 151), // #1480
+ INST(Vpsignb , VexRvm_Lx , V(660F38,08,_,x,I,_,_,_ ), 0 , 96 , 0 , 10106, 202, 148), // #1481
+ INST(Vpsignd , VexRvm_Lx , V(660F38,0A,_,x,I,_,_,_ ), 0 , 96 , 0 , 10114, 202, 148), // #1482
+ INST(Vpsignw , VexRvm_Lx , V(660F38,09,_,x,I,_,_,_ ), 0 , 96 , 0 , 10122, 202, 148), // #1483
+ INST(Vpslld , VexRvmVmi_Lx_MEvex , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 224, 126, 10130, 410, 135), // #1484
+ INST(Vpslldq , VexVmi_Lx_MEvex , V(660F00,73,7,x,I,I,4,FVM), 0 , 225, 0 , 10137, 411, 151), // #1485
+ INST(Vpsllq , VexRvmVmi_Lx_MEvex , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 226, 127, 10145, 412, 135), // #1486
+ INST(Vpsllvd , VexRvm_Lx , V(660F38,47,_,x,0,0,4,FV ), 0 , 110, 0 , 10152, 209, 145), // #1487
+ INST(Vpsllvq , VexRvm_Lx , V(660F38,47,_,x,1,1,4,FV ), 0 , 182, 0 , 10160, 208, 145), // #1488
+ INST(Vpsllvw , VexRvm_Lx , E(660F38,12,_,x,_,1,4,FVM), 0 , 113, 0 , 10168, 357, 139), // #1489
+ INST(Vpsllw , VexRvmVmi_Lx_MEvex , V(660F00,F1,_,x,I,I,4,128), V(660F00,71,6,x,I,I,4,FVM), 224, 128, 10176, 413, 151), // #1490
+ INST(Vpsrad , VexRvmVmi_Lx_MEvex , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 224, 129, 10183, 410, 135), // #1491
+ INST(Vpsraq , VexRvmVmi_Lx_MEvex , E(660F00,E2,_,x,_,1,4,128), E(660F00,72,4,x,_,1,4,FV ), 227, 130, 10190, 414, 131), // #1492
+ INST(Vpsravd , VexRvm_Lx , V(660F38,46,_,x,0,0,4,FV ), 0 , 110, 0 , 10197, 209, 145), // #1493
+ INST(Vpsravq , VexRvm_Lx , E(660F38,46,_,x,_,1,4,FV ), 0 , 113, 0 , 10205, 212, 131), // #1494
+ INST(Vpsravw , VexRvm_Lx , E(660F38,11,_,x,_,1,4,FVM), 0 , 113, 0 , 10213, 357, 139), // #1495
+ INST(Vpsraw , VexRvmVmi_Lx_MEvex , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 224, 131, 10221, 413, 151), // #1496
+ INST(Vpsrld , VexRvmVmi_Lx_MEvex , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 224, 132, 10228, 410, 135), // #1497
+ INST(Vpsrldq , VexVmi_Lx_MEvex , V(660F00,73,3,x,I,I,4,FVM), 0 , 228, 0 , 10235, 411, 151), // #1498
+ INST(Vpsrlq , VexRvmVmi_Lx_MEvex , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 226, 133, 10243, 412, 135), // #1499
+ INST(Vpsrlvd , VexRvm_Lx , V(660F38,45,_,x,0,0,4,FV ), 0 , 110, 0 , 10250, 209, 145), // #1500
+ INST(Vpsrlvq , VexRvm_Lx , V(660F38,45,_,x,1,1,4,FV ), 0 , 182, 0 , 10258, 208, 145), // #1501
+ INST(Vpsrlvw , VexRvm_Lx , E(660F38,10,_,x,_,1,4,FVM), 0 , 113, 0 , 10266, 357, 139), // #1502
+ INST(Vpsrlw , VexRvmVmi_Lx_MEvex , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 224, 134, 10274, 413, 151), // #1503
+ INST(Vpsubb , VexRvm_Lx , V(660F00,F8,_,x,I,I,4,FVM), 0 , 144, 0 , 10281, 415, 151), // #1504
+ INST(Vpsubd , VexRvm_Lx , V(660F00,FA,_,x,I,0,4,FV ), 0 , 144, 0 , 10288, 416, 135), // #1505
+ INST(Vpsubq , VexRvm_Lx , V(660F00,FB,_,x,I,1,4,FV ), 0 , 103, 0 , 10295, 417, 135), // #1506
+ INST(Vpsubsb , VexRvm_Lx , V(660F00,E8,_,x,I,I,4,FVM), 0 , 144, 0 , 10302, 415, 151), // #1507
+ INST(Vpsubsw , VexRvm_Lx , V(660F00,E9,_,x,I,I,4,FVM), 0 , 144, 0 , 10310, 415, 151), // #1508
+ INST(Vpsubusb , VexRvm_Lx , V(660F00,D8,_,x,I,I,4,FVM), 0 , 144, 0 , 10318, 415, 151), // #1509
+ INST(Vpsubusw , VexRvm_Lx , V(660F00,D9,_,x,I,I,4,FVM), 0 , 144, 0 , 10327, 415, 151), // #1510
+ INST(Vpsubw , VexRvm_Lx , V(660F00,F9,_,x,I,I,4,FVM), 0 , 144, 0 , 10336, 415, 151), // #1511
+ INST(Vpternlogd , VexRvmi_Lx , E(660F3A,25,_,x,_,0,4,FV ), 0 , 111, 0 , 10343, 206, 131), // #1512
+ INST(Vpternlogq , VexRvmi_Lx , E(660F3A,25,_,x,_,1,4,FV ), 0 , 112, 0 , 10354, 207, 131), // #1513
+ INST(Vptest , VexRm_Lx , V(660F38,17,_,x,I,_,_,_ ), 0 , 96 , 0 , 10365, 298, 155), // #1514
+ INST(Vptestmb , VexRvm_Lx , E(660F38,26,_,x,_,0,4,FVM), 0 , 114, 0 , 10372, 407, 139), // #1515
+ INST(Vptestmd , VexRvm_Lx , E(660F38,27,_,x,_,0,4,FV ), 0 , 114, 0 , 10381, 418, 131), // #1516
+ INST(Vptestmq , VexRvm_Lx , E(660F38,27,_,x,_,1,4,FV ), 0 , 113, 0 , 10390, 419, 131), // #1517
+ INST(Vptestmw , VexRvm_Lx , E(660F38,26,_,x,_,1,4,FVM), 0 , 113, 0 , 10399, 407, 139), // #1518
+ INST(Vptestnmb , VexRvm_Lx , E(F30F38,26,_,x,_,0,4,FVM), 0 , 132, 0 , 10408, 407, 139), // #1519
+ INST(Vptestnmd , VexRvm_Lx , E(F30F38,27,_,x,_,0,4,FV ), 0 , 132, 0 , 10418, 418, 131), // #1520
+ INST(Vptestnmq , VexRvm_Lx , E(F30F38,27,_,x,_,1,4,FV ), 0 , 229, 0 , 10428, 419, 131), // #1521
+ INST(Vptestnmw , VexRvm_Lx , E(F30F38,26,_,x,_,1,4,FVM), 0 , 229, 0 , 10438, 407, 139), // #1522
+ INST(Vpunpckhbw , VexRvm_Lx , V(660F00,68,_,x,I,I,4,FVM), 0 , 144, 0 , 10448, 315, 151), // #1523
+ INST(Vpunpckhdq , VexRvm_Lx , V(660F00,6A,_,x,I,0,4,FV ), 0 , 144, 0 , 10459, 209, 135), // #1524
+ INST(Vpunpckhqdq , VexRvm_Lx , V(660F00,6D,_,x,I,1,4,FV ), 0 , 103, 0 , 10470, 208, 135), // #1525
+ INST(Vpunpckhwd , VexRvm_Lx , V(660F00,69,_,x,I,I,4,FVM), 0 , 144, 0 , 10482, 315, 151), // #1526
+ INST(Vpunpcklbw , VexRvm_Lx , V(660F00,60,_,x,I,I,4,FVM), 0 , 144, 0 , 10493, 315, 151), // #1527
+ INST(Vpunpckldq , VexRvm_Lx , V(660F00,62,_,x,I,0,4,FV ), 0 , 144, 0 , 10504, 209, 135), // #1528
+ INST(Vpunpcklqdq , VexRvm_Lx , V(660F00,6C,_,x,I,1,4,FV ), 0 , 103, 0 , 10515, 208, 135), // #1529
+ INST(Vpunpcklwd , VexRvm_Lx , V(660F00,61,_,x,I,I,4,FVM), 0 , 144, 0 , 10527, 315, 151), // #1530
+ INST(Vpxor , VexRvm_Lx , V(660F00,EF,_,x,I,_,_,_ ), 0 , 69 , 0 , 10538, 353, 148), // #1531
+ INST(Vpxord , VexRvm_Lx , E(660F00,EF,_,x,_,0,4,FV ), 0 , 198, 0 , 10544, 354, 131), // #1532
+ INST(Vpxorq , VexRvm_Lx , E(660F00,EF,_,x,_,1,4,FV ), 0 , 135, 0 , 10551, 355, 131), // #1533
+ INST(Vrangepd , VexRvmi_Lx , E(660F3A,50,_,x,_,1,4,FV ), 0 , 112, 0 , 10558, 285, 133), // #1534
+ INST(Vrangeps , VexRvmi_Lx , E(660F3A,50,_,x,_,0,4,FV ), 0 , 111, 0 , 10567, 286, 133), // #1535
+ INST(Vrangesd , VexRvmi , E(660F3A,51,_,I,_,1,3,T1S), 0 , 180, 0 , 10576, 287, 66 ), // #1536
+ INST(Vrangess , VexRvmi , E(660F3A,51,_,I,_,0,2,T1S), 0 , 181, 0 , 10585, 288, 66 ), // #1537
+ INST(Vrcp14pd , VexRm_Lx , E(660F38,4C,_,x,_,1,4,FV ), 0 , 113, 0 , 10594, 350, 131), // #1538
+ INST(Vrcp14ps , VexRm_Lx , E(660F38,4C,_,x,_,0,4,FV ), 0 , 114, 0 , 10603, 374, 131), // #1539
+ INST(Vrcp14sd , VexRvm , E(660F38,4D,_,I,_,1,3,T1S), 0 , 128, 0 , 10612, 420, 68 ), // #1540
+ INST(Vrcp14ss , VexRvm , E(660F38,4D,_,I,_,0,2,T1S), 0 , 129, 0 , 10621, 421, 68 ), // #1541
+ INST(Vrcp28pd , VexRm , E(660F38,CA,_,2,_,1,4,FV ), 0 , 170, 0 , 10630, 277, 140), // #1542
+ INST(Vrcp28ps , VexRm , E(660F38,CA,_,2,_,0,4,FV ), 0 , 171, 0 , 10639, 278, 140), // #1543
+ INST(Vrcp28sd , VexRvm , E(660F38,CB,_,I,_,1,3,T1S), 0 , 128, 0 , 10648, 308, 140), // #1544
+ INST(Vrcp28ss , VexRvm , E(660F38,CB,_,I,_,0,2,T1S), 0 , 129, 0 , 10657, 309, 140), // #1545
+ INST(Vrcpph , VexRm_Lx , E(66MAP6,4C,_,_,_,0,4,FV ), 0 , 183, 0 , 10666, 422, 127), // #1546
+ INST(Vrcpps , VexRm_Lx , V(000F00,53,_,x,I,_,_,_ ), 0 , 72 , 0 , 10673, 298, 128), // #1547
+ INST(Vrcpsh , VexRvm , E(66MAP6,4D,_,_,_,0,1,T1S), 0 , 185, 0 , 10680, 423, 127), // #1548
+ INST(Vrcpss , VexRvm , V(F30F00,53,_,I,I,_,_,_ ), 0 , 199, 0 , 10687, 424, 128), // #1549
+ INST(Vreducepd , VexRmi_Lx , E(660F3A,56,_,x,_,1,4,FV ), 0 , 112, 0 , 10694, 400, 133), // #1550
+ INST(Vreduceph , VexRmi_Lx , E(000F3A,56,_,_,_,0,4,FV ), 0 , 123, 0 , 10704, 311, 125), // #1551
+ INST(Vreduceps , VexRmi_Lx , E(660F3A,56,_,x,_,0,4,FV ), 0 , 111, 0 , 10714, 399, 133), // #1552
+ INST(Vreducesd , VexRvmi , E(660F3A,57,_,I,_,1,3,T1S), 0 , 180, 0 , 10724, 425, 66 ), // #1553
+ INST(Vreducesh , VexRvmi , E(000F3A,57,_,_,_,0,1,T1S), 0 , 188, 0 , 10734, 313, 127), // #1554
+ INST(Vreducess , VexRvmi , E(660F3A,57,_,I,_,0,2,T1S), 0 , 181, 0 , 10744, 426, 66 ), // #1555
+ INST(Vrndscalepd , VexRmi_Lx , E(660F3A,09,_,x,_,1,4,FV ), 0 , 112, 0 , 10754, 310, 131), // #1556
+ INST(Vrndscaleph , VexRmi_Lx , E(000F3A,08,_,_,_,0,4,FV ), 0 , 123, 0 , 10766, 311, 125), // #1557
+ INST(Vrndscaleps , VexRmi_Lx , E(660F3A,08,_,x,_,0,4,FV ), 0 , 111, 0 , 10778, 312, 131), // #1558
+ INST(Vrndscalesd , VexRvmi , E(660F3A,0B,_,I,_,1,3,T1S), 0 , 180, 0 , 10790, 287, 68 ), // #1559
+ INST(Vrndscalesh , VexRvmi , E(000F3A,0A,_,_,_,0,1,T1S), 0 , 188, 0 , 10802, 313, 127), // #1560
+ INST(Vrndscaless , VexRvmi , E(660F3A,0A,_,I,_,0,2,T1S), 0 , 181, 0 , 10814, 288, 68 ), // #1561
+ INST(Vroundpd , VexRmi_Lx , V(660F3A,09,_,x,I,_,_,_ ), 0 , 73 , 0 , 10826, 427, 128), // #1562
+ INST(Vroundps , VexRmi_Lx , V(660F3A,08,_,x,I,_,_,_ ), 0 , 73 , 0 , 10835, 427, 128), // #1563
+ INST(Vroundsd , VexRvmi , V(660F3A,0B,_,I,I,_,_,_ ), 0 , 73 , 0 , 10844, 428, 128), // #1564
+ INST(Vroundss , VexRvmi , V(660F3A,0A,_,I,I,_,_,_ ), 0 , 73 , 0 , 10853, 429, 128), // #1565
+ INST(Vrsqrt14pd , VexRm_Lx , E(660F38,4E,_,x,_,1,4,FV ), 0 , 113, 0 , 10862, 350, 131), // #1566
+ INST(Vrsqrt14ps , VexRm_Lx , E(660F38,4E,_,x,_,0,4,FV ), 0 , 114, 0 , 10873, 374, 131), // #1567
+ INST(Vrsqrt14sd , VexRvm , E(660F38,4F,_,I,_,1,3,T1S), 0 , 128, 0 , 10884, 420, 68 ), // #1568
+ INST(Vrsqrt14ss , VexRvm , E(660F38,4F,_,I,_,0,2,T1S), 0 , 129, 0 , 10895, 421, 68 ), // #1569
+ INST(Vrsqrt28pd , VexRm , E(660F38,CC,_,2,_,1,4,FV ), 0 , 170, 0 , 10906, 277, 140), // #1570
+ INST(Vrsqrt28ps , VexRm , E(660F38,CC,_,2,_,0,4,FV ), 0 , 171, 0 , 10917, 278, 140), // #1571
+ INST(Vrsqrt28sd , VexRvm , E(660F38,CD,_,I,_,1,3,T1S), 0 , 128, 0 , 10928, 308, 140), // #1572
+ INST(Vrsqrt28ss , VexRvm , E(660F38,CD,_,I,_,0,2,T1S), 0 , 129, 0 , 10939, 309, 140), // #1573
+ INST(Vrsqrtph , VexRm_Lx , E(66MAP6,4E,_,_,_,0,4,FV ), 0 , 183, 0 , 10950, 422, 125), // #1574
+ INST(Vrsqrtps , VexRm_Lx , V(000F00,52,_,x,I,_,_,_ ), 0 , 72 , 0 , 10959, 298, 128), // #1575
+ INST(Vrsqrtsh , VexRvm , E(66MAP6,4F,_,_,_,0,1,T1S), 0 , 185, 0 , 10968, 423, 127), // #1576
+ INST(Vrsqrtss , VexRvm , V(F30F00,52,_,I,I,_,_,_ ), 0 , 199, 0 , 10977, 424, 128), // #1577
+ INST(Vscalefpd , VexRvm_Lx , E(660F38,2C,_,x,_,1,4,FV ), 0 , 113, 0 , 10986, 430, 131), // #1578
+ INST(Vscalefph , VexRvm_Lx , E(66MAP6,2C,_,_,_,0,4,FV ), 0 , 183, 0 , 10996, 197, 125), // #1579
+ INST(Vscalefps , VexRvm_Lx , E(660F38,2C,_,x,_,0,4,FV ), 0 , 114, 0 , 11006, 284, 131), // #1580
+ INST(Vscalefsd , VexRvm , E(660F38,2D,_,I,_,1,3,T1S), 0 , 128, 0 , 11016, 251, 68 ), // #1581
+ INST(Vscalefsh , VexRvm , E(66MAP6,2D,_,_,_,0,1,T1S), 0 , 185, 0 , 11026, 200, 127), // #1582
+ INST(Vscalefss , VexRvm , E(660F38,2D,_,I,_,0,2,T1S), 0 , 129, 0 , 11036, 259, 68 ), // #1583
+ INST(Vscatterdpd , VexMr_VM , E(660F38,A2,_,x,_,1,3,T1S), 0 , 128, 0 , 11046, 403, 131), // #1584
+ INST(Vscatterdps , VexMr_VM , E(660F38,A2,_,x,_,0,2,T1S), 0 , 129, 0 , 11058, 402, 131), // #1585
+ INST(Vscatterpf0dpd , VexM_VM , E(660F38,C6,5,2,_,1,3,T1S), 0 , 230, 0 , 11070, 303, 146), // #1586
+ INST(Vscatterpf0dps , VexM_VM , E(660F38,C6,5,2,_,0,2,T1S), 0 , 231, 0 , 11085, 304, 146), // #1587
+ INST(Vscatterpf0qpd , VexM_VM , E(660F38,C7,5,2,_,1,3,T1S), 0 , 230, 0 , 11100, 305, 146), // #1588
+ INST(Vscatterpf0qps , VexM_VM , E(660F38,C7,5,2,_,0,2,T1S), 0 , 231, 0 , 11115, 305, 146), // #1589
+ INST(Vscatterpf1dpd , VexM_VM , E(660F38,C6,6,2,_,1,3,T1S), 0 , 232, 0 , 11130, 303, 146), // #1590
+ INST(Vscatterpf1dps , VexM_VM , E(660F38,C6,6,2,_,0,2,T1S), 0 , 233, 0 , 11145, 304, 146), // #1591
+ INST(Vscatterpf1qpd , VexM_VM , E(660F38,C7,6,2,_,1,3,T1S), 0 , 232, 0 , 11160, 305, 146), // #1592
+ INST(Vscatterpf1qps , VexM_VM , E(660F38,C7,6,2,_,0,2,T1S), 0 , 233, 0 , 11175, 305, 146), // #1593
+ INST(Vscatterqpd , VexMr_VM , E(660F38,A3,_,x,_,1,3,T1S), 0 , 128, 0 , 11190, 405, 131), // #1594
+ INST(Vscatterqps , VexMr_VM , E(660F38,A3,_,x,_,0,2,T1S), 0 , 129, 0 , 11202, 404, 131), // #1595
+ INST(Vshuff32x4 , VexRvmi_Lx , E(660F3A,23,_,x,_,0,4,FV ), 0 , 111, 0 , 11214, 431, 131), // #1596
+ INST(Vshuff64x2 , VexRvmi_Lx , E(660F3A,23,_,x,_,1,4,FV ), 0 , 112, 0 , 11225, 432, 131), // #1597
+ INST(Vshufi32x4 , VexRvmi_Lx , E(660F3A,43,_,x,_,0,4,FV ), 0 , 111, 0 , 11236, 431, 131), // #1598
+ INST(Vshufi64x2 , VexRvmi_Lx , E(660F3A,43,_,x,_,1,4,FV ), 0 , 112, 0 , 11247, 432, 131), // #1599
+ INST(Vshufpd , VexRvmi_Lx , V(660F00,C6,_,x,I,1,4,FV ), 0 , 103, 0 , 11258, 433, 124), // #1600
+ INST(Vshufps , VexRvmi_Lx , V(000F00,C6,_,x,I,0,4,FV ), 0 , 105, 0 , 11266, 434, 124), // #1601
+ INST(Vsqrtpd , VexRm_Lx , V(660F00,51,_,x,I,1,4,FV ), 0 , 103, 0 , 11274, 435, 124), // #1602
+ INST(Vsqrtph , VexRm_Lx , E(00MAP5,51,_,_,_,0,4,FV ), 0 , 104, 0 , 11282, 246, 125), // #1603
+ INST(Vsqrtps , VexRm_Lx , V(000F00,51,_,x,I,0,4,FV ), 0 , 105, 0 , 11290, 235, 124), // #1604
+ INST(Vsqrtsd , VexRvm , V(F20F00,51,_,I,I,1,3,T1S), 0 , 106, 0 , 11298, 199, 126), // #1605
+ INST(Vsqrtsh , VexRvm , E(F3MAP5,51,_,_,_,0,1,T1S), 0 , 107, 0 , 11306, 200, 127), // #1606
+ INST(Vsqrtss , VexRvm , V(F30F00,51,_,I,I,0,2,T1S), 0 , 108, 0 , 11314, 201, 126), // #1607
+ INST(Vstmxcsr , VexM , V(000F00,AE,3,0,I,_,_,_ ), 0 , 234, 0 , 11322, 321, 128), // #1608
+ INST(Vsubpd , VexRvm_Lx , V(660F00,5C,_,x,I,1,4,FV ), 0 , 103, 0 , 11331, 196, 124), // #1609
+ INST(Vsubph , VexRvm_Lx , E(00MAP5,5C,_,_,_,0,4,FV ), 0 , 104, 0 , 11338, 197, 125), // #1610
+ INST(Vsubps , VexRvm_Lx , V(000F00,5C,_,x,I,0,4,FV ), 0 , 105, 0 , 11345, 198, 124), // #1611
+ INST(Vsubsd , VexRvm , V(F20F00,5C,_,I,I,1,3,T1S), 0 , 106, 0 , 11352, 199, 126), // #1612
+ INST(Vsubsh , VexRvm , E(F3MAP5,5C,_,_,_,0,1,T1S), 0 , 107, 0 , 11359, 200, 127), // #1613
+ INST(Vsubss , VexRvm , V(F30F00,5C,_,I,I,0,2,T1S), 0 , 108, 0 , 11366, 201, 126), // #1614
+ INST(Vtestpd , VexRm_Lx , V(660F38,0F,_,x,0,_,_,_ ), 0 , 96 , 0 , 11373, 298, 155), // #1615
+ INST(Vtestps , VexRm_Lx , V(660F38,0E,_,x,0,_,_,_ ), 0 , 96 , 0 , 11381, 298, 155), // #1616
+ INST(Vucomisd , VexRm , V(660F00,2E,_,I,I,1,3,T1S), 0 , 125, 0 , 11389, 229, 136), // #1617
+ INST(Vucomish , VexRm , E(00MAP5,2E,_,_,_,0,1,T1S), 0 , 126, 0 , 11398, 230, 127), // #1618
+ INST(Vucomiss , VexRm , V(000F00,2E,_,I,I,0,2,T1S), 0 , 127, 0 , 11407, 231, 136), // #1619
+ INST(Vunpckhpd , VexRvm_Lx , V(660F00,15,_,x,I,1,4,FV ), 0 , 103, 0 , 11416, 208, 124), // #1620
+ INST(Vunpckhps , VexRvm_Lx , V(000F00,15,_,x,I,0,4,FV ), 0 , 105, 0 , 11426, 209, 124), // #1621
+ INST(Vunpcklpd , VexRvm_Lx , V(660F00,14,_,x,I,1,4,FV ), 0 , 103, 0 , 11436, 208, 124), // #1622
+ INST(Vunpcklps , VexRvm_Lx , V(000F00,14,_,x,I,0,4,FV ), 0 , 105, 0 , 11446, 209, 124), // #1623
+ INST(Vxorpd , VexRvm_Lx , V(660F00,57,_,x,I,1,4,FV ), 0 , 103, 0 , 11456, 417, 132), // #1624
+ INST(Vxorps , VexRvm_Lx , V(000F00,57,_,x,I,0,4,FV ), 0 , 105, 0 , 11463, 416, 132), // #1625
+ INST(Vzeroall , VexOp , V(000F00,77,_,1,I,_,_,_ ), 0 , 68 , 0 , 11470, 436, 128), // #1626
+ INST(Vzeroupper , VexOp , V(000F00,77,_,0,I,_,_,_ ), 0 , 72 , 0 , 11479, 436, 128), // #1627
+ INST(Wbinvd , X86Op , O(000F00,09,_,_,_,_,_,_ ), 0 , 4 , 0 , 11490, 30 , 0 ), // #1628
+ INST(Wbnoinvd , X86Op , O(F30F00,09,_,_,_,_,_,_ ), 0 , 6 , 0 , 11497, 30 , 164), // #1629
+ INST(Wrfsbase , X86M , O(F30F00,AE,2,_,x,_,_,_ ), 0 , 235, 0 , 11506, 173, 104), // #1630
+ INST(Wrgsbase , X86M , O(F30F00,AE,3,_,x,_,_,_ ), 0 , 236, 0 , 11515, 173, 104), // #1631
+ INST(Wrmsr , X86Op , O(000F00,30,_,_,_,_,_,_ ), 0 , 4 , 0 , 11524, 174, 105), // #1632
+ INST(Wrssd , X86Mr , O(000F38,F6,_,_,_,_,_,_ ), 0 , 83 , 0 , 11530, 437, 56 ), // #1633
+ INST(Wrssq , X86Mr , O(000F38,F6,_,_,1,_,_,_ ), 0 , 237, 0 , 11536, 438, 56 ), // #1634
+ INST(Wrussd , X86Mr , O(660F38,F5,_,_,_,_,_,_ ), 0 , 2 , 0 , 11542, 437, 56 ), // #1635
+ INST(Wrussq , X86Mr , O(660F38,F5,_,_,1,_,_,_ ), 0 , 238, 0 , 11549, 438, 56 ), // #1636
+ INST(Xabort , X86Op_Mod11RM_I8 , O(000000,C6,7,_,_,_,_,_ ), 0 , 27 , 0 , 11556, 80 , 165), // #1637
+ INST(Xadd , X86Xadd , O(000F00,C0,_,_,x,_,_,_ ), 0 , 4 , 0 , 11563, 439, 38 ), // #1638
+ INST(Xbegin , X86JmpRel , O(000000,C7,7,_,_,_,_,_ ), 0 , 27 , 0 , 11568, 440, 165), // #1639
+ INST(Xchg , X86Xchg , O(000000,86,_,_,x,_,_,_ ), 0 , 0 , 0 , 462 , 441, 0 ), // #1640
+ INST(Xend , X86Op , O(000F01,D5,_,_,_,_,_,_ ), 0 , 21 , 0 , 11575, 30 , 165), // #1641
+ INST(Xgetbv , X86Op , O(000F01,D0,_,_,_,_,_,_ ), 0 , 21 , 0 , 11580, 174, 166), // #1642
+ INST(Xlatb , X86Op , O(000000,D7,_,_,_,_,_,_ ), 0 , 0 , 0 , 11587, 30 , 0 ), // #1643
+ INST(Xor , X86Arith , O(000000,30,6,_,x,_,_,_ ), 0 , 32 , 0 , 10540, 179, 1 ), // #1644
+ INST(Xorpd , ExtRm , O(660F00,57,_,_,_,_,_,_ ), 0 , 3 , 0 , 11457, 151, 4 ), // #1645
+ INST(Xorps , ExtRm , O(000F00,57,_,_,_,_,_,_ ), 0 , 4 , 0 , 11464, 151, 5 ), // #1646
+ INST(Xresldtrk , X86Op , O(F20F01,E9,_,_,_,_,_,_ ), 0 , 92 , 0 , 11593, 30 , 167), // #1647
+ INST(Xrstor , X86M_Only_EDX_EAX , O(000F00,AE,5,_,_,_,_,_ ), 0 , 77 , 0 , 1164 , 442, 166), // #1648
+ INST(Xrstor64 , X86M_Only_EDX_EAX , O(000F00,AE,5,_,1,_,_,_ ), 0 , 239, 0 , 1172 , 443, 166), // #1649
+ INST(Xrstors , X86M_Only_EDX_EAX , O(000F00,C7,3,_,_,_,_,_ ), 0 , 78 , 0 , 11603, 442, 168), // #1650
+ INST(Xrstors64 , X86M_Only_EDX_EAX , O(000F00,C7,3,_,1,_,_,_ ), 0 , 240, 0 , 11611, 443, 168), // #1651
+ INST(Xsave , X86M_Only_EDX_EAX , O(000F00,AE,4,_,_,_,_,_ ), 0 , 97 , 0 , 1182 , 442, 166), // #1652
+ INST(Xsave64 , X86M_Only_EDX_EAX , O(000F00,AE,4,_,1,_,_,_ ), 0 , 241, 0 , 1189 , 443, 166), // #1653
+ INST(Xsavec , X86M_Only_EDX_EAX , O(000F00,C7,4,_,_,_,_,_ ), 0 , 97 , 0 , 11621, 442, 169), // #1654
+ INST(Xsavec64 , X86M_Only_EDX_EAX , O(000F00,C7,4,_,1,_,_,_ ), 0 , 241, 0 , 11628, 443, 169), // #1655
+ INST(Xsaveopt , X86M_Only_EDX_EAX , O(000F00,AE,6,_,_,_,_,_ ), 0 , 80 , 0 , 11637, 442, 170), // #1656
+ INST(Xsaveopt64 , X86M_Only_EDX_EAX , O(000F00,AE,6,_,1,_,_,_ ), 0 , 242, 0 , 11646, 443, 170), // #1657
+ INST(Xsaves , X86M_Only_EDX_EAX , O(000F00,C7,5,_,_,_,_,_ ), 0 , 77 , 0 , 11657, 442, 168), // #1658
+ INST(Xsaves64 , X86M_Only_EDX_EAX , O(000F00,C7,5,_,1,_,_,_ ), 0 , 239, 0 , 11664, 443, 168), // #1659
+ INST(Xsetbv , X86Op , O(000F01,D1,_,_,_,_,_,_ ), 0 , 21 , 0 , 11673, 174, 166), // #1660
+ INST(Xsusldtrk , X86Op , O(F20F01,E8,_,_,_,_,_,_ ), 0 , 92 , 0 , 11680, 30 , 167), // #1661
+ INST(Xtest , X86Op , O(000F01,D6,_,_,_,_,_,_ ), 0 , 21 , 0 , 11690, 30 , 171) // #1662
// ${InstInfo:End}
};
#undef NAME_DATA_INDEX
#undef INST
-// ============================================================================
-// [asmjit::x86::InstDB - Opcode Tables]
-// ============================================================================
+// x86::InstDB - Opcode Tables
+// ===========================
// ${MainOpcodeTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
const uint32_t InstDB::_mainOpcodeTable[] = {
- O(000000,00,0,0,0,0,0,_ ), // #0 [ref=56x]
- O(000000,00,2,0,0,0,0,_ ), // #1 [ref=4x]
- O(660F38,00,0,0,0,0,0,_ ), // #2 [ref=43x]
- O(660F00,00,0,0,0,0,0,_ ), // #3 [ref=38x]
- O(000F00,00,0,0,0,0,0,_ ), // #4 [ref=231x]
- O(F20F00,00,0,0,0,0,0,_ ), // #5 [ref=24x]
- O(F30F00,00,0,0,0,0,0,_ ), // #6 [ref=29x]
- O(F30F38,00,0,0,0,0,0,_ ), // #7 [ref=2x]
- O(660F3A,00,0,0,0,0,0,_ ), // #8 [ref=22x]
- O(000000,00,4,0,0,0,0,_ ), // #9 [ref=5x]
- V(000F38,00,0,0,0,0,0,_ ), // #10 [ref=6x]
- V(XOP_M9,00,1,0,0,0,0,_ ), // #11 [ref=3x]
- V(XOP_M9,00,6,0,0,0,0,_ ), // #12 [ref=2x]
- V(XOP_M9,00,5,0,0,0,0,_ ), // #13 [ref=1x]
- V(XOP_M9,00,3,0,0,0,0,_ ), // #14 [ref=1x]
- V(XOP_M9,00,2,0,0,0,0,_ ), // #15 [ref=1x]
- V(000F38,00,3,0,0,0,0,_ ), // #16 [ref=1x]
- V(000F38,00,2,0,0,0,0,_ ), // #17 [ref=1x]
- V(000F38,00,1,0,0,0,0,_ ), // #18 [ref=1x]
- O(660000,00,0,0,0,0,0,_ ), // #19 [ref=7x]
- O(000000,00,0,0,1,0,0,_ ), // #20 [ref=3x]
- O(000F01,00,0,0,0,0,0,_ ), // #21 [ref=29x]
- O(000F00,00,7,0,0,0,0,_ ), // #22 [ref=5x]
- O(660F00,00,7,0,0,0,0,_ ), // #23 [ref=1x]
- O(F30F00,00,6,0,0,0,0,_ ), // #24 [ref=4x]
- O(F30F01,00,0,0,0,0,0,_ ), // #25 [ref=9x]
- O(660F00,00,6,0,0,0,0,_ ), // #26 [ref=3x]
- O(000000,00,7,0,0,0,0,_ ), // #27 [ref=5x]
- O(000F00,00,1,0,1,0,0,_ ), // #28 [ref=2x]
- O(000F00,00,1,0,0,0,0,_ ), // #29 [ref=6x]
- O(F20F38,00,0,0,0,0,0,_ ), // #30 [ref=2x]
- O(000000,00,1,0,0,0,0,_ ), // #31 [ref=3x]
- O(000000,00,6,0,0,0,0,_ ), // #32 [ref=3x]
- O(F30F00,00,7,0,0,0,0,3 ), // #33 [ref=1x]
- O(F30F00,00,7,0,0,0,0,2 ), // #34 [ref=1x]
- O_FPU(00,D900,_) , // #35 [ref=29x]
- O_FPU(00,C000,0) , // #36 [ref=1x]
- O_FPU(00,DE00,_) , // #37 [ref=7x]
- O_FPU(00,0000,4) , // #38 [ref=4x]
- O_FPU(00,0000,6) , // #39 [ref=4x]
- O_FPU(9B,DB00,_) , // #40 [ref=2x]
- O_FPU(00,DA00,_) , // #41 [ref=5x]
- O_FPU(00,DB00,_) , // #42 [ref=8x]
- O_FPU(00,D000,2) , // #43 [ref=1x]
- O_FPU(00,DF00,_) , // #44 [ref=2x]
- O_FPU(00,D800,3) , // #45 [ref=1x]
- O_FPU(00,F000,6) , // #46 [ref=1x]
- O_FPU(00,F800,7) , // #47 [ref=1x]
- O_FPU(00,DD00,_) , // #48 [ref=3x]
- O_FPU(00,0000,0) , // #49 [ref=3x]
- O_FPU(00,0000,2) , // #50 [ref=3x]
- O_FPU(00,0000,3) , // #51 [ref=3x]
- O_FPU(00,0000,7) , // #52 [ref=3x]
- O_FPU(00,0000,1) , // #53 [ref=2x]
- O_FPU(00,0000,5) , // #54 [ref=2x]
- O_FPU(00,C800,1) , // #55 [ref=1x]
- O_FPU(9B,0000,6) , // #56 [ref=2x]
- O_FPU(9B,0000,7) , // #57 [ref=2x]
- O_FPU(00,E000,4) , // #58 [ref=1x]
- O_FPU(00,E800,5) , // #59 [ref=1x]
- O_FPU(00,0000,_) , // #60 [ref=1x]
- O(000F00,00,0,0,1,0,0,_ ), // #61 [ref=3x]
- O(F30F3A,00,0,0,0,0,0,_ ), // #62 [ref=1x]
- O(000000,00,5,0,0,0,0,_ ), // #63 [ref=4x]
- O(F30F00,00,5,0,0,0,0,_ ), // #64 [ref=2x]
- O(F30F00,00,5,0,1,0,0,_ ), // #65 [ref=1x]
- V(660F00,00,0,1,0,0,0,_ ), // #66 [ref=7x]
- V(660F00,00,0,1,1,0,0,_ ), // #67 [ref=6x]
- V(000F00,00,0,1,1,0,0,_ ), // #68 [ref=7x]
- V(000F00,00,0,1,0,0,0,_ ), // #69 [ref=8x]
- V(660F00,00,0,0,0,0,0,_ ), // #70 [ref=15x]
- V(660F00,00,0,0,1,0,0,_ ), // #71 [ref=4x]
- V(000F00,00,0,0,1,0,0,_ ), // #72 [ref=4x]
- V(000F00,00,0,0,0,0,0,_ ), // #73 [ref=10x]
- V(660F3A,00,0,0,0,0,0,_ ), // #74 [ref=45x]
- V(660F3A,00,0,0,1,0,0,_ ), // #75 [ref=4x]
- O(000000,00,3,0,0,0,0,_ ), // #76 [ref=4x]
- O(000F00,00,2,0,0,0,0,_ ), // #77 [ref=5x]
- O(000F00,00,5,0,0,0,0,_ ), // #78 [ref=4x]
- O(000F00,00,3,0,0,0,0,_ ), // #79 [ref=5x]
- V(XOP_M9,00,0,0,0,0,0,_ ), // #80 [ref=32x]
- O(000F00,00,6,0,0,0,0,_ ), // #81 [ref=5x]
- V(XOP_MA,00,0,0,0,0,0,_ ), // #82 [ref=1x]
- V(XOP_MA,00,1,0,0,0,0,_ ), // #83 [ref=1x]
- O(000F38,00,0,0,0,0,0,_ ), // #84 [ref=24x]
- V(F20F38,00,0,0,0,0,0,_ ), // #85 [ref=6x]
- O(000F3A,00,0,0,0,0,0,_ ), // #86 [ref=4x]
- O(F30000,00,0,0,0,0,0,_ ), // #87 [ref=1x]
- O(000F0F,00,0,0,0,0,0,_ ), // #88 [ref=26x]
- V(F30F38,00,0,0,0,0,0,_ ), // #89 [ref=5x]
- O(000F3A,00,0,0,1,0,0,_ ), // #90 [ref=1x]
- O(660F3A,00,0,0,1,0,0,_ ), // #91 [ref=1x]
- O(F30F00,00,4,0,0,0,0,_ ), // #92 [ref=1x]
- O(F20F01,00,0,0,0,0,0,_ ), // #93 [ref=4x]
- O(F30F00,00,1,0,0,0,0,_ ), // #94 [ref=3x]
- O(F30F00,00,7,0,0,0,0,_ ), // #95 [ref=1x]
- V(F20F3A,00,0,0,0,0,0,_ ), // #96 [ref=1x]
- V(660F38,00,0,0,0,0,0,_ ), // #97 [ref=25x]
- O(000F00,00,4,0,0,0,0,_ ), // #98 [ref=4x]
- V(XOP_M9,00,7,0,0,0,0,_ ), // #99 [ref=1x]
- V(XOP_M9,00,4,0,0,0,0,_ ), // #100 [ref=1x]
- O(F20F00,00,6,0,0,0,0,_ ), // #101 [ref=1x]
- E(F20F38,00,0,2,0,0,4,T4X), // #102 [ref=4x]
- E(F20F38,00,0,0,0,0,4,T4X), // #103 [ref=2x]
- V(660F00,00,0,0,0,1,4,FV ), // #104 [ref=22x]
- V(000F00,00,0,0,0,0,4,FV ), // #105 [ref=16x]
- V(F20F00,00,0,0,0,1,3,T1S), // #106 [ref=10x]
- V(F30F00,00,0,0,0,0,2,T1S), // #107 [ref=10x]
- V(F20F00,00,0,0,0,0,0,_ ), // #108 [ref=4x]
- V(660F38,00,0,0,0,0,4,FVM), // #109 [ref=14x]
- E(660F3A,00,0,0,0,0,4,FV ), // #110 [ref=14x]
- E(660F3A,00,0,0,0,1,4,FV ), // #111 [ref=14x]
- E(660F38,00,0,0,0,1,4,FV ), // #112 [ref=29x]
- E(660F38,00,0,0,0,0,4,FV ), // #113 [ref=18x]
- V(660F38,00,0,1,0,0,0,_ ), // #114 [ref=2x]
- E(660F38,00,0,0,0,0,3,T2 ), // #115 [ref=2x]
- E(660F38,00,0,0,0,0,4,T4 ), // #116 [ref=2x]
- E(660F38,00,0,2,0,0,5,T8 ), // #117 [ref=2x]
- E(660F38,00,0,0,0,1,4,T2 ), // #118 [ref=2x]
- E(660F38,00,0,2,0,1,5,T4 ), // #119 [ref=2x]
- V(660F38,00,0,0,0,1,3,T1S), // #120 [ref=2x]
- V(660F38,00,0,0,0,0,2,T1S), // #121 [ref=14x]
- V(660F00,00,0,0,0,1,3,T1S), // #122 [ref=5x]
- V(000F00,00,0,0,0,0,2,T1S), // #123 [ref=2x]
- E(660F38,00,0,0,0,1,3,T1S), // #124 [ref=14x]
- E(660F38,00,0,0,0,0,2,T1S), // #125 [ref=14x]
- V(F30F00,00,0,0,0,0,3,HV ), // #126 [ref=1x]
- E(F20F38,00,0,0,0,0,4,FV ), // #127 [ref=2x]
- E(F30F38,00,0,0,0,0,4,FV ), // #128 [ref=3x]
- V(F20F00,00,0,0,0,1,4,FV ), // #129 [ref=1x]
- E(660F00,00,0,0,0,1,4,FV ), // #130 [ref=9x]
- E(000F00,00,0,0,0,1,4,FV ), // #131 [ref=3x]
- V(660F38,00,0,0,0,0,3,HVM), // #132 [ref=7x]
- V(660F00,00,0,0,0,0,4,FV ), // #133 [ref=11x]
- V(000F00,00,0,0,0,0,3,HV ), // #134 [ref=1x]
- V(660F3A,00,0,0,0,0,3,HVM), // #135 [ref=1x]
- E(660F00,00,0,0,0,0,3,HV ), // #136 [ref=4x]
- E(000F00,00,0,0,0,0,4,FV ), // #137 [ref=2x]
- E(F30F00,00,0,0,0,1,4,FV ), // #138 [ref=2x]
- V(F20F00,00,0,0,0,0,3,T1F), // #139 [ref=2x]
- E(F20F00,00,0,0,0,0,3,T1F), // #140 [ref=2x]
- V(F20F00,00,0,0,0,0,2,T1W), // #141 [ref=1x]
- V(F30F00,00,0,0,0,0,2,T1W), // #142 [ref=1x]
- V(F30F00,00,0,0,0,0,2,T1F), // #143 [ref=2x]
- E(F30F00,00,0,0,0,0,2,T1F), // #144 [ref=2x]
- V(F30F00,00,0,0,0,0,4,FV ), // #145 [ref=1x]
- E(F30F00,00,0,0,0,0,3,HV ), // #146 [ref=1x]
- E(F20F00,00,0,0,0,0,4,FV ), // #147 [ref=1x]
- E(F20F00,00,0,0,0,1,4,FV ), // #148 [ref=1x]
- E(F20F00,00,0,0,0,0,2,T1W), // #149 [ref=1x]
- E(F30F00,00,0,0,0,0,2,T1W), // #150 [ref=1x]
- E(660F3A,00,0,0,0,0,4,FVM), // #151 [ref=3x]
- E(660F38,00,0,2,0,1,4,FV ), // #152 [ref=3x]
- E(660F38,00,0,2,0,0,4,FV ), // #153 [ref=3x]
- V(660F3A,00,0,1,0,0,0,_ ), // #154 [ref=6x]
- E(660F3A,00,0,0,0,0,4,T4 ), // #155 [ref=4x]
- E(660F3A,00,0,2,0,0,5,T8 ), // #156 [ref=4x]
- E(660F3A,00,0,0,0,1,4,T2 ), // #157 [ref=4x]
- E(660F3A,00,0,2,0,1,5,T4 ), // #158 [ref=4x]
- V(660F3A,00,0,0,0,0,2,T1S), // #159 [ref=4x]
- E(660F3A,00,0,0,0,1,3,T1S), // #160 [ref=6x]
- E(660F3A,00,0,0,0,0,2,T1S), // #161 [ref=6x]
- V(660F38,00,0,0,1,1,4,FV ), // #162 [ref=20x]
- V(660F38,00,0,0,0,0,4,FV ), // #163 [ref=36x]
- V(660F38,00,0,0,1,1,3,T1S), // #164 [ref=12x]
- V(660F38,00,0,0,1,0,0,_ ), // #165 [ref=5x]
- E(660F38,00,1,2,0,1,3,T1S), // #166 [ref=2x]
- E(660F38,00,1,2,0,0,2,T1S), // #167 [ref=2x]
- E(660F38,00,2,2,0,1,3,T1S), // #168 [ref=2x]
- E(660F38,00,2,2,0,0,2,T1S), // #169 [ref=2x]
- V(660F3A,00,0,0,1,1,4,FV ), // #170 [ref=2x]
- V(000F00,00,2,0,0,0,0,_ ), // #171 [ref=1x]
- V(660F00,00,0,0,0,1,4,FVM), // #172 [ref=3x]
- V(000F00,00,0,0,0,0,4,FVM), // #173 [ref=3x]
- V(660F00,00,0,0,0,0,2,T1S), // #174 [ref=1x]
- V(F20F00,00,0,0,0,1,3,DUP), // #175 [ref=1x]
- E(660F00,00,0,0,0,0,4,FVM), // #176 [ref=1x]
- E(660F00,00,0,0,0,1,4,FVM), // #177 [ref=1x]
- V(F30F00,00,0,0,0,0,0,_ ), // #178 [ref=3x]
- E(F20F00,00,0,0,0,1,4,FVM), // #179 [ref=1x]
- E(F30F00,00,0,0,0,0,4,FVM), // #180 [ref=1x]
- E(F30F00,00,0,0,0,1,4,FVM), // #181 [ref=1x]
- E(F20F00,00,0,0,0,0,4,FVM), // #182 [ref=1x]
- V(000F00,00,0,0,0,0,3,T2 ), // #183 [ref=2x]
- V(660F00,00,0,0,0,0,4,FVM), // #184 [ref=32x]
- V(F30F00,00,0,0,0,0,4,FVM), // #185 [ref=3x]
- E(F20F38,00,0,0,0,1,4,FV ), // #186 [ref=1x]
- V(660F3A,00,0,0,0,0,4,FVM), // #187 [ref=2x]
- E(660F00,00,0,0,0,0,4,FV ), // #188 [ref=5x]
- E(660F38,00,0,0,0,0,4,FVM), // #189 [ref=7x]
- E(660F38,00,0,0,0,1,4,FVM), // #190 [ref=11x]
- V(660F38,00,0,0,0,0,0,T1S), // #191 [ref=1x]
- E(F30F38,00,0,0,0,1,0,_ ), // #192 [ref=5x]
- E(F30F38,00,0,0,0,0,0,_ ), // #193 [ref=5x]
- V(660F38,00,0,0,0,0,1,T1S), // #194 [ref=1x]
- V(XOP_M8,00,0,0,0,0,0,_ ), // #195 [ref=22x]
- V(660F38,00,0,0,0,1,4,FVM), // #196 [ref=2x]
- E(660F3A,00,0,0,0,1,4,FVM), // #197 [ref=4x]
- E(660F38,00,0,0,0,0,0,T1S), // #198 [ref=2x]
- E(660F38,00,0,0,0,1,1,T1S), // #199 [ref=2x]
- V(660F38,00,0,0,0,1,4,FV ), // #200 [ref=2x]
- E(660F38,00,0,0,1,1,4,FV ), // #201 [ref=1x]
- V(660F3A,00,0,0,0,0,0,T1S), // #202 [ref=2x]
- V(660F3A,00,0,0,1,1,3,T1S), // #203 [ref=2x]
- V(660F3A,00,0,0,0,0,1,T1S), // #204 [ref=1x]
- V(660F00,00,0,0,0,0,1,T1S), // #205 [ref=1x]
- E(F30F38,00,0,0,0,0,2,QVM), // #206 [ref=6x]
- E(F30F38,00,0,0,0,0,3,HVM), // #207 [ref=9x]
- E(F30F38,00,0,0,0,0,1,OVM), // #208 [ref=3x]
- V(660F38,00,0,0,0,0,2,QVM), // #209 [ref=4x]
- V(660F38,00,0,0,0,0,1,OVM), // #210 [ref=2x]
- E(660F00,00,1,0,0,0,4,FV ), // #211 [ref=1x]
- E(660F00,00,1,0,0,1,4,FV ), // #212 [ref=1x]
- V(F20F00,00,0,0,0,0,4,FVM), // #213 [ref=1x]
- V(660F00,00,0,0,0,0,4,128), // #214 [ref=6x]
- V(660F00,00,7,0,0,0,4,FVM), // #215 [ref=1x]
- V(660F00,00,0,0,0,1,4,128), // #216 [ref=2x]
- E(660F00,00,0,0,0,1,4,128), // #217 [ref=1x]
- V(660F00,00,3,0,0,0,4,FVM), // #218 [ref=1x]
- E(F30F38,00,0,0,0,0,4,FVM), // #219 [ref=1x]
- E(F30F38,00,0,0,0,1,4,FV ), // #220 [ref=1x]
- E(F30F38,00,0,0,0,1,4,FVM), // #221 [ref=1x]
- E(660F38,00,5,2,0,1,3,T1S), // #222 [ref=2x]
- E(660F38,00,5,2,0,0,2,T1S), // #223 [ref=2x]
- E(660F38,00,6,2,0,1,3,T1S), // #224 [ref=2x]
- E(660F38,00,6,2,0,0,2,T1S), // #225 [ref=2x]
- V(000F00,00,3,0,0,0,0,_ ), // #226 [ref=1x]
- O(F30F00,00,2,0,0,0,0,_ ), // #227 [ref=1x]
- O(F30F00,00,3,0,0,0,0,_ ), // #228 [ref=1x]
- O(000F38,00,0,0,1,0,0,_ ), // #229 [ref=1x]
- O(660F38,00,0,0,1,0,0,_ ), // #230 [ref=1x]
- O(000F00,00,5,0,1,0,0,_ ), // #231 [ref=2x]
- O(000F00,00,3,0,1,0,0,_ ), // #232 [ref=1x]
- O(000F00,00,4,0,1,0,0,_ ), // #233 [ref=2x]
- O(000F00,00,6,0,1,0,0,_ ) // #234 [ref=1x]
+ O(000000,00,0,0,0,0,0,0 ), // #0 [ref=56x]
+ O(000000,00,2,0,0,0,0,0 ), // #1 [ref=4x]
+ O(660F38,00,0,0,0,0,0,0 ), // #2 [ref=43x]
+ O(660F00,00,0,0,0,0,0,0 ), // #3 [ref=38x]
+ O(000F00,00,0,0,0,0,0,0 ), // #4 [ref=231x]
+ O(F20F00,00,0,0,0,0,0,0 ), // #5 [ref=24x]
+ O(F30F00,00,0,0,0,0,0,0 ), // #6 [ref=29x]
+ O(F30F38,00,0,0,0,0,0,0 ), // #7 [ref=2x]
+ O(660F3A,00,0,0,0,0,0,0 ), // #8 [ref=22x]
+ O(000000,00,4,0,0,0,0,0 ), // #9 [ref=5x]
+ V(000F38,00,0,0,0,0,0,None), // #10 [ref=6x]
+ V(XOP_M9,00,1,0,0,0,0,None), // #11 [ref=3x]
+ V(XOP_M9,00,6,0,0,0,0,None), // #12 [ref=2x]
+ V(XOP_M9,00,5,0,0,0,0,None), // #13 [ref=1x]
+ V(XOP_M9,00,3,0,0,0,0,None), // #14 [ref=1x]
+ V(XOP_M9,00,2,0,0,0,0,None), // #15 [ref=1x]
+ V(000F38,00,3,0,0,0,0,None), // #16 [ref=1x]
+ V(000F38,00,2,0,0,0,0,None), // #17 [ref=1x]
+ V(000F38,00,1,0,0,0,0,None), // #18 [ref=1x]
+ O(660000,00,0,0,0,0,0,0 ), // #19 [ref=7x]
+ O(000000,00,0,0,1,0,0,0 ), // #20 [ref=3x]
+ O(000F01,00,0,0,0,0,0,0 ), // #21 [ref=29x]
+ O(000F00,00,7,0,0,0,0,0 ), // #22 [ref=5x]
+ O(660F00,00,7,0,0,0,0,0 ), // #23 [ref=1x]
+ O(F30F00,00,6,0,0,0,0,0 ), // #24 [ref=4x]
+ O(F30F01,00,0,0,0,0,0,0 ), // #25 [ref=9x]
+ O(660F00,00,6,0,0,0,0,0 ), // #26 [ref=3x]
+ O(000000,00,7,0,0,0,0,0 ), // #27 [ref=5x]
+ O(000F00,00,1,0,1,0,0,0 ), // #28 [ref=2x]
+ O(000F00,00,1,0,0,0,0,0 ), // #29 [ref=6x]
+ O(F20F38,00,0,0,0,0,0,0 ), // #30 [ref=2x]
+ O(000000,00,1,0,0,0,0,0 ), // #31 [ref=3x]
+ O(000000,00,6,0,0,0,0,0 ), // #32 [ref=3x]
+ O(F30F00,00,7,0,0,0,0,3 ), // #33 [ref=1x]
+ O(F30F00,00,7,0,0,0,0,2 ), // #34 [ref=1x]
+ O_FPU(00,D900,0) , // #35 [ref=29x]
+ O_FPU(00,C000,0) , // #36 [ref=1x]
+ O_FPU(00,DE00,0) , // #37 [ref=7x]
+ O_FPU(00,0000,4) , // #38 [ref=4x]
+ O_FPU(00,0000,6) , // #39 [ref=4x]
+ O_FPU(9B,DB00,0) , // #40 [ref=2x]
+ O_FPU(00,DA00,0) , // #41 [ref=5x]
+ O_FPU(00,DB00,0) , // #42 [ref=8x]
+ O_FPU(00,D000,2) , // #43 [ref=1x]
+ O_FPU(00,DF00,0) , // #44 [ref=2x]
+ O_FPU(00,D800,3) , // #45 [ref=1x]
+ O_FPU(00,F000,6) , // #46 [ref=1x]
+ O_FPU(00,F800,7) , // #47 [ref=1x]
+ O_FPU(00,DD00,0) , // #48 [ref=3x]
+ O_FPU(00,0000,0) , // #49 [ref=4x]
+ O_FPU(00,0000,2) , // #50 [ref=3x]
+ O_FPU(00,0000,3) , // #51 [ref=3x]
+ O_FPU(00,0000,7) , // #52 [ref=3x]
+ O_FPU(00,0000,1) , // #53 [ref=2x]
+ O_FPU(00,0000,5) , // #54 [ref=2x]
+ O_FPU(00,C800,1) , // #55 [ref=1x]
+ O_FPU(9B,0000,6) , // #56 [ref=2x]
+ O_FPU(9B,0000,7) , // #57 [ref=2x]
+ O_FPU(00,E000,4) , // #58 [ref=1x]
+ O_FPU(00,E800,5) , // #59 [ref=1x]
+ O(000F00,00,0,0,1,0,0,0 ), // #60 [ref=3x]
+ O(F30F3A,00,0,0,0,0,0,0 ), // #61 [ref=1x]
+ O(000000,00,5,0,0,0,0,0 ), // #62 [ref=4x]
+ O(F30F00,00,5,0,0,0,0,0 ), // #63 [ref=2x]
+ O(F30F00,00,5,0,1,0,0,0 ), // #64 [ref=1x]
+ V(660F00,00,0,1,0,0,0,None), // #65 [ref=7x]
+ V(660F00,00,0,1,1,0,0,None), // #66 [ref=6x]
+ V(000F00,00,0,1,1,0,0,None), // #67 [ref=7x]
+ V(000F00,00,0,1,0,0,0,None), // #68 [ref=8x]
+ V(660F00,00,0,0,0,0,0,None), // #69 [ref=15x]
+ V(660F00,00,0,0,1,0,0,None), // #70 [ref=4x]
+ V(000F00,00,0,0,1,0,0,None), // #71 [ref=4x]
+ V(000F00,00,0,0,0,0,0,None), // #72 [ref=10x]
+ V(660F3A,00,0,0,0,0,0,None), // #73 [ref=47x]
+ V(660F3A,00,0,0,1,0,0,None), // #74 [ref=4x]
+ O(000000,00,3,0,0,0,0,0 ), // #75 [ref=4x]
+ O(000F00,00,2,0,0,0,0,0 ), // #76 [ref=5x]
+ O(000F00,00,5,0,0,0,0,0 ), // #77 [ref=4x]
+ O(000F00,00,3,0,0,0,0,0 ), // #78 [ref=5x]
+ V(XOP_M9,00,0,0,0,0,0,None), // #79 [ref=32x]
+ O(000F00,00,6,0,0,0,0,0 ), // #80 [ref=5x]
+ V(XOP_MA,00,0,0,0,0,0,None), // #81 [ref=1x]
+ V(XOP_MA,00,1,0,0,0,0,None), // #82 [ref=1x]
+ O(000F38,00,0,0,0,0,0,0 ), // #83 [ref=24x]
+ V(F20F38,00,0,0,0,0,0,None), // #84 [ref=6x]
+ O(000F3A,00,0,0,0,0,0,0 ), // #85 [ref=4x]
+ O(F30000,00,0,0,0,0,0,0 ), // #86 [ref=1x]
+ O(000F0F,00,0,0,0,0,0,0 ), // #87 [ref=26x]
+ V(F30F38,00,0,0,0,0,0,None), // #88 [ref=5x]
+ O(000F3A,00,0,0,1,0,0,0 ), // #89 [ref=1x]
+ O(660F3A,00,0,0,1,0,0,0 ), // #90 [ref=1x]
+ O(F30F00,00,4,0,0,0,0,0 ), // #91 [ref=1x]
+ O(F20F01,00,0,0,0,0,0,0 ), // #92 [ref=4x]
+ O(F30F00,00,1,0,0,0,0,0 ), // #93 [ref=3x]
+ O(F30F00,00,7,0,0,0,0,0 ), // #94 [ref=1x]
+ V(F20F3A,00,0,0,0,0,0,None), // #95 [ref=1x]
+ V(660F38,00,0,0,0,0,0,None), // #96 [ref=26x]
+ O(000F00,00,4,0,0,0,0,0 ), // #97 [ref=4x]
+ V(XOP_M9,00,7,0,0,0,0,None), // #98 [ref=1x]
+ V(XOP_M9,00,4,0,0,0,0,None), // #99 [ref=1x]
+ O(F20F00,00,6,0,0,0,0,0 ), // #100 [ref=1x]
+ E(F20F38,00,0,2,0,0,4,None), // #101 [ref=4x]
+ E(F20F38,00,0,0,0,0,4,None), // #102 [ref=2x]
+ V(660F00,00,0,0,0,1,4,ByLL), // #103 [ref=25x]
+ E(00MAP5,00,0,0,0,0,4,ByLL), // #104 [ref=10x]
+ V(000F00,00,0,0,0,0,4,ByLL), // #105 [ref=19x]
+ V(F20F00,00,0,0,0,1,3,None), // #106 [ref=10x]
+ E(F3MAP5,00,0,0,0,0,1,None), // #107 [ref=13x]
+ V(F30F00,00,0,0,0,0,2,None), // #108 [ref=12x]
+ V(F20F00,00,0,0,0,0,0,None), // #109 [ref=4x]
+ V(660F38,00,0,0,0,0,4,ByLL), // #110 [ref=50x]
+ E(660F3A,00,0,0,0,0,4,ByLL), // #111 [ref=17x]
+ E(660F3A,00,0,0,0,1,4,ByLL), // #112 [ref=18x]
+ E(660F38,00,0,0,0,1,4,ByLL), // #113 [ref=40x]
+ E(660F38,00,0,0,0,0,4,ByLL), // #114 [ref=25x]
+ V(660F38,00,0,1,0,0,0,None), // #115 [ref=2x]
+ E(660F38,00,0,0,0,0,3,None), // #116 [ref=2x]
+ E(660F38,00,0,0,0,0,4,None), // #117 [ref=2x]
+ E(660F38,00,0,2,0,0,5,None), // #118 [ref=2x]
+ E(660F38,00,0,0,0,1,4,None), // #119 [ref=2x]
+ E(660F38,00,0,2,0,1,5,None), // #120 [ref=2x]
+ V(660F38,00,0,0,0,1,3,None), // #121 [ref=2x]
+ V(660F38,00,0,0,0,0,2,None), // #122 [ref=14x]
+ E(000F3A,00,0,0,0,0,4,ByLL), // #123 [ref=5x]
+ E(F30F3A,00,0,0,0,0,1,None), // #124 [ref=1x]
+ V(660F00,00,0,0,0,1,3,None), // #125 [ref=5x]
+ E(00MAP5,00,0,0,0,0,1,None), // #126 [ref=2x]
+ V(000F00,00,0,0,0,0,2,None), // #127 [ref=2x]
+ E(660F38,00,0,0,0,1,3,None), // #128 [ref=14x]
+ E(660F38,00,0,0,0,0,2,None), // #129 [ref=14x]
+ V(F30F00,00,0,0,0,0,3,ByLL), // #130 [ref=1x]
+ E(F20F38,00,0,0,0,0,4,ByLL), // #131 [ref=2x]
+ E(F30F38,00,0,0,0,0,4,ByLL), // #132 [ref=4x]
+ V(F20F00,00,0,0,0,1,4,ByLL), // #133 [ref=1x]
+ E(66MAP5,00,0,0,0,1,4,ByLL), // #134 [ref=1x]
+ E(660F00,00,0,0,0,1,4,ByLL), // #135 [ref=10x]
+ E(000F00,00,0,0,0,1,4,ByLL), // #136 [ref=3x]
+ E(66MAP5,00,0,0,0,0,3,ByLL), // #137 [ref=1x]
+ E(00MAP5,00,0,0,0,0,2,ByLL), // #138 [ref=1x]
+ V(660F38,00,0,0,0,0,3,ByLL), // #139 [ref=7x]
+ E(66MAP6,00,0,0,0,0,3,ByLL), // #140 [ref=1x]
+ E(66MAP5,00,0,0,0,0,2,ByLL), // #141 [ref=4x]
+ E(00MAP5,00,0,0,0,0,3,ByLL), // #142 [ref=2x]
+ E(66MAP5,00,0,0,0,0,4,ByLL), // #143 [ref=3x]
+ V(660F00,00,0,0,0,0,4,ByLL), // #144 [ref=43x]
+ V(000F00,00,0,0,0,0,3,ByLL), // #145 [ref=1x]
+ V(660F3A,00,0,0,0,0,3,ByLL), // #146 [ref=1x]
+ E(660F00,00,0,0,0,0,3,ByLL), // #147 [ref=4x]
+ E(000F00,00,0,0,0,0,4,ByLL), // #148 [ref=2x]
+ E(F30F00,00,0,0,0,1,4,ByLL), // #149 [ref=3x]
+ E(00MAP5,00,0,0,0,1,4,ByLL), // #150 [ref=1x]
+ E(F2MAP5,00,0,0,0,1,3,None), // #151 [ref=1x]
+ V(F20F00,00,0,0,0,0,3,None), // #152 [ref=2x]
+ E(F20F00,00,0,0,0,0,3,None), // #153 [ref=2x]
+ E(00MAP6,00,0,0,0,0,1,None), // #154 [ref=1x]
+ V(F20F00,00,0,0,0,0,2,T1W ), // #155 [ref=1x]
+ E(F3MAP5,00,0,0,0,0,2,T1W ), // #156 [ref=2x]
+ V(F30F00,00,0,0,0,0,2,T1W ), // #157 [ref=1x]
+ E(00MAP5,00,0,0,0,0,2,None), // #158 [ref=1x]
+ E(F30F00,00,0,0,0,0,2,None), // #159 [ref=2x]
+ E(F3MAP5,00,0,0,0,0,3,ByLL), // #160 [ref=1x]
+ V(F30F00,00,0,0,0,0,4,ByLL), // #161 [ref=4x]
+ E(F30F00,00,0,0,0,0,3,ByLL), // #162 [ref=1x]
+ E(F2MAP5,00,0,0,0,0,4,ByLL), // #163 [ref=2x]
+ E(F20F00,00,0,0,0,0,4,ByLL), // #164 [ref=2x]
+ E(F2MAP5,00,0,0,0,1,4,ByLL), // #165 [ref=1x]
+ E(F20F00,00,0,0,0,1,4,ByLL), // #166 [ref=2x]
+ E(F20F00,00,0,0,0,0,2,T1W ), // #167 [ref=1x]
+ E(F30F00,00,0,0,0,0,2,T1W ), // #168 [ref=1x]
+ E(F3MAP5,00,0,0,0,0,4,ByLL), // #169 [ref=1x]
+ E(660F38,00,0,2,0,1,4,ByLL), // #170 [ref=3x]
+ E(660F38,00,0,2,0,0,4,ByLL), // #171 [ref=3x]
+ V(660F3A,00,0,1,0,0,0,None), // #172 [ref=6x]
+ E(660F3A,00,0,0,0,0,4,None), // #173 [ref=4x]
+ E(660F3A,00,0,2,0,0,5,None), // #174 [ref=4x]
+ E(660F3A,00,0,0,0,1,4,None), // #175 [ref=4x]
+ E(660F3A,00,0,2,0,1,5,None), // #176 [ref=4x]
+ V(660F3A,00,0,0,0,0,2,None), // #177 [ref=4x]
+ E(F2MAP6,00,0,0,0,0,4,ByLL), // #178 [ref=2x]
+ E(F2MAP6,00,0,0,0,0,2,None), // #179 [ref=2x]
+ E(660F3A,00,0,0,0,1,3,None), // #180 [ref=6x]
+ E(660F3A,00,0,0,0,0,2,None), // #181 [ref=6x]
+ V(660F38,00,0,0,1,1,4,ByLL), // #182 [ref=20x]
+ E(66MAP6,00,0,0,0,0,4,ByLL), // #183 [ref=22x]
+ V(660F38,00,0,0,1,1,3,None), // #184 [ref=12x]
+ E(66MAP6,00,0,0,0,0,1,None), // #185 [ref=16x]
+ E(F3MAP6,00,0,0,0,0,4,ByLL), // #186 [ref=2x]
+ E(F3MAP6,00,0,0,0,0,2,None), // #187 [ref=2x]
+ E(000F3A,00,0,0,0,0,1,None), // #188 [ref=4x]
+ V(660F38,00,0,0,1,0,0,None), // #189 [ref=5x]
+ E(660F38,00,1,2,0,1,3,None), // #190 [ref=2x]
+ E(660F38,00,1,2,0,0,2,None), // #191 [ref=2x]
+ E(660F38,00,2,2,0,1,3,None), // #192 [ref=2x]
+ E(660F38,00,2,2,0,0,2,None), // #193 [ref=2x]
+ V(660F3A,00,0,0,1,1,4,ByLL), // #194 [ref=2x]
+ V(000F00,00,2,0,0,0,0,None), // #195 [ref=1x]
+ V(660F00,00,0,0,0,0,2,None), // #196 [ref=1x]
+ V(F20F00,00,0,0,0,1,3,DUP ), // #197 [ref=1x]
+ E(660F00,00,0,0,0,0,4,ByLL), // #198 [ref=6x]
+ V(F30F00,00,0,0,0,0,0,None), // #199 [ref=3x]
+ E(F30F00,00,0,0,0,0,4,ByLL), // #200 [ref=1x]
+ V(000F00,00,0,0,0,0,3,None), // #201 [ref=2x]
+ E(66MAP5,00,0,0,0,0,1,None), // #202 [ref=1x]
+ E(F20F38,00,0,0,0,1,4,ByLL), // #203 [ref=1x]
+ V(660F3A,00,0,0,0,0,4,ByLL), // #204 [ref=2x]
+ E(F30F38,00,0,0,0,1,0,None), // #205 [ref=5x]
+ E(F30F38,00,0,0,0,0,0,None), // #206 [ref=5x]
+ V(660F38,00,0,0,0,0,1,None), // #207 [ref=1x]
+ V(XOP_M8,00,0,0,0,0,0,None), // #208 [ref=22x]
+ V(660F38,00,0,0,0,1,4,ByLL), // #209 [ref=4x]
+ E(660F38,00,0,0,0,0,0,None), // #210 [ref=2x]
+ E(660F38,00,0,0,0,1,1,None), // #211 [ref=2x]
+ E(660F38,00,0,0,1,1,4,ByLL), // #212 [ref=1x]
+ V(660F3A,00,0,0,1,1,3,None), // #213 [ref=2x]
+ V(660F3A,00,0,0,0,0,1,None), // #214 [ref=1x]
+ V(660F00,00,0,0,0,0,1,None), // #215 [ref=1x]
+ E(F30F38,00,0,0,0,0,2,ByLL), // #216 [ref=6x]
+ E(F30F38,00,0,0,0,0,3,ByLL), // #217 [ref=9x]
+ E(F30F38,00,0,0,0,0,1,ByLL), // #218 [ref=3x]
+ V(660F38,00,0,0,0,0,2,ByLL), // #219 [ref=4x]
+ V(660F38,00,0,0,0,0,1,ByLL), // #220 [ref=2x]
+ E(660F00,00,1,0,0,0,4,ByLL), // #221 [ref=1x]
+ E(660F00,00,1,0,0,1,4,ByLL), // #222 [ref=1x]
+ V(F20F00,00,0,0,0,0,4,ByLL), // #223 [ref=1x]
+ V(660F00,00,0,0,0,0,4,None), // #224 [ref=6x]
+ V(660F00,00,7,0,0,0,4,ByLL), // #225 [ref=1x]
+ V(660F00,00,0,0,0,1,4,None), // #226 [ref=2x]
+ E(660F00,00,0,0,0,1,4,None), // #227 [ref=1x]
+ V(660F00,00,3,0,0,0,4,ByLL), // #228 [ref=1x]
+ E(F30F38,00,0,0,0,1,4,ByLL), // #229 [ref=2x]
+ E(660F38,00,5,2,0,1,3,None), // #230 [ref=2x]
+ E(660F38,00,5,2,0,0,2,None), // #231 [ref=2x]
+ E(660F38,00,6,2,0,1,3,None), // #232 [ref=2x]
+ E(660F38,00,6,2,0,0,2,None), // #233 [ref=2x]
+ V(000F00,00,3,0,0,0,0,None), // #234 [ref=1x]
+ O(F30F00,00,2,0,0,0,0,0 ), // #235 [ref=1x]
+ O(F30F00,00,3,0,0,0,0,0 ), // #236 [ref=1x]
+ O(000F38,00,0,0,1,0,0,0 ), // #237 [ref=1x]
+ O(660F38,00,0,0,1,0,0,0 ), // #238 [ref=1x]
+ O(000F00,00,5,0,1,0,0,0 ), // #239 [ref=2x]
+ O(000F00,00,3,0,1,0,0,0 ), // #240 [ref=1x]
+ O(000F00,00,4,0,1,0,0,0 ), // #241 [ref=2x]
+ O(000F00,00,6,0,1,0,0,0 ) // #242 [ref=1x]
};
// ----------------------------------------------------------------------------
// ${MainOpcodeTable:End}
@@ -1905,140 +1996,141 @@ const uint32_t InstDB::_mainOpcodeTable[] = {
// ${AltOpcodeTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
const uint32_t InstDB::_altOpcodeTable[] = {
- 0 , // #0 [ref=1410x]
- O(660F00,1B,_,_,_,_,_,_ ), // #1 [ref=1x]
- O(000F00,BA,4,_,x,_,_,_ ), // #2 [ref=1x]
- O(000F00,BA,7,_,x,_,_,_ ), // #3 [ref=1x]
- O(000F00,BA,6,_,x,_,_,_ ), // #4 [ref=1x]
- O(000F00,BA,5,_,x,_,_,_ ), // #5 [ref=1x]
- O(000000,48,_,_,x,_,_,_ ), // #6 [ref=1x]
- O(660F00,78,0,_,_,_,_,_ ), // #7 [ref=1x]
- O_FPU(00,00DF,5) , // #8 [ref=1x]
- O_FPU(00,00DF,7) , // #9 [ref=1x]
- O_FPU(00,00DD,1) , // #10 [ref=1x]
- O_FPU(00,00DB,5) , // #11 [ref=1x]
- O_FPU(00,DFE0,_) , // #12 [ref=1x]
- O(000000,DB,7,_,_,_,_,_ ), // #13 [ref=1x]
- O_FPU(9B,DFE0,_) , // #14 [ref=1x]
- O(000000,E4,_,_,_,_,_,_ ), // #15 [ref=1x]
- O(000000,40,_,_,x,_,_,_ ), // #16 [ref=1x]
- O(F20F00,78,_,_,_,_,_,_ ), // #17 [ref=1x]
- O(000000,77,_,_,_,_,_,_ ), // #18 [ref=2x]
- O(000000,73,_,_,_,_,_,_ ), // #19 [ref=3x]
- O(000000,72,_,_,_,_,_,_ ), // #20 [ref=3x]
- O(000000,76,_,_,_,_,_,_ ), // #21 [ref=2x]
- O(000000,74,_,_,_,_,_,_ ), // #22 [ref=2x]
- O(000000,E3,_,_,_,_,_,_ ), // #23 [ref=1x]
- O(000000,7F,_,_,_,_,_,_ ), // #24 [ref=2x]
- O(000000,7D,_,_,_,_,_,_ ), // #25 [ref=2x]
- O(000000,7C,_,_,_,_,_,_ ), // #26 [ref=2x]
- O(000000,7E,_,_,_,_,_,_ ), // #27 [ref=2x]
- O(000000,EB,_,_,_,_,_,_ ), // #28 [ref=1x]
- O(000000,75,_,_,_,_,_,_ ), // #29 [ref=2x]
- O(000000,71,_,_,_,_,_,_ ), // #30 [ref=1x]
- O(000000,7B,_,_,_,_,_,_ ), // #31 [ref=2x]
- O(000000,79,_,_,_,_,_,_ ), // #32 [ref=1x]
- O(000000,70,_,_,_,_,_,_ ), // #33 [ref=1x]
- O(000000,7A,_,_,_,_,_,_ ), // #34 [ref=2x]
- O(000000,78,_,_,_,_,_,_ ), // #35 [ref=1x]
- V(660F00,92,_,0,0,_,_,_ ), // #36 [ref=1x]
- V(F20F00,92,_,0,0,_,_,_ ), // #37 [ref=1x]
- V(F20F00,92,_,0,1,_,_,_ ), // #38 [ref=1x]
- V(000F00,92,_,0,0,_,_,_ ), // #39 [ref=1x]
- O(000000,9A,_,_,_,_,_,_ ), // #40 [ref=1x]
- O(000000,EA,_,_,_,_,_,_ ), // #41 [ref=1x]
- O(000000,E2,_,_,_,_,_,_ ), // #42 [ref=1x]
- O(000000,E1,_,_,_,_,_,_ ), // #43 [ref=1x]
- O(000000,E0,_,_,_,_,_,_ ), // #44 [ref=1x]
- O(660F00,29,_,_,_,_,_,_ ), // #45 [ref=1x]
- O(000F00,29,_,_,_,_,_,_ ), // #46 [ref=1x]
- O(000F38,F1,_,_,x,_,_,_ ), // #47 [ref=1x]
- O(000F00,7E,_,_,_,_,_,_ ), // #48 [ref=1x]
- O(660F00,7F,_,_,_,_,_,_ ), // #49 [ref=1x]
- O(F30F00,7F,_,_,_,_,_,_ ), // #50 [ref=1x]
- O(660F00,17,_,_,_,_,_,_ ), // #51 [ref=1x]
- O(000F00,17,_,_,_,_,_,_ ), // #52 [ref=1x]
- O(660F00,13,_,_,_,_,_,_ ), // #53 [ref=1x]
- O(000F00,13,_,_,_,_,_,_ ), // #54 [ref=1x]
- O(660F00,E7,_,_,_,_,_,_ ), // #55 [ref=1x]
- O(660F00,2B,_,_,_,_,_,_ ), // #56 [ref=1x]
- O(000F00,2B,_,_,_,_,_,_ ), // #57 [ref=1x]
- O(000F00,E7,_,_,_,_,_,_ ), // #58 [ref=1x]
- O(F20F00,2B,_,_,_,_,_,_ ), // #59 [ref=1x]
- O(F30F00,2B,_,_,_,_,_,_ ), // #60 [ref=1x]
- O(000F00,7E,_,_,x,_,_,_ ), // #61 [ref=1x]
- O(F20F00,11,_,_,_,_,_,_ ), // #62 [ref=1x]
- O(F30F00,11,_,_,_,_,_,_ ), // #63 [ref=1x]
- O(660F00,11,_,_,_,_,_,_ ), // #64 [ref=1x]
- O(000F00,11,_,_,_,_,_,_ ), // #65 [ref=1x]
- O(000000,E6,_,_,_,_,_,_ ), // #66 [ref=1x]
- O(000F3A,15,_,_,_,_,_,_ ), // #67 [ref=1x]
- O(000000,58,_,_,_,_,_,_ ), // #68 [ref=1x]
- O(000F00,72,6,_,_,_,_,_ ), // #69 [ref=1x]
- O(660F00,73,7,_,_,_,_,_ ), // #70 [ref=1x]
- O(000F00,73,6,_,_,_,_,_ ), // #71 [ref=1x]
- O(000F00,71,6,_,_,_,_,_ ), // #72 [ref=1x]
- O(000F00,72,4,_,_,_,_,_ ), // #73 [ref=1x]
- O(000F00,71,4,_,_,_,_,_ ), // #74 [ref=1x]
- O(000F00,72,2,_,_,_,_,_ ), // #75 [ref=1x]
- O(660F00,73,3,_,_,_,_,_ ), // #76 [ref=1x]
- O(000F00,73,2,_,_,_,_,_ ), // #77 [ref=1x]
- O(000F00,71,2,_,_,_,_,_ ), // #78 [ref=1x]
- O(000000,50,_,_,_,_,_,_ ), // #79 [ref=1x]
- O(000000,F6,_,_,x,_,_,_ ), // #80 [ref=1x]
- E(660F38,92,_,x,_,1,3,T1S), // #81 [ref=1x]
- E(660F38,92,_,x,_,0,2,T1S), // #82 [ref=1x]
- E(660F38,93,_,x,_,1,3,T1S), // #83 [ref=1x]
- E(660F38,93,_,x,_,0,2,T1S), // #84 [ref=1x]
- V(660F38,2F,_,x,0,_,_,_ ), // #85 [ref=1x]
- V(660F38,2E,_,x,0,_,_,_ ), // #86 [ref=1x]
- V(660F00,29,_,x,I,1,4,FVM), // #87 [ref=1x]
- V(000F00,29,_,x,I,0,4,FVM), // #88 [ref=1x]
- V(660F00,7E,_,0,0,0,2,T1S), // #89 [ref=1x]
- V(660F00,7F,_,x,I,_,_,_ ), // #90 [ref=1x]
- E(660F00,7F,_,x,_,0,4,FVM), // #91 [ref=1x]
- E(660F00,7F,_,x,_,1,4,FVM), // #92 [ref=1x]
- V(F30F00,7F,_,x,I,_,_,_ ), // #93 [ref=1x]
- E(F20F00,7F,_,x,_,1,4,FVM), // #94 [ref=1x]
- E(F30F00,7F,_,x,_,0,4,FVM), // #95 [ref=1x]
- E(F30F00,7F,_,x,_,1,4,FVM), // #96 [ref=1x]
- E(F20F00,7F,_,x,_,0,4,FVM), // #97 [ref=1x]
- V(660F00,17,_,0,I,1,3,T1S), // #98 [ref=1x]
- V(000F00,17,_,0,I,0,3,T2 ), // #99 [ref=1x]
- V(660F00,13,_,0,I,1,3,T1S), // #100 [ref=1x]
- V(000F00,13,_,0,I,0,3,T2 ), // #101 [ref=1x]
- V(660F00,7E,_,0,I,1,3,T1S), // #102 [ref=1x]
- V(F20F00,11,_,I,I,1,3,T1S), // #103 [ref=1x]
- V(F30F00,11,_,I,I,0,2,T1S), // #104 [ref=1x]
- V(660F00,11,_,x,I,1,4,FVM), // #105 [ref=1x]
- V(000F00,11,_,x,I,0,4,FVM), // #106 [ref=1x]
- E(660F38,7A,_,x,0,0,0,T1S), // #107 [ref=1x]
- E(660F38,7C,_,x,0,0,0,T1S), // #108 [ref=1x]
- E(660F38,7C,_,x,0,1,0,T1S), // #109 [ref=1x]
- E(660F38,7B,_,x,0,0,0,T1S), // #110 [ref=1x]
- V(660F3A,05,_,x,0,1,4,FV ), // #111 [ref=1x]
- V(660F3A,04,_,x,0,0,4,FV ), // #112 [ref=1x]
- V(660F3A,01,_,x,1,1,4,FV ), // #113 [ref=1x]
- V(660F3A,00,_,x,1,1,4,FV ), // #114 [ref=1x]
- E(660F38,90,_,x,_,0,2,T1S), // #115 [ref=1x]
- E(660F38,90,_,x,_,1,3,T1S), // #116 [ref=1x]
- E(660F38,91,_,x,_,0,2,T1S), // #117 [ref=1x]
- E(660F38,91,_,x,_,1,3,T1S), // #118 [ref=1x]
- V(660F38,8E,_,x,0,_,_,_ ), // #119 [ref=1x]
- V(660F38,8E,_,x,1,_,_,_ ), // #120 [ref=1x]
- V(XOP_M8,C0,_,0,x,_,_,_ ), // #121 [ref=1x]
- V(XOP_M8,C2,_,0,x,_,_,_ ), // #122 [ref=1x]
- V(XOP_M8,C3,_,0,x,_,_,_ ), // #123 [ref=1x]
- V(XOP_M8,C1,_,0,x,_,_,_ ), // #124 [ref=1x]
- V(660F00,72,6,x,I,0,4,FV ), // #125 [ref=1x]
- V(660F00,73,6,x,I,1,4,FV ), // #126 [ref=1x]
- V(660F00,71,6,x,I,I,4,FVM), // #127 [ref=1x]
- V(660F00,72,4,x,I,0,4,FV ), // #128 [ref=1x]
- E(660F00,72,4,x,_,1,4,FV ), // #129 [ref=1x]
- V(660F00,71,4,x,I,I,4,FVM), // #130 [ref=1x]
- V(660F00,72,2,x,I,0,4,FV ), // #131 [ref=1x]
- V(660F00,73,2,x,I,1,4,FV ), // #132 [ref=1x]
- V(660F00,71,2,x,I,I,4,FVM) // #133 [ref=1x]
+ O(000000,00,0,0,0,0,0,0 ), // #0 [ref=1514x]
+ O(660F00,1B,0,0,0,0,0,0 ), // #1 [ref=1x]
+ O(000F00,BA,4,0,0,0,0,0 ), // #2 [ref=1x]
+ O(000F00,BA,7,0,0,0,0,0 ), // #3 [ref=1x]
+ O(000F00,BA,6,0,0,0,0,0 ), // #4 [ref=1x]
+ O(000F00,BA,5,0,0,0,0,0 ), // #5 [ref=1x]
+ O(000000,48,0,0,0,0,0,0 ), // #6 [ref=1x]
+ O(660F00,78,0,0,0,0,0,0 ), // #7 [ref=1x]
+ O_FPU(00,00DF,5) , // #8 [ref=1x]
+ O_FPU(00,00DF,7) , // #9 [ref=1x]
+ O_FPU(00,00DD,1) , // #10 [ref=1x]
+ O_FPU(00,00DB,5) , // #11 [ref=1x]
+ O_FPU(00,DFE0,0) , // #12 [ref=1x]
+ O(000000,DB,7,0,0,0,0,0 ), // #13 [ref=1x]
+ O_FPU(9B,DFE0,0) , // #14 [ref=1x]
+ O(000000,E4,0,0,0,0,0,0 ), // #15 [ref=1x]
+ O(000000,40,0,0,0,0,0,0 ), // #16 [ref=1x]
+ O(F20F00,78,0,0,0,0,0,0 ), // #17 [ref=1x]
+ O(000000,77,0,0,0,0,0,0 ), // #18 [ref=2x]
+ O(000000,73,0,0,0,0,0,0 ), // #19 [ref=3x]
+ O(000000,72,0,0,0,0,0,0 ), // #20 [ref=3x]
+ O(000000,76,0,0,0,0,0,0 ), // #21 [ref=2x]
+ O(000000,74,0,0,0,0,0,0 ), // #22 [ref=2x]
+ O(000000,E3,0,0,0,0,0,0 ), // #23 [ref=1x]
+ O(000000,7F,0,0,0,0,0,0 ), // #24 [ref=2x]
+ O(000000,7D,0,0,0,0,0,0 ), // #25 [ref=2x]
+ O(000000,7C,0,0,0,0,0,0 ), // #26 [ref=2x]
+ O(000000,7E,0,0,0,0,0,0 ), // #27 [ref=2x]
+ O(000000,EB,0,0,0,0,0,0 ), // #28 [ref=1x]
+ O(000000,75,0,0,0,0,0,0 ), // #29 [ref=2x]
+ O(000000,71,0,0,0,0,0,0 ), // #30 [ref=1x]
+ O(000000,7B,0,0,0,0,0,0 ), // #31 [ref=2x]
+ O(000000,79,0,0,0,0,0,0 ), // #32 [ref=1x]
+ O(000000,70,0,0,0,0,0,0 ), // #33 [ref=1x]
+ O(000000,7A,0,0,0,0,0,0 ), // #34 [ref=2x]
+ O(000000,78,0,0,0,0,0,0 ), // #35 [ref=1x]
+ V(660F00,92,0,0,0,0,0,None), // #36 [ref=1x]
+ V(F20F00,92,0,0,0,0,0,None), // #37 [ref=1x]
+ V(F20F00,92,0,0,1,0,0,None), // #38 [ref=1x]
+ V(000F00,92,0,0,0,0,0,None), // #39 [ref=1x]
+ O(000000,9A,0,0,0,0,0,0 ), // #40 [ref=1x]
+ O(000000,EA,0,0,0,0,0,0 ), // #41 [ref=1x]
+ O(000000,E2,0,0,0,0,0,0 ), // #42 [ref=1x]
+ O(000000,E1,0,0,0,0,0,0 ), // #43 [ref=1x]
+ O(000000,E0,0,0,0,0,0,0 ), // #44 [ref=1x]
+ O(660F00,29,0,0,0,0,0,0 ), // #45 [ref=1x]
+ O(000F00,29,0,0,0,0,0,0 ), // #46 [ref=1x]
+ O(000F38,F1,0,0,0,0,0,0 ), // #47 [ref=1x]
+ O(000F00,7E,0,0,0,0,0,0 ), // #48 [ref=2x]
+ O(660F00,7F,0,0,0,0,0,0 ), // #49 [ref=1x]
+ O(F30F00,7F,0,0,0,0,0,0 ), // #50 [ref=1x]
+ O(660F00,17,0,0,0,0,0,0 ), // #51 [ref=1x]
+ O(000F00,17,0,0,0,0,0,0 ), // #52 [ref=1x]
+ O(660F00,13,0,0,0,0,0,0 ), // #53 [ref=1x]
+ O(000F00,13,0,0,0,0,0,0 ), // #54 [ref=1x]
+ O(660F00,E7,0,0,0,0,0,0 ), // #55 [ref=1x]
+ O(660F00,2B,0,0,0,0,0,0 ), // #56 [ref=1x]
+ O(000F00,2B,0,0,0,0,0,0 ), // #57 [ref=1x]
+ O(000F00,E7,0,0,0,0,0,0 ), // #58 [ref=1x]
+ O(F20F00,2B,0,0,0,0,0,0 ), // #59 [ref=1x]
+ O(F30F00,2B,0,0,0,0,0,0 ), // #60 [ref=1x]
+ O(F20F00,11,0,0,0,0,0,0 ), // #61 [ref=1x]
+ O(F30F00,11,0,0,0,0,0,0 ), // #62 [ref=1x]
+ O(660F00,11,0,0,0,0,0,0 ), // #63 [ref=1x]
+ O(000F00,11,0,0,0,0,0,0 ), // #64 [ref=1x]
+ O(000000,E6,0,0,0,0,0,0 ), // #65 [ref=1x]
+ O(000F3A,15,0,0,0,0,0,0 ), // #66 [ref=1x]
+ O(000000,58,0,0,0,0,0,0 ), // #67 [ref=1x]
+ O(000F00,72,6,0,0,0,0,0 ), // #68 [ref=1x]
+ O(660F00,73,7,0,0,0,0,0 ), // #69 [ref=1x]
+ O(000F00,73,6,0,0,0,0,0 ), // #70 [ref=1x]
+ O(000F00,71,6,0,0,0,0,0 ), // #71 [ref=1x]
+ O(000F00,72,4,0,0,0,0,0 ), // #72 [ref=1x]
+ O(000F00,71,4,0,0,0,0,0 ), // #73 [ref=1x]
+ O(000F00,72,2,0,0,0,0,0 ), // #74 [ref=1x]
+ O(660F00,73,3,0,0,0,0,0 ), // #75 [ref=1x]
+ O(000F00,73,2,0,0,0,0,0 ), // #76 [ref=1x]
+ O(000F00,71,2,0,0,0,0,0 ), // #77 [ref=1x]
+ O(000000,50,0,0,0,0,0,0 ), // #78 [ref=1x]
+ O(000000,F6,0,0,0,0,0,0 ), // #79 [ref=1x]
+ E(660F38,92,0,0,0,1,3,None), // #80 [ref=1x]
+ E(660F38,92,0,0,0,0,2,None), // #81 [ref=1x]
+ E(660F38,93,0,0,0,1,3,None), // #82 [ref=1x]
+ E(660F38,93,0,0,0,0,2,None), // #83 [ref=1x]
+ V(660F38,2F,0,0,0,0,0,None), // #84 [ref=1x]
+ V(660F38,2E,0,0,0,0,0,None), // #85 [ref=1x]
+ V(660F00,29,0,0,0,1,4,ByLL), // #86 [ref=1x]
+ V(000F00,29,0,0,0,0,4,ByLL), // #87 [ref=1x]
+ V(660F00,7E,0,0,0,0,2,None), // #88 [ref=1x]
+ V(660F00,7F,0,0,0,0,0,None), // #89 [ref=1x]
+ E(660F00,7F,0,0,0,0,4,ByLL), // #90 [ref=1x]
+ E(660F00,7F,0,0,0,1,4,ByLL), // #91 [ref=1x]
+ V(F30F00,7F,0,0,0,0,0,None), // #92 [ref=1x]
+ E(F20F00,7F,0,0,0,1,4,ByLL), // #93 [ref=1x]
+ E(F30F00,7F,0,0,0,0,4,ByLL), // #94 [ref=1x]
+ E(F30F00,7F,0,0,0,1,4,ByLL), // #95 [ref=1x]
+ E(F20F00,7F,0,0,0,0,4,ByLL), // #96 [ref=1x]
+ V(660F00,17,0,0,0,1,3,None), // #97 [ref=1x]
+ V(000F00,17,0,0,0,0,3,None), // #98 [ref=1x]
+ V(660F00,13,0,0,0,1,3,None), // #99 [ref=1x]
+ V(000F00,13,0,0,0,0,3,None), // #100 [ref=1x]
+ V(660F00,7E,0,0,0,1,3,None), // #101 [ref=1x]
+ V(F20F00,11,0,0,0,1,3,None), // #102 [ref=1x]
+ E(F3MAP5,11,0,0,0,0,1,None), // #103 [ref=1x]
+ V(F30F00,11,0,0,0,0,2,None), // #104 [ref=1x]
+ V(660F00,11,0,0,0,1,4,ByLL), // #105 [ref=1x]
+ V(000F00,11,0,0,0,0,4,ByLL), // #106 [ref=1x]
+ E(66MAP5,7E,0,0,0,0,1,None), // #107 [ref=1x]
+ E(660F38,7A,0,0,0,0,0,None), // #108 [ref=1x]
+ E(660F38,7C,0,0,0,0,0,None), // #109 [ref=1x]
+ E(660F38,7C,0,0,0,1,0,None), // #110 [ref=1x]
+ E(660F38,7B,0,0,0,0,0,None), // #111 [ref=1x]
+ V(660F3A,05,0,0,0,1,4,ByLL), // #112 [ref=1x]
+ V(660F3A,04,0,0,0,0,4,ByLL), // #113 [ref=1x]
+ V(660F3A,01,0,0,1,1,4,ByLL), // #114 [ref=1x]
+ V(660F3A,00,0,0,1,1,4,ByLL), // #115 [ref=1x]
+ E(660F38,90,0,0,0,0,2,None), // #116 [ref=1x]
+ E(660F38,90,0,0,0,1,3,None), // #117 [ref=1x]
+ E(660F38,91,0,0,0,0,2,None), // #118 [ref=1x]
+ E(660F38,91,0,0,0,1,3,None), // #119 [ref=1x]
+ V(660F38,8E,0,0,0,0,0,None), // #120 [ref=1x]
+ V(660F38,8E,0,0,1,0,0,None), // #121 [ref=1x]
+ V(XOP_M8,C0,0,0,0,0,0,None), // #122 [ref=1x]
+ V(XOP_M8,C2,0,0,0,0,0,None), // #123 [ref=1x]
+ V(XOP_M8,C3,0,0,0,0,0,None), // #124 [ref=1x]
+ V(XOP_M8,C1,0,0,0,0,0,None), // #125 [ref=1x]
+ V(660F00,72,6,0,0,0,4,ByLL), // #126 [ref=1x]
+ V(660F00,73,6,0,0,1,4,ByLL), // #127 [ref=1x]
+ V(660F00,71,6,0,0,0,4,ByLL), // #128 [ref=1x]
+ V(660F00,72,4,0,0,0,4,ByLL), // #129 [ref=1x]
+ E(660F00,72,4,0,0,1,4,ByLL), // #130 [ref=1x]
+ V(660F00,71,4,0,0,0,4,ByLL), // #131 [ref=1x]
+ V(660F00,72,2,0,0,0,4,ByLL), // #132 [ref=1x]
+ V(660F00,73,2,0,0,1,4,ByLL), // #133 [ref=1x]
+ V(660F00,71,2,0,0,0,4,ByLL) // #134 [ref=1x]
};
// ----------------------------------------------------------------------------
// ${AltOpcodeTable:End}
@@ -2048,450 +2140,475 @@ const uint32_t InstDB::_altOpcodeTable[] = {
#undef E
#undef O_FPU
-// ============================================================================
-// [asmjit::x86::InstDB - CommonInfoTableA]
-// ============================================================================
+// x86::InstDB - CommonInfoTable
+// =============================
// ${InstCommonTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
-#define F(VAL) InstDB::kFlag##VAL
-#define X(VAL) InstDB::kAvx512Flag##VAL
-#define CONTROL(VAL) Inst::kControl##VAL
-#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL
+#define F(VAL) uint32_t(InstDB::InstFlags::k##VAL)
+#define X(VAL) uint32_t(InstDB::Avx512Flags::k##VAL)
+#define CONTROL_FLOW(VAL) uint8_t(InstControlFlow::k##VAL)
+#define SAME_REG_HINT(VAL) uint8_t(InstSameRegHint::k##VAL)
const InstDB::CommonInfo InstDB::_commonInfoTable[] = {
- { 0 , 0 , 0 , 0 , CONTROL(None) , SINGLE_REG(None)}, // #0 [ref=1x]
- { 0 , 0 , 376, 1 , CONTROL(None) , SINGLE_REG(None)}, // #1 [ref=4x]
- { 0 , 0 , 377, 1 , CONTROL(None) , SINGLE_REG(None)}, // #2 [ref=2x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None)}, // #3 [ref=2x]
- { 0 , 0 , 180, 2 , CONTROL(None) , SINGLE_REG(None)}, // #4 [ref=2x]
- { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #5 [ref=54x]
- { F(Vec) , 0 , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #6 [ref=19x]
- { F(Vec) , 0 , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #7 [ref=16x]
- { F(Vec) , 0 , 215, 1 , CONTROL(None) , SINGLE_REG(None)}, // #8 [ref=20x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 28 , 11, CONTROL(None) , SINGLE_REG(RO) }, // #9 [ref=1x]
- { F(Vex) , 0 , 272, 2 , CONTROL(None) , SINGLE_REG(None)}, // #10 [ref=3x]
- { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(RO) }, // #11 [ref=12x]
- { 0 , 0 , 378, 1 , CONTROL(None) , SINGLE_REG(None)}, // #12 [ref=1x]
- { F(Vex) , 0 , 274, 2 , CONTROL(None) , SINGLE_REG(None)}, // #13 [ref=5x]
- { F(Vex) , 0 , 180, 2 , CONTROL(None) , SINGLE_REG(None)}, // #14 [ref=12x]
- { F(Vec) , 0 , 379, 1 , CONTROL(None) , SINGLE_REG(None)}, // #15 [ref=4x]
- { 0 , 0 , 276, 2 , CONTROL(None) , SINGLE_REG(None)}, // #16 [ref=3x]
- { F(Mib) , 0 , 380, 1 , CONTROL(None) , SINGLE_REG(None)}, // #17 [ref=1x]
- { 0 , 0 , 381, 1 , CONTROL(None) , SINGLE_REG(None)}, // #18 [ref=1x]
- { 0 , 0 , 278, 2 , CONTROL(None) , SINGLE_REG(None)}, // #19 [ref=1x]
- { F(Mib) , 0 , 382, 1 , CONTROL(None) , SINGLE_REG(None)}, // #20 [ref=1x]
- { 0 , 0 , 280, 2 , CONTROL(None) , SINGLE_REG(None)}, // #21 [ref=1x]
- { 0 , 0 , 179, 3 , CONTROL(None) , SINGLE_REG(None)}, // #22 [ref=35x]
- { 0 , 0 , 383, 1 , CONTROL(None) , SINGLE_REG(None)}, // #23 [ref=3x]
- { 0 , 0 , 123, 4 , CONTROL(None) , SINGLE_REG(None)}, // #24 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 123, 4 , CONTROL(None) , SINGLE_REG(None)}, // #25 [ref=3x]
- { F(Rep)|F(RepIgnored) , 0 , 282, 2 , CONTROL(Call) , SINGLE_REG(None)}, // #26 [ref=1x]
- { 0 , 0 , 384, 1 , CONTROL(None) , SINGLE_REG(None)}, // #27 [ref=1x]
- { 0 , 0 , 385, 1 , CONTROL(None) , SINGLE_REG(None)}, // #28 [ref=2x]
- { 0 , 0 , 359, 1 , CONTROL(None) , SINGLE_REG(None)}, // #29 [ref=1x]
- { 0 , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #30 [ref=83x]
- { 0 , 0 , 386, 1 , CONTROL(None) , SINGLE_REG(None)}, // #31 [ref=11x]
- { 0 , 0 , 387, 1 , CONTROL(None) , SINGLE_REG(None)}, // #32 [ref=6x]
- { 0 , 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None)}, // #33 [ref=13x]
- { 0 , 0 , 389, 1 , CONTROL(None) , SINGLE_REG(None)}, // #34 [ref=1x]
- { 0 , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(None)}, // #35 [ref=1x]
- { F(Rep) , 0 , 127, 4 , CONTROL(None) , SINGLE_REG(None)}, // #36 [ref=1x]
- { F(Vec) , 0 , 390, 1 , CONTROL(None) , SINGLE_REG(None)}, // #37 [ref=2x]
- { F(Vec) , 0 , 391, 1 , CONTROL(None) , SINGLE_REG(None)}, // #38 [ref=3x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 131, 4 , CONTROL(None) , SINGLE_REG(None)}, // #39 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 392, 1 , CONTROL(None) , SINGLE_REG(None)}, // #40 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 393, 1 , CONTROL(None) , SINGLE_REG(None)}, // #41 [ref=1x]
- { 0 , 0 , 394, 1 , CONTROL(None) , SINGLE_REG(None)}, // #42 [ref=1x]
- { 0 , 0 , 395, 1 , CONTROL(None) , SINGLE_REG(None)}, // #43 [ref=1x]
- { 0 , 0 , 284, 2 , CONTROL(None) , SINGLE_REG(None)}, // #44 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 396, 1 , CONTROL(None) , SINGLE_REG(None)}, // #45 [ref=2x]
- { F(Mmx)|F(Vec) , 0 , 397, 1 , CONTROL(None) , SINGLE_REG(None)}, // #46 [ref=2x]
- { F(Mmx)|F(Vec) , 0 , 398, 1 , CONTROL(None) , SINGLE_REG(None)}, // #47 [ref=2x]
- { F(Vec) , 0 , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #48 [ref=2x]
- { F(Vec) , 0 , 400, 1 , CONTROL(None) , SINGLE_REG(None)}, // #49 [ref=2x]
- { F(Vec) , 0 , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #50 [ref=2x]
- { 0 , 0 , 402, 1 , CONTROL(None) , SINGLE_REG(None)}, // #51 [ref=1x]
- { 0 , 0 , 403, 1 , CONTROL(None) , SINGLE_REG(None)}, // #52 [ref=2x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 286, 2 , CONTROL(None) , SINGLE_REG(None)}, // #53 [ref=2x]
- { 0 , 0 , 39 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #54 [ref=3x]
- { F(Mmx) , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #55 [ref=1x]
- { 0 , 0 , 288, 2 , CONTROL(None) , SINGLE_REG(None)}, // #56 [ref=2x]
- { 0 , 0 , 404, 1 , CONTROL(None) , SINGLE_REG(None)}, // #57 [ref=1x]
- { F(Vec) , 0 , 405, 1 , CONTROL(None) , SINGLE_REG(None)}, // #58 [ref=2x]
- { F(Vec) , 0 , 290, 2 , CONTROL(None) , SINGLE_REG(None)}, // #59 [ref=1x]
- { F(FpuM32)|F(FpuM64) , 0 , 182, 3 , CONTROL(None) , SINGLE_REG(None)}, // #60 [ref=6x]
- { 0 , 0 , 292, 2 , CONTROL(None) , SINGLE_REG(None)}, // #61 [ref=9x]
- { F(FpuM80) , 0 , 406, 1 , CONTROL(None) , SINGLE_REG(None)}, // #62 [ref=2x]
- { 0 , 0 , 293, 1 , CONTROL(None) , SINGLE_REG(None)}, // #63 [ref=13x]
- { F(FpuM32)|F(FpuM64) , 0 , 294, 2 , CONTROL(None) , SINGLE_REG(None)}, // #64 [ref=2x]
- { F(FpuM16)|F(FpuM32) , 0 , 407, 1 , CONTROL(None) , SINGLE_REG(None)}, // #65 [ref=9x]
- { F(FpuM16)|F(FpuM32)|F(FpuM64) , 0 , 408, 1 , CONTROL(None) , SINGLE_REG(None)}, // #66 [ref=3x]
- { F(FpuM32)|F(FpuM64)|F(FpuM80) , 0 , 409, 1 , CONTROL(None) , SINGLE_REG(None)}, // #67 [ref=2x]
- { F(FpuM16) , 0 , 410, 1 , CONTROL(None) , SINGLE_REG(None)}, // #68 [ref=3x]
- { 0 , 0 , 411, 1 , CONTROL(None) , SINGLE_REG(None)}, // #69 [ref=13x]
- { F(FpuM16) , 0 , 412, 1 , CONTROL(None) , SINGLE_REG(None)}, // #70 [ref=2x]
- { F(FpuM32)|F(FpuM64) , 0 , 295, 1 , CONTROL(None) , SINGLE_REG(None)}, // #71 [ref=1x]
- { 0 , 0 , 413, 1 , CONTROL(None) , SINGLE_REG(None)}, // #72 [ref=2x]
- { 0 , 0 , 414, 1 , CONTROL(None) , SINGLE_REG(None)}, // #73 [ref=1x]
- { 0 , 0 , 39 , 10, CONTROL(None) , SINGLE_REG(None)}, // #74 [ref=1x]
- { 0 , 0 , 415, 1 , CONTROL(None) , SINGLE_REG(None)}, // #75 [ref=1x]
- { 0 , 0 , 416, 1 , CONTROL(None) , SINGLE_REG(None)}, // #76 [ref=2x]
- { 0 , 0 , 343, 1 , CONTROL(None) , SINGLE_REG(None)}, // #77 [ref=3x]
- { F(Rep) , 0 , 417, 1 , CONTROL(None) , SINGLE_REG(None)}, // #78 [ref=1x]
- { F(Vec) , 0 , 296, 2 , CONTROL(None) , SINGLE_REG(None)}, // #79 [ref=1x]
- { 0 , 0 , 418, 1 , CONTROL(None) , SINGLE_REG(None)}, // #80 [ref=2x]
- { 0 , 0 , 419, 1 , CONTROL(None) , SINGLE_REG(None)}, // #81 [ref=8x]
- { 0 , 0 , 298, 2 , CONTROL(None) , SINGLE_REG(None)}, // #82 [ref=3x]
- { 0 , 0 , 300, 2 , CONTROL(None) , SINGLE_REG(None)}, // #83 [ref=1x]
- { 0 , 0 , 108, 1 , CONTROL(Return) , SINGLE_REG(None)}, // #84 [ref=2x]
- { 0 , 0 , 388, 1 , CONTROL(Return) , SINGLE_REG(None)}, // #85 [ref=1x]
- { F(Rep)|F(RepIgnored) , 0 , 302, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #86 [ref=30x]
- { F(Rep)|F(RepIgnored) , 0 , 304, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #87 [ref=1x]
- { F(Rep)|F(RepIgnored) , 0 , 306, 2 , CONTROL(Jump) , SINGLE_REG(None)}, // #88 [ref=1x]
- { F(Vex) , 0 , 420, 1 , CONTROL(None) , SINGLE_REG(None)}, // #89 [ref=19x]
- { F(Vex) , 0 , 308, 2 , CONTROL(None) , SINGLE_REG(None)}, // #90 [ref=1x]
- { F(Vex) , 0 , 310, 2 , CONTROL(None) , SINGLE_REG(None)}, // #91 [ref=1x]
- { F(Vex) , 0 , 312, 2 , CONTROL(None) , SINGLE_REG(None)}, // #92 [ref=1x]
- { F(Vex) , 0 , 314, 2 , CONTROL(None) , SINGLE_REG(None)}, // #93 [ref=1x]
- { F(Vex) , 0 , 421, 1 , CONTROL(None) , SINGLE_REG(None)}, // #94 [ref=12x]
- { F(Vex) , 0 , 422, 1 , CONTROL(None) , SINGLE_REG(None)}, // #95 [ref=8x]
- { F(Vex) , 0 , 420, 1 , CONTROL(None) , SINGLE_REG(WO) }, // #96 [ref=8x]
- { 0 , 0 , 423, 1 , CONTROL(None) , SINGLE_REG(None)}, // #97 [ref=2x]
- { 0 , 0 , 316, 2 , CONTROL(None) , SINGLE_REG(None)}, // #98 [ref=1x]
- { 0 , 0 , 318, 2 , CONTROL(Call) , SINGLE_REG(None)}, // #99 [ref=1x]
- { F(Vec) , 0 , 224, 1 , CONTROL(None) , SINGLE_REG(None)}, // #100 [ref=2x]
- { 0 , 0 , 424, 1 , CONTROL(None) , SINGLE_REG(None)}, // #101 [ref=2x]
- { 0 , 0 , 320, 2 , CONTROL(None) , SINGLE_REG(None)}, // #102 [ref=2x]
- { F(Vex) , 0 , 425, 1 , CONTROL(None) , SINGLE_REG(None)}, // #103 [ref=2x]
- { 0 , 0 , 426, 1 , CONTROL(None) , SINGLE_REG(None)}, // #104 [ref=1x]
- { 0 , 0 , 185, 3 , CONTROL(None) , SINGLE_REG(None)}, // #105 [ref=3x]
- { 0 , 0 , 318, 2 , CONTROL(Jump) , SINGLE_REG(None)}, // #106 [ref=1x]
- { 0 , 0 , 427, 1 , CONTROL(None) , SINGLE_REG(None)}, // #107 [ref=5x]
- { F(Vex) , 0 , 428, 1 , CONTROL(None) , SINGLE_REG(None)}, // #108 [ref=2x]
- { F(Rep) , 0 , 135, 4 , CONTROL(None) , SINGLE_REG(None)}, // #109 [ref=1x]
- { 0 , 0 , 304, 2 , CONTROL(Branch) , SINGLE_REG(None)}, // #110 [ref=3x]
- { 0 , 0 , 322, 2 , CONTROL(None) , SINGLE_REG(None)}, // #111 [ref=1x]
- { F(Vex) , 0 , 429, 1 , CONTROL(None) , SINGLE_REG(None)}, // #112 [ref=2x]
- { F(Vec) , 0 , 430, 1 , CONTROL(None) , SINGLE_REG(None)}, // #113 [ref=1x]
- { F(Mmx) , 0 , 431, 1 , CONTROL(None) , SINGLE_REG(None)}, // #114 [ref=1x]
- { 0 , 0 , 432, 1 , CONTROL(None) , SINGLE_REG(None)}, // #115 [ref=2x]
- { F(XRelease) , 0 , 0 , 16, CONTROL(None) , SINGLE_REG(None)}, // #116 [ref=1x]
- { 0 , 0 , 49 , 9 , CONTROL(None) , SINGLE_REG(None)}, // #117 [ref=1x]
- { F(Vec) , 0 , 79 , 2 , CONTROL(None) , SINGLE_REG(None)}, // #118 [ref=6x]
- { 0 , 0 , 73 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #119 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 324, 2 , CONTROL(None) , SINGLE_REG(None)}, // #120 [ref=1x]
- { 0 , 0 , 433, 1 , CONTROL(None) , SINGLE_REG(None)}, // #121 [ref=1x]
- { 0 , 0 , 77 , 2 , CONTROL(None) , SINGLE_REG(None)}, // #122 [ref=2x]
- { F(Mmx)|F(Vec) , 0 , 434, 1 , CONTROL(None) , SINGLE_REG(None)}, // #123 [ref=1x]
- { F(Vec) , 0 , 291, 1 , CONTROL(None) , SINGLE_REG(None)}, // #124 [ref=2x]
- { F(Vec) , 0 , 230, 2 , CONTROL(None) , SINGLE_REG(None)}, // #125 [ref=4x]
- { F(Vec) , 0 , 435, 1 , CONTROL(None) , SINGLE_REG(None)}, // #126 [ref=2x]
- { F(Vec) , 0 , 80 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #127 [ref=3x]
- { F(Mmx) , 0 , 436, 1 , CONTROL(None) , SINGLE_REG(None)}, // #128 [ref=1x]
- { F(Vec) , 0 , 107, 1 , CONTROL(None) , SINGLE_REG(None)}, // #129 [ref=1x]
- { F(Vec) , 0 , 233, 1 , CONTROL(None) , SINGLE_REG(None)}, // #130 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 103, 5 , CONTROL(None) , SINGLE_REG(None)}, // #131 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 437, 1 , CONTROL(None) , SINGLE_REG(None)}, // #132 [ref=1x]
- { F(Rep) , 0 , 139, 4 , CONTROL(None) , SINGLE_REG(None)}, // #133 [ref=1x]
- { F(Vec) , 0 , 106, 2 , CONTROL(None) , SINGLE_REG(None)}, // #134 [ref=1x]
- { F(Vec) , 0 , 326, 2 , CONTROL(None) , SINGLE_REG(None)}, // #135 [ref=1x]
- { 0 , 0 , 328, 2 , CONTROL(None) , SINGLE_REG(None)}, // #136 [ref=2x]
- { 0 , 0 , 438, 1 , CONTROL(None) , SINGLE_REG(None)}, // #137 [ref=1x]
- { F(Vex) , 0 , 330, 2 , CONTROL(None) , SINGLE_REG(None)}, // #138 [ref=1x]
- { 0 , 0 , 439, 1 , CONTROL(None) , SINGLE_REG(None)}, // #139 [ref=1x]
- { 0 , 0 , 440, 1 , CONTROL(None) , SINGLE_REG(None)}, // #140 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 287, 1 , CONTROL(None) , SINGLE_REG(None)}, // #141 [ref=2x]
- { 0 , 0 , 108, 5 , CONTROL(None) , SINGLE_REG(None)}, // #142 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(RO) }, // #143 [ref=1x]
- { 0 , 0 , 441, 1 , CONTROL(None) , SINGLE_REG(None)}, // #144 [ref=1x]
- { F(Rep) , 0 , 442, 1 , CONTROL(None) , SINGLE_REG(None)}, // #145 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(None)}, // #146 [ref=37x]
- { F(Mmx)|F(Vec) , 0 , 334, 2 , CONTROL(None) , SINGLE_REG(None)}, // #147 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(RO) }, // #148 [ref=6x]
- { F(Mmx)|F(Vec) , 0 , 332, 2 , CONTROL(None) , SINGLE_REG(WO) }, // #149 [ref=16x]
- { F(Mmx) , 0 , 332, 1 , CONTROL(None) , SINGLE_REG(None)}, // #150 [ref=26x]
- { F(Vec) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(WO) }, // #151 [ref=4x]
- { F(Vec) , 0 , 443, 1 , CONTROL(None) , SINGLE_REG(None)}, // #152 [ref=1x]
- { F(Vec) , 0 , 444, 1 , CONTROL(None) , SINGLE_REG(None)}, // #153 [ref=1x]
- { F(Vec) , 0 , 445, 1 , CONTROL(None) , SINGLE_REG(None)}, // #154 [ref=1x]
- { F(Vec) , 0 , 446, 1 , CONTROL(None) , SINGLE_REG(None)}, // #155 [ref=1x]
- { F(Vec) , 0 , 447, 1 , CONTROL(None) , SINGLE_REG(None)}, // #156 [ref=1x]
- { F(Vec) , 0 , 448, 1 , CONTROL(None) , SINGLE_REG(None)}, // #157 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 336, 2 , CONTROL(None) , SINGLE_REG(None)}, // #158 [ref=1x]
- { F(Vec) , 0 , 449, 1 , CONTROL(None) , SINGLE_REG(None)}, // #159 [ref=1x]
- { F(Vec) , 0 , 450, 1 , CONTROL(None) , SINGLE_REG(None)}, // #160 [ref=1x]
- { F(Vec) , 0 , 451, 1 , CONTROL(None) , SINGLE_REG(None)}, // #161 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 452, 1 , CONTROL(None) , SINGLE_REG(None)}, // #162 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 453, 1 , CONTROL(None) , SINGLE_REG(None)}, // #163 [ref=1x]
- { F(Vec) , 0 , 260, 1 , CONTROL(None) , SINGLE_REG(None)}, // #164 [ref=2x]
- { 0 , 0 , 143, 4 , CONTROL(None) , SINGLE_REG(None)}, // #165 [ref=1x]
- { F(Mmx) , 0 , 334, 1 , CONTROL(None) , SINGLE_REG(None)}, // #166 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 338, 2 , CONTROL(None) , SINGLE_REG(None)}, // #167 [ref=8x]
- { F(Vec) , 0 , 454, 1 , CONTROL(None) , SINGLE_REG(None)}, // #168 [ref=2x]
- { 0 , 0 , 455, 1 , CONTROL(None) , SINGLE_REG(None)}, // #169 [ref=1x]
- { F(Mmx)|F(Vec) , 0 , 340, 2 , CONTROL(None) , SINGLE_REG(None)}, // #170 [ref=3x]
- { 0 , 0 , 147, 4 , CONTROL(None) , SINGLE_REG(None)}, // #171 [ref=1x]
- { 0 , 0 , 456, 1 , CONTROL(None) , SINGLE_REG(None)}, // #172 [ref=8x]
- { 0 , 0 , 457, 1 , CONTROL(None) , SINGLE_REG(None)}, // #173 [ref=4x]
- { 0 , 0 , 458, 1 , CONTROL(None) , SINGLE_REG(None)}, // #174 [ref=8x]
- { 0 , 0 , 342, 2 , CONTROL(None) , SINGLE_REG(None)}, // #175 [ref=1x]
- { F(Rep)|F(RepIgnored) , 0 , 344, 2 , CONTROL(Return) , SINGLE_REG(None)}, // #176 [ref=1x]
- { 0 , 0 , 344, 2 , CONTROL(Return) , SINGLE_REG(None)}, // #177 [ref=1x]
- { F(Vex) , 0 , 346, 2 , CONTROL(None) , SINGLE_REG(None)}, // #178 [ref=1x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL(None) , SINGLE_REG(WO) }, // #179 [ref=3x]
- { F(Rep) , 0 , 151, 4 , CONTROL(None) , SINGLE_REG(None)}, // #180 [ref=1x]
- { 0 , 0 , 459, 1 , CONTROL(None) , SINGLE_REG(None)}, // #181 [ref=30x]
- { 0 , 0 , 188, 3 , CONTROL(None) , SINGLE_REG(None)}, // #182 [ref=2x]
- { 0 , 0 , 460, 1 , CONTROL(None) , SINGLE_REG(None)}, // #183 [ref=3x]
- { F(Rep) , 0 , 155, 4 , CONTROL(None) , SINGLE_REG(None)}, // #184 [ref=1x]
- { F(Vex) , 0 , 461, 1 , CONTROL(None) , SINGLE_REG(None)}, // #185 [ref=5x]
- { 0 , 0 , 66 , 7 , CONTROL(None) , SINGLE_REG(None)}, // #186 [ref=1x]
- { F(Tsib)|F(Vex) , 0 , 462, 1 , CONTROL(None) , SINGLE_REG(None)}, // #187 [ref=2x]
- { F(Vex) , 0 , 388, 1 , CONTROL(None) , SINGLE_REG(None)}, // #188 [ref=1x]
- { F(Tsib)|F(Vex) , 0 , 463, 1 , CONTROL(None) , SINGLE_REG(None)}, // #189 [ref=1x]
- { F(Vex) , 0 , 464, 1 , CONTROL(None) , SINGLE_REG(None)}, // #190 [ref=1x]
- { 0 , 0 , 465, 1 , CONTROL(None) , SINGLE_REG(None)}, // #191 [ref=2x]
- { 0 , 0 , 180, 1 , CONTROL(None) , SINGLE_REG(None)}, // #192 [ref=2x]
- { 0 , 0 , 466, 1 , CONTROL(None) , SINGLE_REG(None)}, // #193 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(T4X) , 467, 1 , CONTROL(None) , SINGLE_REG(None)}, // #194 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(T4X) , 468, 1 , CONTROL(None) , SINGLE_REG(None)}, // #195 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #196 [ref=22x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #197 [ref=22x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(ER)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #198 [ref=18x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(ER)|X(SAE) , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #199 [ref=17x]
- { F(Vec)|F(Vex) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(None)}, // #200 [ref=15x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #201 [ref=5x]
- { F(Vec)|F(Vex) , 0 , 79 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #202 [ref=17x]
- { F(Vec)|F(Vex) , 0 , 215, 1 , CONTROL(None) , SINGLE_REG(None)}, // #203 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #204 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #205 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #206 [ref=10x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #207 [ref=12x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #208 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #209 [ref=6x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #210 [ref=19x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #211 [ref=12x]
- { F(Vec)|F(Vex) , 0 , 194, 2 , CONTROL(None) , SINGLE_REG(None)}, // #212 [ref=6x]
- { F(Vec)|F(Vex) , 0 , 348, 2 , CONTROL(None) , SINGLE_REG(None)}, // #213 [ref=3x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 471, 1 , CONTROL(None) , SINGLE_REG(None)}, // #214 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 472, 1 , CONTROL(None) , SINGLE_REG(None)}, // #215 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 473, 1 , CONTROL(None) , SINGLE_REG(None)}, // #216 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 474, 1 , CONTROL(None) , SINGLE_REG(None)}, // #217 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 475, 1 , CONTROL(None) , SINGLE_REG(None)}, // #218 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 472, 1 , CONTROL(None) , SINGLE_REG(None)}, // #219 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 476, 1 , CONTROL(None) , SINGLE_REG(None)}, // #220 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(B64)|X(SAE) , 197, 3 , CONTROL(None) , SINGLE_REG(None)}, // #221 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(B32)|X(SAE) , 197, 3 , CONTROL(None) , SINGLE_REG(None)}, // #222 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(SAE) , 477, 1 , CONTROL(None) , SINGLE_REG(None)}, // #223 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(Z)|X(SAE) , 478, 1 , CONTROL(None) , SINGLE_REG(None)}, // #224 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #225 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #226 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 200, 3 , CONTROL(None) , SINGLE_REG(None)}, // #227 [ref=6x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #228 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #229 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #230 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #231 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #232 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #233 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #234 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #235 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 209, 3 , CONTROL(None) , SINGLE_REG(None)}, // #236 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #237 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #238 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #239 [ref=1x]
- { F(Vec)|F(Evex) , X(ER)|X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #240 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 479, 1 , CONTROL(None) , SINGLE_REG(None)}, // #241 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #242 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(ER)|X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #243 [ref=1x]
- { F(Vec)|F(Evex) , X(ER)|X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #244 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #245 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #246 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 350, 2 , CONTROL(None) , SINGLE_REG(None)}, // #247 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #248 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #249 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #250 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #251 [ref=1x]
- { F(Vec)|F(Evex) , X(SAE) , 399, 1 , CONTROL(None) , SINGLE_REG(None)}, // #252 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #253 [ref=1x]
- { F(Vec)|F(Evex) , X(SAE) , 401, 1 , CONTROL(None) , SINGLE_REG(None)}, // #254 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #255 [ref=1x]
- { F(Vec)|F(Evex) , X(ER)|X(SAE) , 479, 1 , CONTROL(None) , SINGLE_REG(None)}, // #256 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #257 [ref=3x]
- { F(Vec)|F(Vex) , 0 , 194, 1 , CONTROL(None) , SINGLE_REG(None)}, // #258 [ref=9x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE)|X(B64) , 83 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #259 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE)|X(B32) , 83 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #260 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #261 [ref=9x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 210, 1 , CONTROL(None) , SINGLE_REG(None)}, // #262 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 480, 1 , CONTROL(None) , SINGLE_REG(None)}, // #263 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 211, 1 , CONTROL(None) , SINGLE_REG(None)}, // #264 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 405, 1 , CONTROL(None) , SINGLE_REG(None)}, // #265 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #266 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #267 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #268 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #269 [ref=4x]
- { F(Vec)|F(Vex) , 0 , 159, 4 , CONTROL(None) , SINGLE_REG(None)}, // #270 [ref=13x]
- { F(Vec)|F(Vex) , 0 , 352, 2 , CONTROL(None) , SINGLE_REG(None)}, // #271 [ref=4x]
- { F(Vec)|F(Vex) , 0 , 354, 2 , CONTROL(None) , SINGLE_REG(None)}, // #272 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(B64) , 483, 1 , CONTROL(None) , SINGLE_REG(None)}, // #273 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(B32) , 483, 1 , CONTROL(None) , SINGLE_REG(None)}, // #274 [ref=1x]
- { F(Vec)|F(Evex) , X(K) , 484, 1 , CONTROL(None) , SINGLE_REG(None)}, // #275 [ref=1x]
- { F(Vec)|F(Evex) , X(K) , 485, 1 , CONTROL(None) , SINGLE_REG(None)}, // #276 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 206, 2 , CONTROL(None) , SINGLE_REG(None)}, // #277 [ref=7x]
- { F(Vec)|F(Vex) , 0 , 106, 1 , CONTROL(None) , SINGLE_REG(None)}, // #278 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 257, 1 , CONTROL(None) , SINGLE_REG(None)}, // #279 [ref=1x]
- { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 163, 4 , CONTROL(None) , SINGLE_REG(None)}, // #280 [ref=2x]
- { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 113, 5 , CONTROL(None) , SINGLE_REG(None)}, // #281 [ref=2x]
- { F(Vsib)|F(Evex) , X(K) , 486, 1 , CONTROL(None) , SINGLE_REG(None)}, // #282 [ref=4x]
- { F(Vsib)|F(Evex) , X(K) , 487, 1 , CONTROL(None) , SINGLE_REG(None)}, // #283 [ref=4x]
- { F(Vsib)|F(Evex) , X(K) , 488, 1 , CONTROL(None) , SINGLE_REG(None)}, // #284 [ref=8x]
- { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 118, 5 , CONTROL(None) , SINGLE_REG(None)}, // #285 [ref=2x]
- { F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(EvexTwoOp) , X(K) , 212, 3 , CONTROL(None) , SINGLE_REG(None)}, // #286 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #287 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(SAE) , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #288 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(SAE) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #289 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(SAE) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #290 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #291 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #292 [ref=22x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 356, 1 , CONTROL(None) , SINGLE_REG(None)}, // #293 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 356, 2 , CONTROL(None) , SINGLE_REG(None)}, // #294 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 489, 1 , CONTROL(None) , SINGLE_REG(None)}, // #295 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #296 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 224, 2 , CONTROL(None) , SINGLE_REG(None)}, // #297 [ref=1x]
- { F(Vex) , 0 , 424, 1 , CONTROL(None) , SINGLE_REG(None)}, // #298 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 430, 1 , CONTROL(None) , SINGLE_REG(None)}, // #299 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 167, 4 , CONTROL(None) , SINGLE_REG(None)}, // #300 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #301 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #302 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #303 [ref=2x]
- { 0 , 0 , 358, 2 , CONTROL(None) , SINGLE_REG(None)}, // #304 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 79 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #305 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 360, 2 , CONTROL(None) , SINGLE_REG(None)}, // #306 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 218, 3 , CONTROL(None) , SINGLE_REG(None)}, // #307 [ref=1x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 79 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #308 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 79 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #309 [ref=6x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 232, 1 , CONTROL(None) , SINGLE_REG(None)}, // #310 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 362, 2 , CONTROL(None) , SINGLE_REG(None)}, // #311 [ref=4x]
- { F(Vec)|F(Vex) , 0 , 490, 1 , CONTROL(None) , SINGLE_REG(None)}, // #312 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 221, 3 , CONTROL(None) , SINGLE_REG(None)}, // #313 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 224, 3 , CONTROL(None) , SINGLE_REG(None)}, // #314 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 227, 3 , CONTROL(None) , SINGLE_REG(None)}, // #315 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 230, 3 , CONTROL(None) , SINGLE_REG(None)}, // #316 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #317 [ref=5x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 233, 3 , CONTROL(None) , SINGLE_REG(None)}, // #318 [ref=1x]
- { 0 , 0 , 364, 2 , CONTROL(None) , SINGLE_REG(None)}, // #319 [ref=1x]
- { 0 , 0 , 366, 2 , CONTROL(None) , SINGLE_REG(None)}, // #320 [ref=1x]
- { F(Vec)|F(Evex) , X(B32) , 236, 3 , CONTROL(None) , SINGLE_REG(None)}, // #321 [ref=1x]
- { F(Vec)|F(Evex) , X(B64) , 236, 3 , CONTROL(None) , SINGLE_REG(None)}, // #322 [ref=1x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(RO) }, // #323 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #324 [ref=2x]
- { F(Vec)|F(Vex)|F(EvexTransformable) , 0 , 191, 2 , CONTROL(None) , SINGLE_REG(WO) }, // #325 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #326 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #327 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #328 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #329 [ref=13x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 491, 1 , CONTROL(None) , SINGLE_REG(None)}, // #330 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 492, 1 , CONTROL(None) , SINGLE_REG(None)}, // #331 [ref=1x]
- { F(Vec)|F(Evex) , 0 , 493, 1 , CONTROL(None) , SINGLE_REG(None)}, // #332 [ref=6x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 239, 3 , CONTROL(None) , SINGLE_REG(None)}, // #333 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 494, 1 , CONTROL(None) , SINGLE_REG(None)}, // #334 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #335 [ref=1x]
- { F(Vec)|F(Evex) , X(K) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #336 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(B32) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #337 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #338 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(B32) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #339 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexKReg) , X(K)|X(B64) , 245, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #340 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 443, 1 , CONTROL(None) , SINGLE_REG(None)}, // #341 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 444, 1 , CONTROL(None) , SINGLE_REG(None)}, // #342 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 445, 1 , CONTROL(None) , SINGLE_REG(None)}, // #343 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 446, 1 , CONTROL(None) , SINGLE_REG(None)}, // #344 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(B64) , 242, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #345 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #346 [ref=6x]
- { F(Vec)|F(Vex)|F(Evex)|F(PreferEvex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #347 [ref=4x]
- { F(Vec)|F(Vex) , 0 , 195, 1 , CONTROL(None) , SINGLE_REG(None)}, // #348 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 192, 2 , CONTROL(None) , SINGLE_REG(None)}, // #349 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 171, 4 , CONTROL(None) , SINGLE_REG(None)}, // #350 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 85 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #351 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 175, 4 , CONTROL(None) , SINGLE_REG(None)}, // #352 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 447, 1 , CONTROL(None) , SINGLE_REG(None)}, // #353 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 448, 1 , CONTROL(None) , SINGLE_REG(None)}, // #354 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 495, 1 , CONTROL(None) , SINGLE_REG(None)}, // #355 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 496, 1 , CONTROL(None) , SINGLE_REG(None)}, // #356 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 497, 1 , CONTROL(None) , SINGLE_REG(None)}, // #357 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 498, 1 , CONTROL(None) , SINGLE_REG(None)}, // #358 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 499, 1 , CONTROL(None) , SINGLE_REG(None)}, // #359 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #360 [ref=4x]
- { F(Vec)|F(Vex) , 0 , 348, 1 , CONTROL(None) , SINGLE_REG(None)}, // #361 [ref=12x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(RO) }, // #362 [ref=8x]
- { F(Vec)|F(Evex) , 0 , 500, 1 , CONTROL(None) , SINGLE_REG(None)}, // #363 [ref=4x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 248, 3 , CONTROL(None) , SINGLE_REG(None)}, // #364 [ref=6x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 251, 3 , CONTROL(None) , SINGLE_REG(None)}, // #365 [ref=9x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 254, 3 , CONTROL(None) , SINGLE_REG(None)}, // #366 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 257, 3 , CONTROL(None) , SINGLE_REG(None)}, // #367 [ref=4x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 260, 3 , CONTROL(None) , SINGLE_REG(None)}, // #368 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 203, 3 , CONTROL(None) , SINGLE_REG(None)}, // #369 [ref=6x]
- { F(Vec)|F(Vex) , 0 , 159, 2 , CONTROL(None) , SINGLE_REG(None)}, // #370 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #371 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #372 [ref=3x]
- { F(Vec)|F(Vex) , 0 , 368, 2 , CONTROL(None) , SINGLE_REG(None)}, // #373 [ref=4x]
- { F(Vec)|F(Vsib)|F(Evex) , X(K) , 263, 3 , CONTROL(None) , SINGLE_REG(None)}, // #374 [ref=2x]
- { F(Vec)|F(Vsib)|F(Evex) , X(K) , 370, 2 , CONTROL(None) , SINGLE_REG(None)}, // #375 [ref=2x]
- { F(Vec)|F(Vsib)|F(Evex) , X(K) , 372, 2 , CONTROL(None) , SINGLE_REG(None)}, // #376 [ref=2x]
- { F(Vec)|F(Vsib)|F(Evex) , X(K) , 266, 3 , CONTROL(None) , SINGLE_REG(None)}, // #377 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 374, 2 , CONTROL(None) , SINGLE_REG(None)}, // #378 [ref=8x]
- { F(Vec)|F(Evex) , X(K) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #379 [ref=5x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #380 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #381 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #382 [ref=3x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , 0 , 215, 3 , CONTROL(None) , SINGLE_REG(None)}, // #383 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #384 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 91 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #385 [ref=3x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 97 , 6 , CONTROL(None) , SINGLE_REG(None)}, // #386 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #387 [ref=6x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #388 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 191, 3 , CONTROL(None) , SINGLE_REG(WO) }, // #389 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(B32) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #390 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(B64) , 269, 3 , CONTROL(None) , SINGLE_REG(None)}, // #391 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #392 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #393 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #394 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #395 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z) , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #396 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 215, 2 , CONTROL(None) , SINGLE_REG(None)}, // #397 [ref=2x]
- { F(Vec)|F(Vex) , 0 , 481, 1 , CONTROL(None) , SINGLE_REG(None)}, // #398 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 482, 1 , CONTROL(None) , SINGLE_REG(None)}, // #399 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #400 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32)|X(ER)|X(SAE) , 191, 3 , CONTROL(None) , SINGLE_REG(None)}, // #401 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(ER)|X(SAE) , 469, 1 , CONTROL(None) , SINGLE_REG(None)}, // #402 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(ER)|X(SAE) , 470, 1 , CONTROL(None) , SINGLE_REG(None)}, // #403 [ref=1x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B32) , 195, 2 , CONTROL(None) , SINGLE_REG(None)}, // #404 [ref=2x]
- { F(Vec)|F(Evex) , X(K)|X(Z)|X(B64) , 195, 2 , CONTROL(None) , SINGLE_REG(None)}, // #405 [ref=2x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B32) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #406 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64) , 194, 3 , CONTROL(None) , SINGLE_REG(None)}, // #407 [ref=1x]
- { F(Vec)|F(Vex)|F(Evex)|F(EvexCompat) , X(K)|X(Z)|X(B64)|X(ER)|X(SAE) , 206, 3 , CONTROL(None) , SINGLE_REG(None)}, // #408 [ref=1x]
- { F(Vec)|F(Vex) , 0 , 108, 1 , CONTROL(None) , SINGLE_REG(None)}, // #409 [ref=2x]
- { 0 , 0 , 23 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #410 [ref=2x]
- { 0 , 0 , 61 , 1 , CONTROL(None) , SINGLE_REG(None)}, // #411 [ref=2x]
- { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 58 , 4 , CONTROL(None) , SINGLE_REG(None)}, // #412 [ref=1x]
- { 0 , 0 , 501, 1 , CONTROL(None) , SINGLE_REG(None)}, // #413 [ref=1x]
- { F(Lock)|F(XAcquire) , 0 , 58 , 8 , CONTROL(None) , SINGLE_REG(RO) }, // #414 [ref=1x]
- { 0 , 0 , 502, 1 , CONTROL(None) , SINGLE_REG(None)}, // #415 [ref=6x]
- { 0 , 0 , 503, 1 , CONTROL(None) , SINGLE_REG(None)} // #416 [ref=6x]
+ { 0 , 0 , 0 , 0 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #0 [ref=1x]
+ { 0 , 0 , 383, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #1 [ref=4x]
+ { 0 , 0 , 384, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #2 [ref=2x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #3 [ref=2x]
+ { 0 , 0 , 180, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #4 [ref=2x]
+ { F(Vec) , 0 , 79 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #5 [ref=54x]
+ { F(Vec) , 0 , 106, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #6 [ref=19x]
+ { F(Vec) , 0 , 212, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #7 [ref=16x]
+ { F(Vec) , 0 , 221, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #8 [ref=20x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 28 , 11, CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #9 [ref=1x]
+ { F(Vex) , 0 , 275, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #10 [ref=3x]
+ { F(Vec) , 0 , 79 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #11 [ref=12x]
+ { 0 , 0 , 385, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #12 [ref=1x]
+ { F(Vex) , 0 , 277, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #13 [ref=5x]
+ { F(Vex) , 0 , 180, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #14 [ref=12x]
+ { F(Vec) , 0 , 386, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #15 [ref=4x]
+ { 0 , 0 , 279, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #16 [ref=3x]
+ { F(Mib) , 0 , 387, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #17 [ref=1x]
+ { 0 , 0 , 388, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #18 [ref=1x]
+ { 0 , 0 , 281, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #19 [ref=1x]
+ { F(Mib) , 0 , 389, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #20 [ref=1x]
+ { 0 , 0 , 283, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #21 [ref=1x]
+ { 0 , 0 , 179, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #22 [ref=35x]
+ { 0 , 0 , 390, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #23 [ref=3x]
+ { 0 , 0 , 123, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #24 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 123, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #25 [ref=3x]
+ { F(Rep)|F(RepIgnored) , 0 , 285, 2 , CONTROL_FLOW(Call), SAME_REG_HINT(None)}, // #26 [ref=1x]
+ { 0 , 0 , 391, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #27 [ref=1x]
+ { 0 , 0 , 392, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #28 [ref=2x]
+ { 0 , 0 , 364, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #29 [ref=1x]
+ { 0 , 0 , 108, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #30 [ref=83x]
+ { 0 , 0 , 393, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #31 [ref=11x]
+ { 0 , 0 , 394, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #32 [ref=6x]
+ { 0 , 0 , 395, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #33 [ref=13x]
+ { 0 , 0 , 396, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #34 [ref=1x]
+ { 0 , 0 , 16 , 12, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #35 [ref=1x]
+ { F(Rep) , 0 , 127, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #36 [ref=1x]
+ { F(Vec) , 0 , 397, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #37 [ref=2x]
+ { F(Vec) , 0 , 398, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #38 [ref=3x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 131, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #39 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 399, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #40 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 400, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #41 [ref=1x]
+ { 0 , 0 , 401, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #42 [ref=1x]
+ { 0 , 0 , 402, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #43 [ref=1x]
+ { 0 , 0 , 287, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #44 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 403, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #45 [ref=2x]
+ { F(Mmx)|F(Vec) , 0 , 404, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #46 [ref=2x]
+ { F(Mmx)|F(Vec) , 0 , 405, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #47 [ref=2x]
+ { F(Vec) , 0 , 406, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #48 [ref=2x]
+ { F(Vec) , 0 , 407, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #49 [ref=2x]
+ { F(Vec) , 0 , 408, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #50 [ref=2x]
+ { 0 , 0 , 409, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #51 [ref=1x]
+ { 0 , 0 , 410, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #52 [ref=2x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 289, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #53 [ref=2x]
+ { 0 , 0 , 39 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #54 [ref=3x]
+ { F(Mmx) , 0 , 108, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #55 [ref=1x]
+ { 0 , 0 , 291, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #56 [ref=2x]
+ { 0 , 0 , 411, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #57 [ref=1x]
+ { F(Vec) , 0 , 412, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #58 [ref=2x]
+ { F(Vec) , 0 , 293, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #59 [ref=1x]
+ { F(FpuM32)|F(FpuM64) , 0 , 182, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #60 [ref=6x]
+ { 0 , 0 , 295, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #61 [ref=9x]
+ { F(FpuM80) , 0 , 413, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #62 [ref=2x]
+ { 0 , 0 , 296, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #63 [ref=13x]
+ { F(FpuM32)|F(FpuM64) , 0 , 297, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #64 [ref=2x]
+ { F(FpuM16)|F(FpuM32) , 0 , 414, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #65 [ref=9x]
+ { F(FpuM16)|F(FpuM32)|F(FpuM64) , 0 , 415, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #66 [ref=3x]
+ { F(FpuM32)|F(FpuM64)|F(FpuM80) , 0 , 416, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #67 [ref=2x]
+ { F(FpuM16) , 0 , 417, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #68 [ref=3x]
+ { 0 , 0 , 418, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #69 [ref=13x]
+ { F(FpuM16) , 0 , 419, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #70 [ref=2x]
+ { F(FpuM32)|F(FpuM64) , 0 , 298, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #71 [ref=1x]
+ { 0 , 0 , 420, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #72 [ref=2x]
+ { 0 , 0 , 421, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #73 [ref=1x]
+ { 0 , 0 , 39 , 10, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #74 [ref=1x]
+ { 0 , 0 , 422, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #75 [ref=1x]
+ { 0 , 0 , 423, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #76 [ref=2x]
+ { 0 , 0 , 348, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #77 [ref=3x]
+ { F(Rep) , 0 , 424, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #78 [ref=1x]
+ { F(Vec) , 0 , 299, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #79 [ref=1x]
+ { 0 , 0 , 425, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #80 [ref=2x]
+ { 0 , 0 , 426, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #81 [ref=8x]
+ { 0 , 0 , 301, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #82 [ref=3x]
+ { 0 , 0 , 303, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #83 [ref=1x]
+ { 0 , 0 , 108, 1 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #84 [ref=2x]
+ { 0 , 0 , 395, 1 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #85 [ref=1x]
+ { F(Rep)|F(RepIgnored) , 0 , 305, 2 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #86 [ref=30x]
+ { F(Rep)|F(RepIgnored) , 0 , 307, 2 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #87 [ref=1x]
+ { F(Rep)|F(RepIgnored) , 0 , 309, 2 , CONTROL_FLOW(Jump), SAME_REG_HINT(None)}, // #88 [ref=1x]
+ { F(Vex) , 0 , 427, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #89 [ref=19x]
+ { F(Vex) , 0 , 311, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #90 [ref=1x]
+ { F(Vex) , 0 , 313, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #91 [ref=1x]
+ { F(Vex) , 0 , 315, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #92 [ref=1x]
+ { F(Vex) , 0 , 317, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #93 [ref=1x]
+ { F(Vex) , 0 , 428, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #94 [ref=12x]
+ { F(Vex) , 0 , 429, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #95 [ref=8x]
+ { F(Vex) , 0 , 427, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #96 [ref=8x]
+ { 0 , 0 , 430, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #97 [ref=2x]
+ { 0 , 0 , 319, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #98 [ref=1x]
+ { 0 , 0 , 321, 2 , CONTROL_FLOW(Call), SAME_REG_HINT(None)}, // #99 [ref=1x]
+ { F(Vec) , 0 , 230, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #100 [ref=2x]
+ { 0 , 0 , 431, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #101 [ref=2x]
+ { 0 , 0 , 323, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #102 [ref=2x]
+ { F(Vex) , 0 , 432, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #103 [ref=2x]
+ { 0 , 0 , 433, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #104 [ref=1x]
+ { 0 , 0 , 185, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #105 [ref=3x]
+ { 0 , 0 , 321, 2 , CONTROL_FLOW(Jump), SAME_REG_HINT(None)}, // #106 [ref=1x]
+ { 0 , 0 , 434, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #107 [ref=5x]
+ { F(Vex) , 0 , 435, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #108 [ref=2x]
+ { F(Rep) , 0 , 135, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #109 [ref=1x]
+ { 0 , 0 , 307, 2 , CONTROL_FLOW(Branch), SAME_REG_HINT(None)}, // #110 [ref=3x]
+ { 0 , 0 , 325, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #111 [ref=1x]
+ { F(Vex) , 0 , 436, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #112 [ref=2x]
+ { F(Vec) , 0 , 437, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #113 [ref=1x]
+ { F(Mmx) , 0 , 438, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #114 [ref=1x]
+ { 0 , 0 , 439, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #115 [ref=2x]
+ { F(XRelease) , 0 , 0 , 16, CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #116 [ref=1x]
+ { 0 , 0 , 49 , 9 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #117 [ref=1x]
+ { F(Vec) , 0 , 79 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #118 [ref=6x]
+ { 0 , 0 , 73 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #119 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 327, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #120 [ref=1x]
+ { 0 , 0 , 440, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #121 [ref=1x]
+ { 0 , 0 , 77 , 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #122 [ref=2x]
+ { F(Mmx)|F(Vec) , 0 , 441, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #123 [ref=1x]
+ { F(Vec) , 0 , 294, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #124 [ref=2x]
+ { F(Vec) , 0 , 236, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #125 [ref=4x]
+ { F(Vec) , 0 , 442, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #126 [ref=2x]
+ { F(Vec) , 0 , 80 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #127 [ref=3x]
+ { F(Mmx) , 0 , 443, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #128 [ref=1x]
+ { F(Vec) , 0 , 107, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #129 [ref=1x]
+ { F(Vec) , 0 , 242, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #130 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 103, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #131 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 444, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #132 [ref=1x]
+ { F(Rep) , 0 , 139, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #133 [ref=1x]
+ { F(Vec) , 0 , 106, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #134 [ref=1x]
+ { F(Vec) , 0 , 329, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #135 [ref=1x]
+ { 0 , 0 , 331, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #136 [ref=2x]
+ { 0 , 0 , 333, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #137 [ref=1x]
+ { F(Vex) , 0 , 335, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #138 [ref=1x]
+ { 0 , 0 , 445, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #139 [ref=1x]
+ { 0 , 0 , 446, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #140 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 290, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #141 [ref=2x]
+ { 0 , 0 , 108, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #142 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #143 [ref=1x]
+ { 0 , 0 , 447, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #144 [ref=1x]
+ { F(Rep) , 0 , 448, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #145 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 337, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #146 [ref=37x]
+ { F(Mmx)|F(Vec) , 0 , 339, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #147 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 337, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #148 [ref=6x]
+ { F(Mmx)|F(Vec) , 0 , 337, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #149 [ref=16x]
+ { F(Mmx) , 0 , 337, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #150 [ref=26x]
+ { F(Vec) , 0 , 79 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #151 [ref=4x]
+ { F(Vec) , 0 , 449, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #152 [ref=1x]
+ { F(Vec) , 0 , 450, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #153 [ref=1x]
+ { F(Vec) , 0 , 451, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #154 [ref=1x]
+ { F(Vec) , 0 , 452, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #155 [ref=1x]
+ { F(Vec) , 0 , 453, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #156 [ref=1x]
+ { F(Vec) , 0 , 454, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #157 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 341, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #158 [ref=1x]
+ { F(Vec) , 0 , 455, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #159 [ref=1x]
+ { F(Vec) , 0 , 456, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #160 [ref=1x]
+ { F(Vec) , 0 , 457, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #161 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 458, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #162 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 459, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #163 [ref=1x]
+ { F(Vec) , 0 , 263, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #164 [ref=2x]
+ { 0 , 0 , 143, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #165 [ref=1x]
+ { F(Mmx) , 0 , 339, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #166 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 343, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #167 [ref=8x]
+ { F(Vec) , 0 , 460, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #168 [ref=2x]
+ { 0 , 0 , 461, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #169 [ref=1x]
+ { F(Mmx)|F(Vec) , 0 , 345, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #170 [ref=3x]
+ { 0 , 0 , 147, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #171 [ref=1x]
+ { 0 , 0 , 462, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #172 [ref=8x]
+ { 0 , 0 , 463, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #173 [ref=4x]
+ { 0 , 0 , 464, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #174 [ref=8x]
+ { 0 , 0 , 347, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #175 [ref=1x]
+ { F(Rep)|F(RepIgnored) , 0 , 349, 2 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #176 [ref=1x]
+ { 0 , 0 , 349, 2 , CONTROL_FLOW(Return), SAME_REG_HINT(None)}, // #177 [ref=1x]
+ { F(Vex) , 0 , 351, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #178 [ref=1x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 16 , 12, CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #179 [ref=3x]
+ { F(Rep) , 0 , 151, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #180 [ref=1x]
+ { 0 , 0 , 465, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #181 [ref=30x]
+ { 0 , 0 , 188, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #182 [ref=2x]
+ { 0 , 0 , 466, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #183 [ref=3x]
+ { F(Rep) , 0 , 155, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #184 [ref=1x]
+ { F(Vex) , 0 , 467, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #185 [ref=5x]
+ { 0 , 0 , 66 , 7 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #186 [ref=1x]
+ { F(Tsib)|F(Vex) , 0 , 468, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #187 [ref=2x]
+ { F(Vex) , 0 , 395, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #188 [ref=1x]
+ { F(Tsib)|F(Vex) , 0 , 469, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #189 [ref=1x]
+ { F(Vex) , 0 , 470, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #190 [ref=1x]
+ { 0 , 0 , 471, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #191 [ref=2x]
+ { 0 , 0 , 180, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #192 [ref=2x]
+ { 0 , 0 , 472, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #193 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(T4X)|X(Z) , 473, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #194 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(T4X)|X(Z) , 474, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #195 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #196 [ref=22x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #197 [ref=23x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #198 [ref=22x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(K)|X(SAE)|X(Z) , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #199 [ref=18x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 476, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #200 [ref=18x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(K)|X(SAE)|X(Z) , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #201 [ref=17x]
+ { F(Vec)|F(Vex) , 0 , 191, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #202 [ref=15x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #203 [ref=5x]
+ { F(Vec)|F(Vex) , 0 , 79 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #204 [ref=17x]
+ { F(Vec)|F(Vex) , 0 , 221, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #205 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #206 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #207 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #208 [ref=10x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #209 [ref=12x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #210 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #211 [ref=6x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #212 [ref=19x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #213 [ref=12x]
+ { F(Vec)|F(Vex) , 0 , 194, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #214 [ref=6x]
+ { F(Vec)|F(Vex) , 0 , 353, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #215 [ref=3x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 478, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #216 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 479, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #217 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 480, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #218 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 481, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #219 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 482, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #220 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 479, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #221 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 483, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #222 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B64)|X(ImplicitZ)|X(K)|X(SAE), 197, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #223 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(ImplicitZ)|X(K)|X(SAE), 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #224 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B32)|X(ImplicitZ)|X(K)|X(SAE), 197, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #225 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K)|X(SAE) , 484, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #226 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K)|X(SAE) , 485, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #227 [ref=1x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K)|X(SAE) , 486, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #228 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 106, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #229 [ref=2x]
+ { F(Evex)|F(Vec) , X(SAE) , 263, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #230 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 212, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #231 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 203, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #232 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #233 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #234 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #235 [ref=3x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #236 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #237 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 487, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #238 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #239 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #240 [ref=3x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #241 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 212, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #242 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #243 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #244 [ref=3x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 212, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #245 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(ER)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #246 [ref=5x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #247 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 215, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #248 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #249 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #250 [ref=2x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #251 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 406, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #252 [ref=1x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 406, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #253 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 476, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #254 [ref=5x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 488, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #255 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 489, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #256 [ref=2x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 489, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #257 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #258 [ref=3x]
+ { F(Evex)|F(Vec) , X(ER)|X(K)|X(SAE)|X(Z) , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #259 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(ER)|X(SAE) , 408, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #260 [ref=1x]
+ { F(Evex)|F(Vec) , X(ER)|X(SAE) , 408, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #261 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(SAE)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #262 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #263 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 355, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #264 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #265 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #266 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #267 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #268 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 406, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #269 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 406, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #270 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 488, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #271 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(SAE) , 408, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #272 [ref=1x]
+ { F(Evex)|F(Vec) , X(SAE) , 408, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #273 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #274 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #275 [ref=3x]
+ { F(Vec)|F(Vex) , 0 , 194, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #276 [ref=9x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 83 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #277 [ref=3x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 83 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #278 [ref=3x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #279 [ref=8x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 216, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #280 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 490, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #281 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 217, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #282 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 412, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #283 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ER)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #284 [ref=5x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #285 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #286 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 491, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #287 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 492, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #288 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 159, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #289 [ref=13x]
+ { F(Vec)|F(Vex) , 0 , 357, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #290 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 359, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #291 [ref=4x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #292 [ref=1x]
+ { F(Evex)|F(Vec) , X(B16)|X(K) , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #293 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 493, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #294 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 494, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #295 [ref=1x]
+ { F(Evex)|F(Vec) , X(K) , 495, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #296 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 496, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #297 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 209, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #298 [ref=7x]
+ { F(Vec)|F(Vex) , 0 , 106, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #299 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 212, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #300 [ref=1x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 163, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #301 [ref=2x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 113, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #302 [ref=2x]
+ { F(Evex)|F(Vsib) , X(K) , 497, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #303 [ref=4x]
+ { F(Evex)|F(Vsib) , X(K) , 498, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #304 [ref=4x]
+ { F(Evex)|F(Vsib) , X(K) , 499, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #305 [ref=8x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 118, 5 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #306 [ref=2x]
+ { F(Evex)|F(EvexTwoOp)|F(Vec)|F(Vex)|F(Vsib) , X(K) , 218, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #307 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #308 [ref=3x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #309 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(SAE)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #310 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #311 [ref=3x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(SAE)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #312 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(SAE)|X(Z) , 500, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #313 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #314 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #315 [ref=22x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 361, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #316 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 361, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #317 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 501, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #318 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 492, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #319 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 230, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #320 [ref=1x]
+ { F(Vex) , 0 , 431, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #321 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 437, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #322 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 167, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #323 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #324 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #325 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #326 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(SAE)|X(Z) , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #327 [ref=2x]
+ { 0 , 0 , 363, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #328 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 79 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #329 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 365, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #330 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 224, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #331 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 79 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #332 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 79 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #333 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 238, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #334 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 367, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #335 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 502, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #336 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 227, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #337 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 230, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #338 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 233, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #339 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 236, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #340 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 239, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #341 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #342 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 242, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #343 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 369, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #344 [ref=1x]
+ { 0 , 0 , 371, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #345 [ref=1x]
+ { 0 , 0 , 373, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #346 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32) , 245, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #347 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64) , 245, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #348 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #349 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #350 [ref=5x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 191, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #351 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #352 [ref=2x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 191, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #353 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #354 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #355 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #356 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #357 [ref=13x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 503, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #358 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 504, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #359 [ref=1x]
+ { F(Evex)|F(Vec) , 0 , 505, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #360 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 248, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #361 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 506, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #362 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #363 [ref=1x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #364 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #365 [ref=2x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(ImplicitZ)|X(K) , 251, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #366 [ref=4x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B32)|X(ImplicitZ)|X(K) , 251, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #367 [ref=2x]
+ { F(Evex)|F(EvexKReg)|F(Vec)|F(Vex) , X(B64)|X(ImplicitZ)|X(K) , 251, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #368 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 449, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #369 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 450, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #370 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 451, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #371 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 452, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #372 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 200, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #373 [ref=4x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #374 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(PreferEvex)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #375 [ref=4x]
+ { F(Vec)|F(Vex) , 0 , 195, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #376 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 192, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #377 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 171, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #378 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 85 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #379 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 85 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #380 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 175, 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #381 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 453, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #382 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 454, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #383 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 507, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #384 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 508, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #385 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 509, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #386 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 510, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #387 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 511, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #388 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 353, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #389 [ref=12x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #390 [ref=8x]
+ { F(Evex)|F(Vec) , 0 , 512, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #391 [ref=4x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 254, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #392 [ref=6x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 257, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #393 [ref=9x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 260, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #394 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 212, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #395 [ref=4x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 263, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #396 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 206, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #397 [ref=6x]
+ { F(Vec)|F(Vex) , 0 , 159, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #398 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #399 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #400 [ref=3x]
+ { F(Vec)|F(Vex) , 0 , 375, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #401 [ref=4x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 266, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #402 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 377, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #403 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 379, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #404 [ref=2x]
+ { F(Evex)|F(Vec)|F(Vsib) , X(K) , 269, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #405 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 381, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #406 [ref=8x]
+ { F(Evex)|F(Vec) , X(ImplicitZ)|X(K) , 272, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #407 [ref=5x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #408 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #409 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 91 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #410 [ref=3x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , 0 , 221, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #411 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 91 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #412 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 91 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #413 [ref=3x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 97 , 6 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #414 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #415 [ref=6x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #416 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(WO)}, // #417 [ref=2x]
+ { F(Evex)|F(Vec) , X(B32)|X(ImplicitZ)|X(K) , 272, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #418 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(ImplicitZ)|X(K) , 272, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #419 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 475, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #420 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #421 [ref=2x]
+ { F(Evex)|F(Vec) , X(B16)|X(K)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #422 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 476, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #423 [ref=2x]
+ { F(Vec)|F(Vex) , 0 , 477, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #424 [ref=2x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 491, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #425 [ref=1x]
+ { F(Evex)|F(Vec) , X(K)|X(Z) , 492, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #426 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 221, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #427 [ref=2x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 491, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #428 [ref=1x]
+ { F(EvexTransformable)|F(Vec)|F(Vex) , 0 , 492, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #429 [ref=1x]
+ { F(Evex)|F(Vec) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 191, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #430 [ref=1x]
+ { F(Evex)|F(Vec) , X(B32)|X(K)|X(Z) , 195, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #431 [ref=2x]
+ { F(Evex)|F(Vec) , X(B64)|X(K)|X(Z) , 195, 2 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #432 [ref=2x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #433 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B32)|X(K)|X(Z) , 194, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #434 [ref=1x]
+ { F(Evex)|F(EvexCompat)|F(Vec)|F(Vex) , X(B64)|X(ER)|X(K)|X(SAE)|X(Z) , 209, 3 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #435 [ref=1x]
+ { F(Vec)|F(Vex) , 0 , 108, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #436 [ref=2x]
+ { 0 , 0 , 23 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #437 [ref=2x]
+ { 0 , 0 , 61 , 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #438 [ref=2x]
+ { F(Lock)|F(XAcquire)|F(XRelease) , 0 , 58 , 4 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #439 [ref=1x]
+ { 0 , 0 , 513, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #440 [ref=1x]
+ { F(Lock)|F(XAcquire) , 0 , 58 , 8 , CONTROL_FLOW(Regular), SAME_REG_HINT(RO)}, // #441 [ref=1x]
+ { 0 , 0 , 514, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)}, // #442 [ref=6x]
+ { 0 , 0 , 515, 1 , CONTROL_FLOW(Regular), SAME_REG_HINT(None)} // #443 [ref=6x]
};
-#undef SINGLE_REG
-#undef CONTROL
+#undef SAME_REG_HINT
+#undef CONTROL_FLOW
#undef X
#undef F
// ----------------------------------------------------------------------------
// ${InstCommonTable:End}
-// ============================================================================
-// [asmjit::x86::InstDB - CommonInfoTableB]
-// ============================================================================
+// x86::InstDB - AdditionalInfoTable
+// =================================
-// ${InstCommonInfoTableB:Begin}
+// ${AdditionalInfoTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
-#define EXT(VAL) uint32_t(Features::k##VAL)
-const InstDB::CommonInfoTableB InstDB::_commonInfoTableB[] = {
+#define EXT(VAL) uint32_t(CpuFeatures::X86::k##VAL)
+const InstDB::AdditionalInfo InstDB::_additionalInfoTable[] = {
{ { 0 }, 0, 0 }, // #0 [ref=149x]
{ { 0 }, 1, 0 }, // #1 [ref=32x]
{ { 0 }, 2, 0 }, // #2 [ref=2x]
@@ -2617,57 +2734,59 @@ const InstDB::CommonInfoTableB InstDB::_commonInfoTableB[] = {
{ { EXT(WAITPKG) }, 0, 0 }, // #122 [ref=1x]
{ { EXT(AVX512_4FMAPS) }, 0, 0 }, // #123 [ref=4x]
{ { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #124 [ref=46x]
- { { EXT(AVX), EXT(AVX512_F) }, 0, 0 }, // #125 [ref=32x]
- { { EXT(AVX) }, 0, 0 }, // #126 [ref=37x]
- { { EXT(AESNI), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(VAES) }, 0, 0 }, // #127 [ref=4x]
- { { EXT(AESNI), EXT(AVX) }, 0, 0 }, // #128 [ref=2x]
- { { EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #129 [ref=112x]
- { { EXT(AVX), EXT(AVX512_DQ), EXT(AVX512_VL) }, 0, 0 }, // #130 [ref=8x]
- { { EXT(AVX512_DQ), EXT(AVX512_VL) }, 0, 0 }, // #131 [ref=30x]
- { { EXT(AVX2) }, 0, 0 }, // #132 [ref=7x]
- { { EXT(AVX), EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #133 [ref=39x]
- { { EXT(AVX), EXT(AVX512_F) }, 1, 0 }, // #134 [ref=4x]
- { { EXT(AVX512_BF16), EXT(AVX512_VL) }, 0, 0 }, // #135 [ref=3x]
- { { EXT(AVX512_F), EXT(AVX512_VL), EXT(F16C) }, 0, 0 }, // #136 [ref=2x]
- { { EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #137 [ref=26x]
- { { EXT(AVX512_ERI) }, 0, 0 }, // #138 [ref=10x]
- { { EXT(AVX512_F), EXT(AVX512_VL), EXT(FMA) }, 0, 0 }, // #139 [ref=36x]
- { { EXT(AVX512_F), EXT(FMA) }, 0, 0 }, // #140 [ref=24x]
- { { EXT(FMA4) }, 0, 0 }, // #141 [ref=20x]
- { { EXT(XOP) }, 0, 0 }, // #142 [ref=55x]
- { { EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #143 [ref=19x]
- { { EXT(AVX512_PFI) }, 0, 0 }, // #144 [ref=16x]
- { { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(GFNI) }, 0, 0 }, // #145 [ref=3x]
- { { EXT(AVX), EXT(AVX2) }, 0, 0 }, // #146 [ref=17x]
- { { EXT(AVX512_VP2INTERSECT) }, 0, 0 }, // #147 [ref=2x]
- { { EXT(AVX512_4VNNIW) }, 0, 0 }, // #148 [ref=2x]
- { { EXT(AVX), EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #149 [ref=54x]
- { { EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #150 [ref=2x]
- { { EXT(AVX512_CDI), EXT(AVX512_VL) }, 0, 0 }, // #151 [ref=6x]
- { { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(PCLMULQDQ), EXT(VPCLMULQDQ) }, 0, 0 }, // #152 [ref=1x]
- { { EXT(AVX) }, 1, 0 }, // #153 [ref=7x]
- { { EXT(AVX512_VBMI2), EXT(AVX512_VL) }, 0, 0 }, // #154 [ref=16x]
- { { EXT(AVX512_VL), EXT(AVX512_VNNI), EXT(AVX_VNNI) }, 0, 0 }, // #155 [ref=4x]
- { { EXT(AVX512_VBMI), EXT(AVX512_VL) }, 0, 0 }, // #156 [ref=4x]
- { { EXT(AVX), EXT(AVX512_BW) }, 0, 0 }, // #157 [ref=4x]
- { { EXT(AVX), EXT(AVX512_DQ) }, 0, 0 }, // #158 [ref=4x]
- { { EXT(AVX512_IFMA), EXT(AVX512_VL) }, 0, 0 }, // #159 [ref=2x]
- { { EXT(AVX512_BITALG), EXT(AVX512_VL) }, 0, 0 }, // #160 [ref=3x]
- { { EXT(AVX512_VL), EXT(AVX512_VPOPCNTDQ) }, 0, 0 }, // #161 [ref=2x]
- { { EXT(WBNOINVD) }, 0, 0 }, // #162 [ref=1x]
- { { EXT(RTM) }, 0, 0 }, // #163 [ref=3x]
- { { EXT(XSAVE) }, 0, 0 }, // #164 [ref=6x]
- { { EXT(TSXLDTRK) }, 0, 0 }, // #165 [ref=2x]
- { { EXT(XSAVES) }, 0, 0 }, // #166 [ref=4x]
- { { EXT(XSAVEC) }, 0, 0 }, // #167 [ref=2x]
- { { EXT(XSAVEOPT) }, 0, 0 }, // #168 [ref=2x]
- { { EXT(TSX) }, 1, 0 } // #169 [ref=1x]
+ { { EXT(AVX512_FP16), EXT(AVX512_VL) }, 0, 0 }, // #125 [ref=63x]
+ { { EXT(AVX), EXT(AVX512_F) }, 0, 0 }, // #126 [ref=32x]
+ { { EXT(AVX512_FP16) }, 0, 0 }, // #127 [ref=43x]
+ { { EXT(AVX) }, 0, 0 }, // #128 [ref=37x]
+ { { EXT(AESNI), EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(VAES) }, 0, 0 }, // #129 [ref=4x]
+ { { EXT(AESNI), EXT(AVX) }, 0, 0 }, // #130 [ref=2x]
+ { { EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #131 [ref=112x]
+ { { EXT(AVX), EXT(AVX512_DQ), EXT(AVX512_VL) }, 0, 0 }, // #132 [ref=8x]
+ { { EXT(AVX512_DQ), EXT(AVX512_VL) }, 0, 0 }, // #133 [ref=30x]
+ { { EXT(AVX2) }, 0, 0 }, // #134 [ref=7x]
+ { { EXT(AVX), EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #135 [ref=39x]
+ { { EXT(AVX), EXT(AVX512_F) }, 1, 0 }, // #136 [ref=4x]
+ { { EXT(AVX512_BF16), EXT(AVX512_VL) }, 0, 0 }, // #137 [ref=3x]
+ { { EXT(AVX512_F), EXT(AVX512_VL), EXT(F16C) }, 0, 0 }, // #138 [ref=2x]
+ { { EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #139 [ref=26x]
+ { { EXT(AVX512_ERI) }, 0, 0 }, // #140 [ref=10x]
+ { { EXT(AVX512_F), EXT(AVX512_VL), EXT(FMA) }, 0, 0 }, // #141 [ref=36x]
+ { { EXT(AVX512_F), EXT(FMA) }, 0, 0 }, // #142 [ref=24x]
+ { { EXT(FMA4) }, 0, 0 }, // #143 [ref=20x]
+ { { EXT(XOP) }, 0, 0 }, // #144 [ref=55x]
+ { { EXT(AVX2), EXT(AVX512_F), EXT(AVX512_VL) }, 0, 0 }, // #145 [ref=19x]
+ { { EXT(AVX512_PFI) }, 0, 0 }, // #146 [ref=16x]
+ { { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(GFNI) }, 0, 0 }, // #147 [ref=3x]
+ { { EXT(AVX), EXT(AVX2) }, 0, 0 }, // #148 [ref=17x]
+ { { EXT(AVX512_VP2INTERSECT) }, 0, 0 }, // #149 [ref=2x]
+ { { EXT(AVX512_4VNNIW) }, 0, 0 }, // #150 [ref=2x]
+ { { EXT(AVX), EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #151 [ref=54x]
+ { { EXT(AVX2), EXT(AVX512_BW), EXT(AVX512_VL) }, 0, 0 }, // #152 [ref=2x]
+ { { EXT(AVX512_CDI), EXT(AVX512_VL) }, 0, 0 }, // #153 [ref=6x]
+ { { EXT(AVX), EXT(AVX512_F), EXT(AVX512_VL), EXT(PCLMULQDQ), EXT(VPCLMULQDQ) }, 0, 0 }, // #154 [ref=1x]
+ { { EXT(AVX) }, 1, 0 }, // #155 [ref=7x]
+ { { EXT(AVX512_VBMI2), EXT(AVX512_VL) }, 0, 0 }, // #156 [ref=16x]
+ { { EXT(AVX512_VL), EXT(AVX512_VNNI), EXT(AVX_VNNI) }, 0, 0 }, // #157 [ref=4x]
+ { { EXT(AVX512_VBMI), EXT(AVX512_VL) }, 0, 0 }, // #158 [ref=4x]
+ { { EXT(AVX), EXT(AVX512_BW) }, 0, 0 }, // #159 [ref=4x]
+ { { EXT(AVX), EXT(AVX512_DQ) }, 0, 0 }, // #160 [ref=4x]
+ { { EXT(AVX512_IFMA), EXT(AVX512_VL) }, 0, 0 }, // #161 [ref=2x]
+ { { EXT(AVX512_BITALG), EXT(AVX512_VL) }, 0, 0 }, // #162 [ref=3x]
+ { { EXT(AVX512_VL), EXT(AVX512_VPOPCNTDQ) }, 0, 0 }, // #163 [ref=2x]
+ { { EXT(WBNOINVD) }, 0, 0 }, // #164 [ref=1x]
+ { { EXT(RTM) }, 0, 0 }, // #165 [ref=3x]
+ { { EXT(XSAVE) }, 0, 0 }, // #166 [ref=6x]
+ { { EXT(TSXLDTRK) }, 0, 0 }, // #167 [ref=2x]
+ { { EXT(XSAVES) }, 0, 0 }, // #168 [ref=4x]
+ { { EXT(XSAVEC) }, 0, 0 }, // #169 [ref=2x]
+ { { EXT(XSAVEOPT) }, 0, 0 }, // #170 [ref=2x]
+ { { EXT(TSX) }, 1, 0 } // #171 [ref=1x]
};
#undef EXT
-#define FLAG(VAL) uint32_t(Status::k##VAL)
+#define FLAG(VAL) uint32_t(CpuRWFlags::kX86_##VAL)
const InstDB::RWFlagsInfoTable InstDB::_rwFlagsInfoTable[] = {
- { 0, 0 }, // #0 [ref=1323x]
+ { 0, 0 }, // #0 [ref=1429x]
{ 0, FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #1 [ref=84x]
{ FLAG(CF), FLAG(AF) | FLAG(CF) | FLAG(OF) | FLAG(PF) | FLAG(SF) | FLAG(ZF) }, // #2 [ref=2x]
{ FLAG(CF), FLAG(CF) }, // #3 [ref=2x]
@@ -2699,11 +2818,10 @@ const InstDB::RWFlagsInfoTable InstDB::_rwFlagsInfoTable[] = {
};
#undef FLAG
// ----------------------------------------------------------------------------
-// ${InstCommonInfoTableB:End}
+// ${AdditionalInfoTable:End}
-// ============================================================================
-// [asmjit::Inst - NameData]
-// ============================================================================
+// Inst - NameData
+// ===============
#ifndef ASMJIT_NO_TEXT
// ${NameData:Begin}
@@ -2756,99 +2874,113 @@ const char InstDB::_nameData[] =
"sysenter\0" "sysexit\0" "sysexitq\0" "sysret\0" "sysretq\0" "t1mskc\0" "tdpbf16ps\0" "tdpbssd\0" "tdpbsud\0"
"tdpbusd\0" "tdpbuud\0" "testui\0" "tileloadd\0" "tileloaddt1\0" "tilerelease\0" "tilestored\0" "tilezero\0"
"tpause\0" "tzcnt\0" "tzmsk\0" "ud0\0" "ud1\0" "ud2\0" "uiret\0" "umonitor\0" "umwait\0" "v4fmaddps\0" "v4fmaddss\0"
- "v4fnmaddps\0" "v4fnmaddss\0" "vaddpd\0" "vaddps\0" "vaddsd\0" "vaddss\0" "vaddsubpd\0" "vaddsubps\0" "vaesdec\0"
- "vaesdeclast\0" "vaesenc\0" "vaesenclast\0" "vaesimc\0" "vaeskeygenassist\0" "valignd\0" "valignq\0" "vandnpd\0"
- "vandnps\0" "vandpd\0" "vandps\0" "vblendmpd\0" "vblendmps\0" "vblendpd\0" "vblendps\0" "vblendvpd\0" "vblendvps\0"
- "vbroadcastf128\0" "vbroadcastf32x2\0" "vbroadcastf32x4\0" "vbroadcastf32x8\0" "vbroadcastf64x2\0"
- "vbroadcastf64x4\0" "vbroadcasti128\0" "vbroadcasti32x2\0" "vbroadcasti32x4\0" "vbroadcasti32x8\0"
- "vbroadcasti64x2\0" "vbroadcasti64x4\0" "vbroadcastsd\0" "vbroadcastss\0" "vcmppd\0" "vcmpps\0" "vcmpsd\0" "vcmpss\0"
- "vcomisd\0" "vcomiss\0" "vcompresspd\0" "vcompressps\0" "vcvtdq2pd\0" "vcvtdq2ps\0" "vcvtne2ps2bf16\0"
- "vcvtneps2bf16\0" "vcvtpd2dq\0" "vcvtpd2ps\0" "vcvtpd2qq\0" "vcvtpd2udq\0" "vcvtpd2uqq\0" "vcvtph2ps\0" "vcvtps2dq\0"
- "vcvtps2pd\0" "vcvtps2ph\0" "vcvtps2qq\0" "vcvtps2udq\0" "vcvtps2uqq\0" "vcvtqq2pd\0" "vcvtqq2ps\0" "vcvtsd2si\0"
- "vcvtsd2ss\0" "vcvtsd2usi\0" "vcvtsi2sd\0" "vcvtsi2ss\0" "vcvtss2sd\0" "vcvtss2si\0" "vcvtss2usi\0" "vcvttpd2dq\0"
- "vcvttpd2qq\0" "vcvttpd2udq\0" "vcvttpd2uqq\0" "vcvttps2dq\0" "vcvttps2qq\0" "vcvttps2udq\0" "vcvttps2uqq\0"
- "vcvttsd2si\0" "vcvttsd2usi\0" "vcvttss2si\0" "vcvttss2usi\0" "vcvtudq2pd\0" "vcvtudq2ps\0" "vcvtuqq2pd\0"
- "vcvtuqq2ps\0" "vcvtusi2sd\0" "vcvtusi2ss\0" "vdbpsadbw\0" "vdivpd\0" "vdivps\0" "vdivsd\0" "vdivss\0" "vdpbf16ps\0"
- "vdppd\0" "vdpps\0" "verr\0" "verw\0" "vexp2pd\0" "vexp2ps\0" "vexpandpd\0" "vexpandps\0" "vextractf128\0"
- "vextractf32x4\0" "vextractf32x8\0" "vextractf64x2\0" "vextractf64x4\0" "vextracti128\0" "vextracti32x4\0"
- "vextracti32x8\0" "vextracti64x2\0" "vextracti64x4\0" "vextractps\0" "vfixupimmpd\0" "vfixupimmps\0" "vfixupimmsd\0"
- "vfixupimmss\0" "vfmadd132pd\0" "vfmadd132ps\0" "vfmadd132sd\0" "vfmadd132ss\0" "vfmadd213pd\0" "vfmadd213ps\0"
- "vfmadd213sd\0" "vfmadd213ss\0" "vfmadd231pd\0" "vfmadd231ps\0" "vfmadd231sd\0" "vfmadd231ss\0" "vfmaddpd\0"
- "vfmaddps\0" "vfmaddsd\0" "vfmaddss\0" "vfmaddsub132pd\0" "vfmaddsub132ps\0" "vfmaddsub213pd\0" "vfmaddsub213ps\0"
- "vfmaddsub231pd\0" "vfmaddsub231ps\0" "vfmaddsubpd\0" "vfmaddsubps\0" "vfmsub132pd\0" "vfmsub132ps\0" "vfmsub132sd\0"
- "vfmsub132ss\0" "vfmsub213pd\0" "vfmsub213ps\0" "vfmsub213sd\0" "vfmsub213ss\0" "vfmsub231pd\0" "vfmsub231ps\0"
- "vfmsub231sd\0" "vfmsub231ss\0" "vfmsubadd132pd\0" "vfmsubadd132ps\0" "vfmsubadd213pd\0" "vfmsubadd213ps\0"
- "vfmsubadd231pd\0" "vfmsubadd231ps\0" "vfmsubaddpd\0" "vfmsubaddps\0" "vfmsubpd\0" "vfmsubps\0" "vfmsubsd\0"
- "vfmsubss\0" "vfnmadd132pd\0" "vfnmadd132ps\0" "vfnmadd132sd\0" "vfnmadd132ss\0" "vfnmadd213pd\0" "vfnmadd213ps\0"
- "vfnmadd213sd\0" "vfnmadd213ss\0" "vfnmadd231pd\0" "vfnmadd231ps\0" "vfnmadd231sd\0" "vfnmadd231ss\0" "vfnmaddpd\0"
- "vfnmaddps\0" "vfnmaddsd\0" "vfnmaddss\0" "vfnmsub132pd\0" "vfnmsub132ps\0" "vfnmsub132sd\0" "vfnmsub132ss\0"
- "vfnmsub213pd\0" "vfnmsub213ps\0" "vfnmsub213sd\0" "vfnmsub213ss\0" "vfnmsub231pd\0" "vfnmsub231ps\0"
- "vfnmsub231sd\0" "vfnmsub231ss\0" "vfnmsubpd\0" "vfnmsubps\0" "vfnmsubsd\0" "vfnmsubss\0" "vfpclasspd\0"
- "vfpclassps\0" "vfpclasssd\0" "vfpclassss\0" "vfrczpd\0" "vfrczps\0" "vfrczsd\0" "vfrczss\0" "vgatherdpd\0"
- "vgatherdps\0" "vgatherpf0dpd\0" "vgatherpf0dps\0" "vgatherpf0qpd\0" "vgatherpf0qps\0" "vgatherpf1dpd\0"
- "vgatherpf1dps\0" "vgatherpf1qpd\0" "vgatherpf1qps\0" "vgatherqpd\0" "vgatherqps\0" "vgetexppd\0" "vgetexpps\0"
- "vgetexpsd\0" "vgetexpss\0" "vgetmantpd\0" "vgetmantps\0" "vgetmantsd\0" "vgetmantss\0" "vgf2p8affineinvqb\0"
- "vgf2p8affineqb\0" "vgf2p8mulb\0" "vhaddpd\0" "vhaddps\0" "vhsubpd\0" "vhsubps\0" "vinsertf128\0" "vinsertf32x4\0"
- "vinsertf32x8\0" "vinsertf64x2\0" "vinsertf64x4\0" "vinserti128\0" "vinserti32x4\0" "vinserti32x8\0" "vinserti64x2\0"
- "vinserti64x4\0" "vinsertps\0" "vlddqu\0" "vldmxcsr\0" "vmaskmovdqu\0" "vmaskmovpd\0" "vmaskmovps\0" "vmaxpd\0"
- "vmaxps\0" "vmaxsd\0" "vmaxss\0" "vmcall\0" "vmclear\0" "vmfunc\0" "vminpd\0" "vminps\0" "vminsd\0" "vminss\0"
- "vmlaunch\0" "vmload\0" "vmmcall\0" "vmovapd\0" "vmovaps\0" "vmovd\0" "vmovddup\0" "vmovdqa\0" "vmovdqa32\0"
- "vmovdqa64\0" "vmovdqu\0" "vmovdqu16\0" "vmovdqu32\0" "vmovdqu64\0" "vmovdqu8\0" "vmovhlps\0" "vmovhpd\0" "vmovhps\0"
- "vmovlhps\0" "vmovlpd\0" "vmovlps\0" "vmovmskpd\0" "vmovmskps\0" "vmovntdq\0" "vmovntdqa\0" "vmovntpd\0" "vmovntps\0"
- "vmovq\0" "vmovsd\0" "vmovshdup\0" "vmovsldup\0" "vmovss\0" "vmovupd\0" "vmovups\0" "vmpsadbw\0" "vmptrld\0"
- "vmptrst\0" "vmread\0" "vmresume\0" "vmrun\0" "vmsave\0" "vmulpd\0" "vmulps\0" "vmulsd\0" "vmulss\0" "vmwrite\0"
- "vmxon\0" "vorpd\0" "vorps\0" "vp2intersectd\0" "vp2intersectq\0" "vp4dpwssd\0" "vp4dpwssds\0" "vpabsb\0" "vpabsd\0"
- "vpabsq\0" "vpabsw\0" "vpackssdw\0" "vpacksswb\0" "vpackusdw\0" "vpackuswb\0" "vpaddb\0" "vpaddd\0" "vpaddq\0"
- "vpaddsb\0" "vpaddsw\0" "vpaddusb\0" "vpaddusw\0" "vpaddw\0" "vpalignr\0" "vpand\0" "vpandd\0" "vpandn\0" "vpandnd\0"
- "vpandnq\0" "vpandq\0" "vpavgb\0" "vpavgw\0" "vpblendd\0" "vpblendmb\0" "vpblendmd\0" "vpblendmq\0" "vpblendmw\0"
- "vpblendvb\0" "vpblendw\0" "vpbroadcastb\0" "vpbroadcastd\0" "vpbroadcastmb2q\0" "vpbroadcastmw2d\0" "vpbroadcastq\0"
- "vpbroadcastw\0" "vpclmulqdq\0" "vpcmov\0" "vpcmpb\0" "vpcmpd\0" "vpcmpeqb\0" "vpcmpeqd\0" "vpcmpeqq\0" "vpcmpeqw\0"
- "vpcmpestri\0" "vpcmpestrm\0" "vpcmpgtb\0" "vpcmpgtd\0" "vpcmpgtq\0" "vpcmpgtw\0" "vpcmpistri\0" "vpcmpistrm\0"
- "vpcmpq\0" "vpcmpub\0" "vpcmpud\0" "vpcmpuq\0" "vpcmpuw\0" "vpcmpw\0" "vpcomb\0" "vpcomd\0" "vpcompressb\0"
- "vpcompressd\0" "vpcompressq\0" "vpcompressw\0" "vpcomq\0" "vpcomub\0" "vpcomud\0" "vpcomuq\0" "vpcomuw\0" "vpcomw\0"
- "vpconflictd\0" "vpconflictq\0" "vpdpbusd\0" "vpdpbusds\0" "vpdpwssd\0" "vpdpwssds\0" "vperm2f128\0" "vperm2i128\0"
- "vpermb\0" "vpermd\0" "vpermi2b\0" "vpermi2d\0" "vpermi2pd\0" "vpermi2ps\0" "vpermi2q\0" "vpermi2w\0" "vpermil2pd\0"
- "vpermil2ps\0" "vpermilpd\0" "vpermilps\0" "vpermpd\0" "vpermps\0" "vpermq\0" "vpermt2b\0" "vpermt2d\0" "vpermt2pd\0"
- "vpermt2ps\0" "vpermt2q\0" "vpermt2w\0" "vpermw\0" "vpexpandb\0" "vpexpandd\0" "vpexpandq\0" "vpexpandw\0"
- "vpextrb\0" "vpextrd\0" "vpextrq\0" "vpextrw\0" "vpgatherdd\0" "vpgatherdq\0" "vpgatherqd\0" "vpgatherqq\0"
- "vphaddbd\0" "vphaddbq\0" "vphaddbw\0" "vphaddd\0" "vphadddq\0" "vphaddsw\0" "vphaddubd\0" "vphaddubq\0"
- "vphaddubw\0" "vphaddudq\0" "vphadduwd\0" "vphadduwq\0" "vphaddw\0" "vphaddwd\0" "vphaddwq\0" "vphminposuw\0"
- "vphsubbw\0" "vphsubd\0" "vphsubdq\0" "vphsubsw\0" "vphsubw\0" "vphsubwd\0" "vpinsrb\0" "vpinsrd\0" "vpinsrq\0"
- "vpinsrw\0" "vplzcntd\0" "vplzcntq\0" "vpmacsdd\0" "vpmacsdqh\0" "vpmacsdql\0" "vpmacssdd\0" "vpmacssdqh\0"
- "vpmacssdql\0" "vpmacsswd\0" "vpmacssww\0" "vpmacswd\0" "vpmacsww\0" "vpmadcsswd\0" "vpmadcswd\0" "vpmadd52huq\0"
- "vpmadd52luq\0" "vpmaddubsw\0" "vpmaddwd\0" "vpmaskmovd\0" "vpmaskmovq\0" "vpmaxsb\0" "vpmaxsd\0" "vpmaxsq\0"
- "vpmaxsw\0" "vpmaxub\0" "vpmaxud\0" "vpmaxuq\0" "vpmaxuw\0" "vpminsb\0" "vpminsd\0" "vpminsq\0" "vpminsw\0"
- "vpminub\0" "vpminud\0" "vpminuq\0" "vpminuw\0" "vpmovb2m\0" "vpmovd2m\0" "vpmovdb\0" "vpmovdw\0" "vpmovm2b\0"
- "vpmovm2d\0" "vpmovm2q\0" "vpmovm2w\0" "vpmovmskb\0" "vpmovq2m\0" "vpmovqb\0" "vpmovqd\0" "vpmovqw\0" "vpmovsdb\0"
- "vpmovsdw\0" "vpmovsqb\0" "vpmovsqd\0" "vpmovsqw\0" "vpmovswb\0" "vpmovsxbd\0" "vpmovsxbq\0" "vpmovsxbw\0"
- "vpmovsxdq\0" "vpmovsxwd\0" "vpmovsxwq\0" "vpmovusdb\0" "vpmovusdw\0" "vpmovusqb\0" "vpmovusqd\0" "vpmovusqw\0"
- "vpmovuswb\0" "vpmovw2m\0" "vpmovwb\0" "vpmovzxbd\0" "vpmovzxbq\0" "vpmovzxbw\0" "vpmovzxdq\0" "vpmovzxwd\0"
- "vpmovzxwq\0" "vpmuldq\0" "vpmulhrsw\0" "vpmulhuw\0" "vpmulhw\0" "vpmulld\0" "vpmullq\0" "vpmullw\0"
- "vpmultishiftqb\0" "vpmuludq\0" "vpopcntb\0" "vpopcntd\0" "vpopcntq\0" "vpopcntw\0" "vpor\0" "vpord\0" "vporq\0"
- "vpperm\0" "vprold\0" "vprolq\0" "vprolvd\0" "vprolvq\0" "vprord\0" "vprorq\0" "vprorvd\0" "vprorvq\0" "vprotb\0"
- "vprotd\0" "vprotq\0" "vprotw\0" "vpsadbw\0" "vpscatterdd\0" "vpscatterdq\0" "vpscatterqd\0" "vpscatterqq\0"
- "vpshab\0" "vpshad\0" "vpshaq\0" "vpshaw\0" "vpshlb\0" "vpshld\0" "vpshldd\0" "vpshldq\0" "vpshldvd\0" "vpshldvq\0"
- "vpshldvw\0" "vpshldw\0" "vpshlq\0" "vpshlw\0" "vpshrdd\0" "vpshrdq\0" "vpshrdvd\0" "vpshrdvq\0" "vpshrdvw\0"
- "vpshrdw\0" "vpshufb\0" "vpshufbitqmb\0" "vpshufd\0" "vpshufhw\0" "vpshuflw\0" "vpsignb\0" "vpsignd\0" "vpsignw\0"
- "vpslld\0" "vpslldq\0" "vpsllq\0" "vpsllvd\0" "vpsllvq\0" "vpsllvw\0" "vpsllw\0" "vpsrad\0" "vpsraq\0" "vpsravd\0"
- "vpsravq\0" "vpsravw\0" "vpsraw\0" "vpsrld\0" "vpsrldq\0" "vpsrlq\0" "vpsrlvd\0" "vpsrlvq\0" "vpsrlvw\0" "vpsrlw\0"
- "vpsubb\0" "vpsubd\0" "vpsubq\0" "vpsubsb\0" "vpsubsw\0" "vpsubusb\0" "vpsubusw\0" "vpsubw\0" "vpternlogd\0"
- "vpternlogq\0" "vptest\0" "vptestmb\0" "vptestmd\0" "vptestmq\0" "vptestmw\0" "vptestnmb\0" "vptestnmd\0"
- "vptestnmq\0" "vptestnmw\0" "vpunpckhbw\0" "vpunpckhdq\0" "vpunpckhqdq\0" "vpunpckhwd\0" "vpunpcklbw\0"
- "vpunpckldq\0" "vpunpcklqdq\0" "vpunpcklwd\0" "vpxor\0" "vpxord\0" "vpxorq\0" "vrangepd\0" "vrangeps\0" "vrangesd\0"
- "vrangess\0" "vrcp14pd\0" "vrcp14ps\0" "vrcp14sd\0" "vrcp14ss\0" "vrcp28pd\0" "vrcp28ps\0" "vrcp28sd\0" "vrcp28ss\0"
- "vrcpps\0" "vrcpss\0" "vreducepd\0" "vreduceps\0" "vreducesd\0" "vreducess\0" "vrndscalepd\0" "vrndscaleps\0"
- "vrndscalesd\0" "vrndscaless\0" "vroundpd\0" "vroundps\0" "vroundsd\0" "vroundss\0" "vrsqrt14pd\0" "vrsqrt14ps\0"
- "vrsqrt14sd\0" "vrsqrt14ss\0" "vrsqrt28pd\0" "vrsqrt28ps\0" "vrsqrt28sd\0" "vrsqrt28ss\0" "vrsqrtps\0" "vrsqrtss\0"
- "vscalefpd\0" "vscalefps\0" "vscalefsd\0" "vscalefss\0" "vscatterdpd\0" "vscatterdps\0" "vscatterpf0dpd\0"
- "vscatterpf0dps\0" "vscatterpf0qpd\0" "vscatterpf0qps\0" "vscatterpf1dpd\0" "vscatterpf1dps\0" "vscatterpf1qpd\0"
- "vscatterpf1qps\0" "vscatterqpd\0" "vscatterqps\0" "vshuff32x4\0" "vshuff64x2\0" "vshufi32x4\0" "vshufi64x2\0"
- "vshufpd\0" "vshufps\0" "vsqrtpd\0" "vsqrtps\0" "vsqrtsd\0" "vsqrtss\0" "vstmxcsr\0" "vsubpd\0" "vsubps\0" "vsubsd\0"
- "vsubss\0" "vtestpd\0" "vtestps\0" "vucomisd\0" "vucomiss\0" "vunpckhpd\0" "vunpckhps\0" "vunpcklpd\0" "vunpcklps\0"
- "vxorpd\0" "vxorps\0" "vzeroall\0" "vzeroupper\0" "wbinvd\0" "wbnoinvd\0" "wrfsbase\0" "wrgsbase\0" "wrmsr\0"
- "wrssd\0" "wrssq\0" "wrussd\0" "wrussq\0" "xabort\0" "xadd\0" "xbegin\0" "xend\0" "xgetbv\0" "xlatb\0" "xresldtrk\0"
- "xrstors\0" "xrstors64\0" "xsavec\0" "xsavec64\0" "xsaveopt\0" "xsaveopt64\0" "xsaves\0" "xsaves64\0" "xsetbv\0"
- "xsusldtrk\0" "xtest";
+ "v4fnmaddps\0" "v4fnmaddss\0" "vaddpd\0" "vaddph\0" "vaddps\0" "vaddsd\0" "vaddsh\0" "vaddss\0" "vaddsubpd\0"
+ "vaddsubps\0" "vaesdec\0" "vaesdeclast\0" "vaesenc\0" "vaesenclast\0" "vaesimc\0" "vaeskeygenassist\0" "valignd\0"
+ "valignq\0" "vandnpd\0" "vandnps\0" "vandpd\0" "vandps\0" "vblendmpd\0" "vblendmps\0" "vblendpd\0" "vblendps\0"
+ "vblendvpd\0" "vblendvps\0" "vbroadcastf128\0" "vbroadcastf32x2\0" "vbroadcastf32x4\0" "vbroadcastf32x8\0"
+ "vbroadcastf64x2\0" "vbroadcastf64x4\0" "vbroadcasti128\0" "vbroadcasti32x2\0" "vbroadcasti32x4\0"
+ "vbroadcasti32x8\0" "vbroadcasti64x2\0" "vbroadcasti64x4\0" "vbroadcastsd\0" "vbroadcastss\0" "vcmppd\0" "vcmpph\0"
+ "vcmpps\0" "vcmpsd\0" "vcmpsh\0" "vcmpss\0" "vcomisd\0" "vcomish\0" "vcomiss\0" "vcompresspd\0" "vcompressps\0"
+ "vcvtdq2pd\0" "vcvtdq2ph\0" "vcvtdq2ps\0" "vcvtne2ps2bf16\0" "vcvtneps2bf16\0" "vcvtpd2dq\0" "vcvtpd2ph\0"
+ "vcvtpd2ps\0" "vcvtpd2qq\0" "vcvtpd2udq\0" "vcvtpd2uqq\0" "vcvtph2dq\0" "vcvtph2pd\0" "vcvtph2ps\0" "vcvtph2psx\0"
+ "vcvtph2qq\0" "vcvtph2udq\0" "vcvtph2uqq\0" "vcvtph2uw\0" "vcvtph2w\0" "vcvtps2dq\0" "vcvtps2pd\0" "vcvtps2ph\0"
+ "vcvtps2phx\0" "vcvtps2qq\0" "vcvtps2udq\0" "vcvtps2uqq\0" "vcvtqq2pd\0" "vcvtqq2ph\0" "vcvtqq2ps\0" "vcvtsd2sh\0"
+ "vcvtsd2si\0" "vcvtsd2ss\0" "vcvtsd2usi\0" "vcvtsh2sd\0" "vcvtsh2si\0" "vcvtsh2ss\0" "vcvtsh2usi\0" "vcvtsi2sd\0"
+ "vcvtsi2sh\0" "vcvtsi2ss\0" "vcvtss2sd\0" "vcvtss2sh\0" "vcvtss2si\0" "vcvtss2usi\0" "vcvttpd2dq\0" "vcvttpd2qq\0"
+ "vcvttpd2udq\0" "vcvttpd2uqq\0" "vcvttph2dq\0" "vcvttph2qq\0" "vcvttph2udq\0" "vcvttph2uqq\0" "vcvttph2uw\0"
+ "vcvttph2w\0" "vcvttps2dq\0" "vcvttps2qq\0" "vcvttps2udq\0" "vcvttps2uqq\0" "vcvttsd2si\0" "vcvttsd2usi\0"
+ "vcvttsh2si\0" "vcvttsh2usi\0" "vcvttss2si\0" "vcvttss2usi\0" "vcvtudq2pd\0" "vcvtudq2ph\0" "vcvtudq2ps\0"
+ "vcvtuqq2pd\0" "vcvtuqq2ph\0" "vcvtuqq2ps\0" "vcvtusi2sd\0" "vcvtusi2sh\0" "vcvtusi2ss\0" "vcvtuw2ph\0" "vcvtw2ph\0"
+ "vdbpsadbw\0" "vdivpd\0" "vdivph\0" "vdivps\0" "vdivsd\0" "vdivsh\0" "vdivss\0" "vdpbf16ps\0" "vdppd\0" "vdpps\0"
+ "verr\0" "verw\0" "vexp2pd\0" "vexp2ps\0" "vexpandpd\0" "vexpandps\0" "vextractf128\0" "vextractf32x4\0"
+ "vextractf32x8\0" "vextractf64x2\0" "vextractf64x4\0" "vextracti128\0" "vextracti32x4\0" "vextracti32x8\0"
+ "vextracti64x2\0" "vextracti64x4\0" "vextractps\0" "vfcmaddcph\0" "vfcmaddcsh\0" "vfcmulcph\0" "vfcmulcsh\0"
+ "vfixupimmpd\0" "vfixupimmps\0" "vfixupimmsd\0" "vfixupimmss\0" "vfmadd132pd\0" "vfmadd132ph\0" "vfmadd132ps\0"
+ "vfmadd132sd\0" "vfmadd132sh\0" "vfmadd132ss\0" "vfmadd213pd\0" "vfmadd213ph\0" "vfmadd213ps\0" "vfmadd213sd\0"
+ "vfmadd213sh\0" "vfmadd213ss\0" "vfmadd231pd\0" "vfmadd231ph\0" "vfmadd231ps\0" "vfmadd231sd\0" "vfmadd231sh\0"
+ "vfmadd231ss\0" "vfmaddcph\0" "vfmaddcsh\0" "vfmaddpd\0" "vfmaddps\0" "vfmaddsd\0" "vfmaddss\0" "vfmaddsub132pd\0"
+ "vfmaddsub132ph\0" "vfmaddsub132ps\0" "vfmaddsub213pd\0" "vfmaddsub213ph\0" "vfmaddsub213ps\0" "vfmaddsub231pd\0"
+ "vfmaddsub231ph\0" "vfmaddsub231ps\0" "vfmaddsubpd\0" "vfmaddsubps\0" "vfmsub132pd\0" "vfmsub132ph\0" "vfmsub132ps\0"
+ "vfmsub132sd\0" "vfmsub132sh\0" "vfmsub132ss\0" "vfmsub213pd\0" "vfmsub213ph\0" "vfmsub213ps\0" "vfmsub213sd\0"
+ "vfmsub213sh\0" "vfmsub213ss\0" "vfmsub231pd\0" "vfmsub231ph\0" "vfmsub231ps\0" "vfmsub231sd\0" "vfmsub231sh\0"
+ "vfmsub231ss\0" "vfmsubadd132pd\0" "vfmsubadd132ph\0" "vfmsubadd132ps\0" "vfmsubadd213pd\0" "vfmsubadd213ph\0"
+ "vfmsubadd213ps\0" "vfmsubadd231pd\0" "vfmsubadd231ph\0" "vfmsubadd231ps\0" "vfmsubaddpd\0" "vfmsubaddps\0"
+ "vfmsubpd\0" "vfmsubps\0" "vfmsubsd\0" "vfmsubss\0" "vfmulcph\0" "vfmulcsh\0" "vfnmadd132pd\0" "vfnmadd132ph\0"
+ "vfnmadd132ps\0" "vfnmadd132sd\0" "vfnmadd132sh\0" "vfnmadd132ss\0" "vfnmadd213pd\0" "vfnmadd213ph\0"
+ "vfnmadd213ps\0" "vfnmadd213sd\0" "vfnmadd213sh\0" "vfnmadd213ss\0" "vfnmadd231pd\0" "vfnmadd231ph\0"
+ "vfnmadd231ps\0" "vfnmadd231sd\0" "vfnmadd231sh\0" "vfnmadd231ss\0" "vfnmaddpd\0" "vfnmaddps\0" "vfnmaddsd\0"
+ "vfnmaddss\0" "vfnmsub132pd\0" "vfnmsub132ph\0" "vfnmsub132ps\0" "vfnmsub132sd\0" "vfnmsub132sh\0" "vfnmsub132ss\0"
+ "vfnmsub213pd\0" "vfnmsub213ph\0" "vfnmsub213ps\0" "vfnmsub213sd\0" "vfnmsub213sh\0" "vfnmsub213ss\0"
+ "vfnmsub231pd\0" "vfnmsub231ph\0" "vfnmsub231ps\0" "vfnmsub231sd\0" "vfnmsub231sh\0" "vfnmsub231ss\0" "vfnmsubpd\0"
+ "vfnmsubps\0" "vfnmsubsd\0" "vfnmsubss\0" "vfpclasspd\0" "vfpclassph\0" "vfpclassps\0" "vfpclasssd\0" "vfpclasssh\0"
+ "vfpclassss\0" "vfrczpd\0" "vfrczps\0" "vfrczsd\0" "vfrczss\0" "vgatherdpd\0" "vgatherdps\0" "vgatherpf0dpd\0"
+ "vgatherpf0dps\0" "vgatherpf0qpd\0" "vgatherpf0qps\0" "vgatherpf1dpd\0" "vgatherpf1dps\0" "vgatherpf1qpd\0"
+ "vgatherpf1qps\0" "vgatherqpd\0" "vgatherqps\0" "vgetexppd\0" "vgetexpph\0" "vgetexpps\0" "vgetexpsd\0" "vgetexpsh\0"
+ "vgetexpss\0" "vgetmantpd\0" "vgetmantph\0" "vgetmantps\0" "vgetmantsd\0" "vgetmantsh\0" "vgetmantss\0"
+ "vgf2p8affineinvqb\0" "vgf2p8affineqb\0" "vgf2p8mulb\0" "vhaddpd\0" "vhaddps\0" "vhsubpd\0" "vhsubps\0"
+ "vinsertf128\0" "vinsertf32x4\0" "vinsertf32x8\0" "vinsertf64x2\0" "vinsertf64x4\0" "vinserti128\0" "vinserti32x4\0"
+ "vinserti32x8\0" "vinserti64x2\0" "vinserti64x4\0" "vinsertps\0" "vlddqu\0" "vldmxcsr\0" "vmaskmovdqu\0"
+ "vmaskmovpd\0" "vmaskmovps\0" "vmaxpd\0" "vmaxph\0" "vmaxps\0" "vmaxsd\0" "vmaxsh\0" "vmaxss\0" "vmcall\0"
+ "vmclear\0" "vmfunc\0" "vminpd\0" "vminph\0" "vminps\0" "vminsd\0" "vminsh\0" "vminss\0" "vmlaunch\0" "vmload\0"
+ "vmmcall\0" "vmovapd\0" "vmovaps\0" "vmovd\0" "vmovddup\0" "vmovdqa\0" "vmovdqa32\0" "vmovdqa64\0" "vmovdqu\0"
+ "vmovdqu16\0" "vmovdqu32\0" "vmovdqu64\0" "vmovdqu8\0" "vmovhlps\0" "vmovhpd\0" "vmovhps\0" "vmovlhps\0" "vmovlpd\0"
+ "vmovlps\0" "vmovmskpd\0" "vmovmskps\0" "vmovntdq\0" "vmovntdqa\0" "vmovntpd\0" "vmovntps\0" "vmovq\0" "vmovsd\0"
+ "vmovsh\0" "vmovshdup\0" "vmovsldup\0" "vmovss\0" "vmovupd\0" "vmovups\0" "vmovw\0" "vmpsadbw\0" "vmptrld\0"
+ "vmptrst\0" "vmread\0" "vmresume\0" "vmrun\0" "vmsave\0" "vmulpd\0" "vmulph\0" "vmulps\0" "vmulsd\0" "vmulsh\0"
+ "vmulss\0" "vmwrite\0" "vmxon\0" "vorpd\0" "vorps\0" "vp2intersectd\0" "vp2intersectq\0" "vp4dpwssd\0" "vp4dpwssds\0"
+ "vpabsb\0" "vpabsd\0" "vpabsq\0" "vpabsw\0" "vpackssdw\0" "vpacksswb\0" "vpackusdw\0" "vpackuswb\0" "vpaddb\0"
+ "vpaddd\0" "vpaddq\0" "vpaddsb\0" "vpaddsw\0" "vpaddusb\0" "vpaddusw\0" "vpaddw\0" "vpalignr\0" "vpand\0" "vpandd\0"
+ "vpandn\0" "vpandnd\0" "vpandnq\0" "vpandq\0" "vpavgb\0" "vpavgw\0" "vpblendd\0" "vpblendmb\0" "vpblendmd\0"
+ "vpblendmq\0" "vpblendmw\0" "vpblendvb\0" "vpblendw\0" "vpbroadcastb\0" "vpbroadcastd\0" "vpbroadcastmb2q\0"
+ "vpbroadcastmw2d\0" "vpbroadcastq\0" "vpbroadcastw\0" "vpclmulqdq\0" "vpcmov\0" "vpcmpb\0" "vpcmpd\0" "vpcmpeqb\0"
+ "vpcmpeqd\0" "vpcmpeqq\0" "vpcmpeqw\0" "vpcmpestri\0" "vpcmpestrm\0" "vpcmpgtb\0" "vpcmpgtd\0" "vpcmpgtq\0"
+ "vpcmpgtw\0" "vpcmpistri\0" "vpcmpistrm\0" "vpcmpq\0" "vpcmpub\0" "vpcmpud\0" "vpcmpuq\0" "vpcmpuw\0" "vpcmpw\0"
+ "vpcomb\0" "vpcomd\0" "vpcompressb\0" "vpcompressd\0" "vpcompressq\0" "vpcompressw\0" "vpcomq\0" "vpcomub\0"
+ "vpcomud\0" "vpcomuq\0" "vpcomuw\0" "vpcomw\0" "vpconflictd\0" "vpconflictq\0" "vpdpbusd\0" "vpdpbusds\0"
+ "vpdpwssd\0" "vpdpwssds\0" "vperm2f128\0" "vperm2i128\0" "vpermb\0" "vpermd\0" "vpermi2b\0" "vpermi2d\0"
+ "vpermi2pd\0" "vpermi2ps\0" "vpermi2q\0" "vpermi2w\0" "vpermil2pd\0" "vpermil2ps\0" "vpermilpd\0" "vpermilps\0"
+ "vpermpd\0" "vpermps\0" "vpermq\0" "vpermt2b\0" "vpermt2d\0" "vpermt2pd\0" "vpermt2ps\0" "vpermt2q\0" "vpermt2w\0"
+ "vpermw\0" "vpexpandb\0" "vpexpandd\0" "vpexpandq\0" "vpexpandw\0" "vpextrb\0" "vpextrd\0" "vpextrq\0" "vpextrw\0"
+ "vpgatherdd\0" "vpgatherdq\0" "vpgatherqd\0" "vpgatherqq\0" "vphaddbd\0" "vphaddbq\0" "vphaddbw\0" "vphaddd\0"
+ "vphadddq\0" "vphaddsw\0" "vphaddubd\0" "vphaddubq\0" "vphaddubw\0" "vphaddudq\0" "vphadduwd\0" "vphadduwq\0"
+ "vphaddw\0" "vphaddwd\0" "vphaddwq\0" "vphminposuw\0" "vphsubbw\0" "vphsubd\0" "vphsubdq\0" "vphsubsw\0" "vphsubw\0"
+ "vphsubwd\0" "vpinsrb\0" "vpinsrd\0" "vpinsrq\0" "vpinsrw\0" "vplzcntd\0" "vplzcntq\0" "vpmacsdd\0" "vpmacsdqh\0"
+ "vpmacsdql\0" "vpmacssdd\0" "vpmacssdqh\0" "vpmacssdql\0" "vpmacsswd\0" "vpmacssww\0" "vpmacswd\0" "vpmacsww\0"
+ "vpmadcsswd\0" "vpmadcswd\0" "vpmadd52huq\0" "vpmadd52luq\0" "vpmaddubsw\0" "vpmaddwd\0" "vpmaskmovd\0"
+ "vpmaskmovq\0" "vpmaxsb\0" "vpmaxsd\0" "vpmaxsq\0" "vpmaxsw\0" "vpmaxub\0" "vpmaxud\0" "vpmaxuq\0" "vpmaxuw\0"
+ "vpminsb\0" "vpminsd\0" "vpminsq\0" "vpminsw\0" "vpminub\0" "vpminud\0" "vpminuq\0" "vpminuw\0" "vpmovb2m\0"
+ "vpmovd2m\0" "vpmovdb\0" "vpmovdw\0" "vpmovm2b\0" "vpmovm2d\0" "vpmovm2q\0" "vpmovm2w\0" "vpmovmskb\0" "vpmovq2m\0"
+ "vpmovqb\0" "vpmovqd\0" "vpmovqw\0" "vpmovsdb\0" "vpmovsdw\0" "vpmovsqb\0" "vpmovsqd\0" "vpmovsqw\0" "vpmovswb\0"
+ "vpmovsxbd\0" "vpmovsxbq\0" "vpmovsxbw\0" "vpmovsxdq\0" "vpmovsxwd\0" "vpmovsxwq\0" "vpmovusdb\0" "vpmovusdw\0"
+ "vpmovusqb\0" "vpmovusqd\0" "vpmovusqw\0" "vpmovuswb\0" "vpmovw2m\0" "vpmovwb\0" "vpmovzxbd\0" "vpmovzxbq\0"
+ "vpmovzxbw\0" "vpmovzxdq\0" "vpmovzxwd\0" "vpmovzxwq\0" "vpmuldq\0" "vpmulhrsw\0" "vpmulhuw\0" "vpmulhw\0"
+ "vpmulld\0" "vpmullq\0" "vpmullw\0" "vpmultishiftqb\0" "vpmuludq\0" "vpopcntb\0" "vpopcntd\0" "vpopcntq\0"
+ "vpopcntw\0" "vpor\0" "vpord\0" "vporq\0" "vpperm\0" "vprold\0" "vprolq\0" "vprolvd\0" "vprolvq\0" "vprord\0"
+ "vprorq\0" "vprorvd\0" "vprorvq\0" "vprotb\0" "vprotd\0" "vprotq\0" "vprotw\0" "vpsadbw\0" "vpscatterdd\0"
+ "vpscatterdq\0" "vpscatterqd\0" "vpscatterqq\0" "vpshab\0" "vpshad\0" "vpshaq\0" "vpshaw\0" "vpshlb\0" "vpshld\0"
+ "vpshldd\0" "vpshldq\0" "vpshldvd\0" "vpshldvq\0" "vpshldvw\0" "vpshldw\0" "vpshlq\0" "vpshlw\0" "vpshrdd\0"
+ "vpshrdq\0" "vpshrdvd\0" "vpshrdvq\0" "vpshrdvw\0" "vpshrdw\0" "vpshufb\0" "vpshufbitqmb\0" "vpshufd\0" "vpshufhw\0"
+ "vpshuflw\0" "vpsignb\0" "vpsignd\0" "vpsignw\0" "vpslld\0" "vpslldq\0" "vpsllq\0" "vpsllvd\0" "vpsllvq\0"
+ "vpsllvw\0" "vpsllw\0" "vpsrad\0" "vpsraq\0" "vpsravd\0" "vpsravq\0" "vpsravw\0" "vpsraw\0" "vpsrld\0" "vpsrldq\0"
+ "vpsrlq\0" "vpsrlvd\0" "vpsrlvq\0" "vpsrlvw\0" "vpsrlw\0" "vpsubb\0" "vpsubd\0" "vpsubq\0" "vpsubsb\0" "vpsubsw\0"
+ "vpsubusb\0" "vpsubusw\0" "vpsubw\0" "vpternlogd\0" "vpternlogq\0" "vptest\0" "vptestmb\0" "vptestmd\0" "vptestmq\0"
+ "vptestmw\0" "vptestnmb\0" "vptestnmd\0" "vptestnmq\0" "vptestnmw\0" "vpunpckhbw\0" "vpunpckhdq\0" "vpunpckhqdq\0"
+ "vpunpckhwd\0" "vpunpcklbw\0" "vpunpckldq\0" "vpunpcklqdq\0" "vpunpcklwd\0" "vpxor\0" "vpxord\0" "vpxorq\0"
+ "vrangepd\0" "vrangeps\0" "vrangesd\0" "vrangess\0" "vrcp14pd\0" "vrcp14ps\0" "vrcp14sd\0" "vrcp14ss\0" "vrcp28pd\0"
+ "vrcp28ps\0" "vrcp28sd\0" "vrcp28ss\0" "vrcpph\0" "vrcpps\0" "vrcpsh\0" "vrcpss\0" "vreducepd\0" "vreduceph\0"
+ "vreduceps\0" "vreducesd\0" "vreducesh\0" "vreducess\0" "vrndscalepd\0" "vrndscaleph\0" "vrndscaleps\0"
+ "vrndscalesd\0" "vrndscalesh\0" "vrndscaless\0" "vroundpd\0" "vroundps\0" "vroundsd\0" "vroundss\0" "vrsqrt14pd\0"
+ "vrsqrt14ps\0" "vrsqrt14sd\0" "vrsqrt14ss\0" "vrsqrt28pd\0" "vrsqrt28ps\0" "vrsqrt28sd\0" "vrsqrt28ss\0" "vrsqrtph\0"
+ "vrsqrtps\0" "vrsqrtsh\0" "vrsqrtss\0" "vscalefpd\0" "vscalefph\0" "vscalefps\0" "vscalefsd\0" "vscalefsh\0"
+ "vscalefss\0" "vscatterdpd\0" "vscatterdps\0" "vscatterpf0dpd\0" "vscatterpf0dps\0" "vscatterpf0qpd\0"
+ "vscatterpf0qps\0" "vscatterpf1dpd\0" "vscatterpf1dps\0" "vscatterpf1qpd\0" "vscatterpf1qps\0" "vscatterqpd\0"
+ "vscatterqps\0" "vshuff32x4\0" "vshuff64x2\0" "vshufi32x4\0" "vshufi64x2\0" "vshufpd\0" "vshufps\0" "vsqrtpd\0"
+ "vsqrtph\0" "vsqrtps\0" "vsqrtsd\0" "vsqrtsh\0" "vsqrtss\0" "vstmxcsr\0" "vsubpd\0" "vsubph\0" "vsubps\0" "vsubsd\0"
+ "vsubsh\0" "vsubss\0" "vtestpd\0" "vtestps\0" "vucomisd\0" "vucomish\0" "vucomiss\0" "vunpckhpd\0" "vunpckhps\0"
+ "vunpcklpd\0" "vunpcklps\0" "vxorpd\0" "vxorps\0" "vzeroall\0" "vzeroupper\0" "wbinvd\0" "wbnoinvd\0" "wrfsbase\0"
+ "wrgsbase\0" "wrmsr\0" "wrssd\0" "wrssq\0" "wrussd\0" "wrussq\0" "xabort\0" "xadd\0" "xbegin\0" "xend\0" "xgetbv\0"
+ "xlatb\0" "xresldtrk\0" "xrstors\0" "xrstors64\0" "xsavec\0" "xsavec64\0" "xsaveopt\0" "xsaveopt64\0" "xsaves\0"
+ "xsaves64\0" "xsetbv\0" "xsusldtrk\0" "xtest";
const InstDB::InstNameIndex InstDB::instNameIndex[26] = {
{ Inst::kIdAaa , Inst::kIdArpl + 1 },
@@ -2882,19 +3014,18 @@ const InstDB::InstNameIndex InstDB::instNameIndex[26] = {
// ${NameData:End}
#endif // !ASMJIT_NO_TEXT
-// ============================================================================
-// [asmjit::x86::InstDB - InstSignature / OpSignature]
-// ============================================================================
+// x86::InstDB - InstSignature & OpSignature
+// =========================================
#ifndef ASMJIT_NO_VALIDATION
// ${InstSignatureTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
-#define ROW(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \
- { count, (x86 ? uint8_t(InstDB::kModeX86) : uint8_t(0)) | \
- (x64 ? uint8_t(InstDB::kModeX64) : uint8_t(0)) , \
- implicit, \
- 0, \
- { o0, o1, o2, o3, o4, o5 } \
+#define ROW(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \
+ { count, uint8_t(x86 ? uint8_t(InstDB::Mode::kX86) : uint8_t(0)) | \
+ (x64 ? uint8_t(InstDB::Mode::kX64) : uint8_t(0)) , \
+ implicit, \
+ 0, \
+ { o0, o1, o2, o3, o4, o5 } \
}
const InstDB::InstSignature InstDB::_instSignatureTable[] = {
ROW(2, 1, 1, 0, 1 , 2 , 0 , 0 , 0 , 0 ), // #0 {r8lo|r8hi|m8|mem, r8lo|r8hi}
@@ -3097,507 +3228,517 @@ const InstDB::InstSignature InstDB::_instSignatureTable[] = {
ROW(4, 1, 1, 0, 104, 50 , 51 , 10 , 0 , 0 ), // #197 {xmm|k, xmm, xmm|m128|mem, i8|u8}
ROW(4, 1, 1, 0, 105, 53 , 54 , 10 , 0 , 0 ), // {ymm|k, ymm, ymm|m256|mem, i8|u8}
ROW(4, 1, 1, 0, 106, 56 , 57 , 10 , 0 , 0 ), // {k, zmm, zmm|m512|mem, i8|u8}
- ROW(2, 1, 1, 0, 51 , 50 , 0 , 0 , 0 , 0 ), // #200 {xmm|m128|mem, xmm}
+ ROW(4, 1, 1, 0, 106, 50 , 51 , 10 , 0 , 0 ), // #200 {k, xmm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 106, 53 , 54 , 10 , 0 , 0 ), // {k, ymm, ymm|m256|mem, i8|u8}
+ ROW(4, 1, 1, 0, 106, 56 , 57 , 10 , 0 , 0 ), // {k, zmm, zmm|m512|mem, i8|u8}
+ ROW(2, 1, 1, 0, 51 , 50 , 0 , 0 , 0 , 0 ), // #203 {xmm|m128|mem, xmm}
ROW(2, 1, 1, 0, 54 , 53 , 0 , 0 , 0 , 0 ), // {ymm|m256|mem, ymm}
ROW(2, 1, 1, 0, 57 , 56 , 0 , 0 , 0 , 0 ), // {zmm|m512|mem, zmm}
- ROW(2, 1, 1, 0, 50 , 65 , 0 , 0 , 0 , 0 ), // #203 {xmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 50 , 65 , 0 , 0 , 0 , 0 ), // #206 {xmm, xmm|m64|mem}
ROW(2, 1, 1, 0, 53 , 51 , 0 , 0 , 0 , 0 ), // {ymm, xmm|m128|mem}
ROW(2, 1, 1, 0, 56 , 54 , 0 , 0 , 0 , 0 ), // {zmm, ymm|m256|mem}
- ROW(2, 1, 1, 0, 50 , 51 , 0 , 0 , 0 , 0 ), // #206 {xmm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 50 , 51 , 0 , 0 , 0 , 0 ), // #209 {xmm, xmm|m128|mem}
ROW(2, 1, 1, 0, 53 , 54 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
ROW(2, 1, 1, 0, 56 , 57 , 0 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem}
- ROW(3, 1, 1, 0, 65 , 50 , 10 , 0 , 0 , 0 ), // #209 {xmm|m64|mem, xmm, i8|u8}
- ROW(3, 1, 1, 0, 51 , 53 , 10 , 0 , 0 , 0 ), // #210 {xmm|m128|mem, ymm, i8|u8}
- ROW(3, 1, 1, 0, 54 , 56 , 10 , 0 , 0 , 0 ), // #211 {ymm|m256|mem, zmm, i8|u8}
- ROW(3, 1, 1, 0, 50 , 107, 50 , 0 , 0 , 0 ), // #212 {xmm, vm64x|vm64y, xmm}
- ROW(2, 1, 1, 0, 50 , 107, 0 , 0 , 0 , 0 ), // {xmm, vm64x|vm64y}
+ ROW(2, 1, 1, 0, 50 , 107, 0 , 0 , 0 , 0 ), // #212 {xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 53 , 65 , 0 , 0 , 0 , 0 ), // {ymm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 56 , 51 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 65 , 50 , 10 , 0 , 0 , 0 ), // #215 {xmm|m64|mem, xmm, i8|u8}
+ ROW(3, 1, 1, 0, 51 , 53 , 10 , 0 , 0 , 0 ), // #216 {xmm|m128|mem, ymm, i8|u8}
+ ROW(3, 1, 1, 0, 54 , 56 , 10 , 0 , 0 , 0 ), // #217 {ymm|m256|mem, zmm, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 108, 50 , 0 , 0 , 0 ), // #218 {xmm, vm64x|vm64y, xmm}
+ ROW(2, 1, 1, 0, 50 , 108, 0 , 0 , 0 , 0 ), // {xmm, vm64x|vm64y}
ROW(2, 1, 1, 0, 53 , 72 , 0 , 0 , 0 , 0 ), // {ymm, vm64z}
- ROW(3, 1, 1, 0, 50 , 51 , 10 , 0 , 0 , 0 ), // #215 {xmm, xmm|m128|mem, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 51 , 10 , 0 , 0 , 0 ), // #221 {xmm, xmm|m128|mem, i8|u8}
ROW(3, 1, 1, 0, 53 , 54 , 10 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem, i8|u8}
ROW(3, 1, 1, 0, 56 , 57 , 10 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem, i8|u8}
- ROW(2, 1, 1, 0, 50 , 65 , 0 , 0 , 0 , 0 ), // #218 {xmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 50 , 65 , 0 , 0 , 0 , 0 ), // #224 {xmm, xmm|m64|mem}
ROW(2, 1, 1, 0, 53 , 54 , 0 , 0 , 0 , 0 ), // {ymm, ymm|m256|mem}
ROW(2, 1, 1, 0, 56 , 57 , 0 , 0 , 0 , 0 ), // {zmm, zmm|m512|mem}
- ROW(2, 1, 1, 0, 52 , 50 , 0 , 0 , 0 , 0 ), // #221 {m128|mem, xmm}
+ ROW(2, 1, 1, 0, 52 , 50 , 0 , 0 , 0 , 0 ), // #227 {m128|mem, xmm}
ROW(2, 1, 1, 0, 55 , 53 , 0 , 0 , 0 , 0 ), // {m256|mem, ymm}
ROW(2, 1, 1, 0, 58 , 56 , 0 , 0 , 0 , 0 ), // {m512|mem, zmm}
- ROW(2, 1, 1, 0, 50 , 52 , 0 , 0 , 0 , 0 ), // #224 {xmm, m128|mem}
+ ROW(2, 1, 1, 0, 50 , 52 , 0 , 0 , 0 , 0 ), // #230 {xmm, m128|mem}
ROW(2, 1, 1, 0, 53 , 55 , 0 , 0 , 0 , 0 ), // {ymm, m256|mem}
ROW(2, 1, 1, 0, 56 , 58 , 0 , 0 , 0 , 0 ), // {zmm, m512|mem}
- ROW(2, 0, 1, 0, 15 , 50 , 0 , 0 , 0 , 0 ), // #227 {r64|m64|mem, xmm}
- ROW(2, 1, 1, 0, 50 , 108, 0 , 0 , 0 , 0 ), // {xmm, xmm|m64|mem|r64}
+ ROW(2, 0, 1, 0, 15 , 50 , 0 , 0 , 0 , 0 ), // #233 {r64|m64|mem, xmm}
+ ROW(2, 1, 1, 0, 50 , 109, 0 , 0 , 0 , 0 ), // {xmm, xmm|m64|mem|r64}
ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // {m64|mem, xmm}
- ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // #230 {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // #236 {m64|mem, xmm}
ROW(2, 1, 1, 0, 50 , 30 , 0 , 0 , 0 , 0 ), // {xmm, m64|mem}
- ROW(3, 1, 1, 0, 50 , 50 , 50 , 0 , 0 , 0 ), // #232 {xmm, xmm, xmm}
- ROW(2, 1, 1, 0, 29 , 50 , 0 , 0 , 0 , 0 ), // #233 {m32|mem, xmm}
+ ROW(3, 1, 1, 0, 50 , 50 , 50 , 0 , 0 , 0 ), // #238 {xmm, xmm, xmm}
+ ROW(2, 1, 1, 0, 21 , 50 , 0 , 0 , 0 , 0 ), // #239 {m16|mem, xmm}
+ ROW(2, 1, 1, 0, 50 , 21 , 0 , 0 , 0 , 0 ), // {xmm, m16|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 50 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
+ ROW(2, 1, 1, 0, 29 , 50 , 0 , 0 , 0 , 0 ), // #242 {m32|mem, xmm}
ROW(2, 1, 1, 0, 50 , 29 , 0 , 0 , 0 , 0 ), // {xmm, m32|mem}
ROW(3, 1, 1, 0, 50 , 50 , 50 , 0 , 0 , 0 ), // {xmm, xmm, xmm}
- ROW(4, 1, 1, 0, 106, 106, 50 , 51 , 0 , 0 ), // #236 {k, k, xmm, xmm|m128|mem}
+ ROW(4, 1, 1, 0, 106, 106, 50 , 51 , 0 , 0 ), // #245 {k, k, xmm, xmm|m128|mem}
ROW(4, 1, 1, 0, 106, 106, 53 , 54 , 0 , 0 ), // {k, k, ymm, ymm|m256|mem}
ROW(4, 1, 1, 0, 106, 106, 56 , 57 , 0 , 0 ), // {k, k, zmm, zmm|m512|mem}
- ROW(2, 1, 1, 0, 96 , 108, 0 , 0 , 0 , 0 ), // #239 {xmm|ymm, xmm|m64|mem|r64}
+ ROW(2, 1, 1, 0, 96 , 109, 0 , 0 , 0 , 0 ), // #248 {xmm|ymm, xmm|m64|mem|r64}
ROW(2, 0, 1, 0, 56 , 8 , 0 , 0 , 0 , 0 ), // {zmm, r64}
ROW(2, 1, 1, 0, 56 , 65 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m64|mem}
- ROW(4, 1, 1, 0, 106, 50 , 51 , 10 , 0 , 0 ), // #242 {k, xmm, xmm|m128|mem, i8|u8}
- ROW(4, 1, 1, 0, 106, 53 , 54 , 10 , 0 , 0 ), // {k, ymm, ymm|m256|mem, i8|u8}
- ROW(4, 1, 1, 0, 106, 56 , 57 , 10 , 0 , 0 ), // {k, zmm, zmm|m512|mem, i8|u8}
- ROW(3, 1, 1, 0, 104, 50 , 51 , 0 , 0 , 0 ), // #245 {xmm|k, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 104, 50 , 51 , 0 , 0 , 0 ), // #251 {xmm|k, xmm, xmm|m128|mem}
ROW(3, 1, 1, 0, 105, 53 , 54 , 0 , 0 , 0 ), // {ymm|k, ymm, ymm|m256|mem}
ROW(3, 1, 1, 0, 106, 56 , 57 , 0 , 0 , 0 ), // {k, zmm, zmm|m512|mem}
- ROW(2, 1, 1, 0, 109, 50 , 0 , 0 , 0 , 0 ), // #248 {xmm|m32|mem, xmm}
+ ROW(2, 1, 1, 0, 107, 50 , 0 , 0 , 0 , 0 ), // #254 {xmm|m32|mem, xmm}
ROW(2, 1, 1, 0, 65 , 53 , 0 , 0 , 0 , 0 ), // {xmm|m64|mem, ymm}
ROW(2, 1, 1, 0, 51 , 56 , 0 , 0 , 0 , 0 ), // {xmm|m128|mem, zmm}
- ROW(2, 1, 1, 0, 65 , 50 , 0 , 0 , 0 , 0 ), // #251 {xmm|m64|mem, xmm}
+ ROW(2, 1, 1, 0, 65 , 50 , 0 , 0 , 0 , 0 ), // #257 {xmm|m64|mem, xmm}
ROW(2, 1, 1, 0, 51 , 53 , 0 , 0 , 0 , 0 ), // {xmm|m128|mem, ymm}
ROW(2, 1, 1, 0, 54 , 56 , 0 , 0 , 0 , 0 ), // {ymm|m256|mem, zmm}
- ROW(2, 1, 1, 0, 110, 50 , 0 , 0 , 0 , 0 ), // #254 {xmm|m16|mem, xmm}
- ROW(2, 1, 1, 0, 109, 53 , 0 , 0 , 0 , 0 ), // {xmm|m32|mem, ymm}
+ ROW(2, 1, 1, 0, 110, 50 , 0 , 0 , 0 , 0 ), // #260 {xmm|m16|mem, xmm}
+ ROW(2, 1, 1, 0, 107, 53 , 0 , 0 , 0 , 0 ), // {xmm|m32|mem, ymm}
ROW(2, 1, 1, 0, 65 , 56 , 0 , 0 , 0 , 0 ), // {xmm|m64|mem, zmm}
- ROW(2, 1, 1, 0, 50 , 109, 0 , 0 , 0 , 0 ), // #257 {xmm, xmm|m32|mem}
- ROW(2, 1, 1, 0, 53 , 65 , 0 , 0 , 0 , 0 ), // {ymm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 56 , 51 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m128|mem}
- ROW(2, 1, 1, 0, 50 , 110, 0 , 0 , 0 , 0 ), // #260 {xmm, xmm|m16|mem}
- ROW(2, 1, 1, 0, 53 , 109, 0 , 0 , 0 , 0 ), // {ymm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 50 , 110, 0 , 0 , 0 , 0 ), // #263 {xmm, xmm|m16|mem}
+ ROW(2, 1, 1, 0, 53 , 107, 0 , 0 , 0 , 0 ), // {ymm, xmm|m32|mem}
ROW(2, 1, 1, 0, 56 , 65 , 0 , 0 , 0 , 0 ), // {zmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 67 , 50 , 0 , 0 , 0 , 0 ), // #263 {vm32x, xmm}
+ ROW(2, 1, 1, 0, 67 , 50 , 0 , 0 , 0 , 0 ), // #266 {vm32x, xmm}
ROW(2, 1, 1, 0, 68 , 53 , 0 , 0 , 0 , 0 ), // {vm32y, ymm}
ROW(2, 1, 1, 0, 69 , 56 , 0 , 0 , 0 , 0 ), // {vm32z, zmm}
- ROW(2, 1, 1, 0, 70 , 50 , 0 , 0 , 0 , 0 ), // #266 {vm64x, xmm}
+ ROW(2, 1, 1, 0, 70 , 50 , 0 , 0 , 0 , 0 ), // #269 {vm64x, xmm}
ROW(2, 1, 1, 0, 71 , 53 , 0 , 0 , 0 , 0 ), // {vm64y, ymm}
ROW(2, 1, 1, 0, 72 , 56 , 0 , 0 , 0 , 0 ), // {vm64z, zmm}
- ROW(3, 1, 1, 0, 106, 50 , 51 , 0 , 0 , 0 ), // #269 {k, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 106, 50 , 51 , 0 , 0 , 0 ), // #272 {k, xmm, xmm|m128|mem}
ROW(3, 1, 1, 0, 106, 53 , 54 , 0 , 0 , 0 ), // {k, ymm, ymm|m256|mem}
ROW(3, 1, 1, 0, 106, 56 , 57 , 0 , 0 , 0 ), // {k, zmm, zmm|m512|mem}
- ROW(3, 1, 1, 0, 6 , 6 , 28 , 0 , 0 , 0 ), // #272 {r32, r32, r32|m32|mem}
+ ROW(3, 1, 1, 0, 6 , 6 , 28 , 0 , 0 , 0 ), // #275 {r32, r32, r32|m32|mem}
ROW(3, 0, 1, 0, 8 , 8 , 15 , 0 , 0 , 0 ), // {r64, r64, r64|m64|mem}
- ROW(3, 1, 1, 0, 6 , 28 , 6 , 0 , 0 , 0 ), // #274 {r32, r32|m32|mem, r32}
+ ROW(3, 1, 1, 0, 6 , 28 , 6 , 0 , 0 , 0 ), // #277 {r32, r32|m32|mem, r32}
ROW(3, 0, 1, 0, 8 , 15 , 8 , 0 , 0 , 0 ), // {r64, r64|m64|mem, r64}
- ROW(2, 1, 0, 0, 111, 28 , 0 , 0 , 0 , 0 ), // #276 {bnd, r32|m32|mem}
+ ROW(2, 1, 0, 0, 111, 28 , 0 , 0 , 0 , 0 ), // #279 {bnd, r32|m32|mem}
ROW(2, 0, 1, 0, 111, 15 , 0 , 0 , 0 , 0 ), // {bnd, r64|m64|mem}
- ROW(2, 1, 1, 0, 111, 112, 0 , 0 , 0 , 0 ), // #278 {bnd, bnd|mem}
+ ROW(2, 1, 1, 0, 111, 112, 0 , 0 , 0 , 0 ), // #281 {bnd, bnd|mem}
ROW(2, 1, 1, 0, 113, 111, 0 , 0 , 0 , 0 ), // {mem, bnd}
- ROW(2, 1, 0, 0, 4 , 29 , 0 , 0 , 0 , 0 ), // #280 {r16, m32|mem}
+ ROW(2, 1, 0, 0, 4 , 29 , 0 , 0 , 0 , 0 ), // #283 {r16, m32|mem}
ROW(2, 1, 0, 0, 6 , 30 , 0 , 0 , 0 , 0 ), // {r32, m64|mem}
- ROW(1, 1, 0, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #282 {rel16|r16|m16|r32|m32}
+ ROW(1, 1, 0, 0, 114, 0 , 0 , 0 , 0 , 0 ), // #285 {rel16|r16|m16|r32|m32}
ROW(1, 1, 1, 0, 115, 0 , 0 , 0 , 0 , 0 ), // {rel32|r64|m64|mem}
- ROW(2, 1, 1, 0, 6 , 116, 0 , 0 , 0 , 0 ), // #284 {r32, r8lo|r8hi|m8|r16|m16|r32|m32}
+ ROW(2, 1, 1, 0, 6 , 116, 0 , 0 , 0 , 0 ), // #287 {r32, r8lo|r8hi|m8|r16|m16|r32|m32}
ROW(2, 0, 1, 0, 8 , 117, 0 , 0 , 0 , 0 ), // {r64, r8lo|r8hi|m8|r64|m64}
- ROW(1, 1, 0, 0, 118, 0 , 0 , 0 , 0 , 0 ), // #286 {r16|r32}
- ROW(1, 1, 1, 0, 31 , 0 , 0 , 0 , 0 , 0 ), // #287 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem}
- ROW(2, 1, 0, 0, 119, 58 , 0 , 0 , 0 , 0 ), // #288 {es:[mem|m512|memBase], m512|mem}
+ ROW(1, 1, 0, 0, 118, 0 , 0 , 0 , 0 , 0 ), // #289 {r16|r32}
+ ROW(1, 1, 1, 0, 31 , 0 , 0 , 0 , 0 , 0 ), // #290 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem}
+ ROW(2, 1, 0, 0, 119, 58 , 0 , 0 , 0 , 0 ), // #291 {es:[mem|m512|memBase], m512|mem}
ROW(2, 0, 1, 0, 119, 58 , 0 , 0 , 0 , 0 ), // {es:[mem|m512|memBase], m512|mem}
- ROW(3, 1, 1, 0, 50 , 10 , 10 , 0 , 0 , 0 ), // #290 {xmm, i8|u8, i8|u8}
- ROW(2, 1, 1, 0, 50 , 50 , 0 , 0 , 0 , 0 ), // #291 {xmm, xmm}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #292 {}
- ROW(1, 1, 1, 0, 100, 0 , 0 , 0 , 0 , 0 ), // #293 {st}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #294 {}
- ROW(1, 1, 1, 0, 120, 0 , 0 , 0 , 0 , 0 ), // #295 {m32|m64|st}
- ROW(2, 1, 1, 0, 50 , 50 , 0 , 0 , 0 , 0 ), // #296 {xmm, xmm}
+ ROW(3, 1, 1, 0, 50 , 10 , 10 , 0 , 0 , 0 ), // #293 {xmm, i8|u8, i8|u8}
+ ROW(2, 1, 1, 0, 50 , 50 , 0 , 0 , 0 , 0 ), // #294 {xmm, xmm}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #295 {}
+ ROW(1, 1, 1, 0, 100, 0 , 0 , 0 , 0 , 0 ), // #296 {st}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #297 {}
+ ROW(1, 1, 1, 0, 120, 0 , 0 , 0 , 0 , 0 ), // #298 {m32|m64|st}
+ ROW(2, 1, 1, 0, 50 , 50 , 0 , 0 , 0 , 0 ), // #299 {xmm, xmm}
ROW(4, 1, 1, 0, 50 , 50 , 10 , 10 , 0 , 0 ), // {xmm, xmm, i8|u8, i8|u8}
- ROW(2, 1, 0, 0, 6 , 52 , 0 , 0 , 0 , 0 ), // #298 {r32, m128|mem}
+ ROW(2, 1, 0, 0, 6 , 52 , 0 , 0 , 0 , 0 ), // #301 {r32, m128|mem}
ROW(2, 0, 1, 0, 8 , 52 , 0 , 0 , 0 , 0 ), // {r64, m128|mem}
- ROW(2, 1, 0, 2, 36 , 121, 0 , 0 , 0 , 0 ), // #300 {<eax>, <ecx>}
+ ROW(2, 1, 0, 2, 36 , 121, 0 , 0 , 0 , 0 ), // #303 {<eax>, <ecx>}
ROW(2, 0, 1, 2, 122, 121, 0 , 0 , 0 , 0 ), // {<eax|rax>, <ecx>}
- ROW(1, 1, 1, 0, 123, 0 , 0 , 0 , 0 , 0 ), // #302 {rel8|rel32}
+ ROW(1, 1, 1, 0, 123, 0 , 0 , 0 , 0 , 0 ), // #305 {rel8|rel32}
ROW(1, 1, 0, 0, 124, 0 , 0 , 0 , 0 , 0 ), // {rel16}
- ROW(2, 1, 0, 1, 125, 126, 0 , 0 , 0 , 0 ), // #304 {<cx|ecx>, rel8}
+ ROW(2, 1, 0, 1, 125, 126, 0 , 0 , 0 , 0 ), // #307 {<cx|ecx>, rel8}
ROW(2, 0, 1, 1, 127, 126, 0 , 0 , 0 , 0 ), // {<ecx|rcx>, rel8}
- ROW(1, 1, 1, 0, 128, 0 , 0 , 0 , 0 , 0 ), // #306 {rel8|rel32|r64|m64|mem}
+ ROW(1, 1, 1, 0, 128, 0 , 0 , 0 , 0 , 0 ), // #309 {rel8|rel32|r64|m64|mem}
ROW(1, 1, 0, 0, 129, 0 , 0 , 0 , 0 , 0 ), // {rel16|r32|m32|mem}
- ROW(2, 1, 1, 0, 106, 130, 0 , 0 , 0 , 0 ), // #308 {k, k|m8|mem|r32}
+ ROW(2, 1, 1, 0, 106, 130, 0 , 0 , 0 , 0 ), // #311 {k, k|m8|mem|r32}
ROW(2, 1, 1, 0, 131, 106, 0 , 0 , 0 , 0 ), // {m8|mem|r32, k}
- ROW(2, 1, 1, 0, 106, 132, 0 , 0 , 0 , 0 ), // #310 {k, k|m32|mem|r32}
+ ROW(2, 1, 1, 0, 106, 132, 0 , 0 , 0 , 0 ), // #313 {k, k|m32|mem|r32}
ROW(2, 1, 1, 0, 28 , 106, 0 , 0 , 0 , 0 ), // {m32|mem|r32, k}
- ROW(2, 1, 1, 0, 106, 133, 0 , 0 , 0 , 0 ), // #312 {k, k|m64|mem|r64}
+ ROW(2, 1, 1, 0, 106, 133, 0 , 0 , 0 , 0 ), // #315 {k, k|m64|mem|r64}
ROW(2, 1, 1, 0, 15 , 106, 0 , 0 , 0 , 0 ), // {m64|mem|r64, k}
- ROW(2, 1, 1, 0, 106, 134, 0 , 0 , 0 , 0 ), // #314 {k, k|m16|mem|r32}
+ ROW(2, 1, 1, 0, 106, 134, 0 , 0 , 0 , 0 ), // #317 {k, k|m16|mem|r32}
ROW(2, 1, 1, 0, 135, 106, 0 , 0 , 0 , 0 ), // {m16|mem|r32, k}
- ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #316 {r16, r16|m16|mem}
+ ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #319 {r16, r16|m16|mem}
ROW(2, 1, 1, 0, 6 , 135, 0 , 0 , 0 , 0 ), // {r32, r32|m16|mem}
- ROW(2, 1, 0, 0, 136, 137, 0 , 0 , 0 , 0 ), // #318 {i16, i16|i32}
+ ROW(2, 1, 0, 0, 136, 137, 0 , 0 , 0 , 0 ), // #321 {i16, i16|i32}
ROW(1, 1, 1, 0, 138, 0 , 0 , 0 , 0 , 0 ), // {m32|m48|m80|mem}
- ROW(2, 1, 0, 0, 4 , 29 , 0 , 0 , 0 , 0 ), // #320 {r16, m32|mem}
+ ROW(2, 1, 0, 0, 4 , 29 , 0 , 0 , 0 , 0 ), // #323 {r16, m32|mem}
ROW(2, 1, 0, 0, 6 , 101, 0 , 0 , 0 , 0 ), // {r32, m48|mem}
- ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #322 {r16, r16|m16|mem}
+ ROW(2, 1, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #325 {r16, r16|m16|mem}
ROW(2, 1, 1, 0, 139, 135, 0 , 0 , 0 , 0 ), // {r32|r64, r32|m16|mem}
- ROW(2, 1, 1, 0, 64 , 28 , 0 , 0 , 0 , 0 ), // #324 {mm|xmm, r32|m32|mem}
+ ROW(2, 1, 1, 0, 64 , 28 , 0 , 0 , 0 , 0 ), // #327 {mm|xmm, r32|m32|mem}
ROW(2, 1, 1, 0, 28 , 64 , 0 , 0 , 0 , 0 ), // {r32|m32|mem, mm|xmm}
- ROW(2, 1, 1, 0, 50 , 109, 0 , 0 , 0 , 0 ), // #326 {xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 50 , 107, 0 , 0 , 0 , 0 ), // #329 {xmm, xmm|m32|mem}
ROW(2, 1, 1, 0, 29 , 50 , 0 , 0 , 0 , 0 ), // {m32|mem, xmm}
- ROW(2, 1, 1, 0, 4 , 9 , 0 , 0 , 0 , 0 ), // #328 {r16, r8lo|r8hi|m8}
+ ROW(2, 1, 1, 0, 4 , 9 , 0 , 0 , 0 , 0 ), // #331 {r16, r8lo|r8hi|m8}
ROW(2, 1, 1, 0, 139, 140, 0 , 0 , 0 , 0 ), // {r32|r64, r8lo|r8hi|m8|r16|m16}
- ROW(4, 1, 1, 1, 6 , 6 , 28 , 35 , 0 , 0 ), // #330 {r32, r32, r32|m32|mem, <edx>}
+ ROW(2, 0, 1, 0, 4 , 27 , 0 , 0 , 0 , 0 ), // #333 {r16, r16|m16|mem}
+ ROW(2, 0, 1, 0, 139, 28 , 0 , 0 , 0 , 0 ), // {r32|r64, r32|m32|mem}
+ ROW(4, 1, 1, 1, 6 , 6 , 28 , 35 , 0 , 0 ), // #335 {r32, r32, r32|m32|mem, <edx>}
ROW(4, 0, 1, 1, 8 , 8 , 15 , 37 , 0 , 0 ), // {r64, r64, r64|m64|mem, <rdx>}
- ROW(2, 1, 1, 0, 62 , 141, 0 , 0 , 0 , 0 ), // #332 {mm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 62 , 141, 0 , 0 , 0 , 0 ), // #337 {mm, mm|m64|mem}
ROW(2, 1, 1, 0, 50 , 51 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem}
- ROW(3, 1, 1, 0, 62 , 141, 10 , 0 , 0 , 0 ), // #334 {mm, mm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 62 , 141, 10 , 0 , 0 , 0 ), // #339 {mm, mm|m64|mem, i8|u8}
ROW(3, 1, 1, 0, 50 , 51 , 10 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem, i8|u8}
- ROW(3, 1, 1, 0, 6 , 64 , 10 , 0 , 0 , 0 ), // #336 {r32, mm|xmm, i8|u8}
+ ROW(3, 1, 1, 0, 6 , 64 , 10 , 0 , 0 , 0 ), // #341 {r32, mm|xmm, i8|u8}
ROW(3, 1, 1, 0, 21 , 50 , 10 , 0 , 0 , 0 ), // {m16|mem, xmm, i8|u8}
- ROW(2, 1, 1, 0, 62 , 142, 0 , 0 , 0 , 0 ), // #338 {mm, i8|u8|mm|m64|mem}
+ ROW(2, 1, 1, 0, 62 , 142, 0 , 0 , 0 , 0 ), // #343 {mm, i8|u8|mm|m64|mem}
ROW(2, 1, 1, 0, 50 , 59 , 0 , 0 , 0 , 0 ), // {xmm, i8|u8|xmm|m128|mem}
- ROW(2, 1, 1, 0, 62 , 143, 0 , 0 , 0 , 0 ), // #340 {mm, mm|m32|mem}
+ ROW(2, 1, 1, 0, 62 , 143, 0 , 0 , 0 , 0 ), // #345 {mm, mm|m32|mem}
ROW(2, 1, 1, 0, 50 , 51 , 0 , 0 , 0 , 0 ), // {xmm, xmm|m128|mem}
- ROW(1, 1, 0, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #342 {r32}
- ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // #343 {r64}
- ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #344 {}
+ ROW(1, 1, 0, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #347 {r32}
+ ROW(1, 0, 1, 0, 8 , 0 , 0 , 0 , 0 , 0 ), // #348 {r64}
+ ROW(0, 1, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #349 {}
ROW(1, 1, 1, 0, 144, 0 , 0 , 0 , 0 , 0 ), // {u16}
- ROW(3, 1, 1, 0, 6 , 28 , 10 , 0 , 0 , 0 ), // #346 {r32, r32|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 6 , 28 , 10 , 0 , 0 , 0 ), // #351 {r32, r32|m32|mem, i8|u8}
ROW(3, 0, 1, 0, 8 , 15 , 10 , 0 , 0 , 0 ), // {r64, r64|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 51 , 50 , 0 , 0 ), // #348 {xmm, xmm, xmm|m128|mem, xmm}
+ ROW(4, 1, 1, 0, 50 , 50 , 51 , 50 , 0 , 0 ), // #353 {xmm, xmm, xmm|m128|mem, xmm}
ROW(4, 1, 1, 0, 53 , 53 , 54 , 53 , 0 , 0 ), // {ymm, ymm, ymm|m256|mem, ymm}
- ROW(2, 1, 1, 0, 50 , 145, 0 , 0 , 0 , 0 ), // #350 {xmm, xmm|m128|ymm|m256}
+ ROW(2, 1, 1, 0, 50 , 145, 0 , 0 , 0 , 0 ), // #355 {xmm, xmm|m128|ymm|m256}
ROW(2, 1, 1, 0, 53 , 57 , 0 , 0 , 0 , 0 ), // {ymm, zmm|m512|mem}
- ROW(4, 1, 1, 0, 50 , 50 , 50 , 65 , 0 , 0 ), // #352 {xmm, xmm, xmm, xmm|m64|mem}
+ ROW(4, 1, 1, 0, 50 , 50 , 50 , 65 , 0 , 0 ), // #357 {xmm, xmm, xmm, xmm|m64|mem}
ROW(4, 1, 1, 0, 50 , 50 , 30 , 50 , 0 , 0 ), // {xmm, xmm, m64|mem, xmm}
- ROW(4, 1, 1, 0, 50 , 50 , 50 , 109, 0 , 0 ), // #354 {xmm, xmm, xmm, xmm|m32|mem}
+ ROW(4, 1, 1, 0, 50 , 50 , 50 , 107, 0 , 0 ), // #359 {xmm, xmm, xmm, xmm|m32|mem}
ROW(4, 1, 1, 0, 50 , 50 , 29 , 50 , 0 , 0 ), // {xmm, xmm, m32|mem, xmm}
- ROW(4, 1, 1, 0, 53 , 53 , 51 , 10 , 0 , 0 ), // #356 {ymm, ymm, xmm|m128|mem, i8|u8}
+ ROW(4, 1, 1, 0, 53 , 53 , 51 , 10 , 0 , 0 ), // #361 {ymm, ymm, xmm|m128|mem, i8|u8}
ROW(4, 1, 1, 0, 56 , 56 , 51 , 10 , 0 , 0 ), // {zmm, zmm, xmm|m128|mem, i8|u8}
- ROW(1, 1, 0, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #358 {<eax>}
- ROW(1, 0, 1, 1, 38 , 0 , 0 , 0 , 0 , 0 ), // #359 {<rax>}
- ROW(2, 1, 1, 0, 28 , 50 , 0 , 0 , 0 , 0 ), // #360 {r32|m32|mem, xmm}
+ ROW(1, 1, 0, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #363 {<eax>}
+ ROW(1, 0, 1, 1, 38 , 0 , 0 , 0 , 0 , 0 ), // #364 {<rax>}
+ ROW(2, 1, 1, 0, 28 , 50 , 0 , 0 , 0 , 0 ), // #365 {r32|m32|mem, xmm}
ROW(2, 1, 1, 0, 50 , 28 , 0 , 0 , 0 , 0 ), // {xmm, r32|m32|mem}
- ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // #362 {m64|mem, xmm}
+ ROW(2, 1, 1, 0, 30 , 50 , 0 , 0 , 0 , 0 ), // #367 {m64|mem, xmm}
ROW(3, 1, 1, 0, 50 , 50 , 30 , 0 , 0 , 0 ), // {xmm, xmm, m64|mem}
- ROW(2, 1, 0, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #364 {r32|m32|mem, r32}
+ ROW(2, 1, 1, 0, 135, 50 , 0 , 0 , 0 , 0 ), // #369 {r32|m16|mem, xmm}
+ ROW(2, 1, 1, 0, 50 , 135, 0 , 0 , 0 , 0 ), // {xmm, r32|m16|mem}
+ ROW(2, 1, 0, 0, 28 , 6 , 0 , 0 , 0 , 0 ), // #371 {r32|m32|mem, r32}
ROW(2, 0, 1, 0, 15 , 8 , 0 , 0 , 0 , 0 ), // {r64|m64|mem, r64}
- ROW(2, 1, 0, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #366 {r32, r32|m32|mem}
+ ROW(2, 1, 0, 0, 6 , 28 , 0 , 0 , 0 , 0 ), // #373 {r32, r32|m32|mem}
ROW(2, 0, 1, 0, 8 , 15 , 0 , 0 , 0 , 0 ), // {r64, r64|m64|mem}
- ROW(3, 1, 1, 0, 50 , 50 , 59 , 0 , 0 , 0 ), // #368 {xmm, xmm, xmm|m128|mem|i8|u8}
+ ROW(3, 1, 1, 0, 50 , 50 , 59 , 0 , 0 , 0 ), // #375 {xmm, xmm, xmm|m128|mem|i8|u8}
ROW(3, 1, 1, 0, 50 , 52 , 146, 0 , 0 , 0 ), // {xmm, m128|mem, i8|u8|xmm}
- ROW(2, 1, 1, 0, 67 , 96 , 0 , 0 , 0 , 0 ), // #370 {vm32x, xmm|ymm}
+ ROW(2, 1, 1, 0, 67 , 96 , 0 , 0 , 0 , 0 ), // #377 {vm32x, xmm|ymm}
ROW(2, 1, 1, 0, 68 , 56 , 0 , 0 , 0 , 0 ), // {vm32y, zmm}
- ROW(2, 1, 1, 0, 107, 50 , 0 , 0 , 0 , 0 ), // #372 {vm64x|vm64y, xmm}
+ ROW(2, 1, 1, 0, 108, 50 , 0 , 0 , 0 , 0 ), // #379 {vm64x|vm64y, xmm}
ROW(2, 1, 1, 0, 72 , 53 , 0 , 0 , 0 , 0 ), // {vm64z, ymm}
- ROW(3, 1, 1, 0, 50 , 50 , 51 , 0 , 0 , 0 ), // #374 {xmm, xmm, xmm|m128|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 51 , 0 , 0 , 0 ), // #381 {xmm, xmm, xmm|m128|mem}
ROW(3, 1, 1, 0, 50 , 52 , 50 , 0 , 0 , 0 ), // {xmm, m128|mem, xmm}
- ROW(1, 1, 0, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #376 {<ax>}
- ROW(2, 1, 0, 1, 33 , 10 , 0 , 0 , 0 , 0 ), // #377 {<ax>, i8|u8}
- ROW(2, 1, 0, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // #378 {r16|m16|mem, r16}
- ROW(3, 1, 1, 1, 50 , 51 , 147, 0 , 0 , 0 ), // #379 {xmm, xmm|m128|mem, <xmm0>}
- ROW(2, 1, 1, 0, 111, 148, 0 , 0 , 0 , 0 ), // #380 {bnd, mib}
- ROW(2, 1, 1, 0, 111, 113, 0 , 0 , 0 , 0 ), // #381 {bnd, mem}
- ROW(2, 1, 1, 0, 148, 111, 0 , 0 , 0 , 0 ), // #382 {mib, bnd}
- ROW(1, 1, 1, 0, 149, 0 , 0 , 0 , 0 , 0 ), // #383 {r16|r32|r64}
- ROW(1, 1, 1, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #384 {<ax>}
- ROW(2, 1, 1, 2, 35 , 36 , 0 , 0 , 0 , 0 ), // #385 {<edx>, <eax>}
- ROW(1, 1, 1, 0, 150, 0 , 0 , 0 , 0 , 0 ), // #386 {mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
- ROW(1, 1, 1, 0, 30 , 0 , 0 , 0 , 0 , 0 ), // #387 {m64|mem}
- ROW(0, 0, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #388 {}
- ROW(1, 1, 1, 1, 151, 0 , 0 , 0 , 0 , 0 ), // #389 {<ds:[mem|m512|memBase|zax]>}
- ROW(3, 1, 1, 0, 50 , 65 , 10 , 0 , 0 , 0 ), // #390 {xmm, xmm|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 50 , 109, 10 , 0 , 0 , 0 ), // #391 {xmm, xmm|m32|mem, i8|u8}
- ROW(5, 0, 1, 4, 52 , 37 , 38 , 152, 153, 0 ), // #392 {m128|mem, <rdx>, <rax>, <rcx>, <rbx>}
- ROW(5, 1, 1, 4, 30 , 35 , 36 , 121, 154, 0 ), // #393 {m64|mem, <edx>, <eax>, <ecx>, <ebx>}
- ROW(4, 1, 1, 4, 36 , 154, 121, 35 , 0 , 0 ), // #394 {<eax>, <ebx>, <ecx>, <edx>}
- ROW(2, 0, 1, 2, 37 , 38 , 0 , 0 , 0 , 0 ), // #395 {<rdx>, <rax>}
- ROW(2, 1, 1, 0, 62 , 51 , 0 , 0 , 0 , 0 ), // #396 {mm, xmm|m128|mem}
- ROW(2, 1, 1, 0, 50 , 141, 0 , 0 , 0 , 0 ), // #397 {xmm, mm|m64|mem}
- ROW(2, 1, 1, 0, 62 , 65 , 0 , 0 , 0 , 0 ), // #398 {mm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 139, 65 , 0 , 0 , 0 , 0 ), // #399 {r32|r64, xmm|m64|mem}
- ROW(2, 1, 1, 0, 50 , 155, 0 , 0 , 0 , 0 ), // #400 {xmm, r32|m32|mem|r64|m64}
- ROW(2, 1, 1, 0, 139, 109, 0 , 0 , 0 , 0 ), // #401 {r32|r64, xmm|m32|mem}
- ROW(2, 1, 1, 2, 34 , 33 , 0 , 0 , 0 , 0 ), // #402 {<dx>, <ax>}
- ROW(1, 1, 1, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #403 {<eax>}
- ROW(2, 1, 1, 0, 12 , 10 , 0 , 0 , 0 , 0 ), // #404 {i16|u16, i8|u8}
- ROW(3, 1, 1, 0, 28 , 50 , 10 , 0 , 0 , 0 ), // #405 {r32|m32|mem, xmm, i8|u8}
- ROW(1, 1, 1, 0, 102, 0 , 0 , 0 , 0 , 0 ), // #406 {m80|mem}
- ROW(1, 1, 1, 0, 156, 0 , 0 , 0 , 0 , 0 ), // #407 {m16|m32}
- ROW(1, 1, 1, 0, 157, 0 , 0 , 0 , 0 , 0 ), // #408 {m16|m32|m64}
- ROW(1, 1, 1, 0, 158, 0 , 0 , 0 , 0 , 0 ), // #409 {m32|m64|m80|st}
- ROW(1, 1, 1, 0, 21 , 0 , 0 , 0 , 0 , 0 ), // #410 {m16|mem}
- ROW(1, 1, 1, 0, 113, 0 , 0 , 0 , 0 , 0 ), // #411 {mem}
- ROW(1, 1, 1, 0, 159, 0 , 0 , 0 , 0 , 0 ), // #412 {ax|m16|mem}
- ROW(1, 0, 1, 0, 113, 0 , 0 , 0 , 0 , 0 ), // #413 {mem}
- ROW(2, 1, 1, 1, 10 , 36 , 0 , 0 , 0 , 0 ), // #414 {i8|u8, <eax>}
- ROW(2, 1, 1, 0, 160, 161, 0 , 0 , 0 , 0 ), // #415 {al|ax|eax, i8|u8|dx}
- ROW(1, 1, 1, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #416 {r32}
- ROW(2, 1, 1, 0, 162, 163, 0 , 0 , 0 , 0 ), // #417 {es:[m8|memBase|zdi|m16|m32], dx}
- ROW(1, 1, 1, 0, 10 , 0 , 0 , 0 , 0 , 0 ), // #418 {i8|u8}
- ROW(0, 1, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #419 {}
- ROW(3, 1, 1, 0, 106, 106, 106, 0 , 0 , 0 ), // #420 {k, k, k}
- ROW(2, 1, 1, 0, 106, 106, 0 , 0 , 0 , 0 ), // #421 {k, k}
- ROW(3, 1, 1, 0, 106, 106, 10 , 0 , 0 , 0 ), // #422 {k, k, i8|u8}
- ROW(1, 1, 1, 1, 164, 0 , 0 , 0 , 0 , 0 ), // #423 {<ah>}
- ROW(1, 1, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // #424 {m32|mem}
- ROW(1, 0, 1, 0, 58 , 0 , 0 , 0 , 0 , 0 ), // #425 {m512|mem}
- ROW(2, 1, 1, 0, 149, 150, 0 , 0 , 0 , 0 ), // #426 {r16|r32|r64, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
- ROW(1, 1, 1, 0, 27 , 0 , 0 , 0 , 0 , 0 ), // #427 {r16|m16|mem}
- ROW(1, 1, 1, 0, 139, 0 , 0 , 0 , 0 , 0 ), // #428 {r32|r64}
- ROW(3, 1, 1, 0, 139, 28 , 14 , 0 , 0 , 0 ), // #429 {r32|r64, r32|m32|mem, i32|u32}
- ROW(3, 1, 1, 1, 50 , 50 , 165, 0 , 0 , 0 ), // #430 {xmm, xmm, <ds:[mem|m128|memBase|zdi]>}
- ROW(3, 1, 1, 1, 62 , 62 , 166, 0 , 0 , 0 ), // #431 {mm, mm, <ds:[mem|m64|memBase|zdi]>}
- ROW(3, 1, 1, 3, 167, 121, 35 , 0 , 0 , 0 ), // #432 {<ds:[mem|memBase|zax]>, <ecx>, <edx>}
- ROW(2, 1, 1, 0, 119, 58 , 0 , 0 , 0 , 0 ), // #433 {es:[mem|m512|memBase], m512|mem}
- ROW(2, 1, 1, 0, 62 , 50 , 0 , 0 , 0 , 0 ), // #434 {mm, xmm}
- ROW(2, 1, 1, 0, 6 , 50 , 0 , 0 , 0 , 0 ), // #435 {r32, xmm}
- ROW(2, 1, 1, 0, 30 , 62 , 0 , 0 , 0 , 0 ), // #436 {m64|mem, mm}
- ROW(2, 1, 1, 0, 50 , 62 , 0 , 0 , 0 , 0 ), // #437 {xmm, mm}
- ROW(2, 0, 1, 0, 149, 28 , 0 , 0 , 0 , 0 ), // #438 {r16|r32|r64, r32|m32|mem}
- ROW(2, 1, 1, 2, 36 , 121, 0 , 0 , 0 , 0 ), // #439 {<eax>, <ecx>}
- ROW(3, 1, 1, 3, 36 , 121, 154, 0 , 0 , 0 ), // #440 {<eax>, <ecx>, <ebx>}
- ROW(2, 1, 1, 0, 168, 160, 0 , 0 , 0 , 0 ), // #441 {u8|dx, al|ax|eax}
- ROW(2, 1, 1, 0, 163, 169, 0 , 0 , 0 , 0 ), // #442 {dx, ds:[m8|memBase|zsi|m16|m32]}
- ROW(6, 1, 1, 3, 50 , 51 , 10 , 121, 36 , 35 ), // #443 {xmm, xmm|m128|mem, i8|u8, <ecx>, <eax>, <edx>}
- ROW(6, 1, 1, 3, 50 , 51 , 10 , 147, 36 , 35 ), // #444 {xmm, xmm|m128|mem, i8|u8, <xmm0>, <eax>, <edx>}
- ROW(4, 1, 1, 1, 50 , 51 , 10 , 121, 0 , 0 ), // #445 {xmm, xmm|m128|mem, i8|u8, <ecx>}
- ROW(4, 1, 1, 1, 50 , 51 , 10 , 147, 0 , 0 ), // #446 {xmm, xmm|m128|mem, i8|u8, <xmm0>}
- ROW(3, 1, 1, 0, 131, 50 , 10 , 0 , 0 , 0 ), // #447 {r32|m8|mem, xmm, i8|u8}
- ROW(3, 0, 1, 0, 15 , 50 , 10 , 0 , 0 , 0 ), // #448 {r64|m64|mem, xmm, i8|u8}
- ROW(3, 1, 1, 0, 50 , 131, 10 , 0 , 0 , 0 ), // #449 {xmm, r32|m8|mem, i8|u8}
- ROW(3, 1, 1, 0, 50 , 28 , 10 , 0 , 0 , 0 ), // #450 {xmm, r32|m32|mem, i8|u8}
- ROW(3, 0, 1, 0, 50 , 15 , 10 , 0 , 0 , 0 ), // #451 {xmm, r64|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 64 , 135, 10 , 0 , 0 , 0 ), // #452 {mm|xmm, r32|m16|mem, i8|u8}
- ROW(2, 1, 1, 0, 6 , 64 , 0 , 0 , 0 , 0 ), // #453 {r32, mm|xmm}
- ROW(2, 1, 1, 0, 50 , 10 , 0 , 0 , 0 , 0 ), // #454 {xmm, i8|u8}
- ROW(1, 1, 1, 0, 155, 0 , 0 , 0 , 0 , 0 ), // #455 {r32|m32|mem|r64|m64}
- ROW(2, 1, 1, 0, 31 , 103, 0 , 0 , 0 , 0 ), // #456 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, cl|i8|u8}
- ROW(1, 0, 1, 0, 139, 0 , 0 , 0 , 0 , 0 ), // #457 {r32|r64}
- ROW(3, 1, 1, 3, 35 , 36 , 121, 0 , 0 , 0 ), // #458 {<edx>, <eax>, <ecx>}
- ROW(1, 1, 1, 0, 1 , 0 , 0 , 0 , 0 , 0 ), // #459 {r8lo|r8hi|m8|mem}
- ROW(1, 1, 1, 0, 170, 0 , 0 , 0 , 0 , 0 ), // #460 {r16|m16|mem|r32|r64}
- ROW(3, 0, 1, 0, 171, 171, 171, 0 , 0 , 0 ), // #461 {tmm, tmm, tmm}
- ROW(2, 0, 1, 0, 171, 113, 0 , 0 , 0 , 0 ), // #462 {tmm, tmem}
- ROW(2, 0, 1, 0, 113, 171, 0 , 0 , 0 , 0 ), // #463 {tmem, tmm}
- ROW(1, 0, 1, 0, 171, 0 , 0 , 0 , 0 , 0 ), // #464 {tmm}
- ROW(3, 1, 1, 2, 6 , 35 , 36 , 0 , 0 , 0 ), // #465 {r32, <edx>, <eax>}
- ROW(1, 1, 1, 0, 172, 0 , 0 , 0 , 0 , 0 ), // #466 {ds:[mem|memBase]}
- ROW(6, 1, 1, 0, 56 , 56 , 56 , 56 , 56 , 52 ), // #467 {zmm, zmm, zmm, zmm, zmm, m128|mem}
- ROW(6, 1, 1, 0, 50 , 50 , 50 , 50 , 50 , 52 ), // #468 {xmm, xmm, xmm, xmm, xmm, m128|mem}
- ROW(3, 1, 1, 0, 50 , 50 , 65 , 0 , 0 , 0 ), // #469 {xmm, xmm, xmm|m64|mem}
- ROW(3, 1, 1, 0, 50 , 50 , 109, 0 , 0 , 0 ), // #470 {xmm, xmm, xmm|m32|mem}
- ROW(2, 1, 1, 0, 53 , 52 , 0 , 0 , 0 , 0 ), // #471 {ymm, m128|mem}
- ROW(2, 1, 1, 0, 173, 65 , 0 , 0 , 0 , 0 ), // #472 {ymm|zmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 173, 52 , 0 , 0 , 0 , 0 ), // #473 {ymm|zmm, m128|mem}
- ROW(2, 1, 1, 0, 56 , 55 , 0 , 0 , 0 , 0 ), // #474 {zmm, m256|mem}
- ROW(2, 1, 1, 0, 174, 65 , 0 , 0 , 0 , 0 ), // #475 {xmm|ymm|zmm, xmm|m64|mem}
- ROW(2, 1, 1, 0, 174, 109, 0 , 0 , 0 , 0 ), // #476 {xmm|ymm|zmm, m32|mem|xmm}
- ROW(4, 1, 1, 0, 104, 50 , 65 , 10 , 0 , 0 ), // #477 {xmm|k, xmm, xmm|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 104, 50 , 109, 10 , 0 , 0 ), // #478 {xmm|k, xmm, xmm|m32|mem, i8|u8}
- ROW(3, 1, 1, 0, 50 , 50 , 155, 0 , 0 , 0 ), // #479 {xmm, xmm, r32|m32|mem|r64|m64}
- ROW(3, 1, 1, 0, 51 , 173, 10 , 0 , 0 , 0 ), // #480 {xmm|m128|mem, ymm|zmm, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 65 , 10 , 0 , 0 ), // #481 {xmm, xmm, xmm|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 109, 10 , 0 , 0 ), // #482 {xmm, xmm, xmm|m32|mem, i8|u8}
- ROW(3, 1, 1, 0, 106, 175, 10 , 0 , 0 , 0 ), // #483 {k, xmm|m128|ymm|m256|zmm|m512, i8|u8}
- ROW(3, 1, 1, 0, 106, 65 , 10 , 0 , 0 , 0 ), // #484 {k, xmm|m64|mem, i8|u8}
- ROW(3, 1, 1, 0, 106, 109, 10 , 0 , 0 , 0 ), // #485 {k, xmm|m32|mem, i8|u8}
- ROW(1, 1, 1, 0, 68 , 0 , 0 , 0 , 0 , 0 ), // #486 {vm32y}
- ROW(1, 1, 1, 0, 69 , 0 , 0 , 0 , 0 , 0 ), // #487 {vm32z}
- ROW(1, 1, 1, 0, 72 , 0 , 0 , 0 , 0 , 0 ), // #488 {vm64z}
- ROW(4, 1, 1, 0, 56 , 56 , 54 , 10 , 0 , 0 ), // #489 {zmm, zmm, ymm|m256|mem, i8|u8}
- ROW(2, 1, 1, 0, 6 , 96 , 0 , 0 , 0 , 0 ), // #490 {r32, xmm|ymm}
- ROW(2, 1, 1, 0, 174, 176, 0 , 0 , 0 , 0 ), // #491 {xmm|ymm|zmm, xmm|m8|mem|r32}
- ROW(2, 1, 1, 0, 174, 177, 0 , 0 , 0 , 0 ), // #492 {xmm|ymm|zmm, xmm|m32|mem|r32}
- ROW(2, 1, 1, 0, 174, 106, 0 , 0 , 0 , 0 ), // #493 {xmm|ymm|zmm, k}
- ROW(2, 1, 1, 0, 174, 178, 0 , 0 , 0 , 0 ), // #494 {xmm|ymm|zmm, xmm|m16|mem|r32}
- ROW(3, 1, 1, 0, 135, 50 , 10 , 0 , 0 , 0 ), // #495 {r32|m16|mem, xmm, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 131, 10 , 0 , 0 ), // #496 {xmm, xmm, r32|m8|mem, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 28 , 10 , 0 , 0 ), // #497 {xmm, xmm, r32|m32|mem, i8|u8}
- ROW(4, 0, 1, 0, 50 , 50 , 15 , 10 , 0 , 0 ), // #498 {xmm, xmm, r64|m64|mem, i8|u8}
- ROW(4, 1, 1, 0, 50 , 50 , 135, 10 , 0 , 0 ), // #499 {xmm, xmm, r32|m16|mem, i8|u8}
- ROW(2, 1, 1, 0, 106, 174, 0 , 0 , 0 , 0 ), // #500 {k, xmm|ymm|zmm}
- ROW(1, 1, 1, 0, 124, 0 , 0 , 0 , 0 , 0 ), // #501 {rel16|rel32}
- ROW(3, 1, 1, 2, 113, 35 , 36 , 0 , 0 , 0 ), // #502 {mem, <edx>, <eax>}
- ROW(3, 0, 1, 2, 113, 35 , 36 , 0 , 0 , 0 ) // #503 {mem, <edx>, <eax>}
+ ROW(1, 1, 0, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #383 {<ax>}
+ ROW(2, 1, 0, 1, 33 , 10 , 0 , 0 , 0 , 0 ), // #384 {<ax>, i8|u8}
+ ROW(2, 1, 0, 0, 27 , 4 , 0 , 0 , 0 , 0 ), // #385 {r16|m16|mem, r16}
+ ROW(3, 1, 1, 1, 50 , 51 , 147, 0 , 0 , 0 ), // #386 {xmm, xmm|m128|mem, <xmm0>}
+ ROW(2, 1, 1, 0, 111, 148, 0 , 0 , 0 , 0 ), // #387 {bnd, mib}
+ ROW(2, 1, 1, 0, 111, 113, 0 , 0 , 0 , 0 ), // #388 {bnd, mem}
+ ROW(2, 1, 1, 0, 148, 111, 0 , 0 , 0 , 0 ), // #389 {mib, bnd}
+ ROW(1, 1, 1, 0, 149, 0 , 0 , 0 , 0 , 0 ), // #390 {r16|r32|r64}
+ ROW(1, 1, 1, 1, 33 , 0 , 0 , 0 , 0 , 0 ), // #391 {<ax>}
+ ROW(2, 1, 1, 2, 35 , 36 , 0 , 0 , 0 , 0 ), // #392 {<edx>, <eax>}
+ ROW(1, 1, 1, 0, 150, 0 , 0 , 0 , 0 , 0 ), // #393 {mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+ ROW(1, 1, 1, 0, 30 , 0 , 0 , 0 , 0 , 0 ), // #394 {m64|mem}
+ ROW(0, 0, 1, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #395 {}
+ ROW(1, 1, 1, 1, 151, 0 , 0 , 0 , 0 , 0 ), // #396 {<ds:[mem|m512|memBase|zax]>}
+ ROW(3, 1, 1, 0, 50 , 65 , 10 , 0 , 0 , 0 ), // #397 {xmm, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 107, 10 , 0 , 0 , 0 ), // #398 {xmm, xmm|m32|mem, i8|u8}
+ ROW(5, 0, 1, 4, 52 , 37 , 38 , 152, 153, 0 ), // #399 {m128|mem, <rdx>, <rax>, <rcx>, <rbx>}
+ ROW(5, 1, 1, 4, 30 , 35 , 36 , 121, 154, 0 ), // #400 {m64|mem, <edx>, <eax>, <ecx>, <ebx>}
+ ROW(4, 1, 1, 4, 36 , 154, 121, 35 , 0 , 0 ), // #401 {<eax>, <ebx>, <ecx>, <edx>}
+ ROW(2, 0, 1, 2, 37 , 38 , 0 , 0 , 0 , 0 ), // #402 {<rdx>, <rax>}
+ ROW(2, 1, 1, 0, 62 , 51 , 0 , 0 , 0 , 0 ), // #403 {mm, xmm|m128|mem}
+ ROW(2, 1, 1, 0, 50 , 141, 0 , 0 , 0 , 0 ), // #404 {xmm, mm|m64|mem}
+ ROW(2, 1, 1, 0, 62 , 65 , 0 , 0 , 0 , 0 ), // #405 {mm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 139, 65 , 0 , 0 , 0 , 0 ), // #406 {r32|r64, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 50 , 155, 0 , 0 , 0 , 0 ), // #407 {xmm, r32|m32|mem|r64|m64}
+ ROW(2, 1, 1, 0, 139, 107, 0 , 0 , 0 , 0 ), // #408 {r32|r64, xmm|m32|mem}
+ ROW(2, 1, 1, 2, 34 , 33 , 0 , 0 , 0 , 0 ), // #409 {<dx>, <ax>}
+ ROW(1, 1, 1, 1, 36 , 0 , 0 , 0 , 0 , 0 ), // #410 {<eax>}
+ ROW(2, 1, 1, 0, 12 , 10 , 0 , 0 , 0 , 0 ), // #411 {i16|u16, i8|u8}
+ ROW(3, 1, 1, 0, 28 , 50 , 10 , 0 , 0 , 0 ), // #412 {r32|m32|mem, xmm, i8|u8}
+ ROW(1, 1, 1, 0, 102, 0 , 0 , 0 , 0 , 0 ), // #413 {m80|mem}
+ ROW(1, 1, 1, 0, 156, 0 , 0 , 0 , 0 , 0 ), // #414 {m16|m32}
+ ROW(1, 1, 1, 0, 157, 0 , 0 , 0 , 0 , 0 ), // #415 {m16|m32|m64}
+ ROW(1, 1, 1, 0, 158, 0 , 0 , 0 , 0 , 0 ), // #416 {m32|m64|m80|st}
+ ROW(1, 1, 1, 0, 21 , 0 , 0 , 0 , 0 , 0 ), // #417 {m16|mem}
+ ROW(1, 1, 1, 0, 113, 0 , 0 , 0 , 0 , 0 ), // #418 {mem}
+ ROW(1, 1, 1, 0, 159, 0 , 0 , 0 , 0 , 0 ), // #419 {ax|m16|mem}
+ ROW(1, 0, 1, 0, 113, 0 , 0 , 0 , 0 , 0 ), // #420 {mem}
+ ROW(2, 1, 1, 1, 10 , 36 , 0 , 0 , 0 , 0 ), // #421 {i8|u8, <eax>}
+ ROW(2, 1, 1, 0, 160, 161, 0 , 0 , 0 , 0 ), // #422 {al|ax|eax, i8|u8|dx}
+ ROW(1, 1, 1, 0, 6 , 0 , 0 , 0 , 0 , 0 ), // #423 {r32}
+ ROW(2, 1, 1, 0, 162, 163, 0 , 0 , 0 , 0 ), // #424 {es:[m8|memBase|zdi|m16|m32], dx}
+ ROW(1, 1, 1, 0, 10 , 0 , 0 , 0 , 0 , 0 ), // #425 {i8|u8}
+ ROW(0, 1, 0, 0, 0 , 0 , 0 , 0 , 0 , 0 ), // #426 {}
+ ROW(3, 1, 1, 0, 106, 106, 106, 0 , 0 , 0 ), // #427 {k, k, k}
+ ROW(2, 1, 1, 0, 106, 106, 0 , 0 , 0 , 0 ), // #428 {k, k}
+ ROW(3, 1, 1, 0, 106, 106, 10 , 0 , 0 , 0 ), // #429 {k, k, i8|u8}
+ ROW(1, 1, 1, 1, 164, 0 , 0 , 0 , 0 , 0 ), // #430 {<ah>}
+ ROW(1, 1, 1, 0, 29 , 0 , 0 , 0 , 0 , 0 ), // #431 {m32|mem}
+ ROW(1, 0, 1, 0, 58 , 0 , 0 , 0 , 0 , 0 ), // #432 {m512|mem}
+ ROW(2, 1, 1, 0, 149, 150, 0 , 0 , 0 , 0 ), // #433 {r16|r32|r64, mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+ ROW(1, 1, 1, 0, 27 , 0 , 0 , 0 , 0 , 0 ), // #434 {r16|m16|mem}
+ ROW(1, 1, 1, 0, 139, 0 , 0 , 0 , 0 , 0 ), // #435 {r32|r64}
+ ROW(3, 1, 1, 0, 139, 28 , 14 , 0 , 0 , 0 ), // #436 {r32|r64, r32|m32|mem, i32|u32}
+ ROW(3, 1, 1, 1, 50 , 50 , 165, 0 , 0 , 0 ), // #437 {xmm, xmm, <ds:[mem|m128|memBase|zdi]>}
+ ROW(3, 1, 1, 1, 62 , 62 , 166, 0 , 0 , 0 ), // #438 {mm, mm, <ds:[mem|m64|memBase|zdi]>}
+ ROW(3, 1, 1, 3, 167, 121, 35 , 0 , 0 , 0 ), // #439 {<ds:[mem|memBase|zax]>, <ecx>, <edx>}
+ ROW(2, 1, 1, 0, 119, 58 , 0 , 0 , 0 , 0 ), // #440 {es:[mem|m512|memBase], m512|mem}
+ ROW(2, 1, 1, 0, 62 , 50 , 0 , 0 , 0 , 0 ), // #441 {mm, xmm}
+ ROW(2, 1, 1, 0, 6 , 50 , 0 , 0 , 0 , 0 ), // #442 {r32, xmm}
+ ROW(2, 1, 1, 0, 30 , 62 , 0 , 0 , 0 , 0 ), // #443 {m64|mem, mm}
+ ROW(2, 1, 1, 0, 50 , 62 , 0 , 0 , 0 , 0 ), // #444 {xmm, mm}
+ ROW(2, 1, 1, 2, 36 , 121, 0 , 0 , 0 , 0 ), // #445 {<eax>, <ecx>}
+ ROW(3, 1, 1, 3, 36 , 121, 154, 0 , 0 , 0 ), // #446 {<eax>, <ecx>, <ebx>}
+ ROW(2, 1, 1, 0, 168, 160, 0 , 0 , 0 , 0 ), // #447 {u8|dx, al|ax|eax}
+ ROW(2, 1, 1, 0, 163, 169, 0 , 0 , 0 , 0 ), // #448 {dx, ds:[m8|memBase|zsi|m16|m32]}
+ ROW(6, 1, 1, 3, 50 , 51 , 10 , 121, 36 , 35 ), // #449 {xmm, xmm|m128|mem, i8|u8, <ecx>, <eax>, <edx>}
+ ROW(6, 1, 1, 3, 50 , 51 , 10 , 147, 36 , 35 ), // #450 {xmm, xmm|m128|mem, i8|u8, <xmm0>, <eax>, <edx>}
+ ROW(4, 1, 1, 1, 50 , 51 , 10 , 121, 0 , 0 ), // #451 {xmm, xmm|m128|mem, i8|u8, <ecx>}
+ ROW(4, 1, 1, 1, 50 , 51 , 10 , 147, 0 , 0 ), // #452 {xmm, xmm|m128|mem, i8|u8, <xmm0>}
+ ROW(3, 1, 1, 0, 131, 50 , 10 , 0 , 0 , 0 ), // #453 {r32|m8|mem, xmm, i8|u8}
+ ROW(3, 0, 1, 0, 15 , 50 , 10 , 0 , 0 , 0 ), // #454 {r64|m64|mem, xmm, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 131, 10 , 0 , 0 , 0 ), // #455 {xmm, r32|m8|mem, i8|u8}
+ ROW(3, 1, 1, 0, 50 , 28 , 10 , 0 , 0 , 0 ), // #456 {xmm, r32|m32|mem, i8|u8}
+ ROW(3, 0, 1, 0, 50 , 15 , 10 , 0 , 0 , 0 ), // #457 {xmm, r64|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 64 , 135, 10 , 0 , 0 , 0 ), // #458 {mm|xmm, r32|m16|mem, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 64 , 0 , 0 , 0 , 0 ), // #459 {r32, mm|xmm}
+ ROW(2, 1, 1, 0, 50 , 10 , 0 , 0 , 0 , 0 ), // #460 {xmm, i8|u8}
+ ROW(1, 1, 1, 0, 155, 0 , 0 , 0 , 0 , 0 ), // #461 {r32|m32|mem|r64|m64}
+ ROW(2, 1, 1, 0, 31 , 103, 0 , 0 , 0 , 0 ), // #462 {r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, cl|i8|u8}
+ ROW(1, 0, 1, 0, 139, 0 , 0 , 0 , 0 , 0 ), // #463 {r32|r64}
+ ROW(3, 1, 1, 3, 35 , 36 , 121, 0 , 0 , 0 ), // #464 {<edx>, <eax>, <ecx>}
+ ROW(1, 1, 1, 0, 1 , 0 , 0 , 0 , 0 , 0 ), // #465 {r8lo|r8hi|m8|mem}
+ ROW(1, 1, 1, 0, 170, 0 , 0 , 0 , 0 , 0 ), // #466 {r16|m16|mem|r32|r64}
+ ROW(3, 0, 1, 0, 171, 171, 171, 0 , 0 , 0 ), // #467 {tmm, tmm, tmm}
+ ROW(2, 0, 1, 0, 171, 172, 0 , 0 , 0 , 0 ), // #468 {tmm, tmem}
+ ROW(2, 0, 1, 0, 172, 171, 0 , 0 , 0 , 0 ), // #469 {tmem, tmm}
+ ROW(1, 0, 1, 0, 171, 0 , 0 , 0 , 0 , 0 ), // #470 {tmm}
+ ROW(3, 1, 1, 2, 6 , 35 , 36 , 0 , 0 , 0 ), // #471 {r32, <edx>, <eax>}
+ ROW(1, 1, 1, 0, 173, 0 , 0 , 0 , 0 , 0 ), // #472 {ds:[mem|memBase]}
+ ROW(6, 1, 1, 0, 56 , 56 , 56 , 56 , 56 , 52 ), // #473 {zmm, zmm, zmm, zmm, zmm, m128|mem}
+ ROW(6, 1, 1, 0, 50 , 50 , 50 , 50 , 50 , 52 ), // #474 {xmm, xmm, xmm, xmm, xmm, m128|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 65 , 0 , 0 , 0 ), // #475 {xmm, xmm, xmm|m64|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 110, 0 , 0 , 0 ), // #476 {xmm, xmm, xmm|m16|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 107, 0 , 0 , 0 ), // #477 {xmm, xmm, xmm|m32|mem}
+ ROW(2, 1, 1, 0, 53 , 52 , 0 , 0 , 0 , 0 ), // #478 {ymm, m128|mem}
+ ROW(2, 1, 1, 0, 174, 65 , 0 , 0 , 0 , 0 ), // #479 {ymm|zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 174, 52 , 0 , 0 , 0 , 0 ), // #480 {ymm|zmm, m128|mem}
+ ROW(2, 1, 1, 0, 56 , 55 , 0 , 0 , 0 , 0 ), // #481 {zmm, m256|mem}
+ ROW(2, 1, 1, 0, 175, 65 , 0 , 0 , 0 , 0 ), // #482 {xmm|ymm|zmm, xmm|m64|mem}
+ ROW(2, 1, 1, 0, 175, 107, 0 , 0 , 0 , 0 ), // #483 {xmm|ymm|zmm, m32|mem|xmm}
+ ROW(4, 1, 1, 0, 104, 50 , 65 , 10 , 0 , 0 ), // #484 {xmm|k, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 106, 50 , 110, 10 , 0 , 0 ), // #485 {k, xmm, xmm|m16|mem, i8|u8}
+ ROW(4, 1, 1, 0, 104, 50 , 107, 10 , 0 , 0 ), // #486 {xmm|k, xmm, xmm|m32|mem, i8|u8}
+ ROW(2, 1, 1, 0, 50 , 176, 0 , 0 , 0 , 0 ), // #487 {xmm, xmm|m128|ymm|m256|zmm|m512}
+ ROW(2, 1, 1, 0, 139, 110, 0 , 0 , 0 , 0 ), // #488 {r32|r64, xmm|m16|mem}
+ ROW(3, 1, 1, 0, 50 , 50 , 155, 0 , 0 , 0 ), // #489 {xmm, xmm, r32|m32|mem|r64|m64}
+ ROW(3, 1, 1, 0, 51 , 174, 10 , 0 , 0 , 0 ), // #490 {xmm|m128|mem, ymm|zmm, i8|u8}
+ ROW(4, 1, 1, 0, 50 , 50 , 65 , 10 , 0 , 0 ), // #491 {xmm, xmm, xmm|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 50 , 50 , 107, 10 , 0 , 0 ), // #492 {xmm, xmm, xmm|m32|mem, i8|u8}
+ ROW(3, 1, 1, 0, 106, 176, 10 , 0 , 0 , 0 ), // #493 {k, xmm|m128|ymm|m256|zmm|m512, i8|u8}
+ ROW(3, 1, 1, 0, 106, 65 , 10 , 0 , 0 , 0 ), // #494 {k, xmm|m64|mem, i8|u8}
+ ROW(3, 1, 1, 0, 106, 110, 10 , 0 , 0 , 0 ), // #495 {k, xmm|m16|mem, i8|u8}
+ ROW(3, 1, 1, 0, 106, 107, 10 , 0 , 0 , 0 ), // #496 {k, xmm|m32|mem, i8|u8}
+ ROW(1, 1, 1, 0, 68 , 0 , 0 , 0 , 0 , 0 ), // #497 {vm32y}
+ ROW(1, 1, 1, 0, 69 , 0 , 0 , 0 , 0 , 0 ), // #498 {vm32z}
+ ROW(1, 1, 1, 0, 72 , 0 , 0 , 0 , 0 , 0 ), // #499 {vm64z}
+ ROW(4, 1, 1, 0, 50 , 50 , 110, 10 , 0 , 0 ), // #500 {xmm, xmm, xmm|m16|mem, i8|u8}
+ ROW(4, 1, 1, 0, 56 , 56 , 54 , 10 , 0 , 0 ), // #501 {zmm, zmm, ymm|m256|mem, i8|u8}
+ ROW(2, 1, 1, 0, 6 , 96 , 0 , 0 , 0 , 0 ), // #502 {r32, xmm|ymm}
+ ROW(2, 1, 1, 0, 175, 177, 0 , 0 , 0 , 0 ), // #503 {xmm|ymm|zmm, xmm|m8|mem|r32}
+ ROW(2, 1, 1, 0, 175, 178, 0 , 0 , 0 , 0 ), // #504 {xmm|ymm|zmm, xmm|m32|mem|r32}
+ ROW(2, 1, 1, 0, 175, 106, 0 , 0 , 0 , 0 ), // #505 {xmm|ymm|zmm, k}
+ ROW(2, 1, 1, 0, 175, 179, 0 , 0 , 0 , 0 ), // #506 {xmm|ymm|zmm, xmm|m16|mem|r32}
+ ROW(3, 1, 1, 0, 135, 50 , 10 , 0 , 0 , 0 ), // #507 {r32|m16|mem, xmm, i8|u8}
+ ROW(4, 1, 1, 0, 50 , 50 , 131, 10 , 0 , 0 ), // #508 {xmm, xmm, r32|m8|mem, i8|u8}
+ ROW(4, 1, 1, 0, 50 , 50 , 28 , 10 , 0 , 0 ), // #509 {xmm, xmm, r32|m32|mem, i8|u8}
+ ROW(4, 0, 1, 0, 50 , 50 , 15 , 10 , 0 , 0 ), // #510 {xmm, xmm, r64|m64|mem, i8|u8}
+ ROW(4, 1, 1, 0, 50 , 50 , 135, 10 , 0 , 0 ), // #511 {xmm, xmm, r32|m16|mem, i8|u8}
+ ROW(2, 1, 1, 0, 106, 175, 0 , 0 , 0 , 0 ), // #512 {k, xmm|ymm|zmm}
+ ROW(1, 1, 1, 0, 124, 0 , 0 , 0 , 0 , 0 ), // #513 {rel16|rel32}
+ ROW(3, 1, 1, 2, 113, 35 , 36 , 0 , 0 , 0 ), // #514 {mem, <edx>, <eax>}
+ ROW(3, 0, 1, 2, 113, 35 , 36 , 0 , 0 , 0 ) // #515 {mem, <edx>, <eax>}
};
#undef ROW
-#define ROW(flags, mFlags, extFlags, regId) { uint32_t(flags), uint16_t(mFlags), uint8_t(extFlags), uint8_t(regId) }
-#define F(VAL) InstDB::kOp##VAL
-#define M(VAL) InstDB::kMemOp##VAL
+#define ROW(opFlags, regId) { opFlags, uint8_t(regId) }
+#define F(VAL) uint64_t(InstDB::OpFlags::k##VAL)
const InstDB::OpSignature InstDB::_opSignatureTable[] = {
- ROW(0, 0, 0, 0xFF),
- ROW(F(GpbLo) | F(GpbHi) | F(Mem), M(M8) | M(Any), 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi), 0, 0, 0x00),
- ROW(F(Gpw) | F(SReg) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(Gpw), 0, 0, 0x00),
- ROW(F(Gpd) | F(SReg) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Gpd), 0, 0, 0x00),
- ROW(F(Gpq) | F(SReg) | F(CReg) | F(DReg) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpq), 0, 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi) | F(Mem), M(M8), 0, 0x00),
- ROW(F(I8) | F(U8), 0, 0, 0x00),
- ROW(F(Gpw) | F(Mem), M(M16), 0, 0x00),
- ROW(F(I16) | F(U16), 0, 0, 0x00),
- ROW(F(Gpd) | F(Mem), M(M32), 0, 0x00),
- ROW(F(I32) | F(U32), 0, 0, 0x00),
- ROW(F(Gpq) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(I32), 0, 0, 0x00),
- ROW(F(SReg) | F(CReg) | F(DReg) | F(Mem) | F(I64) | F(U64), M(M64) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M8) | M(Any), 0, 0x00),
- ROW(F(SReg) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(SReg) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(SReg), 0, 0, 0x00),
- ROW(F(CReg) | F(DReg), 0, 0, 0x00),
- ROW(F(Gpq) | F(I32), 0, 0, 0x00),
- ROW(F(Gpw) | F(Gpd) | F(Gpq) | F(Mem), M(M16) | M(M32) | M(M64) | M(Any), 0, 0x00),
- ROW(F(I8), 0, 0, 0x00),
- ROW(F(Gpw) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi) | F(Gpw) | F(Gpd) | F(Gpq) | F(Mem), M(M8) | M(M16) | M(M32) | M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpq) | F(Mem) | F(I32) | F(U32), M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpw) | F(Implicit), 0, 0, 0x01),
- ROW(F(Gpw) | F(Implicit), 0, 0, 0x04),
- ROW(F(Gpd) | F(Implicit), 0, 0, 0x04),
- ROW(F(Gpd) | F(Implicit), 0, 0, 0x01),
- ROW(F(Gpq) | F(Implicit), 0, 0, 0x04),
- ROW(F(Gpq) | F(Implicit), 0, 0, 0x01),
- ROW(F(Gpw) | F(Mem) | F(I8) | F(I16), M(M16) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Mem) | F(I8) | F(I32), M(M32) | M(Any), 0, 0x00),
- ROW(F(Gpq) | F(Mem) | F(I8) | F(I32), M(M64) | M(Any), 0, 0x00),
- ROW(F(I8) | F(I16) | F(U16), 0, 0, 0x00),
- ROW(F(I8) | F(I32) | F(U32), 0, 0, 0x00),
- ROW(F(I8) | F(I32), 0, 0, 0x00),
- ROW(F(I64) | F(U64), 0, 0, 0x00),
- ROW(F(GpbLo), 0, 0, 0x01),
- ROW(F(Gpw), 0, 0, 0x01),
- ROW(F(Gpd), 0, 0, 0x01),
- ROW(F(Gpq), 0, 0, 0x01),
- ROW(F(Xmm), 0, 0, 0x00),
- ROW(F(Xmm) | F(Mem), M(M128) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M128) | M(Any), 0, 0x00),
- ROW(F(Ymm), 0, 0, 0x00),
- ROW(F(Ymm) | F(Mem), M(M256) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M256) | M(Any), 0, 0x00),
- ROW(F(Zmm), 0, 0, 0x00),
- ROW(F(Zmm) | F(Mem), M(M512) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M512) | M(Any), 0, 0x00),
- ROW(F(Xmm) | F(Mem) | F(I8) | F(U8), M(M128) | M(Any), 0, 0x00),
- ROW(F(Ymm) | F(Mem) | F(I8) | F(U8), M(M256) | M(Any), 0, 0x00),
- ROW(F(Zmm) | F(Mem) | F(I8) | F(U8), M(M512) | M(Any), 0, 0x00),
- ROW(F(Mm), 0, 0, 0x00),
- ROW(F(Gpq) | F(Mm) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Xmm) | F(Mm), 0, 0, 0x00),
- ROW(F(Xmm) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpw) | F(Gpd) | F(Gpq) | F(Mem), M(M16) | M(M32) | M(M64), 0, 0x00),
- ROW(F(Vm), M(Vm32x), 0, 0x00),
- ROW(F(Vm), M(Vm32y), 0, 0x00),
- ROW(F(Vm), M(Vm32z), 0, 0x00),
- ROW(F(Vm), M(Vm64x), 0, 0x00),
- ROW(F(Vm), M(Vm64y), 0, 0x00),
- ROW(F(Vm), M(Vm64z), 0, 0x00),
- ROW(F(Mem) | F(Implicit), M(M8) | M(BaseOnly) | M(Ds), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M8) | M(BaseOnly) | M(Es), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M16) | M(BaseOnly) | M(Ds), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M16) | M(BaseOnly) | M(Es), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M32) | M(BaseOnly) | M(Ds), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M32) | M(BaseOnly) | M(Es), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M64) | M(BaseOnly) | M(Ds), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M64) | M(BaseOnly) | M(Es), 0, 0x80),
- ROW(F(GpbLo) | F(Implicit), 0, 0, 0x01),
- ROW(F(Mem) | F(Implicit), M(M8) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M16) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M32) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x40),
- ROW(F(Mem) | F(Implicit), M(M64) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x40),
- ROW(F(Gpw) | F(Gpq) | F(Mem), M(M16) | M(M64), 0, 0x00),
- ROW(F(SReg), 0, 0, 0x1A),
- ROW(F(SReg), 0, 0, 0x60),
- ROW(F(Gpw) | F(Gpq) | F(Mem) | F(I8) | F(I16) | F(I32), M(M16) | M(M64), 0, 0x00),
- ROW(F(Gpd) | F(Mem) | F(I32) | F(U32), M(M32), 0, 0x00),
- ROW(F(SReg), 0, 0, 0x1E),
- ROW(F(Mem) | F(Implicit), M(M8) | M(BaseOnly) | M(Es) | M(Any), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M16) | M(BaseOnly) | M(Es) | M(Any), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M32) | M(BaseOnly) | M(Es) | M(Any), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M64) | M(BaseOnly) | M(Es) | M(Any), 0, 0x80),
- ROW(F(Xmm) | F(Ymm), 0, 0, 0x00),
- ROW(F(I4) | F(U4), 0, 0, 0x00),
- ROW(F(Mem), M(M32) | M(M64), 0, 0x00),
- ROW(F(St), 0, 0, 0x01),
- ROW(F(St), 0, 0, 0x00),
- ROW(F(Mem), M(M48) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M80) | M(Any), 0, 0x00),
- ROW(F(GpbLo) | F(I8) | F(U8), 0, 0, 0x02),
- ROW(F(Xmm) | F(KReg), 0, 0, 0x00),
- ROW(F(Ymm) | F(KReg), 0, 0, 0x00),
- ROW(F(KReg), 0, 0, 0x00),
- ROW(F(Vm), M(Vm64x) | M(Vm64y), 0, 0x00),
- ROW(F(Gpq) | F(Xmm) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Xmm) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Xmm) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(Bnd), 0, 0, 0x00),
- ROW(F(Bnd) | F(Mem), M(Any), 0, 0x00),
- ROW(F(Mem), M(Any), 0, 0x00),
- ROW(F(Gpw) | F(Gpd) | F(Mem) | F(I32) | F(I64) | F(Rel32), M(M16) | M(M32), 0, 0x00),
- ROW(F(Gpq) | F(Mem) | F(I32) | F(I64) | F(Rel32), M(M64) | M(Any), 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi) | F(Gpw) | F(Gpd) | F(Mem), M(M8) | M(M16) | M(M32), 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi) | F(Gpq) | F(Mem), M(M8) | M(M64), 0, 0x00),
- ROW(F(Gpw) | F(Gpd), 0, 0, 0x00),
- ROW(F(Mem), M(M512) | M(BaseOnly) | M(Es) | M(Any), 0, 0x00),
- ROW(F(St) | F(Mem), M(M32) | M(M64), 0, 0x00),
- ROW(F(Gpd) | F(Implicit), 0, 0, 0x02),
- ROW(F(Gpd) | F(Gpq) | F(Implicit), 0, 0, 0x01),
- ROW(F(I32) | F(I64) | F(Rel8) | F(Rel32), 0, 0, 0x00),
- ROW(F(I32) | F(I64) | F(Rel32), 0, 0, 0x00),
- ROW(F(Gpw) | F(Gpd) | F(Implicit), 0, 0, 0x02),
- ROW(F(I32) | F(I64) | F(Rel8), 0, 0, 0x00),
- ROW(F(Gpd) | F(Gpq) | F(Implicit), 0, 0, 0x02),
- ROW(F(Gpq) | F(Mem) | F(I32) | F(I64) | F(Rel8) | F(Rel32), M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Mem) | F(I32) | F(I64) | F(Rel32), M(M32) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(KReg) | F(Mem), M(M8) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Mem), M(M8) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(KReg) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Gpq) | F(KReg) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(KReg) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(I16), 0, 0, 0x00),
- ROW(F(I16) | F(I32), 0, 0, 0x00),
- ROW(F(Mem), M(M32) | M(M48) | M(M80) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Gpq), 0, 0, 0x00),
- ROW(F(GpbLo) | F(GpbHi) | F(Gpw) | F(Mem), M(M8) | M(M16), 0, 0x00),
- ROW(F(Mm) | F(Mem), M(M64) | M(Any), 0, 0x00),
- ROW(F(Mm) | F(Mem) | F(I8) | F(U8), M(M64) | M(Any), 0, 0x00),
- ROW(F(Mm) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(U16), 0, 0, 0x00),
- ROW(F(Xmm) | F(Ymm) | F(Mem), M(M128) | M(M256), 0, 0x00),
- ROW(F(Xmm) | F(I8) | F(U8), 0, 0, 0x00),
- ROW(F(Xmm) | F(Implicit), 0, 0, 0x01),
- ROW(F(Mem), M(Mib), 0, 0x00),
- ROW(F(Gpw) | F(Gpd) | F(Gpq), 0, 0, 0x00),
- ROW(F(Mem), M(M8) | M(M16) | M(M32) | M(M48) | M(M64) | M(M80) | M(M128) | M(M256) | M(M512) | M(M1024) | M(Any), 0, 0x00),
- ROW(F(Mem) | F(Implicit), M(M512) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x01),
- ROW(F(Gpq) | F(Implicit), 0, 0, 0x02),
- ROW(F(Gpq) | F(Implicit), 0, 0, 0x08),
- ROW(F(Gpd) | F(Implicit), 0, 0, 0x08),
- ROW(F(Gpd) | F(Gpq) | F(Mem), M(M32) | M(M64) | M(Any), 0, 0x00),
- ROW(F(Mem), M(M16) | M(M32), 0, 0x00),
- ROW(F(Mem), M(M16) | M(M32) | M(M64), 0, 0x00),
- ROW(F(St) | F(Mem), M(M32) | M(M64) | M(M80), 0, 0x00),
- ROW(F(Gpw) | F(Mem), M(M16) | M(Any), 0, 0x01),
- ROW(F(GpbLo) | F(Gpw) | F(Gpd), 0, 0, 0x01),
- ROW(F(Gpw) | F(I8) | F(U8), 0, 0, 0x04),
- ROW(F(Mem), M(M8) | M(M16) | M(M32) | M(BaseOnly) | M(Es), 0, 0x80),
- ROW(F(Gpw), 0, 0, 0x04),
- ROW(F(GpbHi) | F(Implicit), 0, 0, 0x01),
- ROW(F(Mem) | F(Implicit), M(M128) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(M64) | M(BaseOnly) | M(Ds) | M(Any), 0, 0x80),
- ROW(F(Mem) | F(Implicit), M(BaseOnly) | M(Ds) | M(Any), 0, 0x01),
- ROW(F(Gpw) | F(U8), 0, 0, 0x04),
- ROW(F(Mem), M(M8) | M(M16) | M(M32) | M(BaseOnly) | M(Ds), 0, 0x40),
- ROW(F(Gpw) | F(Gpd) | F(Gpq) | F(Mem), M(M16) | M(Any), 0, 0x00),
- ROW(F(Tmm), 0, 0, 0x00),
- ROW(F(Mem), M(BaseOnly) | M(Ds) | M(Any), 0, 0x00),
- ROW(F(Ymm) | F(Zmm), 0, 0, 0x00),
- ROW(F(Xmm) | F(Ymm) | F(Zmm), 0, 0, 0x00),
- ROW(F(Xmm) | F(Ymm) | F(Zmm) | F(Mem), M(M128) | M(M256) | M(M512), 0, 0x00),
- ROW(F(Gpd) | F(Xmm) | F(Mem), M(M8) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Xmm) | F(Mem), M(M32) | M(Any), 0, 0x00),
- ROW(F(Gpd) | F(Xmm) | F(Mem), M(M16) | M(Any), 0, 0x00)
+ ROW(0, 0xFF),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(MemUnspecified) | F(Mem8), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi), 0x00),
+ ROW(F(RegGpw) | F(RegSReg) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegGpw), 0x00),
+ ROW(F(RegGpd) | F(RegSReg) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(RegGpd), 0x00),
+ ROW(F(RegGpq) | F(RegSReg) | F(RegCReg) | F(RegDReg) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegGpq), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(Mem8), 0x00),
+ ROW(F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegGpw) | F(Mem16), 0x00),
+ ROW(F(ImmI16) | F(ImmU16), 0x00),
+ ROW(F(RegGpd) | F(Mem32), 0x00),
+ ROW(F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(ImmI32), 0x00),
+ ROW(F(RegSReg) | F(RegCReg) | F(RegDReg) | F(MemUnspecified) | F(Mem64) | F(ImmI64) | F(ImmU64), 0x00),
+ ROW(F(MemUnspecified) | F(Mem8), 0x00),
+ ROW(F(RegSReg) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegSReg) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegSReg), 0x00),
+ ROW(F(RegCReg) | F(RegDReg), 0x00),
+ ROW(F(RegGpq) | F(ImmI32), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(RegGpq) | F(MemUnspecified) | F(Mem16) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(ImmI8), 0x00),
+ ROW(F(RegGpw) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(RegGpw) | F(RegGpd) | F(RegGpq) | F(MemUnspecified) | F(Mem8) | F(Mem16) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64) | F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(RegGpw) | F(FlagImplicit), 0x01),
+ ROW(F(RegGpw) | F(FlagImplicit), 0x04),
+ ROW(F(RegGpd) | F(FlagImplicit), 0x04),
+ ROW(F(RegGpd) | F(FlagImplicit), 0x01),
+ ROW(F(RegGpq) | F(FlagImplicit), 0x04),
+ ROW(F(RegGpq) | F(FlagImplicit), 0x01),
+ ROW(F(RegGpw) | F(MemUnspecified) | F(Mem16) | F(ImmI8) | F(ImmI16), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem32) | F(ImmI8) | F(ImmI32), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64) | F(ImmI8) | F(ImmI32), 0x00),
+ ROW(F(ImmI8) | F(ImmI16) | F(ImmU16), 0x00),
+ ROW(F(ImmI8) | F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(ImmI8) | F(ImmI32), 0x00),
+ ROW(F(ImmI64) | F(ImmU64), 0x00),
+ ROW(F(RegGpbLo), 0x01),
+ ROW(F(RegGpw), 0x01),
+ ROW(F(RegGpd), 0x01),
+ ROW(F(RegGpq), 0x01),
+ ROW(F(RegXmm), 0x00),
+ ROW(F(RegXmm) | F(MemUnspecified) | F(Mem128), 0x00),
+ ROW(F(MemUnspecified) | F(Mem128), 0x00),
+ ROW(F(RegYmm), 0x00),
+ ROW(F(RegYmm) | F(MemUnspecified) | F(Mem256), 0x00),
+ ROW(F(MemUnspecified) | F(Mem256), 0x00),
+ ROW(F(RegZmm), 0x00),
+ ROW(F(RegZmm) | F(MemUnspecified) | F(Mem512), 0x00),
+ ROW(F(MemUnspecified) | F(Mem512), 0x00),
+ ROW(F(RegXmm) | F(MemUnspecified) | F(Mem128) | F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegYmm) | F(MemUnspecified) | F(Mem256) | F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegZmm) | F(MemUnspecified) | F(Mem512) | F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegMm), 0x00),
+ ROW(F(RegGpq) | F(RegMm) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegXmm) | F(RegMm), 0x00),
+ ROW(F(RegXmm) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(RegGpq) | F(Mem16) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(Vm32x), 0x00),
+ ROW(F(Vm32y), 0x00),
+ ROW(F(Vm32z), 0x00),
+ ROW(F(Vm64x), 0x00),
+ ROW(F(Vm64y), 0x00),
+ ROW(F(Vm64z), 0x00),
+ ROW(F(Mem8) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(Mem8) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(Mem16) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(Mem16) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(Mem32) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(Mem32) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(Mem64) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(Mem64) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(RegGpbLo) | F(FlagImplicit), 0x01),
+ ROW(F(MemUnspecified) | F(Mem8) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(MemUnspecified) | F(Mem16) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(MemUnspecified) | F(Mem32) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(MemUnspecified) | F(Mem64) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x40),
+ ROW(F(RegGpw) | F(RegGpq) | F(Mem16) | F(Mem64), 0x00),
+ ROW(F(RegSReg), 0x1A),
+ ROW(F(RegSReg), 0x60),
+ ROW(F(RegGpw) | F(RegGpq) | F(Mem16) | F(Mem64) | F(ImmI8) | F(ImmI16) | F(ImmI32), 0x00),
+ ROW(F(RegGpd) | F(Mem32) | F(ImmI32) | F(ImmU32), 0x00),
+ ROW(F(RegSReg), 0x1E),
+ ROW(F(MemUnspecified) | F(Mem8) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(MemUnspecified) | F(Mem16) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(MemUnspecified) | F(Mem32) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(MemUnspecified) | F(Mem64) | F(FlagMemBase) | F(FlagMemEs) | F(FlagImplicit), 0x80),
+ ROW(F(RegXmm) | F(RegYmm), 0x00),
+ ROW(F(ImmI4) | F(ImmU4), 0x00),
+ ROW(F(Mem32) | F(Mem64), 0x00),
+ ROW(F(RegSt), 0x01),
+ ROW(F(RegSt), 0x00),
+ ROW(F(MemUnspecified) | F(Mem48), 0x00),
+ ROW(F(MemUnspecified) | F(Mem80), 0x00),
+ ROW(F(RegGpbLo) | F(ImmI8) | F(ImmU8), 0x02),
+ ROW(F(RegXmm) | F(RegKReg), 0x00),
+ ROW(F(RegYmm) | F(RegKReg), 0x00),
+ ROW(F(RegKReg), 0x00),
+ ROW(F(RegXmm) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(Vm64x) | F(Vm64y), 0x00),
+ ROW(F(RegGpq) | F(RegXmm) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegXmm) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegBnd), 0x00),
+ ROW(F(RegBnd) | F(MemUnspecified), 0x00),
+ ROW(F(MemUnspecified), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(Mem16) | F(Mem32) | F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64) | F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(RegGpw) | F(RegGpd) | F(Mem8) | F(Mem16) | F(Mem32), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(RegGpq) | F(Mem8) | F(Mem64), 0x00),
+ ROW(F(RegGpw) | F(RegGpd), 0x00),
+ ROW(F(MemUnspecified) | F(Mem512) | F(FlagMemBase) | F(FlagMemEs), 0x00),
+ ROW(F(RegSt) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(RegGpd) | F(FlagImplicit), 0x02),
+ ROW(F(RegGpd) | F(RegGpq) | F(FlagImplicit), 0x01),
+ ROW(F(ImmI32) | F(ImmI64) | F(Rel8) | F(Rel32), 0x00),
+ ROW(F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(FlagImplicit), 0x02),
+ ROW(F(ImmI32) | F(ImmI64) | F(Rel8), 0x00),
+ ROW(F(RegGpd) | F(RegGpq) | F(FlagImplicit), 0x02),
+ ROW(F(RegGpq) | F(MemUnspecified) | F(Mem64) | F(ImmI32) | F(ImmI64) | F(Rel8) | F(Rel32), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem32) | F(ImmI32) | F(ImmI64) | F(Rel32), 0x00),
+ ROW(F(RegGpd) | F(RegKReg) | F(MemUnspecified) | F(Mem8), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem8), 0x00),
+ ROW(F(RegGpd) | F(RegKReg) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(RegGpq) | F(RegKReg) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegGpd) | F(RegKReg) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegGpd) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(ImmI16), 0x00),
+ ROW(F(ImmI16) | F(ImmI32), 0x00),
+ ROW(F(MemUnspecified) | F(Mem32) | F(Mem48) | F(Mem80), 0x00),
+ ROW(F(RegGpd) | F(RegGpq), 0x00),
+ ROW(F(RegGpbLo) | F(RegGpbHi) | F(RegGpw) | F(Mem8) | F(Mem16), 0x00),
+ ROW(F(RegMm) | F(MemUnspecified) | F(Mem64), 0x00),
+ ROW(F(RegMm) | F(MemUnspecified) | F(Mem64) | F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegMm) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(ImmU16), 0x00),
+ ROW(F(RegXmm) | F(RegYmm) | F(Mem128) | F(Mem256), 0x00),
+ ROW(F(RegXmm) | F(ImmI8) | F(ImmU8), 0x00),
+ ROW(F(RegXmm) | F(FlagImplicit), 0x01),
+ ROW(F(MemUnspecified) | F(FlagMib), 0x00),
+ ROW(F(RegGpw) | F(RegGpd) | F(RegGpq), 0x00),
+ ROW(F(MemUnspecified) | F(Mem8) | F(Mem16) | F(Mem32) | F(Mem48) | F(Mem64) | F(Mem80) | F(Mem128) | F(Mem256) | F(Mem512) | F(Mem1024), 0x00),
+ ROW(F(MemUnspecified) | F(Mem512) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x01),
+ ROW(F(RegGpq) | F(FlagImplicit), 0x02),
+ ROW(F(RegGpq) | F(FlagImplicit), 0x08),
+ ROW(F(RegGpd) | F(FlagImplicit), 0x08),
+ ROW(F(RegGpd) | F(RegGpq) | F(MemUnspecified) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(Mem16) | F(Mem32), 0x00),
+ ROW(F(Mem16) | F(Mem32) | F(Mem64), 0x00),
+ ROW(F(RegSt) | F(Mem32) | F(Mem64) | F(Mem80), 0x00),
+ ROW(F(RegGpw) | F(MemUnspecified) | F(Mem16), 0x01),
+ ROW(F(RegGpbLo) | F(RegGpw) | F(RegGpd), 0x01),
+ ROW(F(RegGpw) | F(ImmI8) | F(ImmU8), 0x04),
+ ROW(F(Mem8) | F(Mem16) | F(Mem32) | F(FlagMemBase) | F(FlagMemEs), 0x80),
+ ROW(F(RegGpw), 0x04),
+ ROW(F(RegGpbHi) | F(FlagImplicit), 0x01),
+ ROW(F(MemUnspecified) | F(Mem128) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x80),
+ ROW(F(MemUnspecified) | F(Mem64) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x80),
+ ROW(F(MemUnspecified) | F(FlagMemBase) | F(FlagMemDs) | F(FlagImplicit), 0x01),
+ ROW(F(RegGpw) | F(ImmU8), 0x04),
+ ROW(F(Mem8) | F(Mem16) | F(Mem32) | F(FlagMemBase) | F(FlagMemDs), 0x40),
+ ROW(F(RegGpw) | F(RegGpd) | F(RegGpq) | F(MemUnspecified) | F(Mem16), 0x00),
+ ROW(F(RegTmm), 0x00),
+ ROW(F(MemUnspecified) | F(FlagTMem), 0x00),
+ ROW(F(MemUnspecified) | F(FlagMemBase) | F(FlagMemDs), 0x00),
+ ROW(F(RegYmm) | F(RegZmm), 0x00),
+ ROW(F(RegXmm) | F(RegYmm) | F(RegZmm), 0x00),
+ ROW(F(RegXmm) | F(RegYmm) | F(RegZmm) | F(Mem128) | F(Mem256) | F(Mem512), 0x00),
+ ROW(F(RegGpd) | F(RegXmm) | F(MemUnspecified) | F(Mem8), 0x00),
+ ROW(F(RegGpd) | F(RegXmm) | F(MemUnspecified) | F(Mem32), 0x00),
+ ROW(F(RegGpd) | F(RegXmm) | F(MemUnspecified) | F(Mem16), 0x00)
};
-#undef M
#undef F
#undef ROW
// ----------------------------------------------------------------------------
// ${InstSignatureTable:End}
#endif // !ASMJIT_NO_VALIDATION
-// ============================================================================
-// [asmjit::x86::InstInternal - QueryRWInfo]
-// ============================================================================
+// x86::InstInternal - QueryRWInfo
+// ===============================
// ${InstRWInfoTable:Begin}
// ------------------- Automatically generated, do not edit -------------------
@@ -3621,53 +3762,58 @@ const uint8_t InstDB::rwInfoIndexA[Inst::_kIdCount] = {
0, 0, 0, 0, 0, 62, 63, 63, 63, 58, 60, 0, 0, 0, 9, 0, 0, 4, 4, 5, 6, 0, 0, 4,
4, 5, 6, 0, 0, 64, 65, 66, 66, 67, 47, 24, 36, 67, 52, 66, 66, 68, 69, 69, 70,
71, 71, 72, 72, 59, 59, 67, 59, 59, 71, 71, 73, 48, 52, 74, 48, 7, 7, 47, 75,
- 33, 66, 66, 75, 0, 35, 4, 4, 5, 6, 0, 76, 0, 0, 77, 0, 2, 4, 4, 78, 79, 9,
- 9, 9, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 80, 3, 0, 0, 0, 3, 3,
+ 9, 66, 66, 75, 0, 35, 4, 4, 5, 6, 0, 76, 0, 0, 77, 0, 2, 4, 4, 78, 79, 9, 9,
+ 9, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 80, 3, 0, 0, 0, 3, 3,
4, 3, 0, 0, 3, 3, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 27, 80, 80, 80, 27, 27, 80, 80, 80, 3, 3, 3, 81, 3, 3, 3,
27, 27, 0, 0, 0, 0, 3, 3, 4, 4, 3, 3, 4, 4, 4, 4, 3, 3, 4, 4, 82, 83, 84, 24,
- 24, 24, 83, 83, 84, 24, 24, 24, 83, 4, 3, 80, 3, 3, 4, 3, 3, 0, 0, 0, 9, 0,
- 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 85, 3, 3, 0, 3, 3,
+ 24, 24, 83, 83, 84, 24, 24, 24, 83, 4, 3, 80, 3, 3, 4, 3, 3, 0, 0, 0, 9, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 85, 3, 3, 0, 3, 3,
3, 85, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 86, 0, 3, 3, 4, 3, 87, 87, 4, 87, 0,
0, 0, 0, 0, 0, 0, 3, 88, 7, 89, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0,
0, 0, 0, 88, 88, 0, 0, 0, 0, 0, 0, 7, 89, 0, 0, 88, 88, 0, 0, 2, 91, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 4, 4, 0, 88, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0,
0, 7, 7, 26, 89, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 2, 4, 4, 5, 6, 0, 0, 0, 0, 0,
- 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 93, 93, 0, 94, 0, 0, 9, 9, 20, 21, 95, 95, 0,
- 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 28, 97, 98, 97, 98, 96, 28, 97, 98, 97, 98, 99,
- 100, 0, 0, 0, 0, 20, 21, 101, 101, 102, 9, 0, 75, 103, 103, 9, 103, 9, 102, 9,
- 102, 0, 102, 9, 102, 9, 103, 28, 0, 28, 0, 0, 0, 33, 33, 103, 9, 103, 9, 9,
- 102, 9, 102, 28, 28, 33, 33, 102, 9, 9, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 104, 104, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 93, 93, 0, 94, 0, 0, 9, 9, 20, 21, 95, 95, 0, 0,
+ 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 28, 97, 98, 97, 98, 96, 28, 97, 98, 97, 98,
+ 99, 100, 0, 0, 0, 0, 0, 0, 20, 101, 21, 102, 102, 103, 75, 9, 0, 75, 104, 105,
+ 104, 9, 104, 9, 106, 107, 103, 106, 107, 106, 107, 9, 9, 9, 103, 0, 75, 103,
+ 9, 103, 9, 105, 104, 0, 28, 0, 28, 0, 108, 0, 108, 0, 0, 0, 0, 0, 33, 33, 104,
+ 9, 104, 9, 106, 107, 106, 107, 9, 9, 9, 103, 9, 103, 28, 28, 108, 108, 33,
+ 33, 103, 75, 9, 9, 105, 104, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 109, 109, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 9, 9, 27, 105, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 60, 106, 9, 9, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 47, 108, 107, 107, 107, 107,
- 107, 107, 107, 107, 0, 109, 109, 0, 71, 71, 110, 111, 67, 67, 67, 67, 112, 71,
- 9, 9, 73, 107, 107, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0,
- 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 114, 33, 115, 115, 28, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 101, 101, 101, 0, 0, 0, 0, 0,
- 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 60, 60, 106, 60, 7, 7, 7, 0, 7, 0, 7,
- 7, 7, 7, 7, 7, 0, 7, 7, 81, 7, 0, 7, 0, 0, 7, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 27, 110, 60, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 60, 111, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 112, 47, 113, 112, 112, 112, 112, 112, 112, 112,
+ 112, 0, 114, 114, 0, 71, 71, 115, 116, 67, 67, 67, 67, 117, 71, 118, 9, 9,
+ 73, 112, 112, 49, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0, 0,
+ 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 120, 33, 121, 121, 28, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 0, 0, 0, 0,
+ 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 60, 60, 111, 60, 7, 7, 7, 0, 7, 0,
+ 7, 7, 7, 7, 7, 7, 0, 7, 7, 81, 7, 0, 7, 0, 0, 7, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 117, 117, 118, 119, 115, 115, 115, 115, 82, 117, 120, 119, 118, 118,
- 119, 120, 119, 118, 119, 121, 122, 102, 102, 102, 121, 118, 119, 120, 119, 118,
- 119, 117, 119, 121, 122, 102, 102, 102, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 67, 123, 67,
+ 0, 0, 0, 0, 123, 123, 124, 125, 121, 121, 121, 121, 82, 123, 126, 125, 124, 124,
+ 125, 126, 125, 124, 125, 127, 128, 103, 103, 103, 127, 124, 125, 126, 125,
+ 124, 125, 123, 125, 127, 128, 103, 103, 103, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 67, 129, 67,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 9, 9, 0, 0, 104, 104, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 9, 9, 0, 0, 104, 104, 0, 0, 9, 0, 0, 0, 0, 0, 67, 67, 0, 0, 0, 0, 0, 0,
- 0, 0, 67, 123, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 113, 113, 20, 21,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 125, 124, 125, 0, 126, 0, 127, 0,
- 0, 0, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 9, 0, 0, 109, 109, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 109, 109, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0,
+ 0, 0, 67, 67, 0, 0, 0, 0, 0, 0, 0, 0, 67, 129, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 119, 119, 20, 101, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 130, 131, 130, 131, 0, 132, 0, 133, 0, 0, 0, 2, 4, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const uint8_t InstDB::rwInfoIndexB[Inst::_kIdCount] = {
@@ -3705,48 +3851,53 @@ const uint8_t InstDB::rwInfoIndexB[Inst::_kIdCount] = {
4, 0, 90, 4, 5, 5, 32, 19, 91, 79, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 91, 93,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94, 0, 0, 0, 0, 0,
0, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 56, 96, 0, 0, 0, 0, 97, 98, 97, 98, 3, 3,
- 99, 100, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 101, 101, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 102, 103, 0, 0, 0, 0, 0, 0, 3, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 105, 0, 106, 107, 108, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 3, 3, 3, 99, 100, 3, 109,
- 3, 55, 55, 0, 0, 0, 0, 110, 111, 112, 111, 112, 110, 111, 112, 111, 112, 22,
- 113, 113, 114, 115, 113, 113, 116, 117, 113, 113, 116, 117, 113, 113, 116,
- 117, 118, 118, 119, 120, 113, 113, 113, 113, 113, 113, 118, 118, 113, 113, 116,
- 117, 113, 113, 116, 117, 113, 113, 116, 117, 113, 113, 113, 113, 113, 113, 118,
- 118, 118, 118, 119, 120, 113, 113, 116, 117, 113, 113, 116, 117, 113, 113,
- 116, 117, 118, 118, 119, 120, 113, 113, 116, 117, 113, 113, 116, 117, 113, 113,
- 121, 122, 118, 118, 119, 120, 123, 123, 77, 124, 0, 0, 0, 0, 125, 126, 10,
- 10, 10, 10, 10, 10, 10, 10, 126, 127, 0, 0, 128, 129, 84, 84, 128, 129, 3, 3,
- 3, 3, 3, 3, 3, 130, 131, 132, 131, 132, 130, 131, 132, 131, 132, 100, 0, 53, 58,
- 133, 133, 3, 3, 99, 100, 0, 134, 0, 3, 3, 99, 100, 0, 135, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 136, 137, 137, 138, 139, 139, 0, 0, 0, 0, 0, 0, 0, 140,
- 0, 0, 141, 0, 0, 3, 11, 134, 0, 0, 142, 135, 3, 3, 99, 100, 0, 11, 3, 3, 143,
- 143, 144, 144, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 101, 3, 0, 0, 0, 0, 0, 0, 3, 118, 145, 145, 3, 3,
- 3, 3, 66, 67, 3, 3, 3, 3, 68, 69, 145, 145, 145, 145, 145, 145, 109, 109, 0, 0,
- 0, 0, 109, 109, 109, 109, 109, 109, 0, 0, 113, 113, 113, 113, 146, 146, 3, 3,
- 3, 113, 3, 3, 113, 113, 118, 118, 147, 147, 147, 3, 147, 3, 113, 113, 113, 113,
- 113, 3, 0, 0, 0, 0, 70, 22, 71, 148, 126, 125, 127, 126, 0, 0, 0, 3, 0, 3,
- 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 3, 3, 0, 149, 100, 99, 150, 0, 0, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 113, 113, 3, 3, 133, 133,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 99, 100, 101, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 102, 102,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 103, 3, 104, 105, 106, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107,
+ 0, 0, 0, 0, 0, 0, 0, 108, 0, 109, 0, 110, 0, 110, 0, 111, 112, 113, 114, 115,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 111, 112, 113, 0, 0, 3, 3, 3, 3, 99, 110, 101, 3, 116, 3, 55, 55, 0, 0,
+ 0, 0, 117, 118, 119, 118, 119, 117, 118, 119, 118, 119, 22, 120, 121, 120, 121,
+ 120, 120, 122, 123, 120, 120, 120, 124, 125, 126, 120, 120, 120, 124, 125,
+ 126, 120, 120, 120, 124, 125, 126, 120, 121, 127, 127, 128, 129, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 127, 127, 120, 120, 120, 124, 130, 126, 120,
+ 120, 120, 124, 130, 126, 120, 120, 120, 124, 130, 126, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 127, 127, 127, 127, 128, 129, 120, 121, 120, 120, 120, 124,
+ 125, 126, 120, 120, 120, 124, 125, 126, 120, 120, 120, 124, 125, 126, 127,
+ 127, 128, 129, 120, 120, 120, 124, 130, 126, 120, 120, 120, 124, 130, 126, 120,
+ 120, 120, 131, 130, 132, 127, 127, 128, 129, 133, 133, 133, 77, 134, 135, 0,
+ 0, 0, 0, 136, 137, 10, 10, 10, 10, 10, 10, 10, 10, 137, 138, 0, 0, 0, 139, 140,
+ 141, 84, 84, 84, 139, 140, 141, 3, 3, 3, 3, 3, 3, 3, 142, 143, 144, 143, 144,
+ 142, 143, 144, 143, 144, 101, 0, 53, 58, 145, 145, 3, 3, 3, 99, 100, 101,
+ 0, 146, 0, 3, 3, 3, 99, 100, 101, 0, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 148, 149, 149, 150, 151, 151, 0, 0, 0, 0, 0, 0, 0, 152, 153, 0, 0, 154, 0,
+ 0, 0, 3, 11, 146, 0, 0, 155, 147, 3, 3, 3, 99, 100, 101, 0, 11, 3, 3, 156, 156,
+ 157, 157, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 102, 3, 0, 0, 0, 0, 0, 0, 3, 127, 103, 103, 3, 3, 3, 3,
+ 66, 67, 3, 3, 3, 3, 68, 69, 103, 103, 103, 103, 103, 103, 116, 116, 0, 0, 0,
+ 0, 116, 116, 116, 116, 116, 116, 0, 0, 120, 120, 120, 120, 158, 158, 3, 3, 3,
+ 120, 3, 3, 120, 120, 127, 127, 159, 159, 159, 3, 159, 3, 120, 120, 120, 120,
+ 120, 3, 0, 0, 0, 0, 70, 22, 71, 160, 137, 136, 138, 137, 0, 0, 0, 3, 0, 3, 0,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 3, 3, 0, 161, 101, 99, 100, 0, 0, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 120, 120, 3, 3, 145, 145,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 3, 152, 84, 84, 3, 3,
- 84, 84, 3, 3, 153, 153, 153, 153, 3, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153,
- 3, 3, 113, 113, 113, 3, 153, 153, 3, 3, 113, 113, 113, 3, 3, 145, 84, 84, 84,
- 3, 3, 3, 154, 155, 154, 3, 3, 3, 154, 154, 154, 3, 3, 3, 154, 154, 155, 154,
- 3, 3, 3, 154, 3, 3, 3, 3, 3, 3, 3, 3, 113, 113, 0, 145, 145, 145, 145, 145,
- 145, 145, 145, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 128, 129, 0, 0, 128, 129,
- 0, 0, 128, 129, 0, 129, 84, 84, 128, 129, 84, 84, 128, 129, 84, 84, 128, 129,
- 0, 0, 128, 129, 0, 0, 128, 129, 0, 129, 3, 3, 99, 100, 0, 0, 10, 10, 10, 10,
- 10, 10, 10, 10, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 128, 129, 92, 3, 3, 99, 100, 0,
- 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 56, 56, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 80, 0, 0, 0, 0, 0, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158,
- 156, 0, 0
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 3, 3, 163, 84, 84, 3, 3, 84,
+ 84, 3, 3, 164, 164, 164, 164, 3, 0, 0, 0, 0, 164, 164, 164, 164, 164, 164, 3,
+ 3, 120, 120, 120, 3, 164, 164, 3, 3, 120, 120, 120, 3, 3, 103, 84, 84, 84, 3,
+ 3, 3, 165, 166, 165, 3, 3, 3, 165, 165, 165, 3, 3, 3, 165, 165, 166, 165, 3,
+ 3, 3, 165, 3, 3, 3, 3, 3, 3, 3, 3, 120, 120, 0, 103, 103, 103, 103, 103, 103,
+ 103, 103, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 139, 141, 0, 0, 139, 141, 0,
+ 0, 139, 141, 0, 0, 140, 141, 84, 84, 84, 139, 140, 141, 84, 84, 84, 139, 140,
+ 141, 84, 84, 139, 141, 0, 0, 139, 141, 0, 0, 139, 141, 0, 0, 140, 141, 3, 3,
+ 3, 99, 100, 101, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 139, 140, 141, 92, 3, 3, 3, 99, 100, 101, 0, 0, 0, 0, 0, 3, 3, 3, 3,
+ 3, 3, 0, 0, 0, 0, 56, 56, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0,
+ 168, 168, 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, 167, 0, 0
};
const InstDB::RWInfo InstDB::rwInfoA[] = {
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=936x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=1008x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 1 , 0 , 0 , 0 , 0 , 0 } }, // #1 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 1 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #2 [ref=7x]
{ InstDB::RWInfo::kCategoryGeneric , 2 , { 2 , 3 , 0 , 0 , 0 , 0 } }, // #3 [ref=96x]
@@ -3755,7 +3906,7 @@ const InstDB::RWInfo InstDB::rwInfoA[] = {
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 8 , 9 , 0 , 0 , 0 , 0 } }, // #6 [ref=6x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 10, 5 , 0 , 0 , 0 , 0 } }, // #7 [ref=26x]
{ InstDB::RWInfo::kCategoryGeneric , 7 , { 12, 13, 0 , 0 , 0 , 0 } }, // #8 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #9 [ref=64x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #9 [ref=75x]
{ InstDB::RWInfo::kCategoryGeneric , 2 , { 5 , 3 , 0 , 0 , 0 , 0 } }, // #10 [ref=3x]
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 10, 3 , 0 , 0 , 0 , 0 } }, // #11 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 9 , { 10, 5 , 0 , 0 , 0 , 0 } }, // #12 [ref=1x]
@@ -3779,7 +3930,7 @@ const InstDB::RWInfo InstDB::rwInfoA[] = {
{ InstDB::RWInfo::kCategoryGeneric , 14, { 36, 3 , 0 , 0 , 0 , 0 } }, // #30 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 14, { 37, 3 , 0 , 0 , 0 , 0 } }, // #31 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 36, 9 , 0 , 0 , 0 , 0 } }, // #32 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 11, 9 , 0 , 0 , 0 , 0 } }, // #33 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 11, 9 , 0 , 0 , 0 , 0 } }, // #33 [ref=7x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 38, 39, 0 , 0 , 0 , 0 } }, // #34 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 15, { 1 , 40, 0 , 0 , 0 , 0 } }, // #35 [ref=3x]
{ InstDB::RWInfo::kCategoryGeneric , 16, { 11, 43, 0 , 0 , 0 , 0 } }, // #36 [ref=3x]
@@ -3795,7 +3946,7 @@ const InstDB::RWInfo InstDB::rwInfoA[] = {
{ InstDB::RWInfo::kCategoryGeneric , 23, { 56, 40, 0 , 0 , 0 , 0 } }, // #46 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 24, { 44, 9 , 0 , 0 , 0 , 0 } }, // #47 [ref=4x]
{ InstDB::RWInfo::kCategoryGeneric , 25, { 35, 7 , 0 , 0 , 0 , 0 } }, // #48 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 26, { 48, 13, 0 , 0 , 0 , 0 } }, // #49 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 26, { 48, 13, 0 , 0 , 0 , 0 } }, // #49 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 56, 40, 0 , 0 , 0 , 0 } }, // #50 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 9 , 0 , 0 , 0 , 0 } }, // #51 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 7 , 0 , 0 , 0 , 0 } }, // #52 [ref=3x]
@@ -3821,7 +3972,7 @@ const InstDB::RWInfo InstDB::rwInfoA[] = {
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 56, 5 , 0 , 0 , 0 , 0 } }, // #72 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 28, { 44, 9 , 0 , 0 , 0 , 0 } }, // #73 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 63, 20, 0 , 0 , 0 , 0 } }, // #74 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 11, 3 , 0 , 0 , 0 , 0 } }, // #75 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 11, 3 , 0 , 0 , 0 , 0 } }, // #75 [ref=6x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 17, 29, 0 , 0 , 0 , 0 } }, // #76 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 11, { 3 , 3 , 0 , 0 , 0 , 0 } }, // #77 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 52, 22, 0 , 0 , 0 , 0 } }, // #78 [ref=1x]
@@ -3842,45 +3993,51 @@ const InstDB::RWInfo InstDB::rwInfoA[] = {
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 74, 3 , 0 , 0 , 0 , 0 } }, // #93 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 43, 0 , 0 , 0 , 0 } }, // #94 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 53, 9 , 0 , 0 , 0 , 0 } }, // #95 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 76, 5 , 0 , 0 , 0 , 0 } }, // #96 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 80, 5 , 0 , 0 , 0 , 0 } }, // #96 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 13, { 11, 5 , 0 , 0 , 0 , 0 } }, // #97 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 38, { 74, 77, 0 , 0 , 0 , 0 } }, // #98 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 39, { 11, 7 , 0 , 0 , 0 , 0 } }, // #99 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 40, { 11, 9 , 0 , 0 , 0 , 0 } }, // #100 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #101 [ref=7x]
- { InstDB::RWInfo::kCategoryVmov2_1 , 41, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #102 [ref=14x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 14, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #103 [ref=7x]
- { InstDB::RWInfo::kCategoryGeneric , 45, { 74, 43, 0 , 0 , 0 , 0 } }, // #104 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 44, 9 , 0 , 0 , 0 , 0 } }, // #105 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #106 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 52, { 11, 3 , 0 , 0 , 0 , 0 } }, // #107 [ref=12x]
- { InstDB::RWInfo::kCategoryVmovddup , 34, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #108 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 61, 0 , 0 , 0 , 0 } }, // #109 [ref=2x]
- { InstDB::RWInfo::kCategoryVmovmskpd , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #110 [ref=1x]
- { InstDB::RWInfo::kCategoryVmovmskps , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #111 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 53, { 35, 7 , 0 , 0 , 0 , 0 } }, // #112 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #113 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 15, { 11, 40, 0 , 0 , 0 , 0 } }, // #114 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #115 [ref=6x]
- { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 13, 0 , 0 , 0 , 0 } }, // #116 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 3 , 0 , 0 , 0 , 0 } }, // #117 [ref=4x]
- { InstDB::RWInfo::kCategoryVmov1_4 , 57, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #118 [ref=6x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 42, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #119 [ref=9x]
- { InstDB::RWInfo::kCategoryVmov1_8 , 58, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #120 [ref=3x]
- { InstDB::RWInfo::kCategoryVmov4_1 , 59, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #121 [ref=4x]
- { InstDB::RWInfo::kCategoryVmov8_1 , 60, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #122 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 11, 3 , 0 , 0 , 0 , 0 } }, // #123 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 17, { 44, 9 , 0 , 0 , 0 , 0 } }, // #124 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 32, { 35, 7 , 0 , 0 , 0 , 0 } }, // #125 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 2 , 0 , 0 , 0 , 0 } }, // #126 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 52, { 2 , 2 , 0 , 0 , 0 , 0 } } // #127 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 39, { 74, 81, 0 , 0 , 0 , 0 } }, // #98 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 40, { 11, 7 , 0 , 0 , 0 , 0 } }, // #99 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 41, { 11, 9 , 0 , 0 , 0 , 0 } }, // #100 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 13, 13, 0 , 0 , 0 , 0 } }, // #101 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 11, 3 , 0 , 0 , 0 , 0 } }, // #102 [ref=7x]
+ { InstDB::RWInfo::kCategoryVmov2_1 , 42, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #103 [ref=14x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 14, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #104 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 10, 3 , 0 , 0 , 0 , 0 } }, // #105 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 42, { 11, 3 , 0 , 0 , 0 , 0 } }, // #106 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 43, { 11, 5 , 0 , 0 , 0 , 0 } }, // #107 [ref=5x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 5 , 0 , 0 , 0 , 0 } }, // #108 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 47, { 74, 43, 0 , 0 , 0 , 0 } }, // #109 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 44, 9 , 0 , 0 , 0 , 0 } }, // #110 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 18, { 2 , 3 , 0 , 0 , 0 , 0 } }, // #111 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 54, { 11, 3 , 0 , 0 , 0 , 0 } }, // #112 [ref=12x]
+ { InstDB::RWInfo::kCategoryVmovddup , 34, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #113 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 61, 0 , 0 , 0 , 0 } }, // #114 [ref=2x]
+ { InstDB::RWInfo::kCategoryVmovmskpd , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #115 [ref=1x]
+ { InstDB::RWInfo::kCategoryVmovmskps , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #116 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 55, { 35, 7 , 0 , 0 , 0 , 0 } }, // #117 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 21, { 48, 13, 0 , 0 , 0 , 0 } }, // #118 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 3 , 3 , 0 , 0 , 0 , 0 } }, // #119 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 15, { 11, 40, 0 , 0 , 0 , 0 } }, // #120 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 11, 7 , 0 , 0 , 0 , 0 } }, // #121 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 11, 13, 0 , 0 , 0 , 0 } }, // #122 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 3 , 0 , 0 , 0 , 0 } }, // #123 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmov1_4 , 58, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #124 [ref=6x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 44, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #125 [ref=9x]
+ { InstDB::RWInfo::kCategoryVmov1_8 , 59, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #126 [ref=3x]
+ { InstDB::RWInfo::kCategoryVmov4_1 , 43, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #127 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmov8_1 , 60, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #128 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 18, { 11, 3 , 0 , 0 , 0 , 0 } }, // #129 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 17, { 44, 9 , 0 , 0 , 0 , 0 } }, // #130 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 32, { 35, 7 , 0 , 0 , 0 , 0 } }, // #131 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 11, { 2 , 2 , 0 , 0 , 0 , 0 } }, // #132 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 54, { 2 , 2 , 0 , 0 , 0 , 0 } } // #133 [ref=1x]
};
const InstDB::RWInfo InstDB::rwInfoB[] = {
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=742x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #0 [ref=775x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 1 , 0 , 0 , 0 , 0 , 0 } }, // #1 [ref=5x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 10, 5 , 0 , 0 , 0 , 0 } }, // #2 [ref=7x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 0 , 0 , 0 } }, // #3 [ref=186x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 0 , 0 , 0 } }, // #3 [ref=193x]
{ InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 3 , 0 , 0 , 0 } }, // #4 [ref=5x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 4 , 5 , 0 , 0 , 0 , 0 } }, // #5 [ref=14x]
{ InstDB::RWInfo::kCategoryGeneric , 3 , { 4 , 5 , 14, 0 , 0 , 0 } }, // #6 [ref=4x]
@@ -3961,7 +4118,7 @@ const InstDB::RWInfo InstDB::rwInfoB[] = {
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 44, 0 , 0 , 0 , 0 , 0 } }, // #81 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 35, 0 , 0 , 0 , 0 , 0 } }, // #82 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 16, 50, 67, 0 , 0 , 0 } }, // #83 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #84 [ref=16x]
+ { InstDB::RWInfo::kCategoryGeneric , 2 , { 11, 3 , 0 , 0 , 0 , 0 } }, // #84 [ref=19x]
{ InstDB::RWInfo::kCategoryGeneric , 4 , { 36, 7 , 0 , 0 , 0 , 0 } }, // #85 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 5 , { 37, 9 , 0 , 0 , 0 , 0 } }, // #86 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 72, 0 , 0 , 0 , 0 , 0 } }, // #87 [ref=1x]
@@ -3974,161 +4131,179 @@ const InstDB::RWInfo InstDB::rwInfoB[] = {
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 75, 43, 43, 0 , 0 , 0 } }, // #94 [ref=5x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 74, 0 , 0 , 0 , 0 , 0 } }, // #95 [ref=1x]
{ InstDB::RWInfo::kCategoryGeneric , 0 , { 9 , 60, 17, 0 , 0 , 0 } }, // #96 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 75, 43, 43, 43, 43, 5 } }, // #97 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 4 , 5 , 5 , 5 , 5 , 5 } }, // #98 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 75, 76, 77, 77, 77, 5 } }, // #97 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 4 , 78, 79, 79, 79, 5 } }, // #98 [ref=2x]
{ InstDB::RWInfo::kCategoryGeneric , 36, { 10, 5 , 7 , 0 , 0 , 0 } }, // #99 [ref=8x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 5 , 9 , 0 , 0 , 0 } }, // #100 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #101 [ref=3x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 11, 5 , 7 , 0 , 0 , 0 } }, // #102 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 11, 5 , 9 , 0 , 0 , 0 } }, // #103 [ref=1x]
- { InstDB::RWInfo::kCategoryVmov1_2 , 42, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #104 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 78, 7 , 0 , 0 , 0 } }, // #105 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 43, { 10, 61, 3 , 0 , 0 , 0 } }, // #106 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 43, { 10, 78, 3 , 0 , 0 , 0 } }, // #107 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 61, 9 , 0 , 0 , 0 } }, // #108 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 10, 5 , 5 , 0 , 0 , 0 } }, // #109 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 46, { 10, 77, 0 , 0 , 0 , 0 } }, // #110 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 46, { 10, 3 , 0 , 0 , 0 , 0 } }, // #111 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 47, { 76, 43, 0 , 0 , 0 , 0 } }, // #112 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #113 [ref=60x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 4 , 61, 7 , 0 , 0 , 0 } }, // #114 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 4 , 78, 9 , 0 , 0 , 0 } }, // #115 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #116 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #117 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 48, { 11, 3 , 3 , 3 , 0 , 0 } }, // #118 [ref=15x]
- { InstDB::RWInfo::kCategoryGeneric , 49, { 35, 7 , 7 , 7 , 0 , 0 } }, // #119 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 50, { 44, 9 , 9 , 9 , 0 , 0 } }, // #120 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 26, 7 , 7 , 0 , 0 , 0 } }, // #121 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 53, 9 , 9 , 0 , 0 , 0 } }, // #122 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 14, { 35, 3 , 0 , 0 , 0 , 0 } }, // #123 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 5 , { 35, 9 , 0 , 0 , 0 , 0 } }, // #124 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #125 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #126 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 18, { 4 , 3 , 4 , 0 , 0 , 0 } }, // #127 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 61, 7 , 0 , 0 , 0 } }, // #128 [ref=11x]
- { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 78, 9 , 0 , 0 , 0 } }, // #129 [ref=13x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 76, 77, 5 , 0 , 0 , 0 } }, // #130 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 11, 3 , 5 , 0 , 0 , 0 } }, // #131 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 51, { 74, 43, 77, 0 , 0 , 0 } }, // #132 [ref=4x]
- { InstDB::RWInfo::kCategoryVmaskmov , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #133 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 0 , 0 , 0 , 0 , 0 } }, // #134 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 0 , 0 , 0 , 0 , 0 } }, // #135 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 61, 0 , 0 , 0 } }, // #136 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 7 , 7 , 0 , 0 , 0 } }, // #137 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 7 , 7 , 0 , 0 , 0 } }, // #138 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 61, 7 , 0 , 0 , 0 } }, // #139 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 7 , 0 , 0 , 0 } }, // #140 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 78, 9 , 0 , 0 , 0 } }, // #141 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 79, 0 , 0 , 0 , 0 , 0 } }, // #142 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 54, { 35, 11, 3 , 3 , 0 , 0 } }, // #143 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 13, { 74, 43, 43, 43, 43, 5 } }, // #144 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 6 , { 35, 3 , 3 , 0 , 0 , 0 } }, // #145 [ref=17x]
- { InstDB::RWInfo::kCategoryGeneric , 51, { 76, 77, 77, 0 , 0 , 0 } }, // #146 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 3 , 0 , 0 , 0 } }, // #147 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 7 , { 48, 5 , 0 , 0 , 0 , 0 } }, // #148 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 55, { 10, 5 , 40, 0 , 0 , 0 } }, // #149 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 56, { 10, 5 , 13, 0 , 0 , 0 } }, // #150 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 44, { 10, 5 , 5 , 5 , 0 , 0 } }, // #151 [ref=12x]
- { InstDB::RWInfo::kCategoryGeneric , 61, { 10, 5 , 5 , 5 , 0 , 0 } }, // #152 [ref=1x]
- { InstDB::RWInfo::kCategoryGeneric , 62, { 10, 5 , 5 , 0 , 0 , 0 } }, // #153 [ref=12x]
- { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 5 , 0 , 0 , 0 } }, // #154 [ref=9x]
- { InstDB::RWInfo::kCategoryGeneric , 63, { 11, 3 , 0 , 0 , 0 , 0 } }, // #155 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 0 , { 60, 17, 29, 0 , 0 , 0 } }, // #156 [ref=2x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 60, 17, 0 , 0 , 0 } }, // #157 [ref=4x]
- { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 60, 17, 0 , 0 , 0 } } // #158 [ref=8x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 5 , 13, 0 , 0 , 0 } }, // #100 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 10, 5 , 9 , 0 , 0 , 0 } }, // #101 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 11, 3 , 3 , 3 , 0 , 0 } }, // #102 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 35, 3 , 3 , 0 , 0 , 0 } }, // #103 [ref=18x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 11, 5 , 7 , 0 , 0 , 0 } }, // #104 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 35, 13, 13, 0 , 0 , 0 } }, // #105 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 11, 5 , 9 , 0 , 0 , 0 } }, // #106 [ref=1x]
+ { InstDB::RWInfo::kCategoryVmov1_2 , 44, { 0 , 0 , 0 , 0 , 0 , 0 } }, // #107 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 5 , 5 , 0 , 0 , 0 } }, // #108 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 82, 7 , 0 , 0 , 0 } }, // #109 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 5 , 5 , 0 , 0 , 0 } }, // #110 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 61, 3 , 0 , 0 , 0 } }, // #111 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 3 , 3 , 0 , 0 , 0 } }, // #112 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 45, { 10, 82, 3 , 0 , 0 , 0 } }, // #113 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 10, 61, 9 , 0 , 0 , 0 } }, // #114 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 10, 5 , 5 , 0 , 0 , 0 } }, // #115 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 10, 5 , 5 , 0 , 0 , 0 } }, // #116 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 48, { 10, 81, 0 , 0 , 0 , 0 } }, // #117 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 48, { 10, 3 , 0 , 0 , 0 , 0 } }, // #118 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 49, { 80, 43, 0 , 0 , 0 , 0 } }, // #119 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 6 , { 2 , 3 , 3 , 0 , 0 , 0 } }, // #120 [ref=82x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #121 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 4 , 61, 7 , 0 , 0 , 0 } }, // #122 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 4 , 82, 9 , 0 , 0 , 0 } }, // #123 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 6 , 7 , 7 , 0 , 0 , 0 } }, // #124 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 4 , 5 , 5 , 0 , 0 , 0 } }, // #125 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 8 , 9 , 9 , 0 , 0 , 0 } }, // #126 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 50, { 11, 3 , 3 , 3 , 0 , 0 } }, // #127 [ref=15x]
+ { InstDB::RWInfo::kCategoryGeneric , 51, { 35, 7 , 7 , 7 , 0 , 0 } }, // #128 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 52, { 44, 9 , 9 , 9 , 0 , 0 } }, // #129 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 4 , 5 , 13, 0 , 0 , 0 } }, // #130 [ref=6x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 26, 7 , 7 , 0 , 0 , 0 } }, // #131 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 53, 9 , 9 , 0 , 0 , 0 } }, // #132 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 14, { 35, 3 , 0 , 0 , 0 , 0 } }, // #133 [ref=3x]
+ { InstDB::RWInfo::kCategoryGeneric , 27, { 35, 13, 0 , 0 , 0 , 0 } }, // #134 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 5 , { 35, 9 , 0 , 0 , 0 , 0 } }, // #135 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #136 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 2 , 3 , 2 , 0 , 0 , 0 } }, // #137 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 18, { 4 , 3 , 4 , 0 , 0 , 0 } }, // #138 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 36, { 10, 61, 7 , 0 , 0 , 0 } }, // #139 [ref=11x]
+ { InstDB::RWInfo::kCategoryGeneric , 37, { 10, 83, 13, 0 , 0 , 0 } }, // #140 [ref=7x]
+ { InstDB::RWInfo::kCategoryGeneric , 38, { 10, 82, 9 , 0 , 0 , 0 } }, // #141 [ref=13x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 80, 81, 5 , 0 , 0 , 0 } }, // #142 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 11, 3 , 5 , 0 , 0 , 0 } }, // #143 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 53, { 74, 43, 81, 0 , 0 , 0 } }, // #144 [ref=4x]
+ { InstDB::RWInfo::kCategoryVmaskmov , 0 , { 0 , 0 , 0 , 0 , 0 , 0 } }, // #145 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 35, 0 , 0 , 0 , 0 , 0 } }, // #146 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 22, 0 , 0 , 0 , 0 , 0 } }, // #147 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 61, 0 , 0 , 0 } }, // #148 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 7 , 7 , 0 , 0 , 0 } }, // #149 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 7 , 7 , 0 , 0 , 0 } }, // #150 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 12, { 10, 61, 7 , 0 , 0 , 0 } }, // #151 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 61, 7 , 0 , 0 , 0 } }, // #152 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 83, 13, 0 , 0 , 0 } }, // #153 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 10, 82, 9 , 0 , 0 , 0 } }, // #154 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 84, 0 , 0 , 0 , 0 , 0 } }, // #155 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 56, { 85, 86, 3 , 3 , 0 , 0 } }, // #156 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 13, { 74, 76, 77, 77, 77, 5 } }, // #157 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 53, { 80, 81, 81, 0 , 0 , 0 } }, // #158 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 3 , 0 , 0 , 0 } }, // #159 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 7 , { 48, 5 , 0 , 0 , 0 , 0 } }, // #160 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 57, { 10, 5 , 40, 0 , 0 , 0 } }, // #161 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 46, { 10, 5 , 5 , 5 , 0 , 0 } }, // #162 [ref=12x]
+ { InstDB::RWInfo::kCategoryGeneric , 61, { 10, 5 , 5 , 5 , 0 , 0 } }, // #163 [ref=1x]
+ { InstDB::RWInfo::kCategoryGeneric , 62, { 10, 5 , 5 , 0 , 0 , 0 } }, // #164 [ref=12x]
+ { InstDB::RWInfo::kCategoryGeneric , 22, { 11, 3 , 5 , 0 , 0 , 0 } }, // #165 [ref=9x]
+ { InstDB::RWInfo::kCategoryGeneric , 63, { 11, 3 , 0 , 0 , 0 , 0 } }, // #166 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 0 , { 60, 17, 29, 0 , 0 , 0 } }, // #167 [ref=2x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 3 , 60, 17, 0 , 0 , 0 } }, // #168 [ref=4x]
+ { InstDB::RWInfo::kCategoryGeneric , 8 , { 11, 60, 17, 0 , 0 , 0 } } // #169 [ref=8x]
};
const InstDB::RWInfoOp InstDB::rwInfoOp[] = {
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, 0 }, // #0 [ref=15529x]
- { 0x0000000000000003u, 0x0000000000000003u, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kRegPhysId }, // #1 [ref=10x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #2 [ref=214x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #3 [ref=987x]
- { 0x000000000000FFFFu, 0x000000000000FFFFu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #4 [ref=92x]
- { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #5 [ref=305x]
- { 0x00000000000000FFu, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kRW }, // #6 [ref=18x]
- { 0x00000000000000FFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #7 [ref=186x]
- { 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kRW }, // #8 [ref=18x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #9 [ref=136x]
- { 0x0000000000000000u, 0x000000000000FFFFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #10 [ref=160x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #11 [ref=420x]
- { 0x0000000000000003u, 0x0000000000000003u, 0xFF, { 0 }, OpRWInfo::kRW }, // #12 [ref=1x]
- { 0x0000000000000003u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #13 [ref=34x]
- { 0x000000000000FFFFu, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #14 [ref=4x]
- { 0x0000000000000000u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kMemBaseWrite | OpRWInfo::kMemIndexWrite }, // #15 [ref=1x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #16 [ref=9x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #17 [ref=23x]
- { 0x00000000000000FFu, 0x00000000000000FFu, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #18 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kMemPhysId }, // #19 [ref=3x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x06, { 0 }, OpRWInfo::kRead | OpRWInfo::kMemBaseRW | OpRWInfo::kMemBasePostModify | OpRWInfo::kMemPhysId }, // #20 [ref=3x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x07, { 0 }, OpRWInfo::kRead | OpRWInfo::kMemBaseRW | OpRWInfo::kMemBasePostModify | OpRWInfo::kMemPhysId }, // #21 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #22 [ref=7x]
- { 0x00000000000000FFu, 0x00000000000000FFu, 0x02, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #23 [ref=1x]
- { 0x00000000000000FFu, 0x0000000000000000u, 0x01, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #24 [ref=1x]
- { 0x00000000000000FFu, 0x0000000000000000u, 0x03, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #25 [ref=1x]
- { 0x00000000000000FFu, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #26 [ref=21x]
- { 0x000000000000000Fu, 0x000000000000000Fu, 0x02, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #27 [ref=1x]
- { 0x000000000000000Fu, 0x000000000000000Fu, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #28 [ref=4x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0x01, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #29 [ref=13x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0x03, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #30 [ref=2x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0x03, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #31 [ref=1x]
- { 0x000000000000000Fu, 0x000000000000000Fu, 0x01, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #32 [ref=1x]
- { 0x0000000000000000u, 0x00000000000000FFu, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #33 [ref=1x]
- { 0x00000000000000FFu, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #34 [ref=1x]
- { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #35 [ref=80x]
- { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, { 0 }, OpRWInfo::kWrite }, // #36 [ref=6x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kWrite }, // #37 [ref=6x]
- { 0x0000000000000000u, 0x0000000000000003u, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId }, // #38 [ref=1x]
- { 0x0000000000000003u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #39 [ref=1x]
- { 0x0000000000000001u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #40 [ref=28x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x02, { 0 }, OpRWInfo::kRW | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #41 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #42 [ref=3x]
- { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #43 [ref=45x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #44 [ref=30x]
- { 0x00000000000003FFu, 0x00000000000003FFu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #45 [ref=22x]
- { 0x00000000000003FFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #46 [ref=13x]
- { 0x0000000000000000u, 0x00000000000003FFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #47 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000003u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #48 [ref=15x]
- { 0x0000000000000000u, 0x0000000000000003u, 0x00, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #49 [ref=2x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0x00, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #50 [ref=8x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #51 [ref=2x]
- { 0x0000000000000003u, 0x0000000000000000u, 0x02, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #52 [ref=4x]
- { 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #53 [ref=4x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x07, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kMemPhysId }, // #54 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x01, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #55 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000001u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #56 [ref=14x]
- { 0x0000000000000000u, 0x0000000000000001u, 0x00, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId }, // #57 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x01, { 0 }, OpRWInfo::kRW | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #58 [ref=3x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x07, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kMemPhysId }, // #59 [ref=3x]
- { 0x000000000000000Fu, 0x0000000000000000u, 0x02, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #60 [ref=22x]
- { 0x000000000000FF00u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #61 [ref=23x]
- { 0x0000000000000000u, 0x000000000000FF00u, 0xFF, { 0 }, OpRWInfo::kWrite }, // #62 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x07, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kMemBaseRW | OpRWInfo::kMemBasePostModify | OpRWInfo::kMemPhysId }, // #63 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x02, { 0 }, OpRWInfo::kWrite | OpRWInfo::kRegPhysId | OpRWInfo::kZExt }, // #64 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x02, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #65 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x06, { 0 }, OpRWInfo::kRead | OpRWInfo::kMemPhysId }, // #66 [ref=1x]
- { 0x0000000000000000u, 0x000000000000000Fu, 0x01, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #67 [ref=5x]
- { 0x0000000000000000u, 0x000000000000FFFFu, 0x00, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #68 [ref=4x]
- { 0x0000000000000000u, 0x0000000000000007u, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #69 [ref=2x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x04, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt | OpRWInfo::kRegPhysId }, // #70 [ref=1x]
- { 0x0000000000000001u, 0x0000000000000000u, 0x01, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #71 [ref=10x]
- { 0x0000000000000001u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRead | OpRWInfo::kRegPhysId }, // #72 [ref=1x]
- { 0x0000000000000000u, 0x0000000000000001u, 0xFF, { 0 }, OpRWInfo::kWrite }, // #73 [ref=30x]
- { 0x0000000000000000u, 0xFFFFFFFFFFFFFFFFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #74 [ref=20x]
- { 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFF, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt }, // #75 [ref=7x]
- { 0x0000000000000000u, 0x00000000FFFFFFFFu, 0xFF, { 0 }, OpRWInfo::kWrite | OpRWInfo::kZExt }, // #76 [ref=10x]
- { 0x00000000FFFFFFFFu, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #77 [ref=16x]
- { 0x000000000000FFF0u, 0x0000000000000000u, 0xFF, { 0 }, OpRWInfo::kRead }, // #78 [ref=18x]
- { 0x0000000000000000u, 0x0000000000000000u, 0x00, { 0 }, OpRWInfo::kRW | OpRWInfo::kZExt | OpRWInfo::kRegPhysId } // #79 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kNone }, // #0 [ref=16519x]
+ { 0x0000000000000003u, 0x0000000000000003u, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kRegPhysId }, // #1 [ref=10x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #2 [ref=236x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #3 [ref=1077x]
+ { 0x000000000000FFFFu, 0x000000000000FFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #4 [ref=108x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #5 [ref=348x]
+ { 0x00000000000000FFu, 0x00000000000000FFu, 0xFF, 0, { 0 }, OpRWFlags::kRW }, // #6 [ref=18x]
+ { 0x00000000000000FFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #7 [ref=186x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kRW }, // #8 [ref=18x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #9 [ref=135x]
+ { 0x0000000000000000u, 0x000000000000FFFFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #10 [ref=184x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #11 [ref=455x]
+ { 0x0000000000000003u, 0x0000000000000003u, 0xFF, 0, { 0 }, OpRWFlags::kRW }, // #12 [ref=1x]
+ { 0x0000000000000003u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #13 [ref=63x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #14 [ref=4x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kMemBaseWrite | OpRWFlags::kMemIndexWrite }, // #15 [ref=1x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x02, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #16 [ref=9x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #17 [ref=23x]
+ { 0x00000000000000FFu, 0x00000000000000FFu, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #18 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemPhysId }, // #19 [ref=3x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x06, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemBaseRW | OpRWFlags::kMemBasePostModify | OpRWFlags::kMemPhysId }, // #20 [ref=3x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemBaseRW | OpRWFlags::kMemBasePostModify | OpRWFlags::kMemPhysId }, // #21 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #22 [ref=7x]
+ { 0x00000000000000FFu, 0x00000000000000FFu, 0x02, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #23 [ref=1x]
+ { 0x00000000000000FFu, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #24 [ref=1x]
+ { 0x00000000000000FFu, 0x0000000000000000u, 0x03, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #25 [ref=1x]
+ { 0x00000000000000FFu, 0x00000000000000FFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #26 [ref=21x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0x02, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #27 [ref=1x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #28 [ref=4x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #29 [ref=13x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0x03, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #30 [ref=2x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x03, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #31 [ref=1x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0x01, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #32 [ref=1x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0x02, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #33 [ref=1x]
+ { 0x00000000000000FFu, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #34 [ref=1x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #35 [ref=82x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #36 [ref=6x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #37 [ref=6x]
+ { 0x0000000000000000u, 0x0000000000000003u, 0x02, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId }, // #38 [ref=1x]
+ { 0x0000000000000003u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #39 [ref=1x]
+ { 0x0000000000000001u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #40 [ref=28x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #41 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #42 [ref=3x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #43 [ref=29x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #44 [ref=30x]
+ { 0x00000000000003FFu, 0x00000000000003FFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #45 [ref=22x]
+ { 0x00000000000003FFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #46 [ref=13x]
+ { 0x0000000000000000u, 0x00000000000003FFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #47 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000003u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #48 [ref=17x]
+ { 0x0000000000000000u, 0x0000000000000003u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #49 [ref=2x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #50 [ref=8x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #51 [ref=2x]
+ { 0x0000000000000003u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #52 [ref=4x]
+ { 0x000000000000000Fu, 0x000000000000000Fu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #53 [ref=4x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kMemPhysId }, // #54 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #55 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #56 [ref=14x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId }, // #57 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #58 [ref=3x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kMemPhysId }, // #59 [ref=3x]
+ { 0x000000000000000Fu, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #60 [ref=22x]
+ { 0x000000000000FF00u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #61 [ref=23x]
+ { 0x0000000000000000u, 0x000000000000FF00u, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #62 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x07, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kMemBaseRW | OpRWFlags::kMemBasePostModify | OpRWFlags::kMemPhysId }, // #63 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kRegPhysId | OpRWFlags::kZExt }, // #64 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x02, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #65 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x06, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kMemPhysId }, // #66 [ref=1x]
+ { 0x0000000000000000u, 0x000000000000000Fu, 0x01, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #67 [ref=5x]
+ { 0x0000000000000000u, 0x000000000000FFFFu, 0x00, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #68 [ref=4x]
+ { 0x0000000000000000u, 0x0000000000000007u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #69 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x04, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #70 [ref=1x]
+ { 0x0000000000000001u, 0x0000000000000000u, 0x01, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #71 [ref=10x]
+ { 0x0000000000000001u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kRegPhysId }, // #72 [ref=1x]
+ { 0x0000000000000000u, 0x0000000000000001u, 0xFF, 0, { 0 }, OpRWFlags::kWrite }, // #73 [ref=30x]
+ { 0x0000000000000000u, 0xFFFFFFFFFFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #74 [ref=20x]
+ { 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt }, // #75 [ref=7x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 4, { 0 }, OpRWFlags::kRead }, // #76 [ref=4x]
+ { 0xFFFFFFFFFFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kConsecutive }, // #77 [ref=12x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 4, { 0 }, OpRWFlags::kRead }, // #78 [ref=2x]
+ { 0x000000000000FFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead | OpRWFlags::kConsecutive }, // #79 [ref=6x]
+ { 0x0000000000000000u, 0x00000000FFFFFFFFu, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #80 [ref=10x]
+ { 0x00000000FFFFFFFFu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #81 [ref=16x]
+ { 0x000000000000FFF0u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #82 [ref=18x]
+ { 0x000000000000FFFCu, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kRead }, // #83 [ref=8x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0x00, 0, { 0 }, OpRWFlags::kRW | OpRWFlags::kZExt | OpRWFlags::kRegPhysId }, // #84 [ref=1x]
+ { 0x0000000000000000u, 0x00000000000000FFu, 0xFF, 2, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt }, // #85 [ref=2x]
+ { 0x0000000000000000u, 0x0000000000000000u, 0xFF, 0, { 0 }, OpRWFlags::kWrite | OpRWFlags::kZExt | OpRWFlags::kConsecutive } // #86 [ref=2x]
};
const InstDB::RWInfoRm InstDB::rwInfoRm[] = {
- { InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , 0, 0 }, // #0 [ref=1894x]
+ { InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , 0, 0 }, // #0 [ref=2000x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x03, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #1 [ref=8x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, 0 }, // #2 [ref=190x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, 0 }, // #2 [ref=204x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 16, 0, 0 }, // #3 [ref=122x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 8 , 0, 0 }, // #4 [ref=66x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , 0, 0 }, // #5 [ref=36x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , 0, 0 }, // #6 [ref=270x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , 0, 0 }, // #5 [ref=35x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , 0, 0 }, // #6 [ref=300x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , 0, 0 }, // #7 [ref=9x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 0 , 0, 0 }, // #8 [ref=63x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 0 , 0, 0 }, // #9 [ref=1x]
@@ -4136,78 +4311,76 @@ const InstDB::RWInfoRm InstDB::rwInfoRm[] = {
{ InstDB::RWInfoRm::kCategoryConsistent, 0x01, 0 , 0, 0 }, // #11 [ref=14x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 8 , 0, 0 }, // #12 [ref=22x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 16, 0, 0 }, // #13 [ref=21x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #14 [ref=15x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #14 [ref=22x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x02, 1 , 0, 0 }, // #15 [ref=5x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 64, 0, 0 }, // #16 [ref=5x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 4 , 0, 0 }, // #17 [ref=6x]
{ InstDB::RWInfoRm::kCategoryNone , 0x00, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #18 [ref=26x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 10, 0, 0 }, // #19 [ref=2x]
{ InstDB::RWInfoRm::kCategoryNone , 0x01, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #20 [ref=5x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x00, 2 , 0, 0 }, // #21 [ref=3x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 2 , 0, 0 }, // #21 [ref=4x]
{ InstDB::RWInfoRm::kCategoryConsistent, 0x06, 0 , 0, 0 }, // #22 [ref=14x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 1 , 0, 0 }, // #23 [ref=1x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 4 , 0, 0 }, // #24 [ref=4x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 8 , 0, 0 }, // #25 [ref=3x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x03, 2 , 0, 0 }, // #26 [ref=1x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 2 , 0, 0 }, // #27 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x03, 2 , 0, 0 }, // #26 [ref=2x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 2 , 0, 0 }, // #27 [ref=13x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x00, 4 , 0, 0 }, // #28 [ref=6x]
{ InstDB::RWInfoRm::kCategoryNone , 0x03, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #29 [ref=1x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x03, 16, 0, 0 }, // #30 [ref=6x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 1 , 0, 0 }, // #31 [ref=32x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 8 , 0, 0 }, // #32 [ref=4x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , 0, Features::kSSE4_1 }, // #33 [ref=1x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , 0, uint32_t(CpuFeatures::X86::kSSE4_1) }, // #33 [ref=1x]
{ InstDB::RWInfoRm::kCategoryNone , 0x02, 0 , 0, 0 }, // #34 [ref=4x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x01, 2 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #35 [ref=3x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 8 , 0, 0 }, // #36 [ref=34x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 4 , 0, 0 }, // #37 [ref=37x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x00, 32, 0, 0 }, // #38 [ref=4x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 8 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #39 [ref=1x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #40 [ref=1x]
- { InstDB::RWInfoRm::kCategoryHalf , 0x02, 0 , 0, 0 }, // #41 [ref=14x]
- { InstDB::RWInfoRm::kCategoryHalf , 0x01, 0 , 0, 0 }, // #42 [ref=10x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #43 [ref=4x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 16, 0, 0 }, // #44 [ref=27x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x02, 64, 0, 0 }, // #45 [ref=6x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x01, 16, 0, 0 }, // #46 [ref=6x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x01, 32, 0, 0 }, // #47 [ref=4x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x0C, 0 , 0, 0 }, // #48 [ref=15x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x0C, 8 , 0, 0 }, // #49 [ref=4x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x0C, 4 , 0, 0 }, // #50 [ref=4x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 32, 0, 0 }, // #51 [ref=6x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x03, 0 , 0, 0 }, // #52 [ref=13x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x03, 8 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #53 [ref=1x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x08, 0 , 0, 0 }, // #54 [ref=2x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 1 , 0, 0 }, // #55 [ref=1x]
- { InstDB::RWInfoRm::kCategoryFixed , 0x04, 2 , 0, 0 }, // #56 [ref=1x]
- { InstDB::RWInfoRm::kCategoryQuarter , 0x01, 0 , 0, 0 }, // #57 [ref=6x]
- { InstDB::RWInfoRm::kCategoryEighth , 0x01, 0 , 0, 0 }, // #58 [ref=3x]
- { InstDB::RWInfoRm::kCategoryQuarter , 0x02, 0 , 0, 0 }, // #59 [ref=4x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 8 , 0, 0 }, // #36 [ref=35x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 2 , 0, 0 }, // #37 [ref=30x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 4 , 0, 0 }, // #38 [ref=42x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x00, 32, 0, 0 }, // #39 [ref=4x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 8 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #40 [ref=1x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 4 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #41 [ref=1x]
+ { InstDB::RWInfoRm::kCategoryHalf , 0x02, 0 , 0, 0 }, // #42 [ref=19x]
+ { InstDB::RWInfoRm::kCategoryQuarter , 0x02, 0 , 0, 0 }, // #43 [ref=9x]
+ { InstDB::RWInfoRm::kCategoryHalf , 0x01, 0 , 0, 0 }, // #44 [ref=10x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x04, 0 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #45 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 16, 0, 0 }, // #46 [ref=27x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x02, 64, 0, 0 }, // #47 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x01, 16, 0, 0 }, // #48 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x01, 32, 0, 0 }, // #49 [ref=4x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x0C, 0 , 0, 0 }, // #50 [ref=15x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x0C, 8 , 0, 0 }, // #51 [ref=4x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x0C, 4 , 0, 0 }, // #52 [ref=4x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 32, 0, 0 }, // #53 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x03, 0 , 0, 0 }, // #54 [ref=13x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x03, 8 , InstDB::RWInfoRm::kFlagAmbiguous, 0 }, // #55 [ref=1x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x08, 0 , 0, 0 }, // #56 [ref=2x]
+ { InstDB::RWInfoRm::kCategoryFixed , 0x04, 1 , 0, 0 }, // #57 [ref=1x]
+ { InstDB::RWInfoRm::kCategoryQuarter , 0x01, 0 , 0, 0 }, // #58 [ref=6x]
+ { InstDB::RWInfoRm::kCategoryEighth , 0x01, 0 , 0, 0 }, // #59 [ref=3x]
{ InstDB::RWInfoRm::kCategoryEighth , 0x02, 0 , 0, 0 }, // #60 [ref=2x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x0C, 16, 0, 0 }, // #61 [ref=1x]
{ InstDB::RWInfoRm::kCategoryFixed , 0x06, 16, 0, 0 }, // #62 [ref=12x]
- { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, Features::kAVX512_BW } // #63 [ref=2x]
+ { InstDB::RWInfoRm::kCategoryConsistent, 0x02, 0 , 0, uint32_t(CpuFeatures::X86::kAVX512_BW) } // #63 [ref=2x]
};
// ----------------------------------------------------------------------------
// ${InstRWInfoTable:End}
-// ============================================================================
-// [asmjit::x86::InstDB - Unit]
-// ============================================================================
+// x86::InstDB - Tests
+// ===================
#if defined(ASMJIT_TEST)
UNIT(x86_inst_db) {
INFO("Checking validity of Inst enums");
// Cross-validate prefixes.
- EXPECT(Inst::kOptionRex == 0x40000000u, "REX prefix must be at 0x40000000");
- EXPECT(Inst::kOptionVex3 == 0x00000400u, "VEX3 prefix must be at 0x00000400");
- EXPECT(Inst::kOptionEvex == 0x00001000u, "EVEX prefix must be at 0x00001000");
+ EXPECT(uint32_t(InstOptions::kX86_Rex ) == 0x40000000u, "REX prefix must be at 0x40000000");
+ EXPECT(uint32_t(InstOptions::kX86_Evex) == 0x00001000u, "EVEX prefix must be at 0x00001000");
// These could be combined together to form a valid REX prefix, they must match.
- EXPECT(uint32_t(Inst::kOptionOpCodeB) == uint32_t(Opcode::kB), "Opcode::kB must match Inst::kOptionOpCodeB");
- EXPECT(uint32_t(Inst::kOptionOpCodeX) == uint32_t(Opcode::kX), "Opcode::kX must match Inst::kOptionOpCodeX");
- EXPECT(uint32_t(Inst::kOptionOpCodeR) == uint32_t(Opcode::kR), "Opcode::kR must match Inst::kOptionOpCodeR");
- EXPECT(uint32_t(Inst::kOptionOpCodeW) == uint32_t(Opcode::kW), "Opcode::kW must match Inst::kOptionOpCodeW");
+ EXPECT(uint32_t(InstOptions::kX86_OpCodeB) == uint32_t(Opcode::kB), "Opcode::kB must match InstOptions::kX86_OpCodeB");
+ EXPECT(uint32_t(InstOptions::kX86_OpCodeX) == uint32_t(Opcode::kX), "Opcode::kX must match InstOptions::kX86_OpCodeX");
+ EXPECT(uint32_t(InstOptions::kX86_OpCodeR) == uint32_t(Opcode::kR), "Opcode::kR must match InstOptions::kX86_OpCodeR");
+ EXPECT(uint32_t(InstOptions::kX86_OpCodeW) == uint32_t(Opcode::kW), "Opcode::kW must match InstOptions::kX86_OpCodeW");
uint32_t rex_rb = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kB >> Opcode::kREX_Shift) | 0x40;
uint32_t rex_rw = (Opcode::kR >> Opcode::kREX_Shift) | (Opcode::kW >> Opcode::kREX_Shift) | 0x40;
diff --git a/src/asmjit/x86/x86instdb.h b/src/asmjit/x86/x86instdb.h
index 4c86c9f..9911289 100644
--- a/src/asmjit/x86/x86instdb.h
+++ b/src/asmjit/x86/x86instdb.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86INSTDB_H_INCLUDED
#define ASMJIT_X86_X86INSTDB_H_INCLUDED
@@ -34,241 +16,318 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! Instruction database (X86).
namespace InstDB {
-// ============================================================================
-// [asmjit::x86::InstDB::Mode]
-// ============================================================================
-
-//! Describes which mode is supported by an instruction or instruction signature.
-enum Mode : uint32_t {
+//! Describes which operation mode is supported by an instruction.
+enum class Mode : uint8_t {
//! Invalid mode.
- kModeNone = 0x00u,
+ kNone = 0x00u,
//! X86 mode supported.
- kModeX86 = 0x01u,
+ kX86 = 0x01u,
//! X64 mode supported.
- kModeX64 = 0x02u,
+ kX64 = 0x02u,
//! Both X86 and X64 modes supported.
- kModeAny = 0x03u
+ kAny = 0x03u
};
+ASMJIT_DEFINE_ENUM_FLAGS(Mode)
-static constexpr uint32_t modeFromArch(uint32_t arch) noexcept {
- return arch == Environment::kArchX86 ? kModeX86 :
- arch == Environment::kArchX64 ? kModeX64 : kModeNone;
+//! Converts architecture to operation mode, see \ref Mode.
+static constexpr Mode modeFromArch(Arch arch) noexcept {
+ return arch == Arch::kX86 ? Mode::kX86 :
+ arch == Arch::kX64 ? Mode::kX64 : Mode::kNone;
}
-// ============================================================================
-// [asmjit::x86::InstDB::OpFlags]
-// ============================================================================
-
-//! Operand flags (X86).
-enum OpFlags : uint32_t {
- kOpNone = 0x00000000u, //!< No flags.
-
- kOpGpbLo = 0x00000001u, //!< Operand can be low 8-bit GPB register.
- kOpGpbHi = 0x00000002u, //!< Operand can be high 8-bit GPB register.
- kOpGpw = 0x00000004u, //!< Operand can be 16-bit GPW register.
- kOpGpd = 0x00000008u, //!< Operand can be 32-bit GPD register.
- kOpGpq = 0x00000010u, //!< Operand can be 64-bit GPQ register.
- kOpXmm = 0x00000020u, //!< Operand can be 128-bit XMM register.
- kOpYmm = 0x00000040u, //!< Operand can be 256-bit YMM register.
- kOpZmm = 0x00000080u, //!< Operand can be 512-bit ZMM register.
- kOpMm = 0x00000100u, //!< Operand can be 64-bit MM register.
- kOpKReg = 0x00000200u, //!< Operand can be 64-bit K register.
- kOpSReg = 0x00000400u, //!< Operand can be SReg (segment register).
- kOpCReg = 0x00000800u, //!< Operand can be CReg (control register).
- kOpDReg = 0x00001000u, //!< Operand can be DReg (debug register).
- kOpSt = 0x00002000u, //!< Operand can be 80-bit ST register (X87).
- kOpBnd = 0x00004000u, //!< Operand can be 128-bit BND register.
- kOpTmm = 0x00008000u, //!< Operand can be 0..8192-bit TMM register.
- kOpAllRegs = 0x0000FFFFu, //!< Combination of all possible registers.
-
- kOpI4 = 0x00010000u, //!< Operand can be unsigned 4-bit immediate.
- kOpU4 = 0x00020000u, //!< Operand can be unsigned 4-bit immediate.
- kOpI8 = 0x00040000u, //!< Operand can be signed 8-bit immediate.
- kOpU8 = 0x00080000u, //!< Operand can be unsigned 8-bit immediate.
- kOpI16 = 0x00100000u, //!< Operand can be signed 16-bit immediate.
- kOpU16 = 0x00200000u, //!< Operand can be unsigned 16-bit immediate.
- kOpI32 = 0x00400000u, //!< Operand can be signed 32-bit immediate.
- kOpU32 = 0x00800000u, //!< Operand can be unsigned 32-bit immediate.
- kOpI64 = 0x01000000u, //!< Operand can be signed 64-bit immediate.
- kOpU64 = 0x02000000u, //!< Operand can be unsigned 64-bit immediate.
- kOpAllImm = 0x03FF0000u, //!< Operand can be any immediate.
-
- kOpMem = 0x04000000u, //!< Operand can be a scalar memory pointer.
- kOpVm = 0x08000000u, //!< Operand can be a vector memory pointer.
-
- kOpRel8 = 0x10000000u, //!< Operand can be relative 8-bit displacement.
- kOpRel32 = 0x20000000u, //!< Operand can be relative 32-bit displacement.
-
- kOpImplicit = 0x80000000u //!< Operand is implicit.
-};
-
-// ============================================================================
-// [asmjit::x86::InstDB::MemFlags]
-// ============================================================================
-
-//! Memory operand flags (X86).
-enum MemFlags : uint32_t {
- // NOTE: Instruction uses either scalar or vector memory operands, they never
- // collide. This allows us to share bits between "M" and "Vm" enums.
-
- kMemOpAny = 0x0001u, //!< Operand can be any scalar memory pointer.
- kMemOpM8 = 0x0002u, //!< Operand can be an 8-bit memory pointer.
- kMemOpM16 = 0x0004u, //!< Operand can be a 16-bit memory pointer.
- kMemOpM32 = 0x0008u, //!< Operand can be a 32-bit memory pointer.
- kMemOpM48 = 0x0010u, //!< Operand can be a 48-bit memory pointer (FAR pointers only).
- kMemOpM64 = 0x0020u, //!< Operand can be a 64-bit memory pointer.
- kMemOpM80 = 0x0040u, //!< Operand can be an 80-bit memory pointer.
- kMemOpM128 = 0x0080u, //!< Operand can be a 128-bit memory pointer.
- kMemOpM256 = 0x0100u, //!< Operand can be a 256-bit memory pointer.
- kMemOpM512 = 0x0200u, //!< Operand can be a 512-bit memory pointer.
- kMemOpM1024 = 0x0400u, //!< Operand can be a 1024-bit memory pointer.
-
- kMemOpVm32x = 0x0002u, //!< Operand can be a vm32x (vector) pointer.
- kMemOpVm32y = 0x0004u, //!< Operand can be a vm32y (vector) pointer.
- kMemOpVm32z = 0x0008u, //!< Operand can be a vm32z (vector) pointer.
- kMemOpVm64x = 0x0020u, //!< Operand can be a vm64x (vector) pointer.
- kMemOpVm64y = 0x0040u, //!< Operand can be a vm64y (vector) pointer.
- kMemOpVm64z = 0x0080u, //!< Operand can be a vm64z (vector) pointer.
-
- kMemOpBaseOnly = 0x0800u, //!< Only memory base is allowed (no index, no offset).
- kMemOpDs = 0x1000u, //!< Implicit memory operand's DS segment.
- kMemOpEs = 0x2000u, //!< Implicit memory operand's ES segment.
-
- kMemOpMib = 0x4000u, //!< Operand must be MIB (base+index) pointer.
- kMemOpTMem = 0x8000u //!< Operand is a sib_mem (ADX memory operand).
+//! Operand signature flags used by \ref OpSignature.
+enum class OpFlags : uint64_t {
+ //! No operand flags.
+ kNone = 0u,
+
+ kRegGpbLo = 0x0000000000000001u, //!< Operand can be low 8-bit GPB register.
+ kRegGpbHi = 0x0000000000000002u, //!< Operand can be high 8-bit GPB register.
+ kRegGpw = 0x0000000000000004u, //!< Operand can be 16-bit GPW register.
+ kRegGpd = 0x0000000000000008u, //!< Operand can be 32-bit GPD register.
+ kRegGpq = 0x0000000000000010u, //!< Operand can be 64-bit GPQ register.
+ kRegXmm = 0x0000000000000020u, //!< Operand can be 128-bit XMM register.
+ kRegYmm = 0x0000000000000040u, //!< Operand can be 256-bit YMM register.
+ kRegZmm = 0x0000000000000080u, //!< Operand can be 512-bit ZMM register.
+ kRegMm = 0x0000000000000100u, //!< Operand can be 64-bit MM register.
+ kRegKReg = 0x0000000000000200u, //!< Operand can be 64-bit K register.
+ kRegSReg = 0x0000000000000400u, //!< Operand can be SReg (segment register).
+ kRegCReg = 0x0000000000000800u, //!< Operand can be CReg (control register).
+ kRegDReg = 0x0000000000001000u, //!< Operand can be DReg (debug register).
+ kRegSt = 0x0000000000002000u, //!< Operand can be 80-bit ST register (X87).
+ kRegBnd = 0x0000000000004000u, //!< Operand can be 128-bit BND register.
+ kRegTmm = 0x0000000000008000u, //!< Operand can be 0..8192-bit TMM register.
+ kRegMask = 0x000000000000FFFFu, //!< Mask of all possible register types.
+
+ kMemUnspecified = 0x0000000000040000u, //!< Operand can be a scalar memory pointer without size.
+ kMem8 = 0x0000000000080000u, //!< Operand can be an 8-bit memory pointer.
+ kMem16 = 0x0000000000100000u, //!< Operand can be a 16-bit memory pointer.
+ kMem32 = 0x0000000000200000u, //!< Operand can be a 32-bit memory pointer.
+ kMem48 = 0x0000000000400000u, //!< Operand can be a 48-bit memory pointer (FAR pointers only).
+ kMem64 = 0x0000000000800000u, //!< Operand can be a 64-bit memory pointer.
+ kMem80 = 0x0000000001000000u, //!< Operand can be an 80-bit memory pointer.
+ kMem128 = 0x0000000002000000u, //!< Operand can be a 128-bit memory pointer.
+ kMem256 = 0x0000000004000000u, //!< Operand can be a 256-bit memory pointer.
+ kMem512 = 0x0000000008000000u, //!< Operand can be a 512-bit memory pointer.
+ kMem1024 = 0x0000000010000000u, //!< Operand can be a 1024-bit memory pointer.
+ kMemMask = 0x000000001FFC0000u, //!< Mask of all possible scalar memory types.
+
+ kVm32x = 0x0000000040000000u, //!< Operand can be a vm32x (vector) pointer.
+ kVm32y = 0x0000000080000000u, //!< Operand can be a vm32y (vector) pointer.
+ kVm32z = 0x0000000100000000u, //!< Operand can be a vm32z (vector) pointer.
+ kVm64x = 0x0000000200000000u, //!< Operand can be a vm64x (vector) pointer.
+ kVm64y = 0x0000000400000000u, //!< Operand can be a vm64y (vector) pointer.
+ kVm64z = 0x0000000800000000u, //!< Operand can be a vm64z (vector) pointer.
+ kVmMask = 0x0000000FC0000000u, //!< Mask of all possible vector memory types.
+
+ kImmI4 = 0x0000001000000000u, //!< Operand can be signed 4-bit immediate.
+ kImmU4 = 0x0000002000000000u, //!< Operand can be unsigned 4-bit immediate.
+ kImmI8 = 0x0000004000000000u, //!< Operand can be signed 8-bit immediate.
+ kImmU8 = 0x0000008000000000u, //!< Operand can be unsigned 8-bit immediate.
+ kImmI16 = 0x0000010000000000u, //!< Operand can be signed 16-bit immediate.
+ kImmU16 = 0x0000020000000000u, //!< Operand can be unsigned 16-bit immediate.
+ kImmI32 = 0x0000040000000000u, //!< Operand can be signed 32-bit immediate.
+ kImmU32 = 0x0000080000000000u, //!< Operand can be unsigned 32-bit immediate.
+ kImmI64 = 0x0000100000000000u, //!< Operand can be signed 64-bit immediate.
+ kImmU64 = 0x0000200000000000u, //!< Operand can be unsigned 64-bit immediate.
+ kImmMask = 0x00003FF000000000u, //!< Mask of all immediate types.
+
+ kRel8 = 0x0000400000000000u, //!< Operand can be relative 8-bit displacement.
+ kRel32 = 0x0000800000000000u, //!< Operand can be relative 32-bit displacement.
+ kRelMask = 0x0000C00000000000u, //!< Mask of all relative displacement types.
+
+ kFlagMemBase = 0x0001000000000000u, //!< Flag: Only memory base is allowed (no index, no offset).
+ kFlagMemDs = 0x0002000000000000u, //!< Flag: Implicit memory operand's DS segment.
+ kFlagMemEs = 0x0004000000000000u, //!< Flag: Implicit memory operand's ES segment.
+
+ kFlagMib = 0x0008000000000000u, //!< Flag: Operand is MIB (base+index) pointer.
+ kFlagTMem = 0x0010000000000000u, //!< Flag: Operand is TMEM (sib_mem), AMX memory pointer.
+
+ kFlagImplicit = 0x0080000000000000u, //!< Flag: Operand is implicit.
+ kFlagMask = 0x009F000000000000u, //!< Mask of all flags.
+
+ //! Contains mask of all registers, memory operands, immediate operands, and displacement operands.
+ kOpMask = kRegMask | kMemMask | kVmMask | kImmMask | kRelMask
};
+ASMJIT_DEFINE_ENUM_FLAGS(OpFlags)
-// ============================================================================
-// [asmjit::x86::InstDB::Flags]
-// ============================================================================
-
-//! Instruction flags (X86).
+//! Operand signature.
//!
-//! Details about instruction encoding, operation, features, and some limitations.
-enum Flags : uint32_t {
- kFlagNone = 0x00000000u, //!< No flags.
-
- // Instruction Family
- // ------------------
- //
- // Instruction family information.
+//! Contains all possible operand combinations, memory size information, and a fixed register id (or `BaseReg::kIdBad`
+//! if fixed id isn't required).
+struct OpSignature {
+ //! \name Members
+ //! \{
- kFlagFpu = 0x00000100u, //!< Instruction that accesses FPU registers.
- kFlagMmx = 0x00000200u, //!< Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS.
- kFlagVec = 0x00000400u, //!< Instruction that accesses XMM registers (SSE, AVX, AVX512).
+ uint64_t _flags : 56;
+ uint64_t _regMask : 8;
- // FPU Flags
- // ---------
- //
- // Used to tell the encoder which memory operand sizes are encodable.
+ //! \}
- kFlagFpuM16 = 0x00000800u, //!< FPU instruction can address `word_ptr` (shared with M80).
- kFlagFpuM32 = 0x00001000u, //!< FPU instruction can address `dword_ptr`.
- kFlagFpuM64 = 0x00002000u, //!< FPU instruction can address `qword_ptr`.
- kFlagFpuM80 = 0x00000800u, //!< FPU instruction can address `tword_ptr` (shared with M16).
+ //! \name Accessors
+ //! \{
- // Prefixes and Encoding Flags
- // ---------------------------
- //
- // These describe optional X86 prefixes that can be used to change the instruction's operation.
+ //! Returns operand signature flags.
+ inline OpFlags flags() const noexcept { return (OpFlags)_flags; }
- kFlagTsib = 0x00004000u, //!< Instruction uses TSIB (or SIB_MEM) encoding (MODRM followed by SIB).
- kFlagRep = 0x00008000u, //!< Instruction can be prefixed with using the REP(REPE) or REPNE prefix.
- kFlagRepIgnored = 0x00010000u, //!< Instruction ignores REP|REPNE prefixes, but they are accepted.
- kFlagLock = 0x00020000u, //!< Instruction can be prefixed with using the LOCK prefix.
- kFlagXAcquire = 0x00040000u, //!< Instruction can be prefixed with using the XACQUIRE prefix.
- kFlagXRelease = 0x00080000u, //!< Instruction can be prefixed with using the XRELEASE prefix.
- kFlagMib = 0x00100000u, //!< Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
- kFlagVsib = 0x00200000u, //!< Instruction uses VSIB instead of legacy SIB.
-
- // If both `kFlagPrefixVex` and `kFlagPrefixEvex` flags are specified it
- // means that the instructions can be encoded by either VEX or EVEX prefix.
- // In that case AsmJit checks global options and also instruction options
- // to decide whether to emit VEX or EVEX prefix.
-
- kFlagVex = 0x00400000u, //!< Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
- kFlagEvex = 0x00800000u, //!< Instruction can be encoded by EVEX (AVX512).
- kFlagPreferEvex = 0x01000000u, //!< EVEX encoding is preferred over VEX encoding (AVX515_VNNI vs AVX_VNNI).
- kFlagEvexCompat = 0x02000000u, //!< EVEX and VEX signatures are compatible.
- kFlagEvexKReg = 0x04000000u, //!< EVEX instruction requires K register in the first operand (compare instructions).
- kFlagEvexTwoOp = 0x08000000u, //!< EVEX instruction requires two operands and K register as a selector (gather instructions).
- kFlagEvexTransformable = 0x10000000u //!< VEX instruction that can be transformed to a compatible EVEX instruction.
-};
+ //! Tests whether the given `flag` is set.
+ inline bool hasFlag(OpFlags flag) const noexcept { return (_flags & uint64_t(flag)) != 0; }
-// ============================================================================
-// [asmjit::x86::InstDB::Avx512Flags]
-// ============================================================================
-
-//! AVX512 flags.
-enum Avx512Flags : uint32_t {
- kAvx512Flag_ = 0x00000000u, //!< Internally used in tables, has no meaning.
- kAvx512FlagK = 0x00000001u, //!< Supports masking {k1..k7}.
- kAvx512FlagZ = 0x00000002u, //!< Supports zeroing {z}, must be used together with `kAvx512k`.
- kAvx512FlagER = 0x00000004u, //!< Supports 'embedded-rounding' {er} with implicit {sae},
- kAvx512FlagSAE = 0x00000008u, //!< Supports 'suppress-all-exceptions' {sae}.
- kAvx512FlagB32 = 0x00000010u, //!< Supports 32-bit broadcast 'b32'.
- kAvx512FlagB64 = 0x00000020u, //!< Supports 64-bit broadcast 'b64'.
- kAvx512FlagT4X = 0x00000080u //!< Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW).
-};
+ //! Tests whether this signature contains at least one register operand of any type.
+ inline bool hasReg() const noexcept { return hasFlag(OpFlags::kRegMask); }
+ //! Tests whether this signature contains at least one scalar memory operand of any type.
+ inline bool hasMem() const noexcept { return hasFlag(OpFlags::kMemMask); }
+ //! Tests whether this signature contains at least one vector memory operand of any type.
+ inline bool hasVm() const noexcept { return hasFlag(OpFlags::kVmMask); }
+ //! Tests whether this signature contains at least one immediate operand of any type.
+ inline bool hasImm() const noexcept { return hasFlag(OpFlags::kImmMask); }
+ //! Tests whether this signature contains at least one relative displacement operand of any type.
+ inline bool hasRel() const noexcept { return hasFlag(OpFlags::kRelMask); }
-// ============================================================================
-// [asmjit::x86::InstDB::SingleRegCase]
-// ============================================================================
-
-enum SingleRegCase : uint32_t {
- //! No special handling.
- kSingleRegNone = 0,
- //! Operands become read-only - `REG & REG` and similar.
- kSingleRegRO = 1,
- //! Operands become write-only - `REG ^ REG` and similar.
- kSingleRegWO = 2
-};
+ //! Tests whether the operand is implicit.
+ inline bool isImplicit() const noexcept { return hasFlag(OpFlags::kFlagImplicit); }
-// ============================================================================
-// [asmjit::x86::InstDB::InstSignature / OpSignature]
-// ============================================================================
+ //! Returns a physical register mask.
+ inline RegMask regMask() const noexcept { return _regMask; }
-//! Operand signature (X86).
-//!
-//! Contains all possible operand combinations, memory size information, and
-//! a fixed register id (or `BaseReg::kIdBad` if fixed id isn't required).
-struct OpSignature {
- //! Operand flags.
- uint32_t opFlags;
- //! Memory flags.
- uint16_t memFlags;
- //! Extra flags.
- uint8_t extFlags;
- //! Mask of possible register IDs.
- uint8_t regMask;
+ //! \}
};
ASMJIT_VARAPI const OpSignature _opSignatureTable[];
-//! Instruction signature (X86).
+//! Instruction signature.
//!
-//! Contains a sequence of operands' combinations and other metadata that defines
-//! a single instruction. This data is used by instruction validator.
+//! Contains a sequence of operands' combinations and other metadata that defines a single instruction. This data is
+//! used by instruction validator.
struct InstSignature {
+ //! \name Members
+ //! \{
+
//! Count of operands in `opIndex` (0..6).
- uint8_t opCount : 3;
+ uint8_t _opCount : 3;
//! Architecture modes supported (X86 / X64).
- uint8_t modes : 2;
+ uint8_t _mode : 2;
//! Number of implicit operands.
- uint8_t implicit : 3;
+ uint8_t _implicitOpCount : 3;
//! Reserved for future use.
- uint8_t reserved;
+ uint8_t _reserved;
//! Indexes to `OpSignature` table.
- uint8_t operands[Globals::kMaxOpCount];
+ uint8_t _opSignatureIndexes[Globals::kMaxOpCount];
+
+ //! \}
+
+ //! \name Accessors
+ //! \{
+
+ //! Returns instruction operation mode.
+ inline Mode mode() const noexcept { return (Mode)_mode; }
+ //! Tests whether the instruction supports the given operating mode.
+ inline bool supportsMode(Mode mode) const noexcept { return (uint8_t(_mode) & uint8_t(mode)) != 0; }
+
+ //! Returns the number of operands of this signature.
+ inline uint32_t opCount() const noexcept { return _opCount; }
+ //! Returns the number of implicit operands this signature has.
+ inline uint32_t implicitOpCount() const noexcept { return _implicitOpCount; }
+ //! Tests whether this instruction signature has at least one implicit operand.
+ inline bool hasImplicitOperands() const noexcept { return _implicitOpCount != 0; }
+
+ //! Returns indexes to \ref _opSignatureTable for each operand of the instruction.
+ //!
+ //! \note The returned array always provides indexes for all operands (see \ref Globals::kMaxOpCount) even if the
+ //! instruction provides less operands. Undefined operands have always index of zero.
+ inline const uint8_t* opSignatureIndexes() const noexcept { return _opSignatureIndexes; }
+
+ //! Returns index to \ref _opSignatureTable, corresponding to the requested operand `index` of the instruction.
+ inline uint8_t opSignatureIndex(size_t index) const noexcept {
+ ASMJIT_ASSERT(index < Globals::kMaxOpCount);
+ return _opSignatureIndexes[index];
+ }
+
+ //! Returns \ref OpSignature corresponding to the requested operand `index` of the instruction.
+ inline const OpSignature& opSignature(size_t index) const noexcept {
+ ASMJIT_ASSERT(index < Globals::kMaxOpCount);
+ return _opSignatureTable[_opSignatureIndexes[index]];
+ }
+
+ //! \}
};
ASMJIT_VARAPI const InstSignature _instSignatureTable[];
-// ============================================================================
-// [asmjit::x86::InstDB::CommonInfo]
-// ============================================================================
+//! Instruction flags.
+//!
+//! Details about instruction encoding, operation, features, and some limitations.
+enum class InstFlags : uint32_t {
+ //! No flags.
+ kNone = 0x00000000u,
+
+ // Instruction Family
+ // ------------------
+ //
+ // Instruction family information.
-//! Instruction common information (X86)
+ //! Instruction that accesses FPU registers.
+ kFpu = 0x00000100u,
+ //! Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS.
+ kMmx = 0x00000200u,
+ //! Instruction that accesses XMM registers (SSE, AVX, AVX512).
+ kVec = 0x00000400u,
+
+ // FPU Flags
+ // ---------
+ //
+ // Used to tell the encoder which memory operand sizes are encodable.
+
+ //! FPU instruction can address `word_ptr` (shared with M80).
+ kFpuM16 = 0x00000800u,
+ //! FPU instruction can address `dword_ptr`.
+ kFpuM32 = 0x00001000u,
+ //! FPU instruction can address `qword_ptr`.
+ kFpuM64 = 0x00002000u,
+ //! FPU instruction can address `tword_ptr` (shared with M16).
+ kFpuM80 = 0x00000800u,
+
+ // Prefixes and Encoding Flags
+ // ---------------------------
+ //
+ // These describe optional X86 prefixes that can be used to change the instruction's operation.
+
+ //! Instruction can be prefixed with using the REP(REPE) or REPNE prefix.
+ kRep = 0x00004000u,
+ //! Rep prefix is accepted, but it has no effect other than being emitted with the instruction (as an extra byte).
+ kRepIgnored = 0x00008000u,
+ //! Instruction can be prefixed with using the LOCK prefix.
+ kLock = 0x00010000u,
+ //! Instruction can be prefixed with using the XACQUIRE prefix.
+ kXAcquire = 0x00020000u,
+ //! Instruction can be prefixed with using the XRELEASE prefix.
+ kXRelease = 0x00040000u,
+ //! Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
+ kMib = 0x00080000u,
+ //! Instruction uses VSIB instead of legacy SIB.
+ kVsib = 0x00100000u,
+ //! Instruction uses TSIB (or SIB_MEM) encoding (MODRM followed by SIB).
+ kTsib = 0x00200000u,
+
+ // If both `kPrefixVex` and `kPrefixEvex` flags are specified it means that the instructions can be encoded
+ // by either VEX or EVEX prefix. In that case AsmJit checks global options and also instruction options to decide
+ // whether to emit VEX or EVEX prefix.
+
+ //! Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
+ kVex = 0x00400000u,
+ //! Instruction can be encoded by EVEX (AVX512).
+ kEvex = 0x00800000u,
+ //! EVEX encoding is preferred over VEX encoding (AVX515_VNNI vs AVX_VNNI).
+ kPreferEvex = 0x01000000u,
+ //! EVEX and VEX signatures are compatible.
+ kEvexCompat = 0x02000000u,
+ //! EVEX instruction requires K register in the first operand (compare instructions).
+ kEvexKReg = 0x04000000u,
+ //! EVEX instruction requires two operands and K register as a selector (gather instructions).
+ kEvexTwoOp = 0x08000000u,
+ //! VEX instruction that can be transformed to a compatible EVEX instruction.
+ kEvexTransformable = 0x10000000u,
+
+ // Other Flags
+ // -----------
+
+ //! Instruction uses consecutive registers.
+ //!
+ //! Used by V4FMADDPS, V4FMADDSS, V4FNMADDPS, V4FNMADDSS, VP4DPWSSD, VP4DPWSSDS, VP2INTERSECTD, and VP2INTERSECTQ
+ //! instructions
+ kConsecutiveRegs = 0x20000000u
+};
+ASMJIT_DEFINE_ENUM_FLAGS(InstFlags)
+
+//! AVX-512 flags.
+enum class Avx512Flags : uint32_t {
+ //! No AVX-512 flags.
+ kNone = 0,
+
+ //! Internally used in tables, has no meaning.
+ k_ = 0x00000000u,
+ //! Supports masking {k1..k7}.
+ kK = 0x00000001u,
+ //! Supports zeroing {z}, must be used together with `kAvx512k`.
+ kZ = 0x00000002u,
+ //! Supports 'embedded-rounding' {er} with implicit {sae},
+ kER = 0x00000004u,
+ //! Supports 'suppress-all-exceptions' {sae}.
+ kSAE = 0x00000008u,
+ //! Supports 16-bit broadcast 'b16'.
+ kB16 = 0x00000010u,
+ //! Supports 32-bit broadcast 'b32'.
+ kB32 = 0x00000020u,
+ //! Supports 64-bit broadcast 'b64'.
+ kB64 = 0x00000040u,
+ //! Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW).
+ kT4X = 0x00000080u,
+
+ //! Implicit zeroing if {k} masking is used. Using {z} is not valid in this case as it's implicit.
+ kImplicitZ = 0x00000100,
+};
+ASMJIT_DEFINE_ENUM_FLAGS(Avx512Flags)
+
+//! Instruction common information.
//!
//! Aggregated information shared across one or more instruction.
struct CommonInfo {
@@ -280,82 +339,89 @@ struct CommonInfo {
uint32_t _iSignatureIndex : 11;
//! Number of relevant `ISignature` entries.
uint32_t _iSignatureCount : 5;
- //! Control type, see `ControlType`.
- uint32_t _controlType : 3;
+ //! Instruction control flow category, see \ref InstControlFlow.
+ uint32_t _controlFlow : 3;
//! Specifies what happens if all source operands share the same register.
- uint32_t _singleRegCase : 2;
+ uint32_t _sameRegHint : 2;
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
+ //! \name Accessors
+ //! \{
- //! Returns instruction flags, see \ref Flags.
- inline uint32_t flags() const noexcept { return _flags; }
- //! Tests whether the instruction has a `flag`, see \ref Flags.
- inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+ //! Returns instruction flags.
+ inline InstFlags flags() const noexcept { return (InstFlags)_flags; }
+ //! Tests whether the instruction has a `flag`.
+ inline bool hasFlag(InstFlags flag) const noexcept { return Support::test(_flags, flag); }
- //! Returns instruction AVX-512 flags, see \ref Avx512Flags.
- inline uint32_t avx512Flags() const noexcept { return _avx512Flags; }
- //! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
- inline bool hasAvx512Flag(uint32_t flag) const noexcept { return (_avx512Flags & flag) != 0; }
+ //! Returns instruction AVX-512 flags.
+ inline Avx512Flags avx512Flags() const noexcept { return (Avx512Flags)_avx512Flags; }
+ //! Tests whether the instruction has an AVX-512 `flag`.
+ inline bool hasAvx512Flag(Avx512Flags flag) const noexcept { return Support::test(_avx512Flags, flag); }
//! Tests whether the instruction is FPU instruction.
- inline bool isFpu() const noexcept { return hasFlag(kFlagFpu); }
+ inline bool isFpu() const noexcept { return hasFlag(InstFlags::kFpu); }
//! Tests whether the instruction is MMX/3DNOW instruction that accesses MMX registers (includes EMMS and FEMMS).
- inline bool isMmx() const noexcept { return hasFlag(kFlagMmx); }
+ inline bool isMmx() const noexcept { return hasFlag(InstFlags::kMmx); }
//! Tests whether the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers.
- inline bool isVec() const noexcept { return hasFlag(kFlagVec); }
+ inline bool isVec() const noexcept { return hasFlag(InstFlags::kVec); }
//! Tests whether the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
- inline bool isSse() const noexcept { return (flags() & (kFlagVec | kFlagVex | kFlagEvex)) == kFlagVec; }
+ inline bool isSse() const noexcept { return (flags() & (InstFlags::kVec | InstFlags::kVex | InstFlags::kEvex)) == InstFlags::kVec; }
//! Tests whether the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
inline bool isAvx() const noexcept { return isVec() && isVexOrEvex(); }
//! Tests whether the instruction can be prefixed with LOCK prefix.
- inline bool hasLockPrefix() const noexcept { return hasFlag(kFlagLock); }
+ inline bool hasLockPrefix() const noexcept { return hasFlag(InstFlags::kLock); }
//! Tests whether the instruction can be prefixed with REP (REPE|REPZ) prefix.
- inline bool hasRepPrefix() const noexcept { return hasFlag(kFlagRep); }
+ inline bool hasRepPrefix() const noexcept { return hasFlag(InstFlags::kRep); }
//! Tests whether the instruction can be prefixed with XACQUIRE prefix.
- inline bool hasXAcquirePrefix() const noexcept { return hasFlag(kFlagXAcquire); }
+ inline bool hasXAcquirePrefix() const noexcept { return hasFlag(InstFlags::kXAcquire); }
//! Tests whether the instruction can be prefixed with XRELEASE prefix.
- inline bool hasXReleasePrefix() const noexcept { return hasFlag(kFlagXRelease); }
+ inline bool hasXReleasePrefix() const noexcept { return hasFlag(InstFlags::kXRelease); }
//! Tests whether the rep prefix is supported by the instruction, but ignored (has no effect).
- inline bool isRepIgnored() const noexcept { return hasFlag(kFlagRepIgnored); }
+ inline bool isRepIgnored() const noexcept { return hasFlag(InstFlags::kRepIgnored); }
//! Tests whether the instruction uses MIB.
- inline bool isMibOp() const noexcept { return hasFlag(kFlagMib); }
+ inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
//! Tests whether the instruction uses VSIB.
- inline bool isVsibOp() const noexcept { return hasFlag(kFlagVsib); }
+ inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
//! Tests whether the instruction uses TSIB (AMX, instruction requires MOD+SIB).
- inline bool isTsibOp() const noexcept { return hasFlag(kFlagTsib); }
+ inline bool isTsibOp() const noexcept { return hasFlag(InstFlags::kTsib); }
//! Tests whether the instruction uses VEX (can be set together with EVEX if both are encodable).
- inline bool isVex() const noexcept { return hasFlag(kFlagVex); }
+ inline bool isVex() const noexcept { return hasFlag(InstFlags::kVex); }
//! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
- inline bool isEvex() const noexcept { return hasFlag(kFlagEvex); }
+ inline bool isEvex() const noexcept { return hasFlag(InstFlags::kEvex); }
//! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
- inline bool isVexOrEvex() const noexcept { return hasFlag(kFlagVex | kFlagEvex); }
+ inline bool isVexOrEvex() const noexcept { return hasFlag(InstFlags::kVex | InstFlags::kEvex); }
//! Tests whether the instruction should prefer EVEX prefix instead of VEX prefix.
- inline bool preferEvex() const noexcept { return hasFlag(kFlagPreferEvex); }
+ inline bool preferEvex() const noexcept { return hasFlag(InstFlags::kPreferEvex); }
- inline bool isEvexCompatible() const noexcept { return hasFlag(kFlagEvexCompat); }
- inline bool isEvexKRegOnly() const noexcept { return hasFlag(kFlagEvexKReg); }
- inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(kFlagEvexTwoOp); }
- inline bool isEvexTransformable() const noexcept { return hasFlag(kFlagEvexTransformable); }
+ inline bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
+ inline bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
+ inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
+ inline bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}.
- inline bool hasAvx512K() const noexcept { return hasAvx512Flag(kAvx512FlagK); }
+ inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}.
- inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(kAvx512FlagZ); }
+ inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}.
- inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(kAvx512FlagER); }
+ inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
//! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
- inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(kAvx512FlagSAE); }
+ inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(Avx512Flags::kSAE); }
//! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
- inline bool hasAvx512B() const noexcept { return hasAvx512Flag(kAvx512FlagB32 | kAvx512FlagB64); }
+ inline bool hasAvx512B() const noexcept { return hasAvx512Flag(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
+ //! Tests whether the instruction supports AVX512 broadcast (16-bit).
+ inline bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit).
- inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(kAvx512FlagB32); }
+ inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit).
- inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(kAvx512FlagB64); }
+ inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
+
+ // Returns the size of the broadcast - either 2, 4, or 8, or 0 if broadcast is not supported.
+ inline uint32_t broadcastSize() const noexcept {
+ constexpr uint32_t kShift = Support::ConstCTZ<uint32_t(Avx512Flags::kB16)>::value;
+ return (uint32_t(_avx512Flags) & uint32_t(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64)) >> (kShift - 1);
+ }
inline uint32_t signatureIndex() const noexcept { return _iSignatureIndex; }
inline uint32_t signatureCount() const noexcept { return _iSignatureCount; }
@@ -363,53 +429,50 @@ struct CommonInfo {
inline const InstSignature* signatureData() const noexcept { return _instSignatureTable + _iSignatureIndex; }
inline const InstSignature* signatureEnd() const noexcept { return _instSignatureTable + _iSignatureIndex + _iSignatureCount; }
- //! Returns the control-flow type of the instruction.
- inline uint32_t controlType() const noexcept { return _controlType; }
+ //! Returns a control flow category of the instruction.
+ inline InstControlFlow controlFlow() const noexcept { return (InstControlFlow)_controlFlow; }
+
+ //! Returns a hint that can be used when both inputs are the same register.
+ inline InstSameRegHint sameRegHint() const noexcept { return (InstSameRegHint)_sameRegHint; }
- inline uint32_t singleRegCase() const noexcept { return _singleRegCase; }
+ //! \}
};
ASMJIT_VARAPI const CommonInfo _commonInfoTable[];
-// ============================================================================
-// [asmjit::x86::InstDB::InstInfo]
-// ============================================================================
-
-//! Instruction information (X86).
+//! Instruction information.
struct InstInfo {
//! Index to \ref _nameData.
uint32_t _nameDataIndex : 14;
//! Index to \ref _commonInfoTable.
uint32_t _commonInfoIndex : 10;
- //! Index to \ref _commonInfoTableB.
- uint32_t _commonInfoIndexB : 8;
+ //! Index to \ref _additionalInfoTable.
+ uint32_t _additionalInfoIndex : 8;
//! Instruction encoding (internal encoding identifier used by \ref Assembler).
uint8_t _encoding;
//! Main opcode value (0..255).
uint8_t _mainOpcodeValue;
- //! Index to \ref _mainOpcodeTable` that is combined with \ref _mainOpcodeValue
- //! to form the final opcode.
+ //! Index to \ref _mainOpcodeTable` that is combined with \ref _mainOpcodeValue to form the final opcode.
uint8_t _mainOpcodeIndex;
//! Index to \ref _altOpcodeTable that contains a full alternative opcode.
uint8_t _altOpcodeIndex;
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
+ //! \name Accessors
+ //! \{
//! Returns common information, see `CommonInfo`.
inline const CommonInfo& commonInfo() const noexcept { return _commonInfoTable[_commonInfoIndex]; }
//! Returns instruction flags, see \ref Flags.
- inline uint32_t flags() const noexcept { return commonInfo().flags(); }
+ inline InstFlags flags() const noexcept { return commonInfo().flags(); }
//! Tests whether the instruction has flag `flag`, see \ref Flags.
- inline bool hasFlag(uint32_t flag) const noexcept { return commonInfo().hasFlag(flag); }
+ inline bool hasFlag(InstFlags flag) const noexcept { return commonInfo().hasFlag(flag); }
//! Returns instruction AVX-512 flags, see \ref Avx512Flags.
- inline uint32_t avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
+ inline Avx512Flags avx512Flags() const noexcept { return commonInfo().avx512Flags(); }
//! Tests whether the instruction has an AVX-512 `flag`, see \ref Avx512Flags.
- inline bool hasAvx512Flag(uint32_t flag) const noexcept { return commonInfo().hasAvx512Flag(flag); }
+ inline bool hasAvx512Flag(Avx512Flags flag) const noexcept { return commonInfo().hasAvx512Flag(flag); }
//! Tests whether the instruction is FPU instruction.
inline bool isFpu() const noexcept { return commonInfo().isFpu(); }
@@ -434,54 +497,63 @@ struct InstInfo {
//! Tests whether the rep prefix is supported by the instruction, but ignored (has no effect).
inline bool isRepIgnored() const noexcept { return commonInfo().isRepIgnored(); }
//! Tests whether the instruction uses MIB.
- inline bool isMibOp() const noexcept { return hasFlag(kFlagMib); }
+ inline bool isMibOp() const noexcept { return hasFlag(InstFlags::kMib); }
//! Tests whether the instruction uses VSIB.
- inline bool isVsibOp() const noexcept { return hasFlag(kFlagVsib); }
+ inline bool isVsibOp() const noexcept { return hasFlag(InstFlags::kVsib); }
//! Tests whether the instruction uses VEX (can be set together with EVEX if both are encodable).
- inline bool isVex() const noexcept { return hasFlag(kFlagVex); }
+ inline bool isVex() const noexcept { return hasFlag(InstFlags::kVex); }
//! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
- inline bool isEvex() const noexcept { return hasFlag(kFlagEvex); }
+ inline bool isEvex() const noexcept { return hasFlag(InstFlags::kEvex); }
//! Tests whether the instruction uses EVEX (can be set together with VEX if both are encodable).
- inline bool isVexOrEvex() const noexcept { return hasFlag(kFlagVex | kFlagEvex); }
+ inline bool isVexOrEvex() const noexcept { return hasFlag(InstFlags::kVex | InstFlags::kEvex); }
- inline bool isEvexCompatible() const noexcept { return hasFlag(kFlagEvexCompat); }
- inline bool isEvexKRegOnly() const noexcept { return hasFlag(kFlagEvexKReg); }
- inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(kFlagEvexTwoOp); }
- inline bool isEvexTransformable() const noexcept { return hasFlag(kFlagEvexTransformable); }
+ inline bool isEvexCompatible() const noexcept { return hasFlag(InstFlags::kEvexCompat); }
+ inline bool isEvexKRegOnly() const noexcept { return hasFlag(InstFlags::kEvexKReg); }
+ inline bool isEvexTwoOpOnly() const noexcept { return hasFlag(InstFlags::kEvexTwoOp); }
+ inline bool isEvexTransformable() const noexcept { return hasFlag(InstFlags::kEvexTransformable); }
//! Tests whether the instruction supports AVX512 masking {k}.
- inline bool hasAvx512K() const noexcept { return hasAvx512Flag(kAvx512FlagK); }
+ inline bool hasAvx512K() const noexcept { return hasAvx512Flag(Avx512Flags::kK); }
//! Tests whether the instruction supports AVX512 zeroing {k}{z}.
- inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(kAvx512FlagZ); }
+ inline bool hasAvx512Z() const noexcept { return hasAvx512Flag(Avx512Flags::kZ); }
//! Tests whether the instruction supports AVX512 embedded-rounding {er}.
- inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(kAvx512FlagER); }
+ inline bool hasAvx512ER() const noexcept { return hasAvx512Flag(Avx512Flags::kER); }
//! Tests whether the instruction supports AVX512 suppress-all-exceptions {sae}.
- inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(kAvx512FlagSAE); }
+ inline bool hasAvx512SAE() const noexcept { return hasAvx512Flag(Avx512Flags::kSAE); }
//! Tests whether the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
- inline bool hasAvx512B() const noexcept { return hasAvx512Flag(kAvx512FlagB32 | kAvx512FlagB64); }
+ inline bool hasAvx512B() const noexcept { return hasAvx512Flag(Avx512Flags::kB16 | Avx512Flags::kB32 | Avx512Flags::kB64); }
+ //! Tests whether the instruction supports AVX512 broadcast (16-bit).
+ inline bool hasAvx512B16() const noexcept { return hasAvx512Flag(Avx512Flags::kB16); }
//! Tests whether the instruction supports AVX512 broadcast (32-bit).
- inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(kAvx512FlagB32); }
+ inline bool hasAvx512B32() const noexcept { return hasAvx512Flag(Avx512Flags::kB32); }
//! Tests whether the instruction supports AVX512 broadcast (64-bit).
- inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(kAvx512FlagB64); }
+ inline bool hasAvx512B64() const noexcept { return hasAvx512Flag(Avx512Flags::kB64); }
- //! Gets the control-flow type of the instruction.
- inline uint32_t controlType() const noexcept { return commonInfo().controlType(); }
- inline uint32_t singleRegCase() const noexcept { return commonInfo().singleRegCase(); }
+ //! Returns a control flow category of the instruction.
+ inline InstControlFlow controlFlow() const noexcept { return commonInfo().controlFlow(); }
+ //! Returns a hint that can be used when both inputs are the same register.
+ inline InstSameRegHint sameRegHint() const noexcept { return commonInfo().sameRegHint(); }
inline uint32_t signatureIndex() const noexcept { return commonInfo().signatureIndex(); }
inline uint32_t signatureCount() const noexcept { return commonInfo().signatureCount(); }
inline const InstSignature* signatureData() const noexcept { return commonInfo().signatureData(); }
inline const InstSignature* signatureEnd() const noexcept { return commonInfo().signatureEnd(); }
+
+ //! \}
};
ASMJIT_VARAPI const InstInfo _instInfoTable[];
-static inline const InstInfo& infoById(uint32_t instId) noexcept {
+static inline const InstInfo& infoById(InstId instId) noexcept {
ASMJIT_ASSERT(Inst::isDefinedId(instId));
return _instInfoTable[instId];
}
+//! \cond INTERNAL
+static_assert(sizeof(OpSignature) == 8, "InstDB::OpSignature must be 8 bytes long");
+//! \endcond
+
} // {InstDB}
//! \}
diff --git a/src/asmjit/x86/x86instdb_p.h b/src/asmjit/x86/x86instdb_p.h
index 4573794..9a6f780 100644
--- a/src/asmjit/x86/x86instdb_p.h
+++ b/src/asmjit/x86/x86instdb_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86INSTDB_P_H_INCLUDED
#define ASMJIT_X86_X86INSTDB_P_H_INCLUDED
@@ -34,17 +16,12 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
namespace InstDB {
-// ============================================================================
-// [asmjit::x86::InstDB::Encoding]
-// ============================================================================
-
//! Instruction encoding (X86).
//!
-//! This is a specific identifier that is used by AsmJit to describe the way
-//! each instruction is encoded. Some encodings are special only for a single
-//! instruction as X86 instruction set contains a lot of legacy encodings, and
-//! some encodings describe a group of instructions that share some commons,
-//! like MMX, SSE, AVX, AVX512 instructions, etc...
+//! This is a specific identifier that is used by AsmJit to describe the way each instruction is encoded. Some
+//! encodings are special only for a single instruction as X86 instruction set contains a lot of legacy encodings,
+//! and some encodings describe a group of instructions that share some commons, like MMX, SSE, AVX, AVX512
+//! instructions, etc...
enum EncodingId : uint32_t {
kEncodingNone = 0, //!< Never used.
kEncodingX86Op, //!< X86 [OP].
@@ -210,12 +187,8 @@ enum EncodingId : uint32_t {
kEncodingCount //!< Count of instruction encodings.
};
-// ============================================================================
-// [asmjit::x86::InstDB - CommonInfoTableB]
-// ============================================================================
-
-//! CPU extensions required to execute instruction.
-struct CommonInfoTableB {
+//! Additional information table, provides CPU extensions required to execute an instruction and RW flags.
+struct AdditionalInfo {
//! Features vector.
uint8_t _features[6];
//! Index to `_rwFlagsTable`.
@@ -227,10 +200,6 @@ struct CommonInfoTableB {
inline const uint8_t* featuresEnd() const noexcept { return _features + ASMJIT_ARRAY_SIZE(_features); }
};
-// ============================================================================
-// [asmjit::x86::InstDB - InstNameIndex]
-// ============================================================================
-
// ${NameLimits:Begin}
// ------------------- Automatically generated, do not edit -------------------
enum : uint32_t { kMaxNameSize = 17 };
@@ -242,10 +211,6 @@ struct InstNameIndex {
uint16_t end;
};
-// ============================================================================
-// [asmjit::x86::InstDB - RWInfo]
-// ============================================================================
-
struct RWInfo {
enum Category : uint8_t {
kCategoryGeneric,
@@ -275,8 +240,9 @@ struct RWInfoOp {
uint64_t rByteMask;
uint64_t wByteMask;
uint8_t physId;
- uint8_t reserved[3];
- uint32_t flags;
+ uint8_t consecutiveLeadCount;
+ uint8_t reserved[2];
+ OpRWFlags flags;
};
//! R/M information.
@@ -318,10 +284,6 @@ extern const RWInfoOp rwInfoOp[];
extern const RWInfoRm rwInfoRm[];
extern const RWFlagsInfoTable _rwFlagsInfoTable[];
-// ============================================================================
-// [asmjit::x86::InstDB::Tables]
-// ============================================================================
-
extern const uint32_t _mainOpcodeTable[];
extern const uint32_t _altOpcodeTable[];
@@ -330,7 +292,7 @@ extern const char _nameData[];
extern const InstNameIndex instNameIndex[26];
#endif // !ASMJIT_NO_TEXT
-extern const CommonInfoTableB _commonInfoTableB[];
+extern const AdditionalInfo _additionalInfoTable[];
} // {InstDB}
diff --git a/src/asmjit/x86/x86opcode_p.h b/src/asmjit/x86/x86opcode_p.h
index 80c38fb..94a76f0 100644
--- a/src/asmjit/x86/x86opcode_p.h
+++ b/src/asmjit/x86/x86opcode_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86OPCODE_P_H_INCLUDED
#define ASMJIT_X86_X86OPCODE_P_H_INCLUDED
@@ -32,85 +14,66 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::x86::Opcode]
-// ============================================================================
-
//! Helper class to store and manipulate X86 opcodes.
//!
-//! The first 8 least significant bits describe the opcode byte as defined in
-//! ISA manuals, all other bits describe other properties like prefixes, see
-//! `Opcode::Bits` for more information.
+//! The first 8 least significant bits describe the opcode byte as defined in ISA manuals, all other bits
+//! describe other properties like prefixes, see `Opcode::Bits` for more information.
struct Opcode {
uint32_t v;
//! Describes a meaning of all bits of AsmJit's 32-bit opcode value.
//!
- //! This schema is AsmJit specific and has been designed to allow encoding of
- //! all X86 instructions available. X86, MMX, and SSE+ instructions always use
- //! `MM` and `PP` fields, which are encoded to corresponding prefixes needed
- //! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields
- //! in a VEX prefix, and AVX-512 instructions embed `MM` and `PP` in EVEX prefix.
+ //! This schema is AsmJit specific and has been designed to allow encoding of all X86 instructions available. X86,
+ //! MMX, and SSE+ instructions always use `MM` and `PP` fields, which are encoded to corresponding prefixes needed
+ //! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields in a VEX prefix, and AVX-512
+ //! instructions embed `MM` and `PP` in EVEX prefix.
//!
- //! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1
- //! byte is needed by most of the instructions, 2 bytes are only used by legacy
- //! X87-FPU instructions. This means that a second byte is free to by used by
- //! instructions encoded by using VEX and/or EVEX prefix.
+ //! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1 byte is needed by most of the
+ //! instructions, 2 bytes are only used by legacy X87-FPU instructions. This means that a second byte is free to
+ //! by used by instructions encoded by using VEX and/or EVEX prefix.
//!
//! The fields description:
//!
- //! - `MM` field is used to encode prefixes needed by the instruction or as
- //! a part of VEX/EVEX prefix. Described as `mm` and `mmmmm` in instruction
- //! manuals.
+ //! - `MM` field is used to encode prefixes needed by the instruction or as a part of VEX/EVEX prefix. Described as
+ //! `mm` and `mmmmm` in instruction manuals.
//!
- //! NOTE: Since `MM` field is defined as `mmmmm` (5 bits), but only 2 least
- //! significant bits are used by VEX and EVEX prefixes, and additional 4th
- //! bit is used by XOP prefix, AsmJit uses the 3rd and 5th bit for it's own
- //! purposes. These bits will probably never be used in future encodings as
- //! AVX512 uses only `000mm` from `mmmmm`.
+ //! NOTE: Since `MM` field is defined as `mmmmm` (5 bits), but only 2 least significant bits are used by VEX and
+ //! EVEX prefixes, and additional 4th bit is used by XOP prefix, AsmJit uses the 3rd and 5th bit for it's own
+ //! purposes. These bits will probably never be used in future encodings as AVX512 uses only `000mm` from `mmmmm`.
//!
- //! - `PP` field is used to encode prefixes needed by the instruction or as a
- //! part of VEX/EVEX prefix. Described as `pp` in instruction manuals.
+ //! - `PP` field is used to encode prefixes needed by the instruction or as a part of VEX/EVEX prefix. Described as
+ //! `pp` in instruction manuals.
//!
- //! - `LL` field is used exclusively by AVX+ and AVX512+ instruction sets. It
- //! describes vector size, which is `L.128` for XMM register, `L.256` for
- //! for YMM register, and `L.512` for ZMM register. The `LL` field is omitted
- //! in case that instruction supports multiple vector lengths, however, if the
- //! instruction requires specific `L` value it must be specified as a part of
- //! the opcode.
+ //! - `LL` field is used exclusively by AVX+ and AVX512+ instruction sets. It describes vector size, which is `L.128`
+ //! for XMM register, `L.256` for for YMM register, and `L.512` for ZMM register. The `LL` field is omitted in case
+ //! that instruction supports multiple vector lengths, however, if the instruction requires specific `L` value it
+ //! must be specified as a part of the opcode.
//!
//! NOTE: `LL` having value `11` is not defined yet.
//!
- //! - `W` field is the most complicated. It was added by 64-bit architecture
- //! to promote default operation width (instructions that perform 32-bit
- //! operation by default require to override the width to 64-bit explicitly).
- //! There is nothing wrong on this, however, some instructions introduced
- //! implicit `W` override, for example a `cdqe` instruction is basically a
- //! `cwde` instruction with overridden `W` (set to 1). There are some others
- //! in the base X86 instruction set. More recent instruction sets started
- //! using `W` field more often:
+ //! - `W` field is the most complicated. It was added by 64-bit architecture to promote default operation width
+ //! (instructions that perform 32-bit operation by default require to override the width to 64-bit explicitly).
+ //! There is nothing wrong on this, however, some instructions introduced implicit `W` override, for example a
+ //! `cdqe` instruction is basically a `cwde` instruction with overridden `W` (set to 1). There are some others
+ //! in the base X86 instruction set. More recent instruction sets started using `W` field more often:
//!
- //! - AVX instructions started using `W` field as an extended opcode for FMA,
- //! GATHER, PERM, and other instructions. It also uses `W` field to override
- //! the default operation width in instructions like `vmovq`.
+ //! - AVX instructions started using `W` field as an extended opcode for FMA, GATHER, PERM, and other instructions.
+ //! It also uses `W` field to override the default operation width in instructions like `vmovq`.
//!
- //! - AVX-512 instructions started using `W` field as an extended opcode for
- //! all new instructions. This wouldn't have been an issue if the `W` field
- //! of AVX-512 have matched AVX, but this is not always the case.
+ //! - AVX-512 instructions started using `W` field as an extended opcode for all new instructions. This wouldn't
+ //! have been an issue if the `W` field of AVX-512 have matched AVX, but this is not always the case.
//!
//! - `O` field is an extended opcode field (3 bits) embedded in ModR/M BYTE.
//!
- //! - `CDSHL` and `CDTT` fields describe 'compressed-displacement'. `CDSHL` is
- //! defined for each instruction that is AVX-512 encodable (EVEX) and contains
- //! a base N shift (base shift to perform the calculation). The `CDTT` field
- //! is derived from instruction specification and describes additional shift
- //! to calculate the final `CDSHL` that will be used in SIB byte.
+ //! - `CDSHL` and `CDTT` fields describe 'compressed-displacement'. `CDSHL` is defined for each instruction that is
+ //! AVX-512 encodable (EVEX) and contains a base N shift (base shift to perform the calculation). The `CDTT` field
+ //! is derived from instruction specification and describes additional shift to calculate the final `CDSHL` that
+ //! will be used in SIB byte.
//!
- //! \note Don't reorder any fields here, the shifts and masks were defined
- //! carefully to make encoding of X86 instructions fast, especially to construct
- //! REX, VEX, and EVEX prefixes in the most efficient way. Changing values defined
- //! by these enums many cause AsmJit to emit invalid binary representations of
- //! instructions passed to `x86::Assembler::_emit`.
+ //! \note Don't reorder any fields here, the shifts and masks were defined carefully to make encoding of X86
+ //! instructions fast, especially to construct REX, VEX, and EVEX prefixes in the most efficient way. Changing
+ //! values defined by these enums many cause AsmJit to emit invalid binary representations of instructions passed to
+ //! `x86::Assembler::_emit`.
enum Bits : uint32_t {
// MM & VEX & EVEX & XOP
// ---------------------
@@ -119,22 +82,15 @@ struct Opcode {
// * Part of a legacy opcode (prefixes emitted before the main opcode byte).
// * `MMMMM` field in VEX|EVEX|XOP instruction.
//
- // AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use
- // 2 bits and XOP 3 bits. AVX-512 shrinks `MMMMM` field into `MM` so it's
- // safe to assume that bits [4:2] of `MM` field won't be used in future
- // extensions, which will most probably use EVEX encoding. AsmJit divides
- // MM field into this layout:
+ // AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use 2 bits and XOP 3 bits. AVX-512 shrinks
+ // `MMMMM` field into `MMM` so it's safe to use [4:3] bits of `MMMMM` field for internal payload.
//
- // [1:0] - Used to describe 0F, 0F38 and 0F3A legacy prefix bytes and
- // 2 bits of MM field.
- // [2] - Used to force 3-BYTE VEX prefix, but then cleared to zero before
- // the prefix is emitted. This bit is not used by any instruction
- // so it can be used for any purpose by AsmJit. Also, this bit is
- // used as an extension to `MM` field describing 0F|0F38|0F3A to also
- // describe 0F01 as used by some legacy instructions (instructions
- // not using VEX/EVEX prefix).
- // [3] - Required by XOP instructions, so we use this bit also to indicate
- // that this is a XOP opcode.
+ // AsmJit divides MMMMM field into this layout:
+ //
+ // [2:0] - Used to describe 0F, 0F38 and 0F3A legacy prefix bytes and 3 bits of MMMMM field for XOP/AVX/AVX512.
+ // [3] - Required by XOP instructions, so we use this bit also to indicate that this is a XOP opcode.
+ // [4] - Used to force EVEX prefix - this bit is not used by any X86 instruction yet, so AsmJit uses it to
+ // describe EVEX only instructions or sets its bit when user uses InstOptions::kX86_Evex to force EVEX.
kMM_Shift = 8,
kMM_Mask = 0x1Fu << kMM_Shift,
kMM_00 = 0x00u << kMM_Shift,
@@ -143,11 +99,12 @@ struct Opcode {
kMM_0F3A = 0x03u << kMM_Shift, // Described also as XOP.M3 in AMD manuals.
kMM_0F01 = 0x04u << kMM_Shift, // AsmJit way to describe 0F01 (never VEX/EVEX).
- // `XOP` field is only used to force XOP prefix instead of VEX3 prefix. We
- // know that only XOP encoding uses bit 0b1000 of MM field and that no VEX
- // and EVEX instruction uses such bit, so we can use this bit to force XOP
- // prefix to be emitted instead of VEX3 prefix. See `x86VEXPrefix` defined
- // in `x86assembler.cpp`.
+ kMM_MAP5 = 0x05u << kMM_Shift, // EVEX.MAP5.
+ kMM_MAP6 = 0x06u << kMM_Shift, // EVEX.MAP6.
+
+ // `XOP` field is only used to force XOP prefix instead of VEX3 prefix. We know XOP encodings always use 0b1000
+ // bit of MM field and that no VEX and EVEX instruction use such bit yet, so we can use this bit to force XOP
+ // prefix to be emitted instead of VEX3 prefix. See `x86VEXPrefix` defined in `x86assembler.cpp`.
kMM_XOP08 = 0x08u << kMM_Shift, // XOP.M8.
kMM_XOP09 = 0x09u << kMM_Shift, // XOP.M9.
kMM_XOP0A = 0x0Au << kMM_Shift, // XOP.MA.
@@ -155,21 +112,17 @@ struct Opcode {
kMM_IsXOP_Shift= kMM_Shift + 3,
kMM_IsXOP = kMM_XOP08,
- // NOTE: Force VEX3 allows to force to emit VEX3 instead of VEX2 in some
- // cases (similar to forcing REX prefix). Force EVEX will force emitting
- // EVEX prefix instead of VEX2|VEX3. EVEX-only instructions will have
- // ForceEvex always set, however. instructions that can be encoded by
- // either VEX or EVEX prefix should not have ForceEvex set.
-
- kMM_ForceVex3 = 0x04u << kMM_Shift, // Force 3-BYTE VEX prefix.
+ // NOTE: Force VEX3 allows to force to emit VEX3 instead of VEX2 in some cases (similar to forcing REX prefix).
+ // Force EVEX will force emitting EVEX prefix instead of VEX2|VEX3. EVEX-only instructions will have ForceEvex
+ // always set, however. instructions that can be encoded by either VEX or EVEX prefix should not have ForceEvex
+ // set.
kMM_ForceEvex = 0x10u << kMM_Shift, // Force 4-BYTE EVEX prefix.
// FPU_2B - Second-Byte of the Opcode used by FPU
// ----------------------------------------------
//
- // Second byte opcode. This BYTE is ONLY used by FPU instructions and
- // collides with 3 bits from `MM` and 5 bits from 'CDSHL' and 'CDTT'.
- // It's fine as FPU and AVX512 flags are never used at the same time.
+ // Second byte opcode. This BYTE is ONLY used by FPU instructions and collides with 3 bits from `MM` and 5 bits
+ // from 'CDSHL' and 'CDTT'. It's fine as FPU and AVX512 flags are never used at the same time.
kFPU_2B_Shift = 10,
kFPU_2B_Mask = 0xFF << kFPU_2B_Shift,
@@ -203,8 +156,8 @@ struct Opcode {
// Compressed displacement tuple-type (specific to AsmJit).
//
- // Since we store the base offset independently of CDTT we can simplify the
- // number of 'TUPLE_TYPE' groups significantly and just handle special cases.
+ // Since we store the base offset independently of CDTT we can simplify the number of 'TUPLE_TYPE' groups
+ // significantly and just handle special cases.
kCDTT_Shift = 16,
kCDTT_Mask = 0x3u << kCDTT_Shift,
kCDTT_None = 0x0u << kCDTT_Shift, // Does nothing.
@@ -216,10 +169,12 @@ struct Opcode {
kCDTT__ = kCDTT_None,
kCDTT_FV = kCDTT_ByLL,
kCDTT_HV = kCDTT_ByLL,
+ kCDTT_QV = kCDTT_ByLL,
kCDTT_FVM = kCDTT_ByLL,
kCDTT_T1S = kCDTT_None,
kCDTT_T1F = kCDTT_None,
kCDTT_T1_4X = kCDTT_None,
+ kCDTT_T4X = kCDTT_None, // Alias to have only 3 letters.
kCDTT_T2 = kCDTT_None,
kCDTT_T4 = kCDTT_None,
kCDTT_T8 = kCDTT_None,
@@ -228,8 +183,6 @@ struct Opcode {
kCDTT_OVM = kCDTT_ByLL,
kCDTT_128 = kCDTT_None,
- kCDTT_T4X = kCDTT_T1_4X, // Alias to have only 3 letters.
-
// `O` Field in ModR/M (??:xxx:???)
// --------------------------------
@@ -249,9 +202,8 @@ struct Opcode {
// `RM` Field in ModR/M (??:???:xxx)
// ---------------------------------
//
- // Second data field used by ModR/M byte. This is only used by few
- // instructions that use OPCODE+MOD/RM where both values in Mod/RM
- // are part of the opcode.
+ // Second data field used by ModR/M byte. This is only used by few instructions that use OPCODE+MOD/RM where both
+ // values in Mod/RM are part of the opcode.
kModRM_Shift = 13,
kModRM_Mask = 0x7u << kModRM_Shift,
@@ -269,16 +221,15 @@ struct Opcode {
// `PP` Field
// ----------
//
- // These fields are stored deliberately right after each other as it makes
- // it easier to construct VEX prefix from the opcode value stored in the
- // instruction database.
+ // These fields are stored deliberately right after each other as it makes it easier to construct VEX prefix from
+ // the opcode value stored in the instruction database.
//
// Two meanings:
// * "PP" field in AVX/XOP/AVX-512 instruction.
// * Mandatory Prefix in legacy encoding.
//
- // AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1
- // more bit that is used to emit 9B prefix for some X87-FPU instructions.
+ // AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1 more bit that is used to emit 9B prefix
+ // for some X87-FPU instructions.
kPP_Shift = 21,
kPP_VEXMask = 0x03u << kPP_Shift, // PP field mask used by VEX/EVEX.
@@ -293,9 +244,8 @@ struct Opcode {
// REX|VEX|EVEX B|X|R|W Bits
// -------------------------
//
- // NOTE: REX.[B|X|R] are never stored within the opcode itself, they are
- // reserved by AsmJit are are added dynamically to the opcode to represent
- // [REX|VEX|EVEX].[B|X|R] bits. REX.W can be stored in DB as it's sometimes
+ // NOTE: REX.[B|X|R] are never stored within the opcode itself, they are reserved by AsmJit are are added
+ // dynamically to the opcode to represent [REX|VEX|EVEX].[B|X|R] bits. REX.W can be stored in DB as it's sometimes
// part of the opcode itself.
// These must be binary compatible with instruction options.
@@ -330,11 +280,9 @@ struct Opcode {
// `L` or `LL` field in AVX/XOP/AVX-512
// ------------------------------------
//
- // VEX/XOP prefix can only use the first bit `L.128` or `L.256`. EVEX prefix
- // prefix makes it possible to use also `L.512`.
- //
- // If the instruction set manual describes an instruction by `LIG` it means
- // that the `L` field is ignored and AsmJit defaults to `0` in such case.
+ // VEX/XOP prefix can only use the first bit `L.128` or `L.256`. EVEX prefix prefix makes it possible to use also
+ // `L.512`. If the instruction set manual describes an instruction by `LIG` it means that the `L` field is ignored
+ // and AsmJit defaults to `0` in such case.
kLL_Shift = 29,
kLL_Mask = 0x3u << kLL_Shift,
@@ -353,23 +301,31 @@ struct Opcode {
k000F00 = kPP_00 | kMM_0F, // '0F'
k000F01 = kPP_00 | kMM_0F01, // '0F01'
k000F0F = kPP_00 | kMM_0F, // '0F0F' - 3DNOW, equal to 0x0F, must have special encoding to take effect.
- k000F38 = kPP_00 | kMM_0F38, // '0F38'
- k000F3A = kPP_00 | kMM_0F3A, // '0F3A'
+ k000F38 = kPP_00 | kMM_0F38, // 'NP.0F38'
+ k000F3A = kPP_00 | kMM_0F3A, // 'NP.0F3A'
+ k00MAP5 = kPP_00 | kMM_MAP5, // 'NP.MAP5'
+ k00MAP6 = kPP_00 | kMM_MAP6, // 'NP.MAP5'
k660000 = kPP_66 | kMM_00, // '66'
- k660F00 = kPP_66 | kMM_0F, // '660F'
- k660F01 = kPP_66 | kMM_0F01, // '660F01'
- k660F38 = kPP_66 | kMM_0F38, // '660F38'
- k660F3A = kPP_66 | kMM_0F3A, // '660F3A'
+ k660F00 = kPP_66 | kMM_0F, // '66.0F'
+ k660F01 = kPP_66 | kMM_0F01, // '66.0F01'
+ k660F38 = kPP_66 | kMM_0F38, // '66.0F38'
+ k660F3A = kPP_66 | kMM_0F3A, // '66.0F3A'
+ k66MAP5 = kPP_66 | kMM_MAP5, // '66.MAP5'
+ k66MAP6 = kPP_66 | kMM_MAP6, // '66.MAP5'
kF20000 = kPP_F2 | kMM_00, // 'F2'
- kF20F00 = kPP_F2 | kMM_0F, // 'F20F'
- kF20F01 = kPP_F2 | kMM_0F01, // 'F20F01'
- kF20F38 = kPP_F2 | kMM_0F38, // 'F20F38'
- kF20F3A = kPP_F2 | kMM_0F3A, // 'F20F3A'
+ kF20F00 = kPP_F2 | kMM_0F, // 'F2.0F'
+ kF20F01 = kPP_F2 | kMM_0F01, // 'F2.0F01'
+ kF20F38 = kPP_F2 | kMM_0F38, // 'F2.0F38'
+ kF20F3A = kPP_F2 | kMM_0F3A, // 'F2.0F3A'
+ kF2MAP5 = kPP_F2 | kMM_MAP5, // 'F2.MAP5'
+ kF2MAP6 = kPP_F2 | kMM_MAP6, // 'F2.MAP5'
kF30000 = kPP_F3 | kMM_00, // 'F3'
- kF30F00 = kPP_F3 | kMM_0F, // 'F30F'
- kF30F01 = kPP_F3 | kMM_0F01, // 'F30F01'
- kF30F38 = kPP_F3 | kMM_0F38, // 'F30F38'
- kF30F3A = kPP_F3 | kMM_0F3A, // 'F30F3A'
+ kF30F00 = kPP_F3 | kMM_0F, // 'F3.0F'
+ kF30F01 = kPP_F3 | kMM_0F01, // 'F3.0F01'
+ kF30F38 = kPP_F3 | kMM_0F38, // 'F3.0F38'
+ kF30F3A = kPP_F3 | kMM_0F3A, // 'F3.0F3A'
+ kF3MAP5 = kPP_F3 | kMM_MAP5, // 'F3.MAP5'
+ kF3MAP6 = kPP_F3 | kMM_MAP6, // 'F3.MAP5'
kFPU_00 = kPP_00 | kMM_00, // '__' (FPU)
kFPU_9B = kPP_9B | kMM_00, // '9B' (FPU)
kXOP_M8 = kPP_00 | kMM_XOP08, // 'M8' (XOP)
@@ -377,31 +333,30 @@ struct Opcode {
kXOP_MA = kPP_00 | kMM_XOP0A // 'MA' (XOP)
};
- // --------------------------------------------------------------------------
- // [Opcode Builder]
- // --------------------------------------------------------------------------
+ // Opcode Builder
+ // --------------
- ASMJIT_INLINE uint32_t get() const noexcept { return v; }
+ inline uint32_t get() const noexcept { return v; }
- ASMJIT_INLINE bool hasW() const noexcept { return (v & kW) != 0; }
- ASMJIT_INLINE bool has66h() const noexcept { return (v & kPP_66) != 0; }
+ inline bool hasW() const noexcept { return (v & kW) != 0; }
+ inline bool has66h() const noexcept { return (v & kPP_66) != 0; }
- ASMJIT_INLINE Opcode& add(uint32_t x) noexcept { return operator+=(x); }
+ inline Opcode& add(uint32_t x) noexcept { return operator+=(x); }
- ASMJIT_INLINE Opcode& add66h() noexcept { return operator|=(kPP_66); }
+ inline Opcode& add66h() noexcept { return operator|=(kPP_66); }
template<typename T>
- ASMJIT_INLINE Opcode& add66hIf(T exp) noexcept { return operator|=(uint32_t(exp) << kPP_Shift); }
+ inline Opcode& add66hIf(T exp) noexcept { return operator|=(uint32_t(exp) << kPP_Shift); }
template<typename T>
- ASMJIT_INLINE Opcode& add66hBySize(T size) noexcept { return add66hIf(size == 2); }
+ inline Opcode& add66hBySize(T size) noexcept { return add66hIf(size == 2); }
- ASMJIT_INLINE Opcode& addW() noexcept { return operator|=(kW); }
+ inline Opcode& addW() noexcept { return operator|=(kW); }
template<typename T>
- ASMJIT_INLINE Opcode& addWIf(T exp) noexcept { return operator|=(uint32_t(exp) << kW_Shift); }
+ inline Opcode& addWIf(T exp) noexcept { return operator|=(uint32_t(exp) << kW_Shift); }
template<typename T>
- ASMJIT_INLINE Opcode& addWBySize(T size) noexcept { return addWIf(size == 8); }
+ inline Opcode& addWBySize(T size) noexcept { return addWIf(size == 8); }
template<typename T>
- ASMJIT_INLINE Opcode& addPrefixBySize(T size) noexcept {
+ inline Opcode& addPrefixBySize(T size) noexcept {
static const uint32_t mask[16] = {
0, // #0
0, // #1 -> nothing (already handled or not possible)
@@ -417,7 +372,7 @@ struct Opcode {
}
template<typename T>
- ASMJIT_INLINE Opcode& addArithBySize(T size) noexcept {
+ inline Opcode& addArithBySize(T size) noexcept {
static const uint32_t mask[16] = {
0, // #0
0, // #1 -> nothing
@@ -432,46 +387,45 @@ struct Opcode {
return operator|=(mask[size & 0xF]);
}
- ASMJIT_INLINE Opcode& forceEvex() noexcept { return operator|=(kMM_ForceEvex); }
+ inline Opcode& forceEvex() noexcept { return operator|=(kMM_ForceEvex); }
template<typename T>
- ASMJIT_INLINE Opcode& forceEvexIf(T exp) noexcept { return operator|=(uint32_t(exp) << Support::constCtz(uint32_t(kMM_ForceEvex))); }
+ inline Opcode& forceEvexIf(T exp) noexcept { return operator|=(uint32_t(exp) << Support::ConstCTZ<uint32_t(kMM_ForceEvex)>::value); }
//! Extract `O` field (R) from the opcode (specified as /0..7 in instruction manuals).
- ASMJIT_INLINE uint32_t extractModO() const noexcept {
+ inline uint32_t extractModO() const noexcept {
return (v >> kModO_Shift) & 0x07;
}
//! Extract `RM` field (RM) from the opcode (usually specified as another opcode value).
- ASMJIT_INLINE uint32_t extractModRM() const noexcept {
+ inline uint32_t extractModRM() const noexcept {
return (v >> kModRM_Shift) & 0x07;
}
//! Extract `REX` prefix from opcode combined with `options`.
- ASMJIT_INLINE uint32_t extractRex(uint32_t options) const noexcept {
- // kREX was designed in a way that when shifted there will be no bytes
- // set except REX.[B|X|R|W]. The returned value forms a real REX prefix byte.
- // This case should be unit-tested as well.
- return (v | options) >> kREX_Shift;
+ inline uint32_t extractRex(InstOptions options) const noexcept {
+ // kREX was designed in a way that when shifted there will be no bytes set except REX.[B|X|R|W].
+ // The returned value forms a real REX prefix byte. This case should be unit-tested as well.
+ return (v | uint32_t(options)) >> kREX_Shift;
}
- ASMJIT_INLINE uint32_t extractLLMM(uint32_t options) const noexcept {
- uint32_t x = v & (kLL_Mask | kMM_Mask);
- uint32_t y = options & (Inst::kOptionVex3 | Inst::kOptionEvex);
- return (x | y) >> kMM_Shift;
+ inline uint32_t extractLLMMMMM(InstOptions options) const noexcept {
+ uint32_t llMmmmm = uint32_t(v & (kLL_Mask | kMM_Mask));
+ uint32_t vexEvex = uint32_t(options & InstOptions::kX86_Evex);
+ return (llMmmmm | vexEvex) >> kMM_Shift;
}
- ASMJIT_INLINE Opcode& operator=(uint32_t x) noexcept { v = x; return *this; }
- ASMJIT_INLINE Opcode& operator+=(uint32_t x) noexcept { v += x; return *this; }
- ASMJIT_INLINE Opcode& operator-=(uint32_t x) noexcept { v -= x; return *this; }
- ASMJIT_INLINE Opcode& operator&=(uint32_t x) noexcept { v &= x; return *this; }
- ASMJIT_INLINE Opcode& operator|=(uint32_t x) noexcept { v |= x; return *this; }
- ASMJIT_INLINE Opcode& operator^=(uint32_t x) noexcept { v ^= x; return *this; }
-
- ASMJIT_INLINE uint32_t operator&(uint32_t x) const noexcept { return v & x; }
- ASMJIT_INLINE uint32_t operator|(uint32_t x) const noexcept { return v | x; }
- ASMJIT_INLINE uint32_t operator^(uint32_t x) const noexcept { return v ^ x; }
- ASMJIT_INLINE uint32_t operator<<(uint32_t x) const noexcept { return v << x; }
- ASMJIT_INLINE uint32_t operator>>(uint32_t x) const noexcept { return v >> x; }
+ inline Opcode& operator=(uint32_t x) noexcept { v = x; return *this; }
+ inline Opcode& operator+=(uint32_t x) noexcept { v += x; return *this; }
+ inline Opcode& operator-=(uint32_t x) noexcept { v -= x; return *this; }
+ inline Opcode& operator&=(uint32_t x) noexcept { v &= x; return *this; }
+ inline Opcode& operator|=(uint32_t x) noexcept { v |= x; return *this; }
+ inline Opcode& operator^=(uint32_t x) noexcept { v ^= x; return *this; }
+
+ inline uint32_t operator&(uint32_t x) const noexcept { return v & x; }
+ inline uint32_t operator|(uint32_t x) const noexcept { return v | x; }
+ inline uint32_t operator^(uint32_t x) const noexcept { return v ^ x; }
+ inline uint32_t operator<<(uint32_t x) const noexcept { return v << x; }
+ inline uint32_t operator>>(uint32_t x) const noexcept { return v >> x; }
};
//! \}
diff --git a/src/asmjit/x86/x86operand.cpp b/src/asmjit/x86/x86operand.cpp
index 47270c0..a47fec2 100644
--- a/src/asmjit/x86/x86operand.cpp
+++ b/src/asmjit/x86/x86operand.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86)
@@ -29,9 +11,8 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::Operand - Unit]
-// ============================================================================
+// x86::Operand - Tests
+// ====================
#if defined(ASMJIT_TEST)
UNIT(x86_operand) {
@@ -92,16 +73,16 @@ UNIT(x86_operand) {
EXPECT(eax.isReg() == true);
EXPECT(eax.id() == 0);
EXPECT(eax.size() == 4);
- EXPECT(eax.type() == Reg::kTypeGpd);
- EXPECT(eax.group() == Reg::kGroupGp);
+ EXPECT(eax.type() == RegType::kX86_Gpd);
+ EXPECT(eax.group() == RegGroup::kGp);
INFO("Checking x86::Xmm register properties");
EXPECT(Xmm().isReg() == true);
EXPECT(xmm4.isReg() == true);
EXPECT(xmm4.id() == 4);
EXPECT(xmm4.size() == 16);
- EXPECT(xmm4.type() == Reg::kTypeXmm);
- EXPECT(xmm4.group() == Reg::kGroupVec);
+ EXPECT(xmm4.type() == RegType::kX86_Xmm);
+ EXPECT(xmm4.group() == RegGroup::kVec);
EXPECT(xmm4.isVec());
INFO("Checking x86::Ymm register properties");
@@ -109,8 +90,8 @@ UNIT(x86_operand) {
EXPECT(ymm5.isReg() == true);
EXPECT(ymm5.id() == 5);
EXPECT(ymm5.size() == 32);
- EXPECT(ymm5.type() == Reg::kTypeYmm);
- EXPECT(ymm5.group() == Reg::kGroupVec);
+ EXPECT(ymm5.type() == RegType::kX86_Ymm);
+ EXPECT(ymm5.group() == RegGroup::kVec);
EXPECT(ymm5.isVec());
INFO("Checking x86::Zmm register properties");
@@ -118,8 +99,8 @@ UNIT(x86_operand) {
EXPECT(zmm6.isReg() == true);
EXPECT(zmm6.id() == 6);
EXPECT(zmm6.size() == 64);
- EXPECT(zmm6.type() == Reg::kTypeZmm);
- EXPECT(zmm6.group() == Reg::kGroupVec);
+ EXPECT(zmm6.type() == RegType::kX86_Zmm);
+ EXPECT(zmm6.group() == RegGroup::kVec);
EXPECT(zmm6.isVec());
INFO("Checking x86::Vec register properties");
@@ -149,24 +130,24 @@ UNIT(x86_operand) {
EXPECT(mm2.isReg() == true);
EXPECT(mm2.id() == 2);
EXPECT(mm2.size() == 8);
- EXPECT(mm2.type() == Reg::kTypeMm);
- EXPECT(mm2.group() == Reg::kGroupMm);
+ EXPECT(mm2.type() == RegType::kX86_Mm);
+ EXPECT(mm2.group() == RegGroup::kX86_MM);
INFO("Checking x86::KReg register properties");
EXPECT(KReg().isReg() == true);
EXPECT(k3.isReg() == true);
EXPECT(k3.id() == 3);
EXPECT(k3.size() == 0);
- EXPECT(k3.type() == Reg::kTypeKReg);
- EXPECT(k3.group() == Reg::kGroupKReg);
+ EXPECT(k3.type() == RegType::kX86_KReg);
+ EXPECT(k3.group() == RegGroup::kX86_K);
INFO("Checking x86::St register properties");
EXPECT(St().isReg() == true);
EXPECT(st1.isReg() == true);
EXPECT(st1.id() == 1);
EXPECT(st1.size() == 10);
- EXPECT(st1.type() == Reg::kTypeSt);
- EXPECT(st1.group() == Reg::kGroupSt);
+ EXPECT(st1.type() == RegType::kX86_St);
+ EXPECT(st1.group() == RegGroup::kX86_St);
INFO("Checking if default constructed regs behave as expected");
EXPECT(Reg().isValid() == false);
@@ -207,13 +188,15 @@ UNIT(x86_operand) {
m.addOffset(1);
EXPECT(m.offset() == int64_t(0x0123456789ABCDF0u));
- m = ptr(0x0123456789ABCDEFu, rdi, 4);
+ m = ptr(0x0123456789ABCDEFu, rdi, 3);
+ EXPECT(m.hasSegment() == false);
EXPECT(m.hasBase() == false);
EXPECT(m.hasBaseReg() == false);
EXPECT(m.hasIndex() == true);
EXPECT(m.hasIndexReg() == true);
EXPECT(m.indexType() == rdi.type());
EXPECT(m.indexId() == rdi.id());
+ EXPECT(m.shift() == 3);
EXPECT(m.hasOffset() == true);
EXPECT(m.isOffset64Bit() == true);
EXPECT(m.offset() == int64_t(0x0123456789ABCDEFu));
@@ -229,7 +212,7 @@ UNIT(x86_operand) {
EXPECT(m.baseId() == rax.id());
EXPECT(m.hasIndex() == false);
EXPECT(m.hasIndexReg() == false);
- EXPECT(m.indexType() == 0);
+ EXPECT(m.indexType() == RegType::kNone);
EXPECT(m.indexId() == 0);
EXPECT(m.hasOffset() == false);
EXPECT(m.isOffset64Bit() == false);
diff --git a/src/asmjit/x86/x86operand.h b/src/asmjit/x86/x86operand.h
index 917c0f9..bfd09bd 100644
--- a/src/asmjit/x86/x86operand.h
+++ b/src/asmjit/x86/x86operand.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86OPERAND_H_INCLUDED
#define ASMJIT_X86_X86OPERAND_H_INCLUDED
@@ -31,62 +13,9 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-#define ASMJIT_MEM_PTR(FUNC, SIZE) \
- static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
- return Mem(base, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
- return Mem(base, index, shift, offset, SIZE); \
- } \
- static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
- return Mem(rip_, offset, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base) noexcept { \
- return Mem(base, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE); \
- } \
- \
- static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
- return Mem(base, SIZE, Mem::kSignatureMemAbs); \
- } \
- static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs); \
- } \
- static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs); \
- } \
- \
- static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
- return Mem(base, SIZE, Mem::kSignatureMemRel); \
- } \
- static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, Mem::kSignatureMemRel); \
- } \
- static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
- return Mem(base, index, shift, SIZE, Mem::kSignatureMemRel); \
- }
-
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [Forward Declarations]
-// ============================================================================
-
class Reg;
class Mem;
@@ -111,40 +40,35 @@ class Bnd;
class Tmm;
class Rip;
-// ============================================================================
-// [asmjit::x86::Reg]
-// ============================================================================
-
//! Register traits (X86).
//!
-//! Register traits contains information about a particular register type. It's
-//! used by asmjit to setup register information on-the-fly and to populate
-//! tables that contain register information (this way it's possible to change
+//! Register traits contains information about a particular register type. It's used by asmjit to setup register
+//! information on-the-fly and to populate tables that contain register information (this way it's possible to change
//! register types and groups without having to reorder these tables).
-template<uint32_t REG_TYPE>
+template<RegType kRegType>
struct RegTraits : public BaseRegTraits {};
//! \cond
-// <--------------------+-----+-------------------------+------------------------+---+---+----------------+
-// | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
-// <--------------------+-----+-------------------------+------------------------+---+---+----------------+
-ASMJIT_DEFINE_REG_TRAITS(GpbLo, BaseReg::kTypeGp8Lo , BaseReg::kGroupGp , 1 , 16, Type::kIdI8 );
-ASMJIT_DEFINE_REG_TRAITS(GpbHi, BaseReg::kTypeGp8Hi , BaseReg::kGroupGp , 1 , 4 , Type::kIdI8 );
-ASMJIT_DEFINE_REG_TRAITS(Gpw , BaseReg::kTypeGp16 , BaseReg::kGroupGp , 2 , 16, Type::kIdI16 );
-ASMJIT_DEFINE_REG_TRAITS(Gpd , BaseReg::kTypeGp32 , BaseReg::kGroupGp , 4 , 16, Type::kIdI32 );
-ASMJIT_DEFINE_REG_TRAITS(Gpq , BaseReg::kTypeGp64 , BaseReg::kGroupGp , 8 , 16, Type::kIdI64 );
-ASMJIT_DEFINE_REG_TRAITS(Xmm , BaseReg::kTypeVec128 , BaseReg::kGroupVec , 16, 32, Type::kIdI32x4 );
-ASMJIT_DEFINE_REG_TRAITS(Ymm , BaseReg::kTypeVec256 , BaseReg::kGroupVec , 32, 32, Type::kIdI32x8 );
-ASMJIT_DEFINE_REG_TRAITS(Zmm , BaseReg::kTypeVec512 , BaseReg::kGroupVec , 64, 32, Type::kIdI32x16);
-ASMJIT_DEFINE_REG_TRAITS(Mm , BaseReg::kTypeOther0 , BaseReg::kGroupOther0 , 8 , 8 , Type::kIdMmx64 );
-ASMJIT_DEFINE_REG_TRAITS(KReg , BaseReg::kTypeOther1 , BaseReg::kGroupOther1 , 0 , 8 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(SReg , BaseReg::kTypeCustom + 0, BaseReg::kGroupVirt + 0, 2 , 7 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(CReg , BaseReg::kTypeCustom + 1, BaseReg::kGroupVirt + 1, 0 , 16, Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(DReg , BaseReg::kTypeCustom + 2, BaseReg::kGroupVirt + 2, 0 , 16, Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(St , BaseReg::kTypeCustom + 3, BaseReg::kGroupVirt + 3, 10, 8 , Type::kIdF80 );
-ASMJIT_DEFINE_REG_TRAITS(Bnd , BaseReg::kTypeCustom + 4, BaseReg::kGroupVirt + 4, 16, 4 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(Tmm , BaseReg::kTypeCustom + 5, BaseReg::kGroupVirt + 5, 0 , 8 , Type::kIdVoid );
-ASMJIT_DEFINE_REG_TRAITS(Rip , BaseReg::kTypeIP , BaseReg::kGroupVirt + 6, 0 , 1 , Type::kIdVoid );
+// <--------------------+-----+-------------------------+------------------------+---+---+------------------+
+// | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
+// <--------------------+-----+-------------------------+------------------------+---+---+------------------+
+ASMJIT_DEFINE_REG_TRAITS(Rip , RegType::kX86_Rip , RegGroup::kX86_Rip , 0 , 1 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(GpbLo, RegType::kX86_GpbLo , RegGroup::kGp , 1 , 16, TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(GpbHi, RegType::kX86_GpbHi , RegGroup::kGp , 1 , 4 , TypeId::kInt8 );
+ASMJIT_DEFINE_REG_TRAITS(Gpw , RegType::kX86_Gpw , RegGroup::kGp , 2 , 16, TypeId::kInt16 );
+ASMJIT_DEFINE_REG_TRAITS(Gpd , RegType::kX86_Gpd , RegGroup::kGp , 4 , 16, TypeId::kInt32 );
+ASMJIT_DEFINE_REG_TRAITS(Gpq , RegType::kX86_Gpq , RegGroup::kGp , 8 , 16, TypeId::kInt64 );
+ASMJIT_DEFINE_REG_TRAITS(Xmm , RegType::kX86_Xmm , RegGroup::kVec , 16, 32, TypeId::kInt32x4 );
+ASMJIT_DEFINE_REG_TRAITS(Ymm , RegType::kX86_Ymm , RegGroup::kVec , 32, 32, TypeId::kInt32x8 );
+ASMJIT_DEFINE_REG_TRAITS(Zmm , RegType::kX86_Zmm , RegGroup::kVec , 64, 32, TypeId::kInt32x16);
+ASMJIT_DEFINE_REG_TRAITS(KReg , RegType::kX86_KReg , RegGroup::kX86_K , 0 , 8 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(Mm , RegType::kX86_Mm , RegGroup::kX86_MM , 8 , 8 , TypeId::kMmx64 );
+ASMJIT_DEFINE_REG_TRAITS(SReg , RegType::kX86_SReg , RegGroup::kX86_SReg , 2 , 7 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(CReg , RegType::kX86_CReg , RegGroup::kX86_CReg , 0 , 16, TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(DReg , RegType::kX86_DReg , RegGroup::kX86_DReg , 0 , 16, TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(St , RegType::kX86_St , RegGroup::kX86_St , 10, 8 , TypeId::kFloat80 );
+ASMJIT_DEFINE_REG_TRAITS(Bnd , RegType::kX86_Bnd , RegGroup::kX86_Bnd , 16, 4 , TypeId::kVoid );
+ASMJIT_DEFINE_REG_TRAITS(Tmm , RegType::kX86_Tmm , RegGroup::kX86_Tmm , 0 , 8 , TypeId::kVoid );
//! \endcond
//! Register (X86).
@@ -152,160 +76,84 @@ class Reg : public BaseReg {
public:
ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
- //! Register type.
- enum RegType : uint32_t {
- //! No register type or invalid register.
- kTypeNone = BaseReg::kTypeNone,
-
- //! Low GPB register (AL, BL, CL, DL, ...).
- kTypeGpbLo = BaseReg::kTypeGp8Lo,
- //! High GPB register (AH, BH, CH, DH only).
- kTypeGpbHi = BaseReg::kTypeGp8Hi,
- //! GPW register.
- kTypeGpw = BaseReg::kTypeGp16,
- //! GPD register.
- kTypeGpd = BaseReg::kTypeGp32,
- //! GPQ register (64-bit).
- kTypeGpq = BaseReg::kTypeGp64,
- //! XMM register (SSE+).
- kTypeXmm = BaseReg::kTypeVec128,
- //! YMM register (AVX+).
- kTypeYmm = BaseReg::kTypeVec256,
- //! ZMM register (AVX512+).
- kTypeZmm = BaseReg::kTypeVec512,
- //! MMX register.
- kTypeMm = BaseReg::kTypeOther0,
- //! K register (AVX512+).
- kTypeKReg = BaseReg::kTypeOther1,
- //! Instruction pointer (EIP, RIP).
- kTypeRip = BaseReg::kTypeIP,
- //! Segment register (None, ES, CS, SS, DS, FS, GS).
- kTypeSReg = BaseReg::kTypeCustom + 0,
- //! Control register (CR).
- kTypeCReg = BaseReg::kTypeCustom + 1,
- //! Debug register (DR).
- kTypeDReg = BaseReg::kTypeCustom + 2,
- //! FPU (x87) register.
- kTypeSt = BaseReg::kTypeCustom + 3,
- //! Bound register (BND).
- kTypeBnd = BaseReg::kTypeCustom + 4,
- //! TMM register (AMX_TILE)
- kTypeTmm = BaseReg::kTypeCustom + 5,
-
- //! Count of register types.
- kTypeCount = BaseReg::kTypeCustom + 6
- };
-
- //! Register group.
- enum RegGroup : uint32_t {
- //! GP register group or none (universal).
- kGroupGp = BaseReg::kGroupGp,
- //! XMM|YMM|ZMM register group (universal).
- kGroupVec = BaseReg::kGroupVec,
- //! MMX register group (legacy).
- kGroupMm = BaseReg::kGroupOther0,
- //! K register group.
- kGroupKReg = BaseReg::kGroupOther1,
-
- // These are not managed by Compiler nor used by Func-API:
-
- //! Segment register group.
- kGroupSReg = BaseReg::kGroupVirt+0,
- //! Control register group.
- kGroupCReg = BaseReg::kGroupVirt+1,
- //! Debug register group.
- kGroupDReg = BaseReg::kGroupVirt+2,
- //! FPU register group.
- kGroupSt = BaseReg::kGroupVirt+3,
- //! Bound register group.
- kGroupBnd = BaseReg::kGroupVirt+4,
- //! TMM register group.
- kGroupTmm = BaseReg::kGroupVirt+5,
- //! Instruction pointer (IP).
- kGroupRip = BaseReg::kGroupVirt+6,
-
- //! Count of all register groups.
- kGroupCount
- };
-
//! Tests whether the register is a GPB register (8-bit).
- constexpr bool isGpb() const noexcept { return size() == 1; }
+ inline constexpr bool isGpb() const noexcept { return size() == 1; }
//! Tests whether the register is a low GPB register (8-bit).
- constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<kTypeGpbLo>::kSignature); }
+ inline constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
//! Tests whether the register is a high GPB register (8-bit).
- constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<kTypeGpbHi>::kSignature); }
+ inline constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
//! Tests whether the register is a GPW register (16-bit).
- constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<kTypeGpw>::kSignature); }
+ inline constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
//! Tests whether the register is a GPD register (32-bit).
- constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<kTypeGpd>::kSignature); }
+ inline constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
//! Tests whether the register is a GPQ register (64-bit).
- constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<kTypeGpq>::kSignature); }
+ inline constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
//! Tests whether the register is an XMM register (128-bit).
- constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<kTypeXmm>::kSignature); }
+ inline constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
//! Tests whether the register is a YMM register (256-bit).
- constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<kTypeYmm>::kSignature); }
+ inline constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
//! Tests whether the register is a ZMM register (512-bit).
- constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<kTypeZmm>::kSignature); }
+ inline constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
//! Tests whether the register is an MMX register (64-bit).
- constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<kTypeMm>::kSignature); }
+ inline constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
//! Tests whether the register is a K register (64-bit).
- constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<kTypeKReg>::kSignature); }
+ inline constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
//! Tests whether the register is a segment register.
- constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<kTypeSReg>::kSignature); }
+ inline constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
//! Tests whether the register is a control register.
- constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<kTypeCReg>::kSignature); }
+ inline constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
//! Tests whether the register is a debug register.
- constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<kTypeDReg>::kSignature); }
+ inline constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
//! Tests whether the register is an FPU register (80-bit).
- constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<kTypeSt>::kSignature); }
+ inline constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
//! Tests whether the register is a bound register.
- constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<kTypeBnd>::kSignature); }
+ inline constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
//! Tests whether the register is a TMM register.
- constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<kTypeTmm>::kSignature); }
+ inline constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
//! Tests whether the register is RIP.
- constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<kTypeRip>::kSignature); }
+ inline constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
- template<uint32_t REG_TYPE>
+ template<RegType REG_TYPE>
inline void setRegT(uint32_t rId) noexcept {
- setSignature(RegTraits<REG_TYPE>::kSignature);
+ setSignature(OperandSignature(RegTraits<REG_TYPE>::kSignature));
setId(rId);
}
- inline void setTypeAndId(uint32_t rType, uint32_t rId) noexcept {
- ASMJIT_ASSERT(rType < kTypeCount);
- setSignature(signatureOf(rType));
- setId(rId);
+ inline void setTypeAndId(RegType type, uint32_t id) noexcept {
+ setSignature(signatureOf(type));
+ setId(id);
}
- static inline uint32_t groupOf(uint32_t rType) noexcept { return _archTraits[Environment::kArchX86].regTypeToGroup(rType); }
- static inline uint32_t typeIdOf(uint32_t rType) noexcept { return _archTraits[Environment::kArchX86].regTypeToTypeId(rType); }
- static inline uint32_t signatureOf(uint32_t rType) noexcept { return _archTraits[Environment::kArchX86].regTypeToSignature(rType); }
+ static inline RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToGroup(type); }
+ static inline TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToTypeId(type); }
+ static inline OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToSignature(type); }
- template<uint32_t REG_TYPE>
- static inline uint32_t groupOfT() noexcept { return RegTraits<REG_TYPE>::kGroup; }
+ template<RegType REG_TYPE>
+ static inline RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
- template<uint32_t REG_TYPE>
- static inline uint32_t typeIdOfT() noexcept { return RegTraits<REG_TYPE>::kTypeId; }
+ template<RegType REG_TYPE>
+ static inline TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
- template<uint32_t REG_TYPE>
- static inline uint32_t signatureOfT() noexcept { return RegTraits<REG_TYPE>::kSignature; }
+ template<RegType REG_TYPE>
+ static inline OperandSignature signatureOfT() noexcept { return OperandSignature(RegTraits<REG_TYPE>::kSignature); }
- static inline uint32_t signatureOfVecByType(uint32_t typeId) noexcept {
- return typeId <= Type::_kIdVec128End ? RegTraits<kTypeXmm>::kSignature :
- typeId <= Type::_kIdVec256End ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
+ static inline OperandSignature signatureOfVecByType(TypeId typeId) noexcept {
+ return OperandSignature(typeId <= TypeId::_kVec128End ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
+ typeId <= TypeId::_kVec256End ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature));
}
- static inline uint32_t signatureOfVecBySize(uint32_t size) noexcept {
- return size <= 16 ? RegTraits<kTypeXmm>::kSignature :
- size <= 32 ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
+ static inline OperandSignature signatureOfVecBySize(uint32_t size) noexcept {
+ return OperandSignature(size <= 16 ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
+ size <= 32 ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature));
}
//! Tests whether the `op` operand is either a low or high 8-bit GPB register.
static inline bool isGpb(const Operand_& op) noexcept {
// Check operand type, register group, and size. Not interested in register type.
- const uint32_t kSgn = (Operand::kOpReg << kSignatureOpTypeShift) |
- (1 << kSignatureSizeShift ) ;
- return (op.signature() & (kSignatureOpTypeMask | kSignatureSizeMask)) == kSgn;
+ return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask | Signature::kSizeMask) ==
+ (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kGp) | Signature::fromSize(1));
}
static inline bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
@@ -353,9 +201,8 @@ public:
//! Physical id (X86).
//!
- //! \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.
+ //! \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.
enum Id : uint32_t {
kIdAx = 0, //!< Physical id of AL|AH|AX|EAX|RAX registers.
kIdCx = 1, //!< Physical id of CL|CH|CX|ECX|RCX registers.
@@ -402,13 +249,13 @@ class Vec : public Reg {
//! Casts this register to a register that has half the size (or XMM if it's already XMM).
inline Vec half() const noexcept {
- return Vec::fromSignatureAndId(type() == kTypeZmm ? signatureOfT<kTypeYmm>() : signatureOfT<kTypeXmm>(), id());
+ return Vec(type() == RegType::kX86_Zmm ? signatureOfT<RegType::kX86_Ymm>() : signatureOfT<RegType::kX86_Xmm>(), id());
}
};
//! Segment register (X86).
class SReg : public Reg {
- ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<kTypeSReg>)
+ ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<RegType::kX86_SReg>)
//! X86 segment id.
enum Id : uint32_t {
@@ -429,11 +276,9 @@ class SReg : public Reg {
//! 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 `SReg::kIdNone`, which is AsmJit specific and means that
- //! there is no segment register specified.
+ //! \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 `SReg::kIdNone`, which is AsmJit specific and means that there is no segment register specified.
kIdCount = 7
};
};
@@ -441,53 +286,53 @@ class SReg : public Reg {
//! GPB low or high register (X86).
class Gpb : public Gp { ASMJIT_DEFINE_ABSTRACT_REG(Gpb, Gp) };
//! GPB low register (X86).
-class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<kTypeGpbLo>) };
+class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<RegType::kX86_GpbLo>) };
//! GPB high register (X86).
-class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<kTypeGpbHi>) };
+class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<RegType::kX86_GpbHi>) };
//! GPW register (X86).
-class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<kTypeGpw>) };
+class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<RegType::kX86_Gpw>) };
//! GPD register (X86).
-class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<kTypeGpd>) };
+class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<RegType::kX86_Gpd>) };
//! GPQ register (X86_64).
-class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<kTypeGpq>) };
+class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<RegType::kX86_Gpq>) };
//! 128-bit XMM register (SSE+).
class Xmm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<kTypeXmm>)
+ ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<RegType::kX86_Xmm>)
//! Casts this register to a register that has half the size (XMM).
inline Xmm half() const noexcept { return Xmm(id()); }
};
//! 256-bit YMM register (AVX+).
class Ymm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<kTypeYmm>)
+ ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<RegType::kX86_Ymm>)
//! Casts this register to a register that has half the size (XMM).
inline Xmm half() const noexcept { return Xmm(id()); }
};
//! 512-bit ZMM register (AVX512+).
class Zmm : public Vec {
- ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<kTypeZmm>)
+ ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<RegType::kX86_Zmm>)
//! Casts this register to a register that has half the size (YMM).
inline Ymm half() const noexcept { return Ymm(id()); }
};
//! 64-bit MMX register (MMX+).
-class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<kTypeMm>) };
+class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<RegType::kX86_Mm>) };
//! 64-bit K register (AVX512+).
-class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<kTypeKReg>) };
+class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<RegType::kX86_KReg>) };
//! 32-bit or 64-bit control register (X86).
-class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<kTypeCReg>) };
+class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<RegType::kX86_CReg>) };
//! 32-bit or 64-bit debug register (X86).
-class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<kTypeDReg>) };
+class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<RegType::kX86_DReg>) };
//! 80-bit FPU register (X86).
-class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<kTypeSt>) };
+class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<RegType::kX86_St>) };
//! 128-bit BND register (BND+).
-class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<kTypeBnd>) };
+class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<RegType::kX86_Bnd>) };
//! 8192-bit TMM register (AMX).
-class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<kTypeTmm>) };
+class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<RegType::kX86_Tmm>) };
//! RIP register (X86).
-class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<kTypeRip>) };
+class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<RegType::kX86_Rip>) };
//! \cond
inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
@@ -809,13 +654,12 @@ static constexpr Rip rip = Rip(0);
using namespace regs;
#endif
-// ============================================================================
-// [asmjit::x86::Mem]
-// ============================================================================
-
-//! Memory operand.
+//! Memory operand specific to X86 and X86_64 architecture.
class Mem : public BaseMem {
public:
+ //! \name Constants
+ //! \{
+
//! Additional bits of operand's signature used by `x86::Mem`.
enum AdditionalBits : uint32_t {
// Memory address type (2 bits).
@@ -840,85 +684,111 @@ public:
};
//! Address type.
- enum AddrType : uint32_t {
+ enum class AddrType : uint32_t {
//! Default address type, Assembler will select the best type when necessary.
- kAddrTypeDefault = 0,
+ kDefault = 0,
//! Absolute address type.
- kAddrTypeAbs = 1,
+ kAbs = 1,
//! Relative address type.
- kAddrTypeRel = 2
+ kRel = 2,
+
+ //! Maximum value of `AddrType`.
+ kMaxValue = kRel
};
//! Memory broadcast type.
- enum Broadcast : uint32_t {
- //! Broadcast {1to1}.
- kBroadcast1To1 = 0,
+ enum class Broadcast : uint32_t {
+ //! No broadcast (regular memory operand).
+ kNone = 0,
//! Broadcast {1to2}.
- kBroadcast1To2 = 1,
+ k1To2 = 1,
//! Broadcast {1to4}.
- kBroadcast1To4 = 2,
+ k1To4 = 2,
//! Broadcast {1to8}.
- kBroadcast1To8 = 3,
+ k1To8 = 3,
//! Broadcast {1to16}.
- kBroadcast1To16 = 4,
+ k1To16 = 4,
//! Broadcast {1to32}.
- kBroadcast1To32 = 5,
+ k1To32 = 5,
//! Broadcast {1to64}.
- kBroadcast1To64 = 6
- };
+ k1To64 = 6,
- //! \cond
- //! Shortcuts.
- enum SignatureMem : uint32_t {
- kSignatureMemAbs = kAddrTypeAbs << kSignatureMemAddrTypeShift,
- kSignatureMemRel = kAddrTypeRel << kSignatureMemAddrTypeShift
+ //! Maximum value of `Broadcast`.
+ kMaxValue = k1To64
};
- //! \endcond
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Construction & Destruction
+ //! \{
//! Creates a default `Mem` operand that points to [0].
- constexpr Mem() noexcept
+ inline constexpr Mem() noexcept
: BaseMem() {}
- constexpr Mem(const Mem& other) noexcept
+ inline constexpr Mem(const Mem& other) noexcept
: BaseMem(other) {}
- //! \cond INTERNAL
- //!
- //! A constructor used internally to create `Mem` operand from `Decomposed` data.
- constexpr explicit Mem(const Decomposed& d) noexcept
- : BaseMem(d) {}
- //! \endcond
-
- constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { Label::kLabelTag, base.id(), 0, 0, off, size, flags }) {}
-
- constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { Label::kLabelTag, base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftValueShift) }) {}
-
- constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { base.type(), base.id(), 0, 0, off, size, flags }) {}
-
- constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { base.type(), base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftValueShift) }) {}
+ inline explicit Mem(Globals::NoInit_) noexcept
+ : BaseMem(Globals::NoInit) {}
- constexpr explicit Mem(uint64_t base, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { 0, uint32_t(base >> 32), 0, 0, int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags }) {}
+ inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
+ : BaseMem(signature, baseId, indexId, offset) {}
+
+ inline constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(RegType::kLabelTag) |
+ Signature::fromSize(size) |
+ signature, base.id(), 0, off) {}
+
+ inline constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(RegType::kLabelTag) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, base.id(), index.id(), off) {}
+
+ inline constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(base.type()) |
+ Signature::fromSize(size) |
+ signature, base.id(), 0, off) {}
+
+ inline constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemBaseType(base.type()) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, base.id(), index.id(), off) {}
+
+ inline constexpr explicit Mem(uint64_t base, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromSize(size) |
+ signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
+
+ inline constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, Signature signature = OperandSignature(0)) noexcept
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
+ Signature::fromMemIndexType(index.type()) |
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
+ Signature::fromSize(size) |
+ signature, uint32_t(base >> 32), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
+
+ //! \}
+
+ //! \name Overloaded Operators
+ //! \{
- constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, uint32_t flags = 0) noexcept
- : BaseMem(Decomposed { 0, uint32_t(base >> 32), index.type(), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags | (shift << kSignatureMemShiftValueShift) }) {}
+ inline Mem& operator=(const Mem& other) noexcept = default;
- constexpr Mem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
- : BaseMem(Globals::Init, u0, u1, u2, u3) {}
+ //! \}
- inline explicit Mem(Globals::NoInit_) noexcept
- : BaseMem(Globals::NoInit) {}
+ //! \name Clone
+ //! \{
//! Clones the memory operand.
- constexpr Mem clone() const noexcept { return Mem(*this); }
+ inline constexpr Mem clone() const noexcept { return Mem(*this); }
//! Creates a new copy of this memory operand adjusted by `off`.
inline Mem cloneAdjusted(int64_t off) const noexcept {
@@ -927,6 +797,15 @@ public:
return result;
}
+ inline constexpr Mem cloneBroadcasted(Broadcast b) const noexcept {
+ return Mem((_signature & ~Signature(kSignatureMemBroadcastMask)) | Signature::fromValue<kSignatureMemBroadcastMask>(b), _baseId, _data[0], int32_t(_data[1]));
+ }
+
+ //! \}
+
+ //! \name Base & Index
+ //! \{
+
//! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
//!
//! The memory must have a valid base register otherwise the result will be wrong.
@@ -937,18 +816,6 @@ public:
//! The memory must have a valid index register otherwise the result will be wrong.
inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
- constexpr Mem _1to1() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To1 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to2() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To2 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to4() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To4 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to8() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To8 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to16() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To16 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to32() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To32 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
- constexpr Mem _1to64() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To64 << kSignatureMemBroadcastShift), _baseId, _data[0], _data[1]); }
-
- // --------------------------------------------------------------------------
- // [Mem]
- // --------------------------------------------------------------------------
-
using BaseMem::setIndex;
inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
@@ -956,134 +823,220 @@ public:
setShift(shift);
}
- //! Returns the address type (see \ref AddrType) of the memory operand.
+ //! \}
+
+ //! \name Address Type
+ //! \{
+
+ //! Returns the address type of the memory operand.
//!
- //! By default, address type of newly created memory operands is always \ref kAddrTypeDefault.
- constexpr uint32_t addrType() const noexcept { return _getSignaturePart<kSignatureMemAddrTypeMask>(); }
- //! Sets the address type to `addrType`, see \ref AddrType.
- inline void setAddrType(uint32_t addrType) noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(addrType); }
- //! Resets the address type to \ref kAddrTypeDefault.
- inline void resetAddrType() noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(0); }
-
- //! Tests whether the address type is \ref kAddrTypeAbs.
- constexpr bool isAbs() const noexcept { return addrType() == kAddrTypeAbs; }
- //! Sets the address type to \ref kAddrTypeAbs.
- inline void setAbs() noexcept { setAddrType(kAddrTypeAbs); }
-
- //! Tests whether the address type is \ref kAddrTypeRel.
- constexpr bool isRel() const noexcept { return addrType() == kAddrTypeRel; }
- //! Sets the address type to \ref kAddrTypeRel.
- inline void setRel() noexcept { setAddrType(kAddrTypeRel); }
+ //! By default, address type of newly created memory operands is always \ref AddrType::kDefault.
+ inline constexpr AddrType addrType() const noexcept { return (AddrType)_signature.getField<kSignatureMemAddrTypeMask>(); }
+ //! Sets the address type to `addrType`.
+ inline void setAddrType(AddrType addrType) noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(addrType)); }
+ //! Resets the address type to \ref AddrType::kDefault.
+ inline void resetAddrType() noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(AddrType::kDefault)); }
+
+ //! Tests whether the address type is \ref AddrType::kAbs.
+ inline constexpr bool isAbs() const noexcept { return addrType() == AddrType::kAbs; }
+ //! Sets the address type to \ref AddrType::kAbs.
+ inline void setAbs() noexcept { setAddrType(AddrType::kAbs); }
+
+ //! Tests whether the address type is \ref AddrType::kRel.
+ inline constexpr bool isRel() const noexcept { return addrType() == AddrType::kRel; }
+ //! Sets the address type to \ref AddrType::kRel.
+ inline void setRel() noexcept { setAddrType(AddrType::kRel); }
+
+ //! \}
+
+ //! \name Segment
+ //! \{
//! Tests whether the memory operand has a segment override.
- constexpr bool hasSegment() const noexcept { return _hasSignaturePart<kSignatureMemSegmentMask>(); }
+ inline constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
//! Returns the associated segment override as `SReg` operand.
- constexpr SReg segment() const noexcept { return SReg(segmentId()); }
+ inline constexpr SReg segment() const noexcept { return SReg(segmentId()); }
//! Returns segment override register id, see `SReg::Id`.
- constexpr uint32_t segmentId() const noexcept { return _getSignaturePart<kSignatureMemSegmentMask>(); }
+ inline constexpr uint32_t segmentId() const noexcept { return _signature.getField<kSignatureMemSegmentMask>(); }
//! Sets the segment override to `seg`.
inline void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
//! Sets the segment override to `id`.
- inline void setSegment(uint32_t rId) noexcept { _setSignaturePart<kSignatureMemSegmentMask>(rId); }
+ inline void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
//! Resets the segment override.
- inline void resetSegment() noexcept { _setSignaturePart<kSignatureMemSegmentMask>(0); }
+ inline void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
+
+ //! \}
+
+ //! \name Shift
+ //! \{
//! Tests whether the memory operand has shift (aka scale) value.
- constexpr bool hasShift() const noexcept { return _hasSignaturePart<kSignatureMemShiftValueMask>(); }
+ inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
//! Returns the memory operand's shift (aka scale) value.
- constexpr uint32_t shift() const noexcept { return _getSignaturePart<kSignatureMemShiftValueMask>(); }
+ inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
//! Sets the memory operand's shift (aka scale) value.
- inline void setShift(uint32_t shift) noexcept { _setSignaturePart<kSignatureMemShiftValueMask>(shift); }
+ inline void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
//! Resets the memory operand's shift (aka scale) value to zero.
- inline void resetShift() noexcept { _setSignaturePart<kSignatureMemShiftValueMask>(0); }
+ inline void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
+
+ //! \}
+
+ //! \name Broadcast
+ //! \{
//! Tests whether the memory operand has broadcast {1tox}.
- constexpr bool hasBroadcast() const noexcept { return _hasSignaturePart<kSignatureMemBroadcastMask>(); }
+ inline constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
//! Returns the memory operand's broadcast.
- constexpr uint32_t getBroadcast() const noexcept { return _getSignaturePart<kSignatureMemBroadcastMask>(); }
+ inline constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
//! Sets the memory operand's broadcast.
- inline void setBroadcast(uint32_t bcst) noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(bcst); }
+ inline void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
//! Resets the memory operand's broadcast to none.
- inline void resetBroadcast() noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(0); }
-
- // --------------------------------------------------------------------------
- // [Operator Overload]
- // --------------------------------------------------------------------------
-
- inline Mem& operator=(const Mem& other) noexcept = default;
+ inline void resetBroadcast() noexcept { _signature.setField<kSignatureMemBroadcastMask>(0); }
+
+ //! Returns a new `Mem` without a broadcast (the possible broadcast is cleared).
+ inline constexpr Mem _1to1() const noexcept { return cloneBroadcasted(Broadcast::kNone); }
+ //! Returns a new `Mem` with {1to2} broadcast (AVX-512).
+ inline constexpr Mem _1to2() const noexcept { return cloneBroadcasted(Broadcast::k1To2); }
+ //! Returns a new `Mem` with {1to4} broadcast (AVX-512).
+ inline constexpr Mem _1to4() const noexcept { return cloneBroadcasted(Broadcast::k1To4); }
+ //! Returns a new `Mem` with {1to8} broadcast (AVX-512).
+ inline constexpr Mem _1to8() const noexcept { return cloneBroadcasted(Broadcast::k1To8); }
+ //! Returns a new `Mem` with {1to16} broadcast (AVX-512).
+ inline constexpr Mem _1to16() const noexcept { return cloneBroadcasted(Broadcast::k1To16); }
+ //! Returns a new `Mem` with {1to32} broadcast (AVX-512).
+ inline constexpr Mem _1to32() const noexcept { return cloneBroadcasted(Broadcast::k1To32); }
+ //! Returns a new `Mem` with {1to64} broadcast (AVX-512).
+ inline constexpr Mem _1to64() const noexcept { return cloneBroadcasted(Broadcast::k1To64); }
+
+ //! \}
};
//! Creates `[base.reg + offset]` memory operand.
-static constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, offset, size);
}
//! Creates `[base.reg + (index << shift) + offset]` memory operand (scalar index).
-static constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base.reg + (index << shift) + offset]` memory operand (vector index).
-static constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, offset, size);
}
//! Creates `[base + (index << shift) + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[base + (index << shift) + offset]` memory operand.
-static constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, offset, size);
}
//! Creates `[rip + offset]` memory operand.
-static constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
return Mem(rip_, offset, size);
}
//! Creates `[base]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
return Mem(base, size);
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, size);
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand.
-static constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+static inline constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
return Mem(base, index, shift, size);
}
//! Creates `[base]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
- return Mem(base, size, Mem::kSignatureMemAbs);
+static inline constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, Mem::kSignatureMemAbs);
+static inline constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
-static constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, Mem::kSignatureMemAbs);
+static inline constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
}
//! Creates `[base]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
- return Mem(base, size, Mem::kSignatureMemRel);
+static inline constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
//! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, Mem::kSignatureMemRel);
+static inline constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
//! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
-static constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
- return Mem(base, index, shift, size, Mem::kSignatureMemRel);
+static inline constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
}
+#define ASMJIT_MEM_PTR(FUNC, SIZE) \
+ static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
+ return Mem(base, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
+ return Mem(base, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+ return Mem(base, index, shift, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
+ return Mem(rip_, offset, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base) noexcept { \
+ return Mem(base, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE); \
+ } \
+ static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE); \
+ } \
+ \
+ static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
+ return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
+ } \
+ static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
+ } \
+ static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
+ } \
+ \
+ static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
+ return Mem(base, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
+ } \
+ static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
+ } \
+ static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
+ return Mem(base, index, shift, SIZE, \
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
+ }
+
// Definition of memory operand constructors that use platform independent naming.
ASMJIT_MEM_PTR(ptr_8, 1)
ASMJIT_MEM_PTR(ptr_16, 2)
@@ -1110,27 +1063,23 @@ ASMJIT_MEM_PTR(xmmword_ptr, 16)
ASMJIT_MEM_PTR(ymmword_ptr, 32)
ASMJIT_MEM_PTR(zmmword_ptr, 64)
+#undef ASMJIT_MEM_PTR
+
//! \}
ASMJIT_END_SUB_NAMESPACE
-// ============================================================================
-// [asmjit::Type::IdOfT<x86::Reg>]
-// ============================================================================
-
//! \cond INTERNAL
ASMJIT_BEGIN_NAMESPACE
-ASMJIT_DEFINE_TYPE_ID(x86::Gpb, kIdI8);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpw, kIdI16);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpd, kIdI32);
-ASMJIT_DEFINE_TYPE_ID(x86::Gpq, kIdI64);
-ASMJIT_DEFINE_TYPE_ID(x86::Mm , kIdMmx64);
-ASMJIT_DEFINE_TYPE_ID(x86::Xmm, kIdI32x4);
-ASMJIT_DEFINE_TYPE_ID(x86::Ymm, kIdI32x8);
-ASMJIT_DEFINE_TYPE_ID(x86::Zmm, kIdI32x16);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpb, TypeId::kInt8);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpw, TypeId::kInt16);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpd, TypeId::kInt32);
+ASMJIT_DEFINE_TYPE_ID(x86::Gpq, TypeId::kInt64);
+ASMJIT_DEFINE_TYPE_ID(x86::Mm , TypeId::kMmx64);
+ASMJIT_DEFINE_TYPE_ID(x86::Xmm, TypeId::kInt32x4);
+ASMJIT_DEFINE_TYPE_ID(x86::Ymm, TypeId::kInt32x8);
+ASMJIT_DEFINE_TYPE_ID(x86::Zmm, TypeId::kInt32x16);
ASMJIT_END_NAMESPACE
//! \endcond
-#undef ASMJIT_MEM_PTR
-
#endif // ASMJIT_X86_X86OPERAND_H_INCLUDED
diff --git a/src/asmjit/x86/x86rapass.cpp b/src/asmjit/x86/x86rapass.cpp
index 8fa1c6c..3a63c08 100644
--- a/src/asmjit/x86/x86rapass.cpp
+++ b/src/asmjit/x86/x86rapass.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_COMPILER)
@@ -36,13 +18,12 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::X86RAPass - Helpers]
-// ============================================================================
+// x86::X86RAPass - Utilities
+// ==========================
-static ASMJIT_INLINE uint64_t raImmMaskFromSize(uint32_t size) noexcept {
+static ASMJIT_FORCE_INLINE uint64_t raImmMaskFromSize(uint32_t size) noexcept {
ASMJIT_ASSERT(size > 0 && size < 256);
- static const uint64_t masks[] = {
+ static constexpr uint64_t masks[] = {
0x00000000000000FFu, // 1
0x000000000000FFFFu, // 2
0x00000000FFFFFFFFu, // 4
@@ -56,42 +37,49 @@ static ASMJIT_INLINE uint64_t raImmMaskFromSize(uint32_t size) noexcept {
return masks[Support::ctz(size)];
}
-static ASMJIT_INLINE uint32_t raUseOutFlagsFromRWFlags(uint32_t rwFlags) noexcept {
- static const uint32_t map[] = {
- 0,
- RATiedReg::kRead | RATiedReg::kUse, // kRead
- RATiedReg::kWrite | RATiedReg::kOut, // kWrite
- RATiedReg::kRW | RATiedReg::kUse, // kRW
- 0,
- RATiedReg::kRead | RATiedReg::kUse | RATiedReg::kUseRM, // kRead | kRegMem
- RATiedReg::kWrite | RATiedReg::kOut | RATiedReg::kOutRM, // kWrite | kRegMem
- RATiedReg::kRW | RATiedReg::kUse | RATiedReg::kUseRM // kRW | kRegMem
+static const RegMask raConsecutiveLeadCountToRegMaskFilter[5] = {
+ 0xFFFFFFFFu, // [0] No consecutive.
+ 0x00000000u, // [1] Invalid, never used.
+ 0x55555555u, // [2] Even registers.
+ 0x00000000u, // [3] Invalid, never used.
+ 0x11111111u // [4] Every fourth register.
+};
+
+static ASMJIT_FORCE_INLINE RATiedFlags raUseOutFlagsFromRWFlags(OpRWFlags rwFlags) noexcept {
+ static constexpr RATiedFlags map[] = {
+ RATiedFlags::kNone,
+ RATiedFlags::kRead | RATiedFlags::kUse, // kRead
+ RATiedFlags::kWrite | RATiedFlags::kOut, // kWrite
+ RATiedFlags::kRW | RATiedFlags::kUse, // kRW
+ RATiedFlags::kNone,
+ RATiedFlags::kRead | RATiedFlags::kUse | RATiedFlags::kUseRM, // kRead | kRegMem
+ RATiedFlags::kWrite | RATiedFlags::kOut | RATiedFlags::kOutRM, // kWrite | kRegMem
+ RATiedFlags::kRW | RATiedFlags::kUse | RATiedFlags::kUseRM // kRW | kRegMem
};
- return map[rwFlags & (OpRWInfo::kRW | OpRWInfo::kRegMem)];
+ return map[uint32_t(rwFlags & (OpRWFlags::kRW | OpRWFlags::kRegMem))];
}
-static ASMJIT_INLINE uint32_t raRegRwFlags(uint32_t flags) noexcept {
- return raUseOutFlagsFromRWFlags(flags);
+static ASMJIT_FORCE_INLINE RATiedFlags raRegRwFlags(OpRWFlags flags) noexcept {
+ return (RATiedFlags)raUseOutFlagsFromRWFlags(flags);
}
-static ASMJIT_INLINE uint32_t raMemBaseRwFlags(uint32_t flags) noexcept {
- constexpr uint32_t shift = Support::constCtz(OpRWInfo::kMemBaseRW);
- return raUseOutFlagsFromRWFlags((flags >> shift) & OpRWInfo::kRW);
+static ASMJIT_FORCE_INLINE RATiedFlags raMemBaseRwFlags(OpRWFlags flags) noexcept {
+ constexpr uint32_t kShift = Support::ConstCTZ<uint32_t(OpRWFlags::kMemBaseRW)>::value;
+ return (RATiedFlags)raUseOutFlagsFromRWFlags(OpRWFlags(uint32_t(flags) >> kShift) & OpRWFlags::kRW);
}
-static ASMJIT_INLINE uint32_t raMemIndexRwFlags(uint32_t flags) noexcept {
- constexpr uint32_t shift = Support::constCtz(OpRWInfo::kMemIndexRW);
- return raUseOutFlagsFromRWFlags((flags >> shift) & OpRWInfo::kRW);
+static ASMJIT_FORCE_INLINE RATiedFlags raMemIndexRwFlags(OpRWFlags flags) noexcept {
+ constexpr uint32_t kShift = Support::ConstCTZ<uint32_t(OpRWFlags::kMemIndexRW)>::value;
+ return (RATiedFlags)raUseOutFlagsFromRWFlags(OpRWFlags(uint32_t(flags) >> kShift) & OpRWFlags::kRW);
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder]
-// ============================================================================
+// x86::RACFGBuilder
+// =================
class RACFGBuilder : public RACFGBuilderT<RACFGBuilder> {
public:
- uint32_t _arch;
+ Arch _arch;
bool _is64Bit;
bool _avxEnabled;
@@ -108,7 +96,7 @@ public:
return _avxEnabled ? avxInst : sseInst;
}
- Error onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder& ib) noexcept;
+ Error onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& ib) noexcept;
Error onBeforeInvoke(InvokeNode* invokeNode) noexcept;
Error onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept;
@@ -122,14 +110,13 @@ public:
Error onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept;
};
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - OnInst]
-// ============================================================================
+// x86::RACFGBuilder - OnInst
+// ==========================
-Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder& ib) noexcept {
+Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& ib) noexcept {
InstRWInfo rwInfo;
- uint32_t instId = inst->id();
+ InstId instId = inst->id();
if (Inst::isDefinedId(instId)) {
uint32_t opCount = inst->opCount();
const Operand* opArray = inst->operands();
@@ -140,15 +127,18 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t singleRegOps = 0;
if (opCount) {
- // The mask is for all registers, but we are mostly interested in AVX-512
- // registers at the moment. The mask will be combined with all available
- // registers of the Compiler at the end so we it never use more registers
+ // The mask is for all registers, but we are mostly interested in AVX-512 registers at the moment. The mask
+ // will be combined with all available registers of the Compiler at the end so we it never use more registers
// than available.
- uint32_t instructionAllowedRegs = 0xFFFFFFFFu;
+ RegMask instructionAllowedRegs = 0xFFFFFFFFu;
+
+ uint32_t consecutiveOffset = 0;
+ uint32_t consecutiveLeadId = Globals::kInvalidId;
+ uint32_t consecutiveParent = Globals::kInvalidId;
if (instInfo.isEvex()) {
- // EVEX instruction and VEX instructions that can be encoded with EVEX
- // have the possibility to use 32 SIMD registers (XMM/YMM/ZMM).
+ // EVEX instruction and VEX instructions that can be encoded with EVEX have the possibility to use 32 SIMD
+ // registers (XMM/YMM/ZMM).
if (instInfo.isVex() && !instInfo.isEvexCompatible()) {
if (instInfo.isEvexKRegOnly()) {
// EVEX encodable only if the first operand is K register (compare instructions).
@@ -166,7 +156,7 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
}
}
else if (instInfo.isEvexTransformable()) {
- ib.addAggregatedFlags(RAInst::kFlagIsTransformable);
+ ib.addAggregatedFlags(RATiedFlags::kInst_IsTransformable);
}
else {
// Not EVEX, restrict everything to [0-15] registers.
@@ -182,26 +172,24 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
// ----------------
const Reg& reg = op.as<Reg>();
- uint32_t flags = raRegRwFlags(opRwInfo.opFlags());
- uint32_t allowedRegs = instructionAllowedRegs;
+ RATiedFlags flags = raRegRwFlags(opRwInfo.opFlags());
+ RegMask allowedRegs = instructionAllowedRegs;
- // X86-specific constraints related to LO|HI general purpose registers.
- // This is only required when the register is part of the encoding. If
- // the register is fixed we won't restrict anything as it doesn't restrict
- // encoding of other registers.
- if (reg.isGpb() && !(opRwInfo.opFlags() & OpRWInfo::kRegPhysId)) {
- flags |= RATiedReg::kX86Gpb;
+ // X86-specific constraints related to LO|HI general purpose registers. This is only required when the
+ // register is part of the encoding. If the register is fixed we won't restrict anything as it doesn't
+ // restrict encoding of other registers.
+ if (reg.isGpb() && !opRwInfo.hasOpFlag(OpRWFlags::kRegPhysId)) {
+ flags |= RATiedFlags::kX86_Gpb;
if (!_is64Bit) {
- // Restrict to first four - AL|AH|BL|BH|CL|CH|DL|DH. In 32-bit mode
- // it's not possible to access SIL|DIL, etc, so this is just enough.
+ // Restrict to first four - AL|AH|BL|BH|CL|CH|DL|DH. In 32-bit mode it's not possible to access
+ // SIL|DIL, etc, so this is just enough.
allowedRegs = 0x0Fu;
}
else {
- // If we encountered GPB-HI register the situation is much more
- // complicated than in 32-bit mode. We need to patch all registers
- // to not use ID higher than 7 and all GPB-LO registers to not use
- // index higher than 3. Instead of doing the patching here we just
- // set a flag and will do it later, to not complicate this loop.
+ // If we encountered GPB-HI register the situation is much more complicated than in 32-bit mode.
+ // We need to patch all registers to not use ID higher than 7 and all GPB-LO registers to not use
+ // index higher than 3. Instead of doing the patching here we just set a flag and will do it later,
+ // to not complicate this loop.
if (reg.isGpbHi()) {
hasGpbHiConstraint = true;
allowedRegs = 0x0Fu;
@@ -214,25 +202,24 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- // Use RW instead of Write in case that not the whole register is
- // overwritten. This is important for liveness as we cannot kill a
- // register that will be used. For example `mov al, 0xFF` is not a
- // write-only operation if user allocated the whole `rax` register.
- if ((flags & RATiedReg::kRW) == RATiedReg::kWrite) {
+ // Use RW instead of Write in case that not the whole register is overwritten. This is important
+ // for liveness as we cannot kill a register that will be used. For example `mov al, 0xFF` is not
+ // a write-only operation if user allocated the whole `rax` register.
+ if ((flags & RATiedFlags::kRW) == RATiedFlags::kWrite) {
if (workReg->regByteMask() & ~(opRwInfo.writeByteMask() | opRwInfo.extendByteMask())) {
// Not write-only operation.
- flags = (flags & ~RATiedReg::kOut) | (RATiedReg::kRead | RATiedReg::kUse);
+ flags = (flags & ~RATiedFlags::kOut) | (RATiedFlags::kRead | RATiedFlags::kUse);
}
}
- // Do not use RegMem flag if changing Reg to Mem requires additional
- // CPU feature that may not be enabled.
- if (rwInfo.rmFeature() && (flags & (RATiedReg::kUseRM | RATiedReg::kOutRM))) {
- flags &= ~(RATiedReg::kUseRM | RATiedReg::kOutRM);
+ // Do not use RegMem flag if changing Reg to Mem requires additional CPU feature that may not be enabled.
+ if (rwInfo.rmFeature() && Support::test(flags, RATiedFlags::kUseRM | RATiedFlags::kOutRM)) {
+ flags &= ~(RATiedFlags::kUseRM | RATiedFlags::kOutRM);
}
- uint32_t group = workReg->group();
- uint32_t allocable = _pass->_availableRegs[group] & allowedRegs;
+ RegGroup group = workReg->group();
+ RegMask useRegs = _pass->_availableRegs[group] & allowedRegs;
+ RegMask outRegs = useRegs;
uint32_t useId = BaseReg::kIdBad;
uint32_t outId = BaseReg::kIdBad;
@@ -240,31 +227,75 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t useRewriteMask = 0;
uint32_t outRewriteMask = 0;
- if (flags & RATiedReg::kUse) {
+ if (opRwInfo.consecutiveLeadCount()) {
+ // There must be a single consecutive register lead, otherwise the RW data is invalid.
+ if (consecutiveLeadId != Globals::kInvalidId)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ // A consecutive lead register cannot be used as a consecutive +1/+2/+3 register, the registers must be distinct.
+ if (RATiedReg::consecutiveDataFromFlags(flags) != 0)
+ return DebugUtils::errored(kErrorNotConsecutiveRegs);
+
+ flags |= RATiedFlags::kLeadConsecutive | RATiedReg::consecutiveDataToFlags(opRwInfo.consecutiveLeadCount() - 1);
+ consecutiveLeadId = workReg->workId();
+
+ RegMask filter = raConsecutiveLeadCountToRegMaskFilter[opRwInfo.consecutiveLeadCount()];
+ if (Support::test(flags, RATiedFlags::kUse)) {
+ flags |= RATiedFlags::kUseConsecutive;
+ useRegs &= filter;
+ }
+ else {
+ flags |= RATiedFlags::kOutConsecutive;
+ outRegs &= filter;
+ }
+ }
+
+ if (Support::test(flags, RATiedFlags::kUse)) {
useRewriteMask = Support::bitMask(inst->getRewriteIndex(&reg._baseId));
- if (opRwInfo.opFlags() & OpRWInfo::kRegPhysId) {
+ if (opRwInfo.hasOpFlag(OpRWFlags::kRegPhysId)) {
useId = opRwInfo.physId();
- flags |= RATiedReg::kUseFixed;
+ flags |= RATiedFlags::kUseFixed;
+ }
+ else if (opRwInfo.hasOpFlag(OpRWFlags::kConsecutive)) {
+ if (consecutiveLeadId == Globals::kInvalidId)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ if (consecutiveLeadId == workReg->workId())
+ return DebugUtils::errored(kErrorOverlappedRegs);
+
+ flags |= RATiedFlags::kUseConsecutive | RATiedReg::consecutiveDataToFlags(++consecutiveOffset);
}
}
else {
outRewriteMask = Support::bitMask(inst->getRewriteIndex(&reg._baseId));
- if (opRwInfo.opFlags() & OpRWInfo::kRegPhysId) {
+ if (opRwInfo.hasOpFlag(OpRWFlags::kRegPhysId)) {
outId = opRwInfo.physId();
- flags |= RATiedReg::kOutFixed;
+ flags |= RATiedFlags::kOutFixed;
+ }
+ else if (opRwInfo.hasOpFlag(OpRWFlags::kConsecutive)) {
+ if (consecutiveLeadId == Globals::kInvalidId)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ if (consecutiveLeadId == workReg->workId())
+ return DebugUtils::errored(kErrorOverlappedRegs);
+
+ flags |= RATiedFlags::kOutConsecutive | RATiedReg::consecutiveDataToFlags(++consecutiveOffset);
}
}
- ASMJIT_PROPAGATE(ib.add(workReg, flags, allocable, useId, useRewriteMask, outId, outRewriteMask, opRwInfo.rmSize()));
+ ASMJIT_PROPAGATE(ib.add(workReg, flags, useRegs, useId, useRewriteMask, outRegs, outId, outRewriteMask, opRwInfo.rmSize(), consecutiveParent));
if (singleRegOps == i)
singleRegOps++;
+
+ if (Support::test(flags, RATiedFlags::kLeadConsecutive | RATiedFlags::kUseConsecutive | RATiedFlags::kOutConsecutive))
+ consecutiveParent = workReg->workId();
}
}
else if (op.isMem()) {
// Memory Operand
// --------------
const Mem& mem = op.as<Mem>();
- ib.addForbiddenFlags(RATiedReg::kUseRM | RATiedReg::kOutRM);
+ ib.addForbiddenFlags(RATiedFlags::kUseRM | RATiedFlags::kOutRM);
if (mem.isRegHome()) {
RAWorkReg* workReg;
@@ -277,9 +308,9 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- uint32_t flags = raMemBaseRwFlags(opRwInfo.opFlags());
- uint32_t group = workReg->group();
- uint32_t allocable = _pass->_availableRegs[group];
+ RATiedFlags flags = raMemBaseRwFlags(opRwInfo.opFlags());
+ RegGroup group = workReg->group();
+ RegMask inOutRegs = _pass->_availableRegs[group];
uint32_t useId = BaseReg::kIdBad;
uint32_t outId = BaseReg::kIdBad;
@@ -287,22 +318,22 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t useRewriteMask = 0;
uint32_t outRewriteMask = 0;
- if (flags & RATiedReg::kUse) {
+ if (Support::test(flags, RATiedFlags::kUse)) {
useRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._baseId));
- if (opRwInfo.opFlags() & OpRWInfo::kMemPhysId) {
+ if (opRwInfo.hasOpFlag(OpRWFlags::kMemPhysId)) {
useId = opRwInfo.physId();
- flags |= RATiedReg::kUseFixed;
+ flags |= RATiedFlags::kUseFixed;
}
}
else {
outRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._baseId));
- if (opRwInfo.opFlags() & OpRWInfo::kMemPhysId) {
+ if (opRwInfo.hasOpFlag(OpRWFlags::kMemPhysId)) {
outId = opRwInfo.physId();
- flags |= RATiedReg::kOutFixed;
+ flags |= RATiedFlags::kOutFixed;
}
}
- ASMJIT_PROPAGATE(ib.add(workReg, flags, allocable, useId, useRewriteMask, outId, outRewriteMask));
+ ASMJIT_PROPAGATE(ib.add(workReg, flags, inOutRegs, useId, useRewriteMask, inOutRegs, outId, outRewriteMask));
}
}
@@ -312,9 +343,9 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- uint32_t flags = raMemIndexRwFlags(opRwInfo.opFlags());
- uint32_t group = workReg->group();
- uint32_t allocable = _pass->_availableRegs[group] & instructionAllowedRegs;
+ RATiedFlags flags = raMemIndexRwFlags(opRwInfo.opFlags());
+ RegGroup group = workReg->group();
+ RegMask inOutRegs = _pass->_availableRegs[group] & instructionAllowedRegs;
// Index registers have never fixed id on X86/x64.
const uint32_t useId = BaseReg::kIdBad;
@@ -323,12 +354,12 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
uint32_t useRewriteMask = 0;
uint32_t outRewriteMask = 0;
- if (flags & RATiedReg::kUse)
+ if (Support::test(flags, RATiedFlags::kUse))
useRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._data[Operand::kDataMemIndexId]));
else
outRewriteMask = Support::bitMask(inst->getRewriteIndex(&mem._data[Operand::kDataMemIndexId]));
- ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRead, allocable, useId, useRewriteMask, outId, outRewriteMask));
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRead, inOutRegs, useId, useRewriteMask, inOutRegs, outId, outRewriteMask));
}
}
}
@@ -342,23 +373,23 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
+ RegMask inOutRegs = _pass->_availableRegs[group];
uint32_t rewriteMask = Support::bitMask(inst->getRewriteIndex(&inst->extraReg()._id));
- if (group == Gp::kGroupKReg) {
+ if (group == RegGroup::kX86_K) {
// AVX-512 mask selector {k} register - read-only, allocable to any register except {k0}.
- uint32_t allocableRegs = _pass->_availableRegs[group];
- ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRead, allocableRegs, BaseReg::kIdBad, rewriteMask, BaseReg::kIdBad, 0));
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRead, inOutRegs, BaseReg::kIdBad, rewriteMask, inOutRegs, BaseReg::kIdBad, 0));
singleRegOps = 0;
}
else {
// REP {cx|ecx|rcx} register - read & write, allocable to {cx|ecx|rcx} only.
- ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRW, 0, Gp::kIdCx, rewriteMask, Gp::kIdBad, 0));
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRW, inOutRegs, Gp::kIdCx, rewriteMask, inOutRegs, Gp::kIdBad, 0));
}
}
else {
- uint32_t group = inst->extraReg().group();
- if (group == Gp::kGroupKReg && inst->extraReg().id() != 0)
+ RegGroup group = inst->extraReg().group();
+ if (group == RegGroup::kX86_K && inst->extraReg().id() != 0)
singleRegOps = 0;
}
}
@@ -366,16 +397,18 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
// Handle X86 constraints.
if (hasGpbHiConstraint) {
for (RATiedReg& tiedReg : ib) {
- tiedReg._allocableRegs &= tiedReg.hasFlag(RATiedReg::kX86Gpb) ? 0x0Fu : 0xFFu;
+ RegMask filter = tiedReg.hasFlag(RATiedFlags::kX86_Gpb) ? 0x0Fu : 0xFFu;
+ tiedReg._useRegMask &= filter;
+ tiedReg._outRegMask &= filter;
}
}
if (ib.tiedRegCount() == 1) {
// Handle special cases of some instructions where all operands share the same
// register. In such case the single operand becomes read-only or write-only.
- uint32_t singleRegCase = InstDB::kSingleRegNone;
+ InstSameRegHint sameRegHint = InstSameRegHint::kNone;
if (singleRegOps == opCount) {
- singleRegCase = instInfo.singleRegCase();
+ sameRegHint = instInfo.sameRegHint();
}
else if (opCount == 2 && inst->op(1).isImm()) {
// Handle some tricks used by X86 asm.
@@ -383,14 +416,14 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
const Imm& imm = inst->op(1).as<Imm>();
const RAWorkReg* workReg = _pass->workRegById(ib[0]->workId());
- uint32_t workRegSize = workReg->info().size();
+ uint32_t workRegSize = workReg->signature().size();
switch (inst->id()) {
case Inst::kIdOr: {
// Sets the value of the destination register to -1, previous content unused.
if (reg.size() >= 4 || reg.size() >= workRegSize) {
if (imm.value() == -1 || imm.valueAs<uint64_t>() == raImmMaskFromSize(reg.size()))
- singleRegCase = InstDB::kSingleRegWO;
+ sameRegHint = InstSameRegHint::kWO;
}
ASMJIT_FALLTHROUGH;
}
@@ -407,41 +440,40 @@ Error RACFGBuilder::onInst(InstNode* inst, uint32_t& controlType, RAInstBuilder&
// Updates [E|R]FLAGS without changing the content.
if (reg.size() != 4 || reg.size() >= workRegSize) {
if (imm.value() == 0)
- singleRegCase = InstDB::kSingleRegRO;
+ sameRegHint = InstSameRegHint::kRO;
}
break;
}
}
}
- switch (singleRegCase) {
- case InstDB::kSingleRegNone:
+ switch (sameRegHint) {
+ case InstSameRegHint::kNone:
break;
- case InstDB::kSingleRegRO:
+ case InstSameRegHint::kRO:
ib[0]->makeReadOnly();
break;
- case InstDB::kSingleRegWO:
+ case InstSameRegHint::kWO:
ib[0]->makeWriteOnly();
break;
}
}
- controlType = instInfo.controlType();
+ cf = instInfo.controlFlow();
}
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - OnInvoke]
-// ============================================================================
+// x86::RACFGBuilder - OnInvoke
+// ============================
Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
const FuncDetail& fd = invokeNode->detail();
uint32_t argCount = invokeNode->argCount();
cc()->_setCursor(invokeNode->prev());
- uint32_t nativeRegType = cc()->_gpRegInfo.type();
+ RegType nativeRegType = cc()->_gpSignature.regType();
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
const FuncValuePack& argPack = fd.argPack(argIndex);
@@ -461,8 +493,8 @@ Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
if (arg.isReg()) {
- uint32_t regGroup = workReg->group();
- uint32_t argGroup = Reg::groupOf(arg.regType());
+ RegGroup regGroup = workReg->group();
+ RegGroup argGroup = Reg::groupOf(arg.regType());
if (arg.isIndirect()) {
if (reg.isGp()) {
@@ -516,7 +548,7 @@ Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
}
cc()->_setCursor(invokeNode);
- if (fd.hasFlag(CallConv::kFlagCalleePopsStack) && fd.argStackSize() != 0)
+ if (fd.hasFlag(CallConvFlags::kCalleePopsStack) && fd.argStackSize() != 0)
ASMJIT_PROPAGATE(cc()->sub(cc()->zsp(), fd.argStackSize()));
if (fd.hasRet()) {
@@ -532,26 +564,26 @@ Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
if (ret.isReg()) {
- if (ret.regType() == Reg::kTypeSt) {
- if (workReg->group() != Reg::kGroupVec)
+ if (ret.regType() == RegType::kX86_St) {
+ if (workReg->group() != RegGroup::kVec)
return DebugUtils::errored(kErrorInvalidAssignment);
- Reg dst = Reg::fromSignatureAndId(workReg->signature(), workReg->virtId());
+ Reg dst(workReg->signature(), workReg->virtId());
Mem mem;
- uint32_t typeId = Type::baseOf(workReg->typeId());
+ TypeId typeId = TypeUtils::scalarOf(workReg->typeId());
if (ret.hasTypeId())
typeId = ret.typeId();
switch (typeId) {
- case Type::kIdF32:
+ case TypeId::kFloat32:
ASMJIT_PROPAGATE(_pass->useTemporaryMem(mem, 4, 4));
mem.setSize(4);
ASMJIT_PROPAGATE(cc()->fstp(mem));
ASMJIT_PROPAGATE(cc()->emit(choose(Inst::kIdMovss, Inst::kIdVmovss), dst.as<Xmm>(), mem));
break;
- case Type::kIdF64:
+ case TypeId::kFloat64:
ASMJIT_PROPAGATE(_pass->useTemporaryMem(mem, 8, 4));
mem.setSize(8);
ASMJIT_PROPAGATE(cc()->fstp(mem));
@@ -563,8 +595,8 @@ Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
}
}
else {
- uint32_t regGroup = workReg->group();
- uint32_t retGroup = Reg::groupOf(ret.regType());
+ RegGroup regGroup = workReg->group();
+ RegGroup retGroup = Reg::groupOf(ret.regType());
if (regGroup != retGroup) {
// TODO: Conversion is not supported.
@@ -577,8 +609,8 @@ Error RACFGBuilder::onBeforeInvoke(InvokeNode* invokeNode) noexcept {
}
// This block has function call(s).
- _curBlock->addFlags(RABlock::kFlagHasFuncCalls);
- _pass->func()->frame().addAttributes(FuncFrame::kAttrHasFuncCalls);
+ _curBlock->addFlags(RABlockFlags::kHasFuncCalls);
+ _pass->func()->frame().addAttributes(FuncAttributes::kHasFuncCalls);
_pass->func()->frame().updateCallStackSize(fd.argStackSize());
return kErrorOk;
@@ -606,14 +638,14 @@ Error RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
if (arg.isIndirect()) {
- uint32_t regGroup = workReg->group();
- if (regGroup != BaseReg::kGroupGp)
+ RegGroup regGroup = workReg->group();
+ if (regGroup != RegGroup::kGp)
return DebugUtils::errored(kErrorInvalidState);
ASMJIT_PROPAGATE(ib.addCallArg(workReg, arg.regId()));
}
else if (arg.isReg()) {
- uint32_t regGroup = workReg->group();
- uint32_t argGroup = Reg::groupOf(arg.regType());
+ RegGroup regGroup = workReg->group();
+ RegGroup argGroup = Reg::groupOf(arg.regType());
if (regGroup == argGroup) {
ASMJIT_PROPAGATE(ib.addCallArg(workReg, arg.regId()));
@@ -630,7 +662,7 @@ Error RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept
// Not handled here...
const Operand& op = invokeNode->ret(retIndex);
- if (ret.regType() == Reg::kTypeSt)
+ if (ret.regType() == RegType::kX86_St)
continue;
if (op.isReg()) {
@@ -639,8 +671,8 @@ Error RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(Operand::virtIdToIndex(reg.id()), &workReg));
if (ret.isReg()) {
- uint32_t regGroup = workReg->group();
- uint32_t retGroup = Reg::groupOf(ret.regType());
+ RegGroup regGroup = workReg->group();
+ RegGroup retGroup = Reg::groupOf(ret.regType());
if (regGroup == retGroup) {
ASMJIT_PROPAGATE(ib.addCallRet(workReg, ret.regId()));
@@ -653,32 +685,25 @@ Error RACFGBuilder::onInvoke(InvokeNode* invokeNode, RAInstBuilder& ib) noexcept
}
// Setup clobbered registers.
- ib._clobbered[0] = Support::lsbMask<uint32_t>(_pass->_physRegCount[0]) & ~fd.preservedRegs(0);
- ib._clobbered[1] = Support::lsbMask<uint32_t>(_pass->_physRegCount[1]) & ~fd.preservedRegs(1);
- ib._clobbered[2] = Support::lsbMask<uint32_t>(_pass->_physRegCount[2]) & ~fd.preservedRegs(2);
- ib._clobbered[3] = Support::lsbMask<uint32_t>(_pass->_physRegCount[3]) & ~fd.preservedRegs(3);
+ for (RegGroup group : RegGroupVirtValues{})
+ ib._clobbered[group] = Support::lsbMask<RegMask>(_pass->_physRegCount[group]) & ~fd.preservedRegs(group);
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - MoveVecToPtr]
-// ============================================================================
-
-static uint32_t x86VecRegSignatureBySize(uint32_t size) noexcept {
- if (size >= 64)
- return Zmm::kSignature;
- else if (size >= 32)
- return Ymm::kSignature;
- else
- return Xmm::kSignature;
+// x86::RACFGBuilder - MoveVecToPtr
+// ================================
+
+static inline OperandSignature x86VecRegSignatureBySize(uint32_t size) noexcept {
+ return OperandSignature(size >= 64 ? uint32_t(Zmm::kSignature) :
+ size >= 32 ? uint32_t(Ymm::kSignature) : uint32_t(Xmm::kSignature));
}
Error RACFGBuilder::moveVecToPtr(InvokeNode* invokeNode, const FuncValue& arg, const Vec& src, BaseReg* out) noexcept {
DebugUtils::unused(invokeNode);
ASMJIT_ASSERT(arg.isReg());
- uint32_t argSize = Type::sizeOf(arg.typeId());
+ uint32_t argSize = TypeUtils::sizeOf(arg.typeId());
if (argSize == 0)
return DebugUtils::errored(kErrorInvalidState);
@@ -689,14 +714,14 @@ Error RACFGBuilder::moveVecToPtr(InvokeNode* invokeNode, const FuncValue& arg, c
_funcNode->frame().updateCallStackAlignment(argSize);
invokeNode->detail()._argStackSize = argStackOffset + argSize;
- Vec vecReg = Vec::fromSignatureAndId(x86VecRegSignatureBySize(argSize), src.id());
+ Vec vecReg(x86VecRegSignatureBySize(argSize), src.id());
Mem vecPtr = ptr(_pass->_sp.as<Gp>(), int32_t(argStackOffset));
uint32_t vMovInstId = choose(Inst::kIdMovaps, Inst::kIdVmovaps);
if (argSize > 16)
vMovInstId = Inst::kIdVmovaps;
- ASMJIT_PROPAGATE(cc()->_newReg(out, cc()->_gpRegInfo.type(), nullptr));
+ ASMJIT_PROPAGATE(cc()->_newReg(out, ArchTraits::byArch(cc()->arch()).regTypeToTypeId(cc()->_gpSignature.regType()), nullptr));
VirtReg* vReg = cc()->virtRegById(out->id());
vReg->setWeight(BaseRAPass::kCallArgWeight);
@@ -712,38 +737,37 @@ Error RACFGBuilder::moveVecToPtr(InvokeNode* invokeNode, const FuncValue& arg, c
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - MoveImmToRegArg]
-// ============================================================================
+// x86::RACFGBuilder - MoveImmToRegArg
+// ===================================
Error RACFGBuilder::moveImmToRegArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_, BaseReg* out) noexcept {
DebugUtils::unused(invokeNode);
ASMJIT_ASSERT(arg.isReg());
Imm imm(imm_);
- uint32_t rTypeId = Type::kIdU32;
+ TypeId rTypeId = TypeId::kUInt32;
switch (arg.typeId()) {
- case Type::kIdI8: imm.signExtend8Bits(); goto MovU32;
- case Type::kIdU8: imm.zeroExtend8Bits(); goto MovU32;
- case Type::kIdI16: imm.signExtend16Bits(); goto MovU32;
- case Type::kIdU16: imm.zeroExtend16Bits(); goto MovU32;
+ case TypeId::kInt8: imm.signExtend8Bits(); goto MovU32;
+ case TypeId::kUInt8: imm.zeroExtend8Bits(); goto MovU32;
+ case TypeId::kInt16: imm.signExtend16Bits(); goto MovU32;
+ case TypeId::kUInt16: imm.zeroExtend16Bits(); goto MovU32;
- case Type::kIdI32:
- case Type::kIdU32:
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
MovU32:
imm.zeroExtend32Bits();
break;
- case Type::kIdI64:
- case Type::kIdU64:
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
// Moving to GPD automatically zero extends in 64-bit mode.
if (imm.isUInt32()) {
imm.zeroExtend32Bits();
break;
}
- rTypeId = Type::kIdU64;
+ rTypeId = TypeId::kUInt64;
break;
default:
@@ -756,9 +780,8 @@ MovU32:
return cc()->mov(out->as<x86::Gp>(), imm);
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - MoveImmToStackArg]
-// ============================================================================
+// x86::RACFGBuilder - MoveImmToStackArg
+// =====================================
Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const Imm& imm_) noexcept {
DebugUtils::unused(invokeNode);
@@ -771,30 +794,28 @@ Error RACFGBuilder::moveImmToStackArg(InvokeNode* invokeNode, const FuncValue& a
imm[0] = imm_;
uint32_t nMovs = 0;
- // One stack entry has the same size as the native register size. That means
- // that if we want to move a 32-bit integer on the stack in 64-bit mode, we
- // need to extend it to a 64-bit integer first. In 32-bit mode, pushing a
- // 64-bit on stack is done in two steps by pushing low and high parts
- // separately.
+ // One stack entry has the same size as the native register size. That means that if we want to move a 32-bit
+ // integer on the stack in 64-bit mode, we need to extend it to a 64-bit integer first. In 32-bit mode, pushing
+ // a 64-bit on stack is done in two steps by pushing low and high parts separately.
switch (arg.typeId()) {
- case Type::kIdI8: imm[0].signExtend8Bits(); goto MovU32;
- case Type::kIdU8: imm[0].zeroExtend8Bits(); goto MovU32;
- case Type::kIdI16: imm[0].signExtend16Bits(); goto MovU32;
- case Type::kIdU16: imm[0].zeroExtend16Bits(); goto MovU32;
-
- case Type::kIdI32:
- case Type::kIdU32:
- case Type::kIdF32:
+ case TypeId::kInt8: imm[0].signExtend8Bits(); goto MovU32;
+ case TypeId::kUInt8: imm[0].zeroExtend8Bits(); goto MovU32;
+ case TypeId::kInt16: imm[0].signExtend16Bits(); goto MovU32;
+ case TypeId::kUInt16: imm[0].zeroExtend16Bits(); goto MovU32;
+
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ case TypeId::kFloat32:
MovU32:
imm[0].zeroExtend32Bits();
nMovs = 1;
break;
- case Type::kIdI64:
- case Type::kIdU64:
- case Type::kIdF64:
- case Type::kIdMmx32:
- case Type::kIdMmx64:
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
+ case TypeId::kFloat64:
+ case TypeId::kMmx32:
+ case TypeId::kMmx64:
if (_is64Bit && imm[0].isInt32()) {
stackPtr.setSize(8);
nMovs = 1;
@@ -818,9 +839,8 @@ MovU32:
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - MoveRegToStackArg]
-// ============================================================================
+// x86::RACFGBuilder - MoveRegToStackArg
+// =====================================
Error RACFGBuilder::moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& arg, const BaseReg& reg) noexcept {
DebugUtils::unused(invokeNode);
@@ -831,124 +851,124 @@ Error RACFGBuilder::moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& a
VirtReg* vr = cc()->virtRegById(reg.id());
uint32_t registerSize = cc()->registerSize();
- uint32_t instId = 0;
+ InstId instId = 0;
- uint32_t dstTypeId = arg.typeId();
- uint32_t srcTypeId = vr->typeId();
+ TypeId dstTypeId = arg.typeId();
+ TypeId srcTypeId = vr->typeId();
switch (dstTypeId) {
- case Type::kIdI64:
- case Type::kIdU64:
+ case TypeId::kInt64:
+ case TypeId::kUInt64:
// Extend BYTE->QWORD (GP).
- if (Type::isGp8(srcTypeId)) {
- r1.setRegT<Reg::kTypeGpbLo>(reg.id());
+ if (TypeUtils::isGp8(srcTypeId)) {
+ r1.setRegT<RegType::kX86_GpbLo>(reg.id());
- instId = (dstTypeId == Type::kIdI64 && srcTypeId == Type::kIdI8) ? Inst::kIdMovsx : Inst::kIdMovzx;
+ instId = (dstTypeId == TypeId::kInt64 && srcTypeId == TypeId::kInt8) ? Inst::kIdMovsx : Inst::kIdMovzx;
goto ExtendMovGpXQ;
}
// Extend WORD->QWORD (GP).
- if (Type::isGp16(srcTypeId)) {
- r1.setRegT<Reg::kTypeGpw>(reg.id());
+ if (TypeUtils::isGp16(srcTypeId)) {
+ r1.setRegT<RegType::kX86_Gpw>(reg.id());
- instId = (dstTypeId == Type::kIdI64 && srcTypeId == Type::kIdI16) ? Inst::kIdMovsx : Inst::kIdMovzx;
+ instId = (dstTypeId == TypeId::kInt64 && srcTypeId == TypeId::kInt16) ? Inst::kIdMovsx : Inst::kIdMovzx;
goto ExtendMovGpXQ;
}
// Extend DWORD->QWORD (GP).
- if (Type::isGp32(srcTypeId)) {
- r1.setRegT<Reg::kTypeGpd>(reg.id());
+ if (TypeUtils::isGp32(srcTypeId)) {
+ r1.setRegT<RegType::kX86_Gpd>(reg.id());
instId = Inst::kIdMovsxd;
- if (dstTypeId == Type::kIdI64 && srcTypeId == Type::kIdI32)
+ if (dstTypeId == TypeId::kInt64 && srcTypeId == TypeId::kInt32)
goto ExtendMovGpXQ;
else
goto ZeroExtendGpDQ;
}
// Move QWORD (GP).
- if (Type::isGp64(srcTypeId)) goto MovGpQ;
- if (Type::isMmx(srcTypeId)) goto MovMmQ;
- if (Type::isVec(srcTypeId)) goto MovXmmQ;
+ if (TypeUtils::isGp64(srcTypeId)) goto MovGpQ;
+ if (TypeUtils::isMmx(srcTypeId)) goto MovMmQ;
+ if (TypeUtils::isVec(srcTypeId)) goto MovXmmQ;
break;
- case Type::kIdI32:
- case Type::kIdU32:
- case Type::kIdI16:
- case Type::kIdU16:
+ case TypeId::kInt32:
+ case TypeId::kUInt32:
+ case TypeId::kInt16:
+ case TypeId::kUInt16:
// DWORD <- WORD (Zero|Sign Extend).
- if (Type::isGp16(srcTypeId)) {
- bool isDstSigned = dstTypeId == Type::kIdI16 || dstTypeId == Type::kIdI32;
- bool isSrcSigned = srcTypeId == Type::kIdI8 || srcTypeId == Type::kIdI16;
+ if (TypeUtils::isGp16(srcTypeId)) {
+ bool isDstSigned = dstTypeId == TypeId::kInt16 || dstTypeId == TypeId::kInt32;
+ bool isSrcSigned = srcTypeId == TypeId::kInt8 || srcTypeId == TypeId::kInt16;
- r1.setRegT<Reg::kTypeGpw>(reg.id());
+ r1.setRegT<RegType::kX86_Gpw>(reg.id());
instId = isDstSigned && isSrcSigned ? Inst::kIdMovsx : Inst::kIdMovzx;
goto ExtendMovGpD;
}
// DWORD <- BYTE (Zero|Sign Extend).
- if (Type::isGp8(srcTypeId)) {
- bool isDstSigned = dstTypeId == Type::kIdI16 || dstTypeId == Type::kIdI32;
- bool isSrcSigned = srcTypeId == Type::kIdI8 || srcTypeId == Type::kIdI16;
+ if (TypeUtils::isGp8(srcTypeId)) {
+ bool isDstSigned = dstTypeId == TypeId::kInt16 || dstTypeId == TypeId::kInt32;
+ bool isSrcSigned = srcTypeId == TypeId::kInt8 || srcTypeId == TypeId::kInt16;
- r1.setRegT<Reg::kTypeGpbLo>(reg.id());
+ r1.setRegT<RegType::kX86_GpbLo>(reg.id());
instId = isDstSigned && isSrcSigned ? Inst::kIdMovsx : Inst::kIdMovzx;
goto ExtendMovGpD;
}
ASMJIT_FALLTHROUGH;
- case Type::kIdI8:
- case Type::kIdU8:
- if (Type::isInt(srcTypeId)) goto MovGpD;
- if (Type::isMmx(srcTypeId)) goto MovMmD;
- if (Type::isVec(srcTypeId)) goto MovXmmD;
+ case TypeId::kInt8:
+ case TypeId::kUInt8:
+ if (TypeUtils::isInt(srcTypeId)) goto MovGpD;
+ if (TypeUtils::isMmx(srcTypeId)) goto MovMmD;
+ if (TypeUtils::isVec(srcTypeId)) goto MovXmmD;
break;
- case Type::kIdMmx32:
- case Type::kIdMmx64:
+ case TypeId::kMmx32:
+ case TypeId::kMmx64:
// Extend BYTE->QWORD (GP).
- if (Type::isGp8(srcTypeId)) {
- r1.setRegT<Reg::kTypeGpbLo>(reg.id());
+ if (TypeUtils::isGp8(srcTypeId)) {
+ r1.setRegT<RegType::kX86_GpbLo>(reg.id());
instId = Inst::kIdMovzx;
goto ExtendMovGpXQ;
}
// Extend WORD->QWORD (GP).
- if (Type::isGp16(srcTypeId)) {
- r1.setRegT<Reg::kTypeGpw>(reg.id());
+ if (TypeUtils::isGp16(srcTypeId)) {
+ r1.setRegT<RegType::kX86_Gpw>(reg.id());
instId = Inst::kIdMovzx;
goto ExtendMovGpXQ;
}
- if (Type::isGp32(srcTypeId)) goto ExtendMovGpDQ;
- if (Type::isGp64(srcTypeId)) goto MovGpQ;
- if (Type::isMmx(srcTypeId)) goto MovMmQ;
- if (Type::isVec(srcTypeId)) goto MovXmmQ;
+ if (TypeUtils::isGp32(srcTypeId)) goto ExtendMovGpDQ;
+ if (TypeUtils::isGp64(srcTypeId)) goto MovGpQ;
+ if (TypeUtils::isMmx(srcTypeId)) goto MovMmQ;
+ if (TypeUtils::isVec(srcTypeId)) goto MovXmmQ;
break;
- case Type::kIdF32:
- case Type::kIdF32x1:
- if (Type::isVec(srcTypeId)) goto MovXmmD;
+ case TypeId::kFloat32:
+ case TypeId::kFloat32x1:
+ if (TypeUtils::isVec(srcTypeId)) goto MovXmmD;
break;
- case Type::kIdF64:
- case Type::kIdF64x1:
- if (Type::isVec(srcTypeId)) goto MovXmmQ;
+ case TypeId::kFloat64:
+ case TypeId::kFloat64x1:
+ if (TypeUtils::isVec(srcTypeId)) goto MovXmmQ;
break;
default:
- if (Type::isVec(dstTypeId) && reg.as<Reg>().isVec()) {
- stackPtr.setSize(Type::sizeOf(dstTypeId));
+ if (TypeUtils::isVec(dstTypeId) && reg.as<Reg>().isVec()) {
+ stackPtr.setSize(TypeUtils::sizeOf(dstTypeId));
uint32_t vMovInstId = choose(Inst::kIdMovaps, Inst::kIdVmovaps);
- if (Type::isVec128(dstTypeId))
- r0.setRegT<Reg::kTypeXmm>(reg.id());
- else if (Type::isVec256(dstTypeId))
- r0.setRegT<Reg::kTypeYmm>(reg.id());
- else if (Type::isVec512(dstTypeId))
- r0.setRegT<Reg::kTypeZmm>(reg.id());
+ if (TypeUtils::isVec128(dstTypeId))
+ r0.setRegT<RegType::kX86_Xmm>(reg.id());
+ else if (TypeUtils::isVec256(dstTypeId))
+ r0.setRegT<RegType::kX86_Ymm>(reg.id());
+ else if (TypeUtils::isVec512(dstTypeId))
+ r0.setRegT<RegType::kX86_Zmm>(reg.id());
else
break;
@@ -961,7 +981,7 @@ Error RACFGBuilder::moveRegToStackArg(InvokeNode* invokeNode, const FuncValue& a
// Extend+Move Gp.
ExtendMovGpD:
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeGpd>(reg.id());
+ r0.setRegT<RegType::kX86_Gpd>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, stackPtr, r0));
@@ -970,14 +990,14 @@ ExtendMovGpD:
ExtendMovGpXQ:
if (registerSize == 8) {
stackPtr.setSize(8);
- r0.setRegT<Reg::kTypeGpq>(reg.id());
+ r0.setRegT<RegType::kX86_Gpq>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
ASMJIT_PROPAGATE(cc()->emit(Inst::kIdMov, stackPtr, r0));
}
else {
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeGpd>(reg.id());
+ r0.setRegT<RegType::kX86_Gpd>(reg.id());
ASMJIT_PROPAGATE(cc()->emit(instId, r0, r1));
@@ -990,43 +1010,42 @@ ExtendMovGpDQ:
ZeroExtendGpDQ:
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeGpd>(reg.id());
+ r0.setRegT<RegType::kX86_Gpd>(reg.id());
goto ExtendMovGpDQ;
MovGpD:
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeGpd>(reg.id());
+ r0.setRegT<RegType::kX86_Gpd>(reg.id());
return cc()->emit(Inst::kIdMov, stackPtr, r0);
MovGpQ:
stackPtr.setSize(8);
- r0.setRegT<Reg::kTypeGpq>(reg.id());
+ r0.setRegT<RegType::kX86_Gpq>(reg.id());
return cc()->emit(Inst::kIdMov, stackPtr, r0);
MovMmD:
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeMm>(reg.id());
+ r0.setRegT<RegType::kX86_Mm>(reg.id());
return cc()->emit(choose(Inst::kIdMovd, Inst::kIdVmovd), stackPtr, r0);
MovMmQ:
stackPtr.setSize(8);
- r0.setRegT<Reg::kTypeMm>(reg.id());
+ r0.setRegT<RegType::kX86_Mm>(reg.id());
return cc()->emit(choose(Inst::kIdMovq, Inst::kIdVmovq), stackPtr, r0);
MovXmmD:
stackPtr.setSize(4);
- r0.setRegT<Reg::kTypeXmm>(reg.id());
+ r0.setRegT<RegType::kX86_Xmm>(reg.id());
return cc()->emit(choose(Inst::kIdMovss, Inst::kIdVmovss), stackPtr, r0);
MovXmmQ:
stackPtr.setSize(8);
- r0.setRegT<Reg::kTypeXmm>(reg.id());
+ r0.setRegT<RegType::kX86_Xmm>(reg.id());
return cc()->emit(choose(Inst::kIdMovlps, Inst::kIdVmovlps), stackPtr, r0);
}
-// ============================================================================
-// [asmjit::x86::RACFGBuilder - OnReg]
-// ============================================================================
+// x86::RACFGBuilder - OnReg
+// =========================
Error RACFGBuilder::onBeforeRet(FuncRetNode* funcRet) noexcept {
const FuncDetail& funcDetail = _pass->func()->detail();
@@ -1042,7 +1061,7 @@ Error RACFGBuilder::onBeforeRet(FuncRetNode* funcRet) noexcept {
if (!op.isReg())
continue;
- if (ret.regType() == Reg::kTypeSt) {
+ if (ret.regType() == RegType::kX86_St) {
const Reg& reg = op.as<Reg>();
uint32_t vIndex = Operand::virtIdToIndex(reg.id());
@@ -1050,25 +1069,25 @@ Error RACFGBuilder::onBeforeRet(FuncRetNode* funcRet) noexcept {
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- if (workReg->group() != Reg::kGroupVec)
+ if (workReg->group() != RegGroup::kVec)
return DebugUtils::errored(kErrorInvalidAssignment);
- Reg src = Reg::fromSignatureAndId(workReg->signature(), workReg->virtId());
+ Reg src(workReg->signature(), workReg->virtId());
Mem mem;
- uint32_t typeId = Type::baseOf(workReg->typeId());
+ TypeId typeId = TypeUtils::scalarOf(workReg->typeId());
if (ret.hasTypeId())
typeId = ret.typeId();
switch (typeId) {
- case Type::kIdF32:
+ case TypeId::kFloat32:
ASMJIT_PROPAGATE(_pass->useTemporaryMem(mem, 4, 4));
mem.setSize(4);
ASMJIT_PROPAGATE(cc()->emit(choose(Inst::kIdMovss, Inst::kIdVmovss), mem, src.as<Xmm>()));
ASMJIT_PROPAGATE(cc()->fld(mem));
break;
- case Type::kIdF64:
+ case TypeId::kFloat64:
ASMJIT_PROPAGATE(_pass->useTemporaryMem(mem, 8, 4));
mem.setSize(8);
ASMJIT_PROPAGATE(cc()->emit(choose(Inst::kIdMovsd, Inst::kIdVmovsd), mem, src.as<Xmm>()));
@@ -1099,7 +1118,7 @@ Error RACFGBuilder::onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept {
return DebugUtils::errored(kErrorInvalidAssignment);
// Not handled here...
- if (ret.regType() == Reg::kTypeSt)
+ if (ret.regType() == RegType::kX86_St)
continue;
if (op.isReg()) {
@@ -1111,9 +1130,9 @@ Error RACFGBuilder::onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept {
RAWorkReg* workReg;
ASMJIT_PROPAGATE(_pass->virtIndexAsWorkReg(vIndex, &workReg));
- uint32_t group = workReg->group();
- uint32_t allocable = _pass->_availableRegs[group];
- ASMJIT_PROPAGATE(ib.add(workReg, RATiedReg::kUse | RATiedReg::kRead, allocable, ret.regId(), 0, BaseReg::kIdBad, 0));
+ RegGroup group = workReg->group();
+ RegMask inOutRegs = _pass->_availableRegs[group];
+ ASMJIT_PROPAGATE(ib.add(workReg, RATiedFlags::kUse | RATiedFlags::kRead, inOutRegs, ret.regId(), 0, inOutRegs, BaseReg::kIdBad, 0));
}
}
else {
@@ -1124,20 +1143,18 @@ Error RACFGBuilder::onRet(FuncRetNode* funcRet, RAInstBuilder& ib) noexcept {
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::X86RAPass - Construction / Destruction]
-// ============================================================================
+// x86::X86RAPass - Construction & Destruction
+// ===========================================
X86RAPass::X86RAPass() noexcept
: BaseRAPass() { _iEmitHelper = &_emitHelper; }
X86RAPass::~X86RAPass() noexcept {}
-// ============================================================================
-// [asmjit::x86::X86RAPass - OnInit / OnDone]
-// ============================================================================
+// x86::X86RAPass - OnInit & OnDone
+// ================================
void X86RAPass::onInit() noexcept {
- uint32_t arch = cc()->arch();
+ Arch arch = cc()->arch();
uint32_t baseRegCount = Environment::is32Bit(arch) ? 8u : 16u;
uint32_t simdRegCount = baseRegCount;
@@ -1152,17 +1169,17 @@ void X86RAPass::onInit() noexcept {
_emitHelper._avx512Enabled = avx512Enabled;
_archTraits = &ArchTraits::byArch(arch);
- _physRegCount.set(Reg::kGroupGp , baseRegCount);
- _physRegCount.set(Reg::kGroupVec , simdRegCount);
- _physRegCount.set(Reg::kGroupMm , 8);
- _physRegCount.set(Reg::kGroupKReg, 8);
+ _physRegCount.set(RegGroup::kGp, baseRegCount);
+ _physRegCount.set(RegGroup::kVec, simdRegCount);
+ _physRegCount.set(RegGroup::kX86_K, 8);
+ _physRegCount.set(RegGroup::kX86_MM, 8);
_buildPhysIndex();
_availableRegCount = _physRegCount;
- _availableRegs[Reg::kGroupGp ] = Support::lsbMask<uint32_t>(_physRegCount.get(Reg::kGroupGp ));
- _availableRegs[Reg::kGroupVec ] = Support::lsbMask<uint32_t>(_physRegCount.get(Reg::kGroupVec ));
- _availableRegs[Reg::kGroupMm ] = Support::lsbMask<uint32_t>(_physRegCount.get(Reg::kGroupMm ));
- _availableRegs[Reg::kGroupKReg] = Support::lsbMask<uint32_t>(_physRegCount.get(Reg::kGroupKReg)) ^ 1u;
+ _availableRegs[RegGroup::kGp] = Support::lsbMask<RegMask>(_physRegCount.get(RegGroup::kGp));
+ _availableRegs[RegGroup::kVec] = Support::lsbMask<RegMask>(_physRegCount.get(RegGroup::kVec));
+ _availableRegs[RegGroup::kX86_K] = Support::lsbMask<RegMask>(_physRegCount.get(RegGroup::kX86_K)) ^ 1u;
+ _availableRegs[RegGroup::kX86_MM] = Support::lsbMask<RegMask>(_physRegCount.get(RegGroup::kX86_MM));
_scratchRegIndexes[0] = uint8_t(Gp::kIdCx);
_scratchRegIndexes[1] = uint8_t(baseRegCount - 1);
@@ -1171,8 +1188,8 @@ void X86RAPass::onInit() noexcept {
// make unavailable all registers that are special and cannot be used in general.
bool hasFP = _func->frame().hasPreservedFP();
- makeUnavailable(Reg::kGroupGp, Gp::kIdSp); // ESP|RSP used as a stack-pointer (SP).
- if (hasFP) makeUnavailable(Reg::kGroupGp, Gp::kIdBp); // EBP|RBP used as a frame-pointer (FP).
+ makeUnavailable(RegGroup::kGp, Gp::kIdSp); // ESP|RSP used as a stack-pointer (SP).
+ if (hasFP) makeUnavailable(RegGroup::kGp, Gp::kIdBp); // EBP|RBP used as a frame-pointer (FP).
_sp = cc()->zsp();
_fp = cc()->zbp();
@@ -1180,19 +1197,17 @@ void X86RAPass::onInit() noexcept {
void X86RAPass::onDone() noexcept {}
-// ============================================================================
-// [asmjit::x86::X86RAPass - BuildCFG]
-// ============================================================================
+// x86::X86RAPass - BuildCFG
+// =========================
Error X86RAPass::buildCFG() noexcept {
return RACFGBuilder(this).run();
}
-// ============================================================================
-// [asmjit::x86::X86RAPass - Rewrite]
-// ============================================================================
+// x86::X86RAPass - Rewrite
+// ========================
-static uint32_t transformVexToEvex(uint32_t instId) {
+static InstId transformVexToEvex(InstId instId) {
switch (instId) {
case Inst::kIdVbroadcastf128: return Inst::kIdVbroadcastf32x4;
case Inst::kIdVbroadcasti128: return Inst::kIdVbroadcasti32x4;
@@ -1206,6 +1221,10 @@ static uint32_t transformVexToEvex(uint32_t instId) {
case Inst::kIdVpandn: return Inst::kIdVpandnd;
case Inst::kIdVpor: return Inst::kIdVpord;
case Inst::kIdVpxor: return Inst::kIdVpxord;
+ case Inst::kIdVroundpd: return Inst::kIdVrndscalepd;
+ case Inst::kIdVroundps: return Inst::kIdVrndscaleps;
+ case Inst::kIdVroundsd: return Inst::kIdVrndscalesd;
+ case Inst::kIdVroundss: return Inst::kIdVrndscaless;
default:
// This should never happen as only transformable instructions should go this path.
@@ -1232,8 +1251,8 @@ ASMJIT_FAVOR_SPEED Error X86RAPass::_rewrite(BaseNode* first, BaseNode* stop) no
// Rewrite virtual registers into physical registers.
if (raInst) {
- // If the instruction contains pass data (raInst) then it was a subject
- // for register allocation and must be rewritten to use physical regs.
+ // If the instruction contains pass data (raInst) then it was a subject for register allocation and must be
+ // rewritten to use physical regs.
RATiedReg* tiedRegs = raInst->tiedRegs();
uint32_t tiedCount = raInst->tiedCount();
@@ -1262,17 +1281,14 @@ ASMJIT_FAVOR_SPEED Error X86RAPass::_rewrite(BaseNode* first, BaseNode* stop) no
}
}
- // This data is allocated by Zone passed to `runOnFunction()`, which
- // will be reset after the RA pass finishes. So reset this data to
- // prevent having a dead pointer after the RA pass is complete.
+ // This data is allocated by Zone passed to `runOnFunction()`, which will be reset after the RA pass finishes.
+ // So reset this data to prevent having a dead pointer after the RA pass is complete.
node->resetPassData();
- if (ASMJIT_UNLIKELY(node->type() != BaseNode::kNodeInst)) {
- // FuncRet terminates the flow, it must either be removed if the exit
- // label is next to it (optimization) or patched to an architecture
- // dependent jump instruction that jumps to the function's exit before
- // the epilog.
- if (node->type() == BaseNode::kNodeFuncRet) {
+ if (ASMJIT_UNLIKELY(node->type() != NodeType::kInst)) {
+ // FuncRet terminates the flow, it must either be removed if the exit label is next to it (optimization) or
+ // patched to an architecture dependent jump instruction that jumps to the function's exit before the epilog.
+ if (node->type() == NodeType::kFuncRet) {
RABlock* block = raInst->block();
if (!isNextTo(node, _func->exitNode())) {
cc()->_setCursor(node->prev());
@@ -1317,19 +1333,18 @@ ASMJIT_FAVOR_SPEED Error X86RAPass::_rewrite(BaseNode* first, BaseNode* stop) no
return kErrorOk;
}
-// ============================================================================
-// [asmjit::x86::X86RAPass - OnEmit]
-// ============================================================================
+// x86::X86RAPass - OnEmit
+// =======================
Error X86RAPass::emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
RAWorkReg* wReg = workRegById(workId);
- BaseReg dst = BaseReg::fromSignatureAndId(wReg->info().signature(), dstPhysId);
- BaseReg src = BaseReg::fromSignatureAndId(wReg->info().signature(), srcPhysId);
+ BaseReg dst(wReg->signature(), dstPhysId);
+ BaseReg src(wReg->signature(), srcPhysId);
const char* comment = nullptr;
#ifndef ASMJIT_NO_LOGGING
- if (_loggerFlags & FormatOptions::kFlagAnnotations) {
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
_tmpString.assignFormat("<MOVE> %s", workRegById(workId)->name());
comment = _tmpString.data();
}
@@ -1342,31 +1357,29 @@ Error X86RAPass::emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId,
RAWorkReg* waReg = workRegById(aWorkId);
RAWorkReg* wbReg = workRegById(bWorkId);
- bool is64Bit = Support::max(waReg->typeId(), wbReg->typeId()) >= Type::kIdI64;
- uint32_t sign = is64Bit ? uint32_t(RegTraits<Reg::kTypeGpq>::kSignature)
- : uint32_t(RegTraits<Reg::kTypeGpd>::kSignature);
+ bool is64Bit = Support::max(waReg->typeId(), wbReg->typeId()) >= TypeId::kInt64;
+ OperandSignature sign = is64Bit ? OperandSignature(RegTraits<RegType::kX86_Gpq>::kSignature)
+ : OperandSignature(RegTraits<RegType::kX86_Gpd>::kSignature);
#ifndef ASMJIT_NO_LOGGING
- if (_loggerFlags & FormatOptions::kFlagAnnotations) {
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
_tmpString.assignFormat("<SWAP> %s, %s", waReg->name(), wbReg->name());
cc()->setInlineComment(_tmpString.data());
}
#endif
- return cc()->emit(Inst::kIdXchg,
- Reg::fromSignatureAndId(sign, aPhysId),
- Reg::fromSignatureAndId(sign, bPhysId));
+ return cc()->emit(Inst::kIdXchg, Reg(sign, aPhysId), Reg(sign, bPhysId));
}
Error X86RAPass::emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept {
RAWorkReg* wReg = workRegById(workId);
- BaseReg dstReg = BaseReg::fromSignatureAndId(wReg->info().signature(), dstPhysId);
- BaseMem srcMem = BaseMem(workRegAsMem(wReg));
+ BaseReg dstReg(wReg->signature(), dstPhysId);
+ BaseMem srcMem(workRegAsMem(wReg));
const char* comment = nullptr;
#ifndef ASMJIT_NO_LOGGING
- if (_loggerFlags & FormatOptions::kFlagAnnotations) {
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
_tmpString.assignFormat("<LOAD> %s", workRegById(workId)->name());
comment = _tmpString.data();
}
@@ -1377,13 +1390,13 @@ Error X86RAPass::emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept {
Error X86RAPass::emitSave(uint32_t workId, uint32_t srcPhysId) noexcept {
RAWorkReg* wReg = workRegById(workId);
- BaseMem dstMem = BaseMem(workRegAsMem(wReg));
- BaseReg srcReg = BaseReg::fromSignatureAndId(wReg->info().signature(), srcPhysId);
+ BaseMem dstMem(workRegAsMem(wReg));
+ BaseReg srcReg(wReg->signature(), srcPhysId);
const char* comment = nullptr;
#ifndef ASMJIT_NO_LOGGING
- if (_loggerFlags & FormatOptions::kFlagAnnotations) {
+ if (hasDiagnosticOption(DiagnosticOptions::kRAAnnotate)) {
_tmpString.assignFormat("<SAVE> %s", workRegById(workId)->name());
comment = _tmpString.data();
}
@@ -1402,7 +1415,7 @@ Error X86RAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
uint32_t argCount = invokeNode->argCount();
switch (invokeNode->detail().callConv().id()) {
- case CallConv::kIdX64SystemV: {
+ case CallConvId::kX64SystemV: {
// AL register contains the number of arguments passed in XMM register(s).
uint32_t n = 0;
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
@@ -1412,7 +1425,7 @@ Error X86RAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
if (!arg)
break;
- if (arg.isReg() && Reg::groupOf(arg.regType()) == Reg::kGroupVec)
+ if (arg.isReg() && Reg::groupOf(arg.regType()) == RegGroup::kVec)
n++;
}
}
@@ -1424,7 +1437,7 @@ Error X86RAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
break;
}
- case CallConv::kIdX64Windows: {
+ case CallConvId::kX64Windows: {
// Each double-precision argument passed in XMM must be also passed in GP.
for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
const FuncValuePack& argPack = fd.argPack(argIndex);
@@ -1433,8 +1446,8 @@ Error X86RAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
if (!arg)
break;
- if (arg.isReg() && Reg::groupOf(arg.regType()) == Reg::kGroupVec) {
- Gp dst = gpq(fd.callConv().passedOrder(Reg::kGroupGp)[argIndex]);
+ if (arg.isReg() && Reg::groupOf(arg.regType()) == RegGroup::kVec) {
+ Gp dst = gpq(fd.callConv().passedOrder(RegGroup::kGp)[argIndex]);
Xmm src = xmm(arg.regId());
ASMJIT_PROPAGATE(cc()->emit(choose(Inst::kIdMovq, Inst::kIdVmovq), dst, src));
}
diff --git a/src/asmjit/x86/x86rapass_p.h b/src/asmjit/x86/x86rapass_p.h
index 5faa04f..b9603c2 100644
--- a/src/asmjit/x86/x86rapass_p.h
+++ b/src/asmjit/x86/x86rapass_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_X86_X86RAPASS_P_H_INCLUDED
#define ASMJIT_X86_X86RAPASS_P_H_INCLUDED
@@ -40,14 +22,9 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
//! \addtogroup asmjit_x86
//! \{
-// ============================================================================
-// [asmjit::X86RAPass]
-// ============================================================================
-
//! X86 register allocation pass.
//!
-//! Takes care of generating function prologs and epilogs, and also performs
-//! register allocation.
+//! Takes care of generating function prologs and epilogs, and also performs register allocation.
class X86RAPass : public BaseRAPass {
public:
ASMJIT_NONCOPYABLE(X86RAPass)
@@ -55,16 +32,16 @@ public:
EmitHelper _emitHelper;
- // --------------------------------------------------------------------------
- // [Construction / Destruction]
- // --------------------------------------------------------------------------
+ //! \name Construction & Destruction
+ //! \{
X86RAPass() noexcept;
virtual ~X86RAPass() noexcept;
- // --------------------------------------------------------------------------
- // [Accessors]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Accessors
+ //! \{
//! Returns the compiler casted to `x86::Compiler`.
inline Compiler* cc() const noexcept { return static_cast<Compiler*>(_cb); }
@@ -72,40 +49,30 @@ public:
//! Returns emit helper.
inline EmitHelper* emitHelper() noexcept { return &_emitHelper; }
- // --------------------------------------------------------------------------
- // [Utilities]
- // --------------------------------------------------------------------------
-
inline bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; }
inline bool avx512Enabled() const noexcept { return _emitHelper._avx512Enabled; }
+ //! \}
+
+ //! \name Utilities
+ //! \{
+
inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept {
return avxEnabled() ? avxInstId : sseInstId;
}
- // --------------------------------------------------------------------------
- // [OnInit / OnDone]
- // --------------------------------------------------------------------------
+ //! \}
+
+ //! \name Interface
+ //! \{
void onInit() noexcept override;
void onDone() noexcept override;
- // --------------------------------------------------------------------------
- // [CFG]
- // --------------------------------------------------------------------------
-
Error buildCFG() noexcept override;
- // --------------------------------------------------------------------------
- // [Rewrite]
- // --------------------------------------------------------------------------
-
Error _rewrite(BaseNode* first, BaseNode* stop) noexcept override;
- // --------------------------------------------------------------------------
- // [Emit]
- // --------------------------------------------------------------------------
-
Error emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept override;
Error emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept override;
@@ -114,6 +81,8 @@ public:
Error emitJump(const Label& label) noexcept override;
Error emitPreCall(InvokeNode* invokeNode) noexcept override;
+
+ //! \}
};
//! \}
diff --git a/test/asmjit_test_assembler.cpp b/test/asmjit_test_assembler.cpp
index 5ae19ab..bcb16ad 100644
--- a/test/asmjit_test_assembler.cpp
+++ b/test/asmjit_test_assembler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
#include <stdio.h>
@@ -41,6 +23,7 @@ int main(int argc, char* argv[]) {
TestSettings settings {};
settings.quiet = cmdLine.hasArg("--quiet");
+ settings.validate = cmdLine.hasArg("--validate");
printf("AsmJit Assembler Test-Suite v%u.%u.%u:\n\n",
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
@@ -51,6 +34,7 @@ int main(int argc, char* argv[]) {
printf(" --help Show usage only\n");
printf(" --arch=<ARCH> Select architecture to run ('all' by default)\n");
printf(" --quiet Show only assembling errors [%s]\n", settings.quiet ? "x" : " ");
+ printf(" --validate Use instruction validation [%s]\n", settings.validate ? "x" : " ");
printf("\n");
if (cmdLine.hasArg("--help"))
diff --git a/test/asmjit_test_assembler.h b/test/asmjit_test_assembler.h
index c14a300..0e98c26 100644
--- a/test/asmjit_test_assembler.h
+++ b/test/asmjit_test_assembler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_TEST_ASSEMBLER_H_INCLUDED
#define ASMJIT_TEST_ASSEMBLER_H_INCLUDED
@@ -29,6 +11,7 @@
struct TestSettings {
bool quiet;
+ bool validate;
};
template<typename AssemblerType>
@@ -42,7 +25,7 @@ public:
size_t passed {};
size_t count {};
- AssemblerTester(uint32_t arch, const TestSettings& settings) noexcept
+ AssemblerTester(asmjit::Arch arch, const TestSettings& settings) noexcept
: env(arch),
settings(settings) {
prepare();
@@ -62,6 +45,9 @@ public:
code.reset();
code.init(env, 0);
code.attach(&assembler);
+
+ if (settings.validate)
+ assembler.addDiagnosticOptions(asmjit::DiagnosticOptions::kValidateAssembler);
}
ASMJIT_NOINLINE bool testInstruction(const char* expectedOpcode, const char* s, uint32_t err) noexcept {
diff --git a/test/asmjit_test_assembler_x64.cpp b/test/asmjit_test_assembler_x64.cpp
index ab7b780..bedf796 100644
--- a/test/asmjit_test_assembler_x64.cpp
+++ b/test/asmjit_test_assembler_x64.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
#if !defined(ASMJIT_NO_X86)
@@ -1074,9 +1056,9 @@ static void ASMJIT_NOINLINE testX64AssemblerBase(AssemblerTester<x86::Assembler>
TEST_INSTRUCTION("480FBFCA" , movsx(rcx, dx));
TEST_INSTRUCTION("480FBE8C1A80000000" , movsx(rcx, byte_ptr(rdx, rbx, 0, 128)));
TEST_INSTRUCTION("480FBF8C1A80000000" , movsx(rcx, word_ptr(rdx, rbx, 0, 128)));
- TEST_INSTRUCTION("6663CA" , movsxd(cx, edx));
+ TEST_INSTRUCTION("6663CA" , movsxd(cx, dx));
TEST_INSTRUCTION("66638C1A80000000" , movsxd(cx, ptr(rdx, rbx, 0, 128)));
- TEST_INSTRUCTION("66638C1A80000000" , movsxd(cx, dword_ptr(rdx, rbx, 0, 128)));
+ TEST_INSTRUCTION("66638C1A80000000" , movsxd(cx, word_ptr(rdx, rbx, 0, 128)));
TEST_INSTRUCTION("63CA" , movsxd(ecx, edx));
TEST_INSTRUCTION("638C1A80000000" , movsxd(ecx, ptr(rdx, rbx, 0, 128)));
TEST_INSTRUCTION("638C1A80000000" , movsxd(ecx, dword_ptr(rdx, rbx, 0, 128)));
@@ -8033,6 +8015,9625 @@ static void ASMJIT_NOINLINE testX64AssemblerAVX(AssemblerTester<x86::Assembler>&
TEST_INSTRUCTION("C5F877" , vzeroupper());
}
+static void ASMJIT_NOINLINE testX64AssemblerAVX512_FP16(AssemblerTester<x86::Assembler>& tester) noexcept {
+ using namespace x86;
+
+ TEST_INSTRUCTION("62F5560810F4" , vmovsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F57E0F10B4F400000010" , k(k7).vmovsh(xmm6, word_ptr(rsp, rsi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E081031" , vmovsh(xmm6, word_ptr(rcx)));
+ TEST_INSTRUCTION("62F57E0810717F" , vmovsh(xmm6, word_ptr(rcx, 254)));
+ TEST_INSTRUCTION("62F57E8F107280" , k(k7).z().vmovsh(xmm6, word_ptr(rdx, -256)));
+ TEST_INSTRUCTION("62F57E0F11B4F400000010" , k(k7).vmovsh(word_ptr(rsp, rsi, 3, 268435456), xmm6));
+ TEST_INSTRUCTION("62F57E081131" , vmovsh(word_ptr(rcx), xmm6));
+ TEST_INSTRUCTION("62F57E0811717F" , vmovsh(word_ptr(rcx, 254), xmm6));
+ TEST_INSTRUCTION("62F57E0F117280" , k(k7).vmovsh(word_ptr(rdx, -256), xmm6));
+ TEST_INSTRUCTION("62F57D086EF2" , vmovw(xmm6, edx));
+ TEST_INSTRUCTION("62F57D087EF2" , vmovw(edx, xmm6));
+ TEST_INSTRUCTION("62F57D086EB4F400000010" , vmovw(xmm6, word_ptr(rsp, rsi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D086E31" , vmovw(xmm6, word_ptr(rcx)));
+ TEST_INSTRUCTION("62F57D086E717F" , vmovw(xmm6, word_ptr(rcx, 254)));
+ TEST_INSTRUCTION("62F57D086E717F" , vmovw(xmm6, word_ptr(rcx, 254)));
+ TEST_INSTRUCTION("62F57D086E7280" , vmovw(xmm6, word_ptr(rdx, -256)));
+ TEST_INSTRUCTION("62F57D087EB4F400000010" , vmovw(word_ptr(rsp, esi, 3, 268435456), xmm6));
+ TEST_INSTRUCTION("62F57D087E31" , vmovw(word_ptr(rcx), xmm6));
+ TEST_INSTRUCTION("62F57D087E717F" , vmovw(word_ptr(rcx, 254), xmm6));
+ TEST_INSTRUCTION("62F57D087E7280" , vmovw(word_ptr(rdx, -256), xmm6));
+}
+
+// Tests generated from 'llvm/test/MC/X86/intel-syntax-avx512.s' file.
+static void ASMJIT_NOINLINE testX64AssemblerAVX512_LLVM(AssemblerTester<x86::Assembler>& tester) noexcept {
+ using namespace x86;
+
+ TEST_INSTRUCTION("62F174485808" , vaddps(zmm1, zmm1, zmmword_ptr(rax)));
+ TEST_INSTRUCTION("62F1F54858CA" , vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F54D58CA" , k(k5).vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F5CD58CA" , k(k5).z().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F5CD58CA" , k(k5).z().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F51858CA" , rn_sae().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F55858CA" , ru_sae().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F53858CA" , rd_sae().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62F1F57858CA" , rz_sae().vaddpd(zmm1, zmm1, zmm2));
+ TEST_INSTRUCTION("62919D48C2D2AB" , vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D4BC2D2AB" , k(k3).vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D18C2D2AB" , sae().vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D48C2D27B" , vcmppd(k2, zmm12, zmm26, 123));
+ TEST_INSTRUCTION("62919D18C2D27B" , sae().vcmppd(k2, zmm12, zmm26, 123));
+ TEST_INSTRUCTION("62F19D48C2117B" , vcmppd(k2, zmm12, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B19D48C294F0230100007B" , vcmppd(k2, zmm12, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F19D58C2117B" , vcmppd(k2, zmm12, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D48C2527F7B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F19D48C292002000007B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F19D48C252807B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F19D48C292C0DFFFFF7B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F19D58C2527F7B" , vcmppd(k2, zmm12, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C292000400007B" , vcmppd(k2, zmm12, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C252807B" , vcmppd(k2, zmm12, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C292F8FBFFFF7B" , vcmppd(k2, zmm12, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62B17440C2D6AB" , vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17443C2D6AB" , k(k3).vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17410C2D6AB" , sae().vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17440C2D67B" , vcmpps(k2, zmm17, zmm22, 123));
+ TEST_INSTRUCTION("62B17410C2D67B" , sae().vcmpps(k2, zmm17, zmm22, 123));
+ TEST_INSTRUCTION("62F17440C2117B" , vcmpps(k2, zmm17, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B17440C294F0230100007B" , vcmpps(k2, zmm17, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F17450C2117B" , vcmpps(k2, zmm17, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F17440C2527F7B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F17440C292002000007B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F17440C252807B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F17440C292C0DFFFFF7B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F17450C2527F7B" , vcmpps(k2, zmm17, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C292000200007B" , vcmpps(k2, zmm17, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C252807B" , vcmpps(k2, zmm17, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C292FCFDFFFF7B" , vcmpps(k2, zmm17, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62136D0055FCAB" , vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D0555FCAB" , k(k5).vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D8555FCAB" , k(k5).z().vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D1055FCAB" , sae().vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D0055FC7B" , vfixupimmss(xmm15, xmm18, xmm28, 123));
+ TEST_INSTRUCTION("62136D1055FC7B" , sae().vfixupimmss(xmm15, xmm18, xmm28, 123));
+ TEST_INSTRUCTION("62736D0055397B" , vfixupimmss(xmm15, xmm18, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62336D0055BCF0230100007B" , vfixupimmss(xmm15, xmm18, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62736D00557A7F7B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62736D0055BA000200007B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62736D00557A807B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62736D0055BAFCFDFFFF7B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("6273AD0055EDAB" , vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD0655EDAB" , k(k6).vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD8655EDAB" , k(k6).z().vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD1055EDAB" , sae().vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD0055ED7B" , vfixupimmsd(xmm13, xmm26, xmm5, 123));
+ TEST_INSTRUCTION("6273AD1055ED7B" , sae().vfixupimmsd(xmm13, xmm26, xmm5, 123));
+ TEST_INSTRUCTION("6273AD0055297B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233AD0055ACF0230100007B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6273AD00556A7F7B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("6273AD0055AA000400007B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("6273AD00556A807B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("6273AD0055AAF8FBFFFF7B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62E1FD082F39" , vcomisd(xmm23, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62E17C082F01" , vcomiss(xmm16, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62717E0A1129" , k(k2).vmovss(dword_ptr(rcx), xmm13));
+ TEST_INSTRUCTION("C4217A11ACF034120000" , vmovss(dword_ptr(rax, r14, 3, 4660), xmm13));
+ TEST_INSTRUCTION("C57A11AAFC010000" , vmovss(dword_ptr(rdx, 508), xmm13));
+ TEST_INSTRUCTION("C57A11AA00020000" , vmovss(dword_ptr(rdx, 512), xmm13));
+ TEST_INSTRUCTION("C57A11AA00FEFFFF" , vmovss(dword_ptr(rdx, -512), xmm13));
+ TEST_INSTRUCTION("C57A11AAFCFDFFFF" , vmovss(dword_ptr(rdx, -516), xmm13));
+ TEST_INSTRUCTION("C5FA11AAFC010000" , vmovss(dword_ptr(rdx, 508), xmm5));
+ TEST_INSTRUCTION("C5FA11AA00020000" , vmovss(dword_ptr(rdx, 512), xmm5));
+ TEST_INSTRUCTION("C5FA11AA00FEFFFF" , vmovss(dword_ptr(rdx, -512), xmm5));
+ TEST_INSTRUCTION("C5FA11AAFCFDFFFF" , vmovss(dword_ptr(rdx, -516), xmm5));
+ TEST_INSTRUCTION("C57A1129" , vmovss(dword_ptr(rcx), xmm13));
+ TEST_INSTRUCTION("C5FA1011" , vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E0C1011" , k(k4).vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E8C1011" , k(k4).z().vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6261FF081009" , vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6261FF0B1009" , k(k3).vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6261FF8B1009" , k(k3).z().vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FF08108CF023010000" , vmovsd(xmm25, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261FF08104A7F" , vmovsd(xmm25, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261FF08108A00040000" , vmovsd(xmm25, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261FF08104A80" , vmovsd(xmm25, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261FF08108AF8FBFFFF" , vmovsd(xmm25, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6271A54058C6" , vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A54758C6" , k(k7).vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A5C758C6" , k(k7).z().vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A51058C6" , rn_sae().vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A55058C6" , ru_sae().vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A53058C6" , rd_sae().vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A57058C6" , rz_sae().vaddpd(zmm8, zmm27, zmm6));
+ TEST_INSTRUCTION("6271A5405801" , vaddpd(zmm8, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231A5405884F023010000" , vaddpd(zmm8, zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271A5505801" , vaddpd(zmm8, zmm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271A54058427F" , vaddpd(zmm8, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271A540588200200000" , vaddpd(zmm8, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271A540584280" , vaddpd(zmm8, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271A5405882C0DFFFFF" , vaddpd(zmm8, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271A55058427F" , vaddpd(zmm8, zmm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271A550588200040000" , vaddpd(zmm8, zmm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271A550584280" , vaddpd(zmm8, zmm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271A5505882F8FBFFFF" , vaddpd(zmm8, zmm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E1144858D2" , vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E1144C58D2" , k(k4).vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E114CC58D2" , k(k4).z().vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E1141858D2" , rn_sae().vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E1145858D2" , ru_sae().vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E1143858D2" , rd_sae().vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E1147858D2" , rz_sae().vaddps(zmm18, zmm13, zmm2));
+ TEST_INSTRUCTION("62E114485811" , vaddps(zmm18, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A114485894F023010000" , vaddps(zmm18, zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E114585811" , vaddps(zmm18, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E1144858527F" , vaddps(zmm18, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E11448589200200000" , vaddps(zmm18, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E11448585280" , vaddps(zmm18, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E114485892C0DFFFFF" , vaddps(zmm18, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1145858527F" , vaddps(zmm18, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E11458589200020000" , vaddps(zmm18, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E11458585280" , vaddps(zmm18, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E114585892FCFDFFFF" , vaddps(zmm18, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D1F70058D8" , vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F70358D8" , k(k3).vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F78358D8" , k(k3).z().vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F71058D8" , rn_sae().vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F75058D8" , ru_sae().vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F73058D8" , rd_sae().vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62D1F77058D8" , rz_sae().vaddsd(xmm3, xmm17, xmm8));
+ TEST_INSTRUCTION("62F1F7005819" , vaddsd(xmm3, xmm17, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1F700589CF023010000" , vaddsd(xmm3, xmm17, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1F700585A7F" , vaddsd(xmm3, xmm17, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1F700589A00040000" , vaddsd(xmm3, xmm17, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1F700585A80" , vaddsd(xmm3, xmm17, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1F700589AF8FBFFFF" , vaddsd(xmm3, xmm17, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B1560858FB" , vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1560A58FB" , k(k2).vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1568A58FB" , k(k2).z().vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1561858FB" , rn_sae().vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1565858FB" , ru_sae().vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1563858FB" , rd_sae().vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("62B1567858FB" , rz_sae().vaddss(xmm7, xmm5, xmm19));
+ TEST_INSTRUCTION("C5D25839" , vaddss(xmm7, xmm5, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A15258BCF023010000" , vaddss(xmm7, xmm5, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5D258BAFC010000" , vaddss(xmm7, xmm5, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5D258BA00020000" , vaddss(xmm7, xmm5, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5D258BA00FEFFFF" , vaddss(xmm7, xmm5, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5D258BAFCFDFFFF" , vaddss(xmm7, xmm5, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62136D4003CAAB" , valignd(zmm9, zmm18, zmm26, 171));
+ TEST_INSTRUCTION("62136D4403CAAB" , k(k4).valignd(zmm9, zmm18, zmm26, 171));
+ TEST_INSTRUCTION("62136DC403CAAB" , k(k4).z().valignd(zmm9, zmm18, zmm26, 171));
+ TEST_INSTRUCTION("62136D4003CA7B" , valignd(zmm9, zmm18, zmm26, 123));
+ TEST_INSTRUCTION("62736D4003097B" , valignd(zmm9, zmm18, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62336D40038CF0230100007B" , valignd(zmm9, zmm18, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62736D5003097B" , valignd(zmm9, zmm18, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62736D40034A7F7B" , valignd(zmm9, zmm18, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62736D40038A002000007B" , valignd(zmm9, zmm18, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62736D40034A807B" , valignd(zmm9, zmm18, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62736D40038AC0DFFFFF7B" , valignd(zmm9, zmm18, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62736D50034A7F7B" , valignd(zmm9, zmm18, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62736D50038A000200007B" , valignd(zmm9, zmm18, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62736D50034A807B" , valignd(zmm9, zmm18, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62736D50038AFCFDFFFF7B" , valignd(zmm9, zmm18, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62529D4065C4" , vblendmpd(zmm8, zmm28, zmm12));
+ TEST_INSTRUCTION("62529D4165C4" , k(k1).vblendmpd(zmm8, zmm28, zmm12));
+ TEST_INSTRUCTION("62529DC165C4" , k(k1).z().vblendmpd(zmm8, zmm28, zmm12));
+ TEST_INSTRUCTION("62729D406501" , vblendmpd(zmm8, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62329D406584F023010000" , vblendmpd(zmm8, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62729D506501" , vblendmpd(zmm8, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62729D4065427F" , vblendmpd(zmm8, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62729D40658200200000" , vblendmpd(zmm8, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62729D40654280" , vblendmpd(zmm8, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62729D406582C0DFFFFF" , vblendmpd(zmm8, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62729D5065427F" , vblendmpd(zmm8, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62729D50658200040000" , vblendmpd(zmm8, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62729D50654280" , vblendmpd(zmm8, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62729D506582F8FBFFFF" , vblendmpd(zmm8, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62721D4065FC" , vblendmps(zmm15, zmm28, zmm4));
+ TEST_INSTRUCTION("62721D4365FC" , k(k3).vblendmps(zmm15, zmm28, zmm4));
+ TEST_INSTRUCTION("62721DC365FC" , k(k3).z().vblendmps(zmm15, zmm28, zmm4));
+ TEST_INSTRUCTION("62721D406539" , vblendmps(zmm15, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D4065BCF023010000" , vblendmps(zmm15, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62721D506539" , vblendmps(zmm15, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62721D40657A7F" , vblendmps(zmm15, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62721D4065BA00200000" , vblendmps(zmm15, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62721D40657A80" , vblendmps(zmm15, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62721D4065BAC0DFFFFF" , vblendmps(zmm15, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62721D50657A7F" , vblendmps(zmm15, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62721D5065BA00020000" , vblendmps(zmm15, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62721D50657A80" , vblendmps(zmm15, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62721D5065BAFCFDFFFF" , vblendmps(zmm15, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F27D481A19" , vbroadcastf32x4(zmm3, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D4F1A19" , k(k7).vbroadcastf32x4(zmm3, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DCF1A19" , k(k7).z().vbroadcastf32x4(zmm3, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D481A9CF023010000" , vbroadcastf32x4(zmm3, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D481A5A7F" , vbroadcastf32x4(zmm3, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62F27D481A9A00080000" , vbroadcastf32x4(zmm3, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62F27D481A5A80" , vbroadcastf32x4(zmm3, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62F27D481A9AF0F7FFFF" , vbroadcastf32x4(zmm3, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6262FD481B09" , vbroadcastf64x4(zmm25, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4E1B09" , k(k6).vbroadcastf64x4(zmm25, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCE1B09" , k(k6).z().vbroadcastf64x4(zmm25, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD481B8CF023010000" , vbroadcastf64x4(zmm25, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD481B4A7F" , vbroadcastf64x4(zmm25, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("6262FD481B8A00100000" , vbroadcastf64x4(zmm25, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("6262FD481B4A80" , vbroadcastf64x4(zmm25, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("6262FD481B8AE0EFFFFF" , vbroadcastf64x4(zmm25, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62627D485A31" , vbroadcasti32x4(zmm30, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62627D4B5A31" , k(k3).vbroadcasti32x4(zmm30, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62627DCB5A31" , k(k3).z().vbroadcasti32x4(zmm30, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D485AB4F023010000" , vbroadcasti32x4(zmm30, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62627D485A727F" , vbroadcasti32x4(zmm30, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62627D485AB200080000" , vbroadcasti32x4(zmm30, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62627D485A7280" , vbroadcasti32x4(zmm30, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62627D485AB2F0F7FFFF" , vbroadcasti32x4(zmm30, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6272FD485B29" , vbroadcasti64x4(zmm13, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6272FD4C5B29" , k(k4).vbroadcasti64x4(zmm13, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6272FDCC5B29" , k(k4).z().vbroadcasti64x4(zmm13, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232FD485BACF023010000" , vbroadcasti64x4(zmm13, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272FD485B6A7F" , vbroadcasti64x4(zmm13, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("6272FD485BAA00100000" , vbroadcasti64x4(zmm13, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("6272FD485B6A80" , vbroadcasti64x4(zmm13, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("6272FD485BAAE0EFFFFF" , vbroadcasti64x4(zmm13, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("6262FD481931" , vbroadcastsd(zmm30, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4C1931" , k(k4).vbroadcastsd(zmm30, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCC1931" , k(k4).z().vbroadcastsd(zmm30, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD4819B4F023010000" , vbroadcastsd(zmm30, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD4819727F" , vbroadcastsd(zmm30, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262FD4819B200040000" , vbroadcastsd(zmm30, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262FD48197280" , vbroadcastsd(zmm30, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262FD4819B2F8FBFFFF" , vbroadcastsd(zmm30, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A2FD4819EE" , vbroadcastsd(zmm21, xmm22));
+ TEST_INSTRUCTION("62A2FD4F19EE" , k(k7).vbroadcastsd(zmm21, xmm22));
+ TEST_INSTRUCTION("62A2FDCF19EE" , k(k7).z().vbroadcastsd(zmm21, xmm22));
+ TEST_INSTRUCTION("62F27D481819" , vbroadcastss(zmm3, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D4C1819" , k(k4).vbroadcastss(zmm3, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DCC1819" , k(k4).z().vbroadcastss(zmm3, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D48189CF023010000" , vbroadcastss(zmm3, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D48185A7F" , vbroadcastss(zmm3, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F27D48189A00020000" , vbroadcastss(zmm3, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F27D48185A80" , vbroadcastss(zmm3, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F27D48189AFCFDFFFF" , vbroadcastss(zmm3, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62A27D4818D2" , vbroadcastss(zmm18, xmm18));
+ TEST_INSTRUCTION("62A27D4A18D2" , k(k2).vbroadcastss(zmm18, xmm18));
+ TEST_INSTRUCTION("62A27DCA18D2" , k(k2).z().vbroadcastss(zmm18, xmm18));
+ TEST_INSTRUCTION("62919D48C2D2AB" , vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D4BC2D2AB" , k(k3).vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D18C2D2AB" , sae().vcmppd(k2, zmm12, zmm26, 171));
+ TEST_INSTRUCTION("62919D48C2D27B" , vcmppd(k2, zmm12, zmm26, 123));
+ TEST_INSTRUCTION("62919D18C2D27B" , sae().vcmppd(k2, zmm12, zmm26, 123));
+ TEST_INSTRUCTION("62F19D48C2117B" , vcmppd(k2, zmm12, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B19D48C294F0230100007B" , vcmppd(k2, zmm12, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F19D58C2117B" , vcmppd(k2, zmm12, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D48C2527F7B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F19D48C292002000007B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F19D48C252807B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F19D48C292C0DFFFFF7B" , vcmppd(k2, zmm12, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F19D58C2527F7B" , vcmppd(k2, zmm12, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C292000400007B" , vcmppd(k2, zmm12, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C252807B" , vcmppd(k2, zmm12, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F19D58C292F8FBFFFF7B" , vcmppd(k2, zmm12, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62B17440C2D6AB" , vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17443C2D6AB" , k(k3).vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17410C2D6AB" , sae().vcmpps(k2, zmm17, zmm22, 171));
+ TEST_INSTRUCTION("62B17440C2D67B" , vcmpps(k2, zmm17, zmm22, 123));
+ TEST_INSTRUCTION("62B17410C2D67B" , sae().vcmpps(k2, zmm17, zmm22, 123));
+ TEST_INSTRUCTION("62F17440C2117B" , vcmpps(k2, zmm17, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B17440C294F0230100007B" , vcmpps(k2, zmm17, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F17450C2117B" , vcmpps(k2, zmm17, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F17440C2527F7B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F17440C292002000007B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F17440C252807B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F17440C292C0DFFFFF7B" , vcmpps(k2, zmm17, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F17450C2527F7B" , vcmpps(k2, zmm17, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C292000200007B" , vcmpps(k2, zmm17, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C252807B" , vcmpps(k2, zmm17, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17450C292FCFDFFFF7B" , vcmpps(k2, zmm17, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62F1E700C2ECAB" , vcmpsd(k5, xmm19, xmm4, 171));
+ TEST_INSTRUCTION("62F1E701C2ECAB" , k(k1).vcmpsd(k5, xmm19, xmm4, 171));
+ TEST_INSTRUCTION("62F1E710C2ECAB" , sae().vcmpsd(k5, xmm19, xmm4, 171));
+ TEST_INSTRUCTION("62F1E700C2EC7B" , vcmpsd(k5, xmm19, xmm4, 123));
+ TEST_INSTRUCTION("62F1E710C2EC7B" , sae().vcmpsd(k5, xmm19, xmm4, 123));
+ TEST_INSTRUCTION("62F1E700C2297B" , vcmpsd(k5, xmm19, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1E700C2ACF0230100007B" , vcmpsd(k5, xmm19, qword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1E700C26A7F7B" , vcmpsd(k5, xmm19, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62F1E700C2AA000400007B" , vcmpsd(k5, xmm19, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62F1E700C26A807B" , vcmpsd(k5, xmm19, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62F1E700C2AAF8FBFFFF7B" , vcmpsd(k5, xmm19, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62D10608C2E4AB" , vcmpss(k4, xmm15, xmm12, 171));
+ TEST_INSTRUCTION("62D1060DC2E4AB" , k(k5).vcmpss(k4, xmm15, xmm12, 171));
+ TEST_INSTRUCTION("62D10618C2E4AB" , sae().vcmpss(k4, xmm15, xmm12, 171));
+ TEST_INSTRUCTION("62D10608C2E47B" , vcmpss(k4, xmm15, xmm12, 123));
+ TEST_INSTRUCTION("62D10618C2E47B" , sae().vcmpss(k4, xmm15, xmm12, 123));
+ TEST_INSTRUCTION("62F10608C2217B" , vcmpss(k4, xmm15, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B10608C2A4F0230100007B" , vcmpss(k4, xmm15, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F10608C2627F7B" , vcmpss(k4, xmm15, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62F10608C2A2000200007B" , vcmpss(k4, xmm15, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62F10608C262807B" , vcmpss(k4, xmm15, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62F10608C2A2FCFDFFFF7B" , vcmpss(k4, xmm15, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62A1FD082FFD" , vcomisd(xmm23, xmm21));
+ TEST_INSTRUCTION("62A1FD182FFD" , sae().vcomisd(xmm23, xmm21));
+ TEST_INSTRUCTION("62E1FD082F39" , vcomisd(xmm23, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD082FBCF023010000" , vcomisd(xmm23, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1FD082F7A7F" , vcomisd(xmm23, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1FD082FBA00040000" , vcomisd(xmm23, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1FD082F7A80" , vcomisd(xmm23, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1FD082FBAF8FBFFFF" , vcomisd(xmm23, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62117C082FF4" , vcomiss(xmm14, xmm28));
+ TEST_INSTRUCTION("62117C182FF4" , sae().vcomiss(xmm14, xmm28));
+ TEST_INSTRUCTION("C5782F31" , vcomiss(xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C421782FB4F023010000" , vcomiss(xmm14, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5782FB2FC010000" , vcomiss(xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5782FB200020000" , vcomiss(xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5782FB200FEFFFF" , vcomiss(xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5782FB2FCFDFFFF" , vcomiss(xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6272FD488A09" , vcompresspd(zmmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("6272FD4C8A09" , k(k4).vcompresspd(zmmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("6232FD488A8CF023010000" , vcompresspd(zmmword_ptr(rax, r14, 3, 291), zmm9));
+ TEST_INSTRUCTION("6272FD488A4A7F" , vcompresspd(zmmword_ptr(rdx, 1016), zmm9));
+ TEST_INSTRUCTION("6272FD488A8A00040000" , vcompresspd(zmmword_ptr(rdx, 1024), zmm9));
+ TEST_INSTRUCTION("6272FD488A4A80" , vcompresspd(zmmword_ptr(rdx, -1024), zmm9));
+ TEST_INSTRUCTION("6272FD488A8AF8FBFFFF" , vcompresspd(zmmword_ptr(rdx, -1032), zmm9));
+ TEST_INSTRUCTION("62D2FD488AE0" , vcompresspd(zmm8, zmm4));
+ TEST_INSTRUCTION("62D2FD4E8AE0" , k(k6).vcompresspd(zmm8, zmm4));
+ TEST_INSTRUCTION("62D2FDCE8AE0" , k(k6).z().vcompresspd(zmm8, zmm4));
+ TEST_INSTRUCTION("62727D488A11" , vcompressps(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62727D4F8A11" , k(k7).vcompressps(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62327D488A94F023010000" , vcompressps(zmmword_ptr(rax, r14, 3, 291), zmm10));
+ TEST_INSTRUCTION("62727D488A527F" , vcompressps(zmmword_ptr(rdx, 508), zmm10));
+ TEST_INSTRUCTION("62727D488A9200020000" , vcompressps(zmmword_ptr(rdx, 512), zmm10));
+ TEST_INSTRUCTION("62727D488A5280" , vcompressps(zmmword_ptr(rdx, -512), zmm10));
+ TEST_INSTRUCTION("62727D488A92FCFDFFFF" , vcompressps(zmmword_ptr(rdx, -516), zmm10));
+ TEST_INSTRUCTION("62727D488AF4" , vcompressps(zmm4, zmm14));
+ TEST_INSTRUCTION("62727D4A8AF4" , k(k2).vcompressps(zmm4, zmm14));
+ TEST_INSTRUCTION("62727DCA8AF4" , k(k2).z().vcompressps(zmm4, zmm14));
+ TEST_INSTRUCTION("62817E48E6F0" , vcvtdq2pd(zmm22, ymm24));
+ TEST_INSTRUCTION("62817E4CE6F0" , k(k4).vcvtdq2pd(zmm22, ymm24));
+ TEST_INSTRUCTION("62817ECCE6F0" , k(k4).z().vcvtdq2pd(zmm22, ymm24));
+ TEST_INSTRUCTION("62E17E48E631" , vcvtdq2pd(zmm22, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E48E6B4F023010000" , vcvtdq2pd(zmm22, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17E58E631" , vcvtdq2pd(zmm22, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E17E48E6727F" , vcvtdq2pd(zmm22, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E17E48E6B200100000" , vcvtdq2pd(zmm22, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E17E48E67280" , vcvtdq2pd(zmm22, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E17E48E6B2E0EFFFFF" , vcvtdq2pd(zmm22, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62E17E58E6727F" , vcvtdq2pd(zmm22, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62E17E58E6B200020000" , vcvtdq2pd(zmm22, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62E17E58E67280" , vcvtdq2pd(zmm22, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62E17E58E6B2FCFDFFFF" , vcvtdq2pd(zmm22, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62917C485BF9" , vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917C4D5BF9" , k(k5).vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917CCD5BF9" , k(k5).z().vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917C185BF9" , rn_sae().vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917C585BF9" , ru_sae().vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917C385BF9" , rd_sae().vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62917C785BF9" , rz_sae().vcvtdq2ps(zmm7, zmm25));
+ TEST_INSTRUCTION("62F17C485B39" , vcvtdq2ps(zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17C485BBCF023010000" , vcvtdq2ps(zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17C585B39" , vcvtdq2ps(zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F17C485B7A7F" , vcvtdq2ps(zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17C485BBA00200000" , vcvtdq2ps(zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17C485B7A80" , vcvtdq2ps(zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17C485BBAC0DFFFFF" , vcvtdq2ps(zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F17C585B7A7F" , vcvtdq2ps(zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F17C585BBA00020000" , vcvtdq2ps(zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F17C585B7A80" , vcvtdq2ps(zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F17C585BBAFCFDFFFF" , vcvtdq2ps(zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6241FF48E6C7" , vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FF4BE6C7" , k(k3).vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FFCBE6C7" , k(k3).z().vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FF18E6C7" , rn_sae().vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FF58E6C7" , ru_sae().vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FF38E6C7" , rd_sae().vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6241FF78E6C7" , rz_sae().vcvtpd2dq(ymm24, zmm15));
+ TEST_INSTRUCTION("6261FF48E601" , vcvtpd2dq(ymm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FF48E684F023010000" , vcvtpd2dq(ymm24, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261FF58E601" , vcvtpd2dq(ymm24, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261FF48E6427F" , vcvtpd2dq(ymm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261FF48E68200200000" , vcvtpd2dq(ymm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261FF48E64280" , vcvtpd2dq(ymm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261FF48E682C0DFFFFF" , vcvtpd2dq(ymm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261FF58E6427F" , vcvtpd2dq(ymm24, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261FF58E68200040000" , vcvtpd2dq(ymm24, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261FF58E64280" , vcvtpd2dq(ymm24, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261FF58E682F8FBFFFF" , vcvtpd2dq(ymm24, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B1FD485AEF" , vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FD4D5AEF" , k(k5).vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FDCD5AEF" , k(k5).z().vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FD185AEF" , rn_sae().vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FD585AEF" , ru_sae().vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FD385AEF" , rd_sae().vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62B1FD785AEF" , rz_sae().vcvtpd2ps(ymm5, zmm23));
+ TEST_INSTRUCTION("62F1FD485A29" , vcvtpd2ps(ymm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FD485AACF023010000" , vcvtpd2ps(ymm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FD585A29" , vcvtpd2ps(ymm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1FD485A6A7F" , vcvtpd2ps(ymm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FD485AAA00200000" , vcvtpd2ps(ymm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FD485A6A80" , vcvtpd2ps(ymm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FD485AAAC0DFFFFF" , vcvtpd2ps(ymm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1FD585A6A7F" , vcvtpd2ps(ymm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1FD585AAA00040000" , vcvtpd2ps(ymm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1FD585A6A80" , vcvtpd2ps(ymm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1FD585AAAF8FBFFFF" , vcvtpd2ps(ymm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6231FC4879FB" , vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FC4F79FB" , k(k7).vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FCCF79FB" , k(k7).z().vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FC1879FB" , rn_sae().vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FC5879FB" , ru_sae().vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FC3879FB" , rd_sae().vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6231FC7879FB" , rz_sae().vcvtpd2udq(ymm15, zmm19));
+ TEST_INSTRUCTION("6271FC487939" , vcvtpd2udq(ymm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FC4879BCF023010000" , vcvtpd2udq(ymm15, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271FC587939" , vcvtpd2udq(ymm15, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271FC48797A7F" , vcvtpd2udq(ymm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271FC4879BA00200000" , vcvtpd2udq(ymm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271FC48797A80" , vcvtpd2udq(ymm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271FC4879BAC0DFFFFF" , vcvtpd2udq(ymm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271FC58797A7F" , vcvtpd2udq(ymm15, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271FC5879BA00040000" , vcvtpd2udq(ymm15, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271FC58797A80" , vcvtpd2udq(ymm15, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271FC5879BAF8FBFFFF" , vcvtpd2udq(ymm15, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62127D4813EB" , vcvtph2ps(zmm13, ymm27));
+ TEST_INSTRUCTION("62127D4B13EB" , k(k3).vcvtph2ps(zmm13, ymm27));
+ TEST_INSTRUCTION("62127DCB13EB" , k(k3).z().vcvtph2ps(zmm13, ymm27));
+ TEST_INSTRUCTION("62127D1813EB" , sae().vcvtph2ps(zmm13, ymm27));
+ TEST_INSTRUCTION("62727D481329" , vcvtph2ps(zmm13, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D4813ACF023010000" , vcvtph2ps(zmm13, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62727D48136A7F" , vcvtph2ps(zmm13, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D4813AA00100000" , vcvtph2ps(zmm13, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48136A80" , vcvtph2ps(zmm13, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D4813AAE0EFFFFF" , vcvtph2ps(zmm13, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62117D485BE0" , vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117D4C5BE0" , k(k4).vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117DCC5BE0" , k(k4).z().vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117D185BE0" , rn_sae().vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117D585BE0" , ru_sae().vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117D385BE0" , rd_sae().vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62117D785BE0" , rz_sae().vcvtps2dq(zmm12, zmm24));
+ TEST_INSTRUCTION("62717D485B21" , vcvtps2dq(zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317D485BA4F023010000" , vcvtps2dq(zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717D585B21" , vcvtps2dq(zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62717D485B627F" , vcvtps2dq(zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717D485BA200200000" , vcvtps2dq(zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717D485B6280" , vcvtps2dq(zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717D485BA2C0DFFFFF" , vcvtps2dq(zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62717D585B627F" , vcvtps2dq(zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62717D585BA200020000" , vcvtps2dq(zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62717D585B6280" , vcvtps2dq(zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62717D585BA2FCFDFFFF" , vcvtps2dq(zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62717C485AEE" , vcvtps2pd(zmm13, ymm6));
+ TEST_INSTRUCTION("62717C4B5AEE" , k(k3).vcvtps2pd(zmm13, ymm6));
+ TEST_INSTRUCTION("62717CCB5AEE" , k(k3).z().vcvtps2pd(zmm13, ymm6));
+ TEST_INSTRUCTION("62717C185AEE" , sae().vcvtps2pd(zmm13, ymm6));
+ TEST_INSTRUCTION("62717C485A29" , vcvtps2pd(zmm13, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317C485AACF023010000" , vcvtps2pd(zmm13, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717C585A29" , vcvtps2pd(zmm13, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62717C485A6A7F" , vcvtps2pd(zmm13, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62717C485AAA00100000" , vcvtps2pd(zmm13, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62717C485A6A80" , vcvtps2pd(zmm13, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62717C485AAAE0EFFFFF" , vcvtps2pd(zmm13, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62717C585A6A7F" , vcvtps2pd(zmm13, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62717C585AAA00020000" , vcvtps2pd(zmm13, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62717C585A6A80" , vcvtps2pd(zmm13, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62717C585AAAFCFDFFFF" , vcvtps2pd(zmm13, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62537D481DF3AB" , vcvtps2ph(ymm11, zmm14, 171));
+ TEST_INSTRUCTION("62537D4E1DF3AB" , k(k6).vcvtps2ph(ymm11, zmm14, 171));
+ TEST_INSTRUCTION("62537DCE1DF3AB" , k(k6).z().vcvtps2ph(ymm11, zmm14, 171));
+ TEST_INSTRUCTION("62537D181DF3AB" , sae().vcvtps2ph(ymm11, zmm14, 171));
+ TEST_INSTRUCTION("62537D481DF37B" , vcvtps2ph(ymm11, zmm14, 123));
+ TEST_INSTRUCTION("62537D181DF37B" , sae().vcvtps2ph(ymm11, zmm14, 123));
+ TEST_INSTRUCTION("62117C4879E2" , vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117C4C79E2" , k(k4).vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117CCC79E2" , k(k4).z().vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117C1879E2" , rn_sae().vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117C5879E2" , ru_sae().vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117C3879E2" , rd_sae().vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62117C7879E2" , rz_sae().vcvtps2udq(zmm12, zmm26));
+ TEST_INSTRUCTION("62717C487921" , vcvtps2udq(zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317C4879A4F023010000" , vcvtps2udq(zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717C587921" , vcvtps2udq(zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62717C4879627F" , vcvtps2udq(zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717C4879A200200000" , vcvtps2udq(zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717C48796280" , vcvtps2udq(zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717C4879A2C0DFFFFF" , vcvtps2udq(zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62717C5879627F" , vcvtps2udq(zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62717C5879A200020000" , vcvtps2udq(zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62717C58796280" , vcvtps2udq(zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62717C5879A2FCFDFFFF" , vcvtps2udq(zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F17F182DC7" , rn_sae().vcvtsd2si(eax, xmm7));
+ TEST_INSTRUCTION("62F17F582DC7" , ru_sae().vcvtsd2si(eax, xmm7));
+ TEST_INSTRUCTION("62F17F382DC7" , rd_sae().vcvtsd2si(eax, xmm7));
+ TEST_INSTRUCTION("62F17F782DC7" , rz_sae().vcvtsd2si(eax, xmm7));
+ TEST_INSTRUCTION("62F17F182DEF" , rn_sae().vcvtsd2si(ebp, xmm7));
+ TEST_INSTRUCTION("62F17F582DEF" , ru_sae().vcvtsd2si(ebp, xmm7));
+ TEST_INSTRUCTION("62F17F382DEF" , rd_sae().vcvtsd2si(ebp, xmm7));
+ TEST_INSTRUCTION("62F17F782DEF" , rz_sae().vcvtsd2si(ebp, xmm7));
+ TEST_INSTRUCTION("62717F182DEF" , rn_sae().vcvtsd2si(r13d, xmm7));
+ TEST_INSTRUCTION("62717F582DEF" , ru_sae().vcvtsd2si(r13d, xmm7));
+ TEST_INSTRUCTION("62717F382DEF" , rd_sae().vcvtsd2si(r13d, xmm7));
+ TEST_INSTRUCTION("62717F782DEF" , rz_sae().vcvtsd2si(r13d, xmm7));
+ TEST_INSTRUCTION("62D1FF182DC2" , rn_sae().vcvtsd2si(rax, xmm10));
+ TEST_INSTRUCTION("62D1FF582DC2" , ru_sae().vcvtsd2si(rax, xmm10));
+ TEST_INSTRUCTION("62D1FF382DC2" , rd_sae().vcvtsd2si(rax, xmm10));
+ TEST_INSTRUCTION("62D1FF782DC2" , rz_sae().vcvtsd2si(rax, xmm10));
+ TEST_INSTRUCTION("6251FF182DC2" , rn_sae().vcvtsd2si(r8, xmm10));
+ TEST_INSTRUCTION("6251FF582DC2" , ru_sae().vcvtsd2si(r8, xmm10));
+ TEST_INSTRUCTION("6251FF382DC2" , rd_sae().vcvtsd2si(r8, xmm10));
+ TEST_INSTRUCTION("6251FF782DC2" , rz_sae().vcvtsd2si(r8, xmm10));
+ TEST_INSTRUCTION("62C1B7085ACC" , vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B70E5ACC" , k(k6).vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B78E5ACC" , k(k6).z().vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B7185ACC" , rn_sae().vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B7585ACC" , ru_sae().vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B7385ACC" , rd_sae().vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62C1B7785ACC" , rz_sae().vcvtsd2ss(xmm17, xmm9, xmm12));
+ TEST_INSTRUCTION("62E1B7085A09" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1B7085A8CF023010000" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1B7085A4A7F" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1B7085A8A00040000" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1B7085A4A80" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1B7085A8AF8FBFFFF" , vcvtsd2ss(xmm17, xmm9, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5AB2AF8" , vcvtsi2sd(xmm7, xmm10, eax));
+ TEST_INSTRUCTION("C5AB2AFD" , vcvtsi2sd(xmm7, xmm10, ebp));
+ TEST_INSTRUCTION("C4C12B2AFD" , vcvtsi2sd(xmm7, xmm10, r13d));
+ TEST_INSTRUCTION("C5AB2A39" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A12B2ABCF023010000" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5AB2ABAFC010000" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5AB2ABA00020000" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5AB2ABA00FEFFFF" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5AB2ABAFCFDFFFF" , vcvtsi2sd(xmm7, xmm10, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62619F082AE8" , vcvtsi2sd(xmm29, xmm12, rax));
+ TEST_INSTRUCTION("62619F182AE8" , rn_sae().vcvtsi2sd(xmm29, xmm12, rax));
+ TEST_INSTRUCTION("62619F582AE8" , ru_sae().vcvtsi2sd(xmm29, xmm12, rax));
+ TEST_INSTRUCTION("62619F382AE8" , rd_sae().vcvtsi2sd(xmm29, xmm12, rax));
+ TEST_INSTRUCTION("62619F782AE8" , rz_sae().vcvtsi2sd(xmm29, xmm12, rax));
+ TEST_INSTRUCTION("62419F082AE8" , vcvtsi2sd(xmm29, xmm12, r8));
+ TEST_INSTRUCTION("62419F182AE8" , rn_sae().vcvtsi2sd(xmm29, xmm12, r8));
+ TEST_INSTRUCTION("62419F582AE8" , ru_sae().vcvtsi2sd(xmm29, xmm12, r8));
+ TEST_INSTRUCTION("62419F382AE8" , rd_sae().vcvtsi2sd(xmm29, xmm12, r8));
+ TEST_INSTRUCTION("62419F782AE8" , rz_sae().vcvtsi2sd(xmm29, xmm12, r8));
+ TEST_INSTRUCTION("62619F082A29" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62219F082AACF023010000" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62619F082A6A7F" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62619F082AAA00040000" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62619F082A6A80" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62619F082AAAF8FBFFFF" , vcvtsi2sd(xmm29, xmm12, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C52A2AF8" , vcvtsi2ss(xmm15, xmm10, eax));
+ TEST_INSTRUCTION("62712E182AF8" , rn_sae().vcvtsi2ss(xmm15, xmm10, eax));
+ TEST_INSTRUCTION("62712E582AF8" , ru_sae().vcvtsi2ss(xmm15, xmm10, eax));
+ TEST_INSTRUCTION("62712E382AF8" , rd_sae().vcvtsi2ss(xmm15, xmm10, eax));
+ TEST_INSTRUCTION("62712E782AF8" , rz_sae().vcvtsi2ss(xmm15, xmm10, eax));
+ TEST_INSTRUCTION("C52A2AFD" , vcvtsi2ss(xmm15, xmm10, ebp));
+ TEST_INSTRUCTION("62712E182AFD" , rn_sae().vcvtsi2ss(xmm15, xmm10, ebp));
+ TEST_INSTRUCTION("62712E582AFD" , ru_sae().vcvtsi2ss(xmm15, xmm10, ebp));
+ TEST_INSTRUCTION("62712E382AFD" , rd_sae().vcvtsi2ss(xmm15, xmm10, ebp));
+ TEST_INSTRUCTION("62712E782AFD" , rz_sae().vcvtsi2ss(xmm15, xmm10, ebp));
+ TEST_INSTRUCTION("C4412A2AFD" , vcvtsi2ss(xmm15, xmm10, r13d));
+ TEST_INSTRUCTION("62512E182AFD" , rn_sae().vcvtsi2ss(xmm15, xmm10, r13d));
+ TEST_INSTRUCTION("62512E582AFD" , ru_sae().vcvtsi2ss(xmm15, xmm10, r13d));
+ TEST_INSTRUCTION("62512E382AFD" , rd_sae().vcvtsi2ss(xmm15, xmm10, r13d));
+ TEST_INSTRUCTION("62512E782AFD" , rz_sae().vcvtsi2ss(xmm15, xmm10, r13d));
+ TEST_INSTRUCTION("C52A2A39" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4212A2ABCF023010000" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C52A2ABAFC010000" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C52A2ABA00020000" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C52A2ABA00FEFFFF" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C52A2ABAFCFDFFFF" , vcvtsi2ss(xmm15, xmm10, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62E1AE082AC0" , vcvtsi2ss(xmm16, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE182AC0" , rn_sae().vcvtsi2ss(xmm16, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE582AC0" , ru_sae().vcvtsi2ss(xmm16, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE382AC0" , rd_sae().vcvtsi2ss(xmm16, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE782AC0" , rz_sae().vcvtsi2ss(xmm16, xmm10, rax));
+ TEST_INSTRUCTION("62C1AE082AC0" , vcvtsi2ss(xmm16, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE182AC0" , rn_sae().vcvtsi2ss(xmm16, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE582AC0" , ru_sae().vcvtsi2ss(xmm16, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE382AC0" , rd_sae().vcvtsi2ss(xmm16, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE782AC0" , rz_sae().vcvtsi2ss(xmm16, xmm10, r8));
+ TEST_INSTRUCTION("62E1AE082A01" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1AE082A84F023010000" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1AE082A427F" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1AE082A8200040000" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1AE082A4280" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1AE082A82F8FBFFFF" , vcvtsi2ss(xmm16, xmm10, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62614E085AE6" , vcvtss2sd(xmm28, xmm6, xmm6));
+ TEST_INSTRUCTION("62614E0B5AE6" , k(k3).vcvtss2sd(xmm28, xmm6, xmm6));
+ TEST_INSTRUCTION("62614E8B5AE6" , k(k3).z().vcvtss2sd(xmm28, xmm6, xmm6));
+ TEST_INSTRUCTION("62614E185AE6" , sae().vcvtss2sd(xmm28, xmm6, xmm6));
+ TEST_INSTRUCTION("62614E085A21" , vcvtss2sd(xmm28, xmm6, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62214E085AA4F023010000" , vcvtss2sd(xmm28, xmm6, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62614E085A627F" , vcvtss2sd(xmm28, xmm6, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62614E085AA200020000" , vcvtss2sd(xmm28, xmm6, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62614E085A6280" , vcvtss2sd(xmm28, xmm6, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62614E085AA2FCFDFFFF" , vcvtss2sd(xmm28, xmm6, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B17E182DC6" , rn_sae().vcvtss2si(eax, xmm22));
+ TEST_INSTRUCTION("62B17E582DC6" , ru_sae().vcvtss2si(eax, xmm22));
+ TEST_INSTRUCTION("62B17E382DC6" , rd_sae().vcvtss2si(eax, xmm22));
+ TEST_INSTRUCTION("62B17E782DC6" , rz_sae().vcvtss2si(eax, xmm22));
+ TEST_INSTRUCTION("62B17E182DEE" , rn_sae().vcvtss2si(ebp, xmm22));
+ TEST_INSTRUCTION("62B17E582DEE" , ru_sae().vcvtss2si(ebp, xmm22));
+ TEST_INSTRUCTION("62B17E382DEE" , rd_sae().vcvtss2si(ebp, xmm22));
+ TEST_INSTRUCTION("62B17E782DEE" , rz_sae().vcvtss2si(ebp, xmm22));
+ TEST_INSTRUCTION("62317E182DEE" , rn_sae().vcvtss2si(r13d, xmm22));
+ TEST_INSTRUCTION("62317E582DEE" , ru_sae().vcvtss2si(r13d, xmm22));
+ TEST_INSTRUCTION("62317E382DEE" , rd_sae().vcvtss2si(r13d, xmm22));
+ TEST_INSTRUCTION("62317E782DEE" , rz_sae().vcvtss2si(r13d, xmm22));
+ TEST_INSTRUCTION("6291FE182DC5" , rn_sae().vcvtss2si(rax, xmm29));
+ TEST_INSTRUCTION("6291FE582DC5" , ru_sae().vcvtss2si(rax, xmm29));
+ TEST_INSTRUCTION("6291FE382DC5" , rd_sae().vcvtss2si(rax, xmm29));
+ TEST_INSTRUCTION("6291FE782DC5" , rz_sae().vcvtss2si(rax, xmm29));
+ TEST_INSTRUCTION("6211FE182DC5" , rn_sae().vcvtss2si(r8, xmm29));
+ TEST_INSTRUCTION("6211FE582DC5" , ru_sae().vcvtss2si(r8, xmm29));
+ TEST_INSTRUCTION("6211FE382DC5" , rd_sae().vcvtss2si(r8, xmm29));
+ TEST_INSTRUCTION("6211FE782DC5" , rz_sae().vcvtss2si(r8, xmm29));
+ TEST_INSTRUCTION("6241FD48E6D9" , vcvttpd2dq(ymm27, zmm9));
+ TEST_INSTRUCTION("6241FD4DE6D9" , k(k5).vcvttpd2dq(ymm27, zmm9));
+ TEST_INSTRUCTION("6241FDCDE6D9" , k(k5).z().vcvttpd2dq(ymm27, zmm9));
+ TEST_INSTRUCTION("6241FD18E6D9" , sae().vcvttpd2dq(ymm27, zmm9));
+ TEST_INSTRUCTION("6261FD48E619" , vcvttpd2dq(ymm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FD48E69CF023010000" , vcvttpd2dq(ymm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261FD58E619" , vcvttpd2dq(ymm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261FD48E65A7F" , vcvttpd2dq(ymm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261FD48E69A00200000" , vcvttpd2dq(ymm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261FD48E65A80" , vcvttpd2dq(ymm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261FD48E69AC0DFFFFF" , vcvttpd2dq(ymm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261FD58E65A7F" , vcvttpd2dq(ymm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261FD58E69A00040000" , vcvttpd2dq(ymm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261FD58E65A80" , vcvttpd2dq(ymm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261FD58E69AF8FBFFFF" , vcvttpd2dq(ymm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62117E485BF1" , vcvttps2dq(zmm14, zmm25));
+ TEST_INSTRUCTION("62117E4B5BF1" , k(k3).vcvttps2dq(zmm14, zmm25));
+ TEST_INSTRUCTION("62117ECB5BF1" , k(k3).z().vcvttps2dq(zmm14, zmm25));
+ TEST_INSTRUCTION("62117E185BF1" , sae().vcvttps2dq(zmm14, zmm25));
+ TEST_INSTRUCTION("62717E485B31" , vcvttps2dq(zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E485BB4F023010000" , vcvttps2dq(zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717E585B31" , vcvttps2dq(zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62717E485B727F" , vcvttps2dq(zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717E485BB200200000" , vcvttps2dq(zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717E485B7280" , vcvttps2dq(zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717E485BB2C0DFFFFF" , vcvttps2dq(zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62717E585B727F" , vcvttps2dq(zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62717E585BB200020000" , vcvttps2dq(zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62717E585B7280" , vcvttps2dq(zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62717E585BB2FCFDFFFF" , vcvttps2dq(zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F17F182CC3" , sae().vcvttsd2si(eax, xmm3));
+ TEST_INSTRUCTION("62F17F182CEB" , sae().vcvttsd2si(ebp, xmm3));
+ TEST_INSTRUCTION("62717F182CEB" , sae().vcvttsd2si(r13d, xmm3));
+ TEST_INSTRUCTION("62F1FF182CC1" , sae().vcvttsd2si(rax, xmm1));
+ TEST_INSTRUCTION("6271FF182CC1" , sae().vcvttsd2si(r8, xmm1));
+ TEST_INSTRUCTION("62D17E182CC6" , sae().vcvttss2si(eax, xmm14));
+ TEST_INSTRUCTION("62D17E182CEE" , sae().vcvttss2si(ebp, xmm14));
+ TEST_INSTRUCTION("62517E182CEE" , sae().vcvttss2si(r13d, xmm14));
+ TEST_INSTRUCTION("62B1FE182CC5" , sae().vcvttss2si(rax, xmm21));
+ TEST_INSTRUCTION("6231FE182CC5" , sae().vcvttss2si(r8, xmm21));
+ TEST_INSTRUCTION("62C17E487AD6" , vcvtudq2pd(zmm18, ymm14));
+ TEST_INSTRUCTION("62C17E4B7AD6" , k(k3).vcvtudq2pd(zmm18, ymm14));
+ TEST_INSTRUCTION("62C17ECB7AD6" , k(k3).z().vcvtudq2pd(zmm18, ymm14));
+ TEST_INSTRUCTION("62E17E487A11" , vcvtudq2pd(zmm18, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E487A94F023010000" , vcvtudq2pd(zmm18, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17E587A11" , vcvtudq2pd(zmm18, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E17E487A527F" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E17E487A9200100000" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E17E487A5280" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E17E487A92E0EFFFFF" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62E17E587A527F" , vcvtudq2pd(zmm18, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62E17E587A9200020000" , vcvtudq2pd(zmm18, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62E17E587A5280" , vcvtudq2pd(zmm18, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62E17E587A92FCFDFFFF" , vcvtudq2pd(zmm18, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62E17F487AD7" , vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F4A7AD7" , k(k2).vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17FCA7AD7" , k(k2).z().vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F187AD7" , rn_sae().vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F587AD7" , ru_sae().vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F387AD7" , rd_sae().vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F787AD7" , rz_sae().vcvtudq2ps(zmm18, zmm7));
+ TEST_INSTRUCTION("62E17F487A11" , vcvtudq2ps(zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17F487A94F023010000" , vcvtudq2ps(zmm18, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17F587A11" , vcvtudq2ps(zmm18, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E17F487A527F" , vcvtudq2ps(zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17F487A9200200000" , vcvtudq2ps(zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17F487A5280" , vcvtudq2ps(zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17F487A92C0DFFFFF" , vcvtudq2ps(zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17F587A527F" , vcvtudq2ps(zmm18, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E17F587A9200020000" , vcvtudq2ps(zmm18, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E17F587A5280" , vcvtudq2ps(zmm18, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E17F587A92FCFDFFFF" , vcvtudq2ps(zmm18, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C1CD485ED3" , vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CD4C5ED3" , k(k4).vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CDCC5ED3" , k(k4).z().vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CD185ED3" , rn_sae().vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CD585ED3" , ru_sae().vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CD385ED3" , rd_sae().vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62C1CD785ED3" , rz_sae().vdivpd(zmm18, zmm6, zmm11));
+ TEST_INSTRUCTION("62E1CD485E11" , vdivpd(zmm18, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1CD485E94F023010000" , vdivpd(zmm18, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1CD585E11" , vdivpd(zmm18, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1CD485E527F" , vdivpd(zmm18, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1CD485E9200200000" , vdivpd(zmm18, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1CD485E5280" , vdivpd(zmm18, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1CD485E92C0DFFFFF" , vdivpd(zmm18, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1CD585E527F" , vdivpd(zmm18, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1CD585E9200040000" , vdivpd(zmm18, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1CD585E5280" , vdivpd(zmm18, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1CD585E92F8FBFFFF" , vdivpd(zmm18, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("628144405EFC" , vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144425EFC" , k(k2).vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144C25EFC" , k(k2).z().vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144105EFC" , rn_sae().vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144505EFC" , ru_sae().vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144305EFC" , rd_sae().vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("628144705EFC" , rz_sae().vdivps(zmm23, zmm23, zmm28));
+ TEST_INSTRUCTION("62E144405E39" , vdivps(zmm23, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A144405EBCF023010000" , vdivps(zmm23, zmm23, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E144505E39" , vdivps(zmm23, zmm23, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E144405E7A7F" , vdivps(zmm23, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E144405EBA00200000" , vdivps(zmm23, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E144405E7A80" , vdivps(zmm23, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E144405EBAC0DFFFFF" , vdivps(zmm23, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E144505E7A7F" , vdivps(zmm23, zmm23, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E144505EBA00020000" , vdivps(zmm23, zmm23, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E144505E7A80" , vdivps(zmm23, zmm23, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E144505EBAFCFDFFFF" , vdivps(zmm23, zmm23, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("622197085EEE" , vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("6221970B5EEE" , k(k3).vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("6221978B5EEE" , k(k3).z().vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("622197185EEE" , rn_sae().vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("622197585EEE" , ru_sae().vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("622197385EEE" , rd_sae().vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("622197785EEE" , rz_sae().vdivsd(xmm29, xmm13, xmm22));
+ TEST_INSTRUCTION("626197085E29" , vdivsd(xmm29, xmm13, qword_ptr(rcx)));
+ TEST_INSTRUCTION("622197085EACF023010000" , vdivsd(xmm29, xmm13, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626197085E6A7F" , vdivsd(xmm29, xmm13, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("626197085EAA00040000" , vdivsd(xmm29, xmm13, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("626197085E6A80" , vdivsd(xmm29, xmm13, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("626197085EAAF8FBFFFF" , vdivsd(xmm29, xmm13, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A14E085EE9" , vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E0D5EE9" , k(k5).vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E8D5EE9" , k(k5).z().vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E185EE9" , rn_sae().vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E585EE9" , ru_sae().vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E385EE9" , rd_sae().vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62A14E785EE9" , rz_sae().vdivss(xmm21, xmm6, xmm17));
+ TEST_INSTRUCTION("62E14E085E29" , vdivss(xmm21, xmm6, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A14E085EACF023010000" , vdivss(xmm21, xmm6, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E14E085E6A7F" , vdivss(xmm21, xmm6, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E14E085EAA00020000" , vdivss(xmm21, xmm6, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E14E085E6A80" , vdivss(xmm21, xmm6, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E14E085EAAFCFDFFFF" , vdivss(xmm21, xmm6, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6262FD488801" , vexpandpd(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4C8801" , k(k4).vexpandpd(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCC8801" , k(k4).z().vexpandpd(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD488884F023010000" , vexpandpd(zmm24, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD4888427F" , vexpandpd(zmm24, zmmword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262FD48888200040000" , vexpandpd(zmm24, zmmword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262FD48884280" , vexpandpd(zmm24, zmmword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262FD488882F8FBFFFF" , vexpandpd(zmm24, zmmword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C2FD4888FF" , vexpandpd(zmm23, zmm15));
+ TEST_INSTRUCTION("62C2FD4D88FF" , k(k5).vexpandpd(zmm23, zmm15));
+ TEST_INSTRUCTION("62C2FDCD88FF" , k(k5).z().vexpandpd(zmm23, zmm15));
+ TEST_INSTRUCTION("62F27D488821" , vexpandps(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D4E8821" , k(k6).vexpandps(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DCE8821" , k(k6).z().vexpandps(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D4888A4F023010000" , vexpandps(zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D4888627F" , vexpandps(zmm4, zmmword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F27D4888A200020000" , vexpandps(zmm4, zmmword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F27D48886280" , vexpandps(zmm4, zmmword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F27D4888A2FCFDFFFF" , vexpandps(zmm4, zmmword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62527D4888F1" , vexpandps(zmm14, zmm9));
+ TEST_INSTRUCTION("62527D4A88F1" , k(k2).vexpandps(zmm14, zmm9));
+ TEST_INSTRUCTION("62527DCA88F1" , k(k2).z().vexpandps(zmm14, zmm9));
+ TEST_INSTRUCTION("62C37D4819EFAB" , vextractf32x4(xmm15, zmm21, 171));
+ TEST_INSTRUCTION("62C37D4919EFAB" , k(k1).vextractf32x4(xmm15, zmm21, 171));
+ TEST_INSTRUCTION("62C37DC919EFAB" , k(k1).z().vextractf32x4(xmm15, zmm21, 171));
+ TEST_INSTRUCTION("62C37D4819EF7B" , vextractf32x4(xmm15, zmm21, 123));
+ TEST_INSTRUCTION("6243FD481BC3AB" , vextractf64x4(ymm11, zmm24, 171));
+ TEST_INSTRUCTION("6243FD4D1BC3AB" , k(k5).vextractf64x4(ymm11, zmm24, 171));
+ TEST_INSTRUCTION("6243FDCD1BC3AB" , k(k5).z().vextractf64x4(ymm11, zmm24, 171));
+ TEST_INSTRUCTION("6243FD481BC37B" , vextractf64x4(ymm11, zmm24, 123));
+ TEST_INSTRUCTION("62C37D4839C5AB" , vextracti32x4(xmm13, zmm16, 171));
+ TEST_INSTRUCTION("62C37D4D39C5AB" , k(k5).vextracti32x4(xmm13, zmm16, 171));
+ TEST_INSTRUCTION("62C37DCD39C5AB" , k(k5).z().vextracti32x4(xmm13, zmm16, 171));
+ TEST_INSTRUCTION("62C37D4839C57B" , vextracti32x4(xmm13, zmm16, 123));
+ TEST_INSTRUCTION("62C3FD483BC5AB" , vextracti64x4(ymm13, zmm16, 171));
+ TEST_INSTRUCTION("62C3FD4B3BC5AB" , k(k3).vextracti64x4(ymm13, zmm16, 171));
+ TEST_INSTRUCTION("62C3FDCB3BC5AB" , k(k3).z().vextracti64x4(ymm13, zmm16, 171));
+ TEST_INSTRUCTION("62C3FD483BC57B" , vextracti64x4(ymm13, zmm16, 123));
+ TEST_INSTRUCTION("62637D0817C0AB" , vextractps(eax, xmm24, 171));
+ TEST_INSTRUCTION("62637D0817C07B" , vextractps(eax, xmm24, 123));
+ TEST_INSTRUCTION("62437D0817C07B" , vextractps(r8d, xmm24, 123));
+ TEST_INSTRUCTION("62637D0817017B" , vextractps(dword_ptr(rcx), xmm24, 123));
+ TEST_INSTRUCTION("62237D081784F0230100007B" , vextractps(dword_ptr(rax, r14, 3, 291), xmm24, 123));
+ TEST_INSTRUCTION("62637D0817427F7B" , vextractps(dword_ptr(rdx, 508), xmm24, 123));
+ TEST_INSTRUCTION("62637D081782000200007B" , vextractps(dword_ptr(rdx, 512), xmm24, 123));
+ TEST_INSTRUCTION("62637D081742807B" , vextractps(dword_ptr(rdx, -512), xmm24, 123));
+ TEST_INSTRUCTION("62637D081782FCFDFFFF7B" , vextractps(dword_ptr(rdx, -516), xmm24, 123));
+ TEST_INSTRUCTION("6222FD4098D5" , vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FD4598D5" , k(k5).vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FDC598D5" , k(k5).z().vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FD1098D5" , rn_sae().vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FD5098D5" , ru_sae().vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FD3098D5" , rd_sae().vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6222FD7098D5" , rz_sae().vfmadd132pd(zmm26, zmm16, zmm21));
+ TEST_INSTRUCTION("6262FD409811" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD409894F023010000" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD509811" , vfmadd132pd(zmm26, zmm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262FD4098527F" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262FD40989200200000" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262FD40985280" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262FD409892C0DFFFFF" , vfmadd132pd(zmm26, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262FD5098527F" , vfmadd132pd(zmm26, zmm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262FD50989200040000" , vfmadd132pd(zmm26, zmm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262FD50985280" , vfmadd132pd(zmm26, zmm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262FD509892F8FBFFFF" , vfmadd132pd(zmm26, zmm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62925D4098C9" , vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925D4198C9" , k(k1).vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925DC198C9" , k(k1).z().vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925D1098C9" , rn_sae().vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925D5098C9" , ru_sae().vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925D3098C9" , rd_sae().vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62925D7098C9" , rz_sae().vfmadd132ps(zmm1, zmm20, zmm25));
+ TEST_INSTRUCTION("62F25D409809" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B25D40988CF023010000" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F25D509809" , vfmadd132ps(zmm1, zmm20, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F25D40984A7F" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F25D40988A00200000" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F25D40984A80" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F25D40988AC0DFFFFF" , vfmadd132ps(zmm1, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F25D50984A7F" , vfmadd132ps(zmm1, zmm20, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F25D50988A00020000" , vfmadd132ps(zmm1, zmm20, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F25D50984A80" , vfmadd132ps(zmm1, zmm20, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F25D50988AFCFDFFFF" , vfmadd132ps(zmm1, zmm20, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6262F50099E3" , vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F50299E3" , k(k2).vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F58299E3" , k(k2).z().vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F51099E3" , rn_sae().vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F55099E3" , ru_sae().vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F53099E3" , rd_sae().vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F57099E3" , rz_sae().vfmadd132sd(xmm28, xmm17, xmm3));
+ TEST_INSTRUCTION("6262F5009921" , vfmadd132sd(xmm28, xmm17, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222F50099A4F023010000" , vfmadd132sd(xmm28, xmm17, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262F50099627F" , vfmadd132sd(xmm28, xmm17, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262F50099A200040000" , vfmadd132sd(xmm28, xmm17, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262F500996280" , vfmadd132sd(xmm28, xmm17, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262F50099A2F8FBFFFF" , vfmadd132sd(xmm28, xmm17, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6222750099F6" , vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222750399F6" , k(k3).vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222758399F6" , k(k3).z().vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222751099F6" , rn_sae().vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222755099F6" , ru_sae().vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222753099F6" , rd_sae().vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("6222757099F6" , rz_sae().vfmadd132ss(xmm30, xmm17, xmm22));
+ TEST_INSTRUCTION("626275009931" , vfmadd132ss(xmm30, xmm17, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6222750099B4F023010000" , vfmadd132ss(xmm30, xmm17, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262750099727F" , vfmadd132ss(xmm30, xmm17, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("6262750099B200020000" , vfmadd132ss(xmm30, xmm17, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62627500997280" , vfmadd132ss(xmm30, xmm17, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("6262750099B2FCFDFFFF" , vfmadd132ss(xmm30, xmm17, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6282FD40A8D1" , vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FD43A8D1" , k(k3).vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FDC3A8D1" , k(k3).z().vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FD10A8D1" , rn_sae().vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FD50A8D1" , ru_sae().vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FD30A8D1" , rd_sae().vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("6282FD70A8D1" , rz_sae().vfmadd213pd(zmm18, zmm16, zmm25));
+ TEST_INSTRUCTION("62E2FD40A811" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD40A894F023010000" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2FD50A811" , vfmadd213pd(zmm18, zmm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2FD40A8527F" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2FD40A89200200000" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2FD40A85280" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2FD40A892C0DFFFFF" , vfmadd213pd(zmm18, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2FD50A8527F" , vfmadd213pd(zmm18, zmm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2FD50A89200040000" , vfmadd213pd(zmm18, zmm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD50A85280" , vfmadd213pd(zmm18, zmm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD50A892F8FBFFFF" , vfmadd213pd(zmm18, zmm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C26540A8E6" , vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C26544A8E6" , k(k4).vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C265C4A8E6" , k(k4).z().vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C26510A8E6" , rn_sae().vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C26550A8E6" , ru_sae().vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C26530A8E6" , rd_sae().vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62C26570A8E6" , rz_sae().vfmadd213ps(zmm20, zmm19, zmm14));
+ TEST_INSTRUCTION("62E26540A821" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A26540A8A4F023010000" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E26550A821" , vfmadd213ps(zmm20, zmm19, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E26540A8627F" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E26540A8A200200000" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E26540A86280" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E26540A8A2C0DFFFFF" , vfmadd213ps(zmm20, zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E26550A8627F" , vfmadd213ps(zmm20, zmm19, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E26550A8A200020000" , vfmadd213ps(zmm20, zmm19, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E26550A86280" , vfmadd213ps(zmm20, zmm19, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E26550A8A2FCFDFFFF" , vfmadd213ps(zmm20, zmm19, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6242AD00A9C5" , vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD03A9C5" , k(k3).vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD83A9C5" , k(k3).z().vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD10A9C5" , rn_sae().vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD50A9C5" , ru_sae().vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD30A9C5" , rd_sae().vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6242AD70A9C5" , rz_sae().vfmadd213sd(xmm24, xmm26, xmm13));
+ TEST_INSTRUCTION("6262AD00A901" , vfmadd213sd(xmm24, xmm26, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222AD00A984F023010000" , vfmadd213sd(xmm24, xmm26, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262AD00A9427F" , vfmadd213sd(xmm24, xmm26, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262AD00A98200040000" , vfmadd213sd(xmm24, xmm26, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262AD00A94280" , vfmadd213sd(xmm24, xmm26, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262AD00A982F8FBFFFF" , vfmadd213sd(xmm24, xmm26, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62224D00A9F0" , vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D01A9F0" , k(k1).vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D81A9F0" , k(k1).z().vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D10A9F0" , rn_sae().vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D50A9F0" , ru_sae().vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D30A9F0" , rd_sae().vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62224D70A9F0" , rz_sae().vfmadd213ss(xmm30, xmm22, xmm16));
+ TEST_INSTRUCTION("62624D00A931" , vfmadd213ss(xmm30, xmm22, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62224D00A9B4F023010000" , vfmadd213ss(xmm30, xmm22, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62624D00A9727F" , vfmadd213ss(xmm30, xmm22, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62624D00A9B200020000" , vfmadd213ss(xmm30, xmm22, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62624D00A97280" , vfmadd213ss(xmm30, xmm22, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62624D00A9B2FCFDFFFF" , vfmadd213ss(xmm30, xmm22, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6242CD48B8F1" , vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CD4CB8F1" , k(k4).vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CDCCB8F1" , k(k4).z().vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CD18B8F1" , rn_sae().vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CD58B8F1" , ru_sae().vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CD38B8F1" , rd_sae().vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6242CD78B8F1" , rz_sae().vfmadd231pd(zmm30, zmm6, zmm9));
+ TEST_INSTRUCTION("6262CD48B831" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222CD48B8B4F023010000" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262CD58B831" , vfmadd231pd(zmm30, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262CD48B8727F" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262CD48B8B200200000" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262CD48B87280" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262CD48B8B2C0DFFFFF" , vfmadd231pd(zmm30, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262CD58B8727F" , vfmadd231pd(zmm30, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262CD58B8B200040000" , vfmadd231pd(zmm30, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262CD58B87280" , vfmadd231pd(zmm30, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262CD58B8B2F8FBFFFF" , vfmadd231pd(zmm30, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62021D40B8D9" , vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021D43B8D9" , k(k3).vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021DC3B8D9" , k(k3).z().vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021D10B8D9" , rn_sae().vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021D50B8D9" , ru_sae().vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021D30B8D9" , rd_sae().vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62021D70B8D9" , rz_sae().vfmadd231ps(zmm27, zmm28, zmm25));
+ TEST_INSTRUCTION("62621D40B819" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62221D40B89CF023010000" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62621D50B819" , vfmadd231ps(zmm27, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62621D40B85A7F" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62621D40B89A00200000" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62621D40B85A80" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62621D40B89AC0DFFFFF" , vfmadd231ps(zmm27, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62621D50B85A7F" , vfmadd231ps(zmm27, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62621D50B89A00020000" , vfmadd231ps(zmm27, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62621D50B85A80" , vfmadd231ps(zmm27, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62621D50B89AFCFDFFFF" , vfmadd231ps(zmm27, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4C2F1B9E6" , vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F509B9E6" , k(k1).vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F589B9E6" , k(k1).z().vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F518B9E6" , rn_sae().vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F558B9E6" , ru_sae().vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F538B9E6" , rd_sae().vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("62D2F578B9E6" , rz_sae().vfmadd231sd(xmm4, xmm1, xmm14));
+ TEST_INSTRUCTION("C4E2F1B921" , vfmadd231sd(xmm4, xmm1, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2F1B9A4F023010000" , vfmadd231sd(xmm4, xmm1, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C4E2F1B9A2F8030000" , vfmadd231sd(xmm4, xmm1, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2F1B9A200040000" , vfmadd231sd(xmm4, xmm1, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2F1B9A200FCFFFF" , vfmadd231sd(xmm4, xmm1, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2F1B9A2F8FBFFFF" , vfmadd231sd(xmm4, xmm1, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62420508B9EA" , vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("6242050CB9EA" , k(k4).vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("6242058CB9EA" , k(k4).z().vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("62420518B9EA" , rn_sae().vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("62420558B9EA" , ru_sae().vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("62420538B9EA" , rd_sae().vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("62420578B9EA" , rz_sae().vfmadd231ss(xmm29, xmm15, xmm10));
+ TEST_INSTRUCTION("62620508B929" , vfmadd231ss(xmm29, xmm15, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62220508B9ACF023010000" , vfmadd231ss(xmm29, xmm15, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62620508B96A7F" , vfmadd231ss(xmm29, xmm15, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62620508B9AA00020000" , vfmadd231ss(xmm29, xmm15, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62620508B96A80" , vfmadd231ss(xmm29, xmm15, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62620508B9AAFCFDFFFF" , vfmadd231ss(xmm29, xmm15, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62A2B54096E5" , vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B54296E5" , k(k2).vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B5C296E5" , k(k2).z().vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B51096E5" , rn_sae().vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B55096E5" , ru_sae().vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B53096E5" , rd_sae().vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62A2B57096E5" , rz_sae().vfmaddsub132pd(zmm20, zmm25, zmm21));
+ TEST_INSTRUCTION("62E2B5409621" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2B54096A4F023010000" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2B5509621" , vfmaddsub132pd(zmm20, zmm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2B54096627F" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2B54096A200200000" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2B540966280" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2B54096A2C0DFFFFF" , vfmaddsub132pd(zmm20, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2B55096627F" , vfmaddsub132pd(zmm20, zmm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2B55096A200040000" , vfmaddsub132pd(zmm20, zmm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2B550966280" , vfmaddsub132pd(zmm20, zmm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2B55096A2F8FBFFFF" , vfmaddsub132pd(zmm20, zmm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6232354896D4" , vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("6232354B96D4" , k(k3).vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("623235CB96D4" , k(k3).z().vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("6232351896D4" , rn_sae().vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("6232355896D4" , ru_sae().vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("6232353896D4" , rd_sae().vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("6232357896D4" , rz_sae().vfmaddsub132ps(zmm10, zmm9, zmm20));
+ TEST_INSTRUCTION("627235489611" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("623235489694F023010000" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("627235589611" , vfmaddsub132ps(zmm10, zmm9, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("6272354896527F" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62723548969200200000" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62723548965280" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("627235489692C0DFFFFF" , vfmaddsub132ps(zmm10, zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272355896527F" , vfmaddsub132ps(zmm10, zmm9, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62723558969200020000" , vfmaddsub132ps(zmm10, zmm9, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62723558965280" , vfmaddsub132ps(zmm10, zmm9, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("627235589692FCFDFFFF" , vfmaddsub132ps(zmm10, zmm9, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6242CD48A6D2" , vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CD4EA6D2" , k(k6).vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CDCEA6D2" , k(k6).z().vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CD18A6D2" , rn_sae().vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CD58A6D2" , ru_sae().vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CD38A6D2" , rd_sae().vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6242CD78A6D2" , rz_sae().vfmaddsub213pd(zmm26, zmm6, zmm10));
+ TEST_INSTRUCTION("6262CD48A611" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222CD48A694F023010000" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262CD58A611" , vfmaddsub213pd(zmm26, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262CD48A6527F" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262CD48A69200200000" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262CD48A65280" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262CD48A692C0DFFFFF" , vfmaddsub213pd(zmm26, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262CD58A6527F" , vfmaddsub213pd(zmm26, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262CD58A69200040000" , vfmaddsub213pd(zmm26, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262CD58A65280" , vfmaddsub213pd(zmm26, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262CD58A692F8FBFFFF" , vfmaddsub213pd(zmm26, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62823D40A6CC" , vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823D46A6CC" , k(k6).vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823DC6A6CC" , k(k6).z().vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823D10A6CC" , rn_sae().vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823D50A6CC" , ru_sae().vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823D30A6CC" , rd_sae().vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62823D70A6CC" , rz_sae().vfmaddsub213ps(zmm17, zmm24, zmm28));
+ TEST_INSTRUCTION("62E23D40A609" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A23D40A68CF023010000" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E23D50A609" , vfmaddsub213ps(zmm17, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E23D40A64A7F" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E23D40A68A00200000" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E23D40A64A80" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E23D40A68AC0DFFFFF" , vfmaddsub213ps(zmm17, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E23D50A64A7F" , vfmaddsub213ps(zmm17, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E23D50A68A00020000" , vfmaddsub213ps(zmm17, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E23D50A64A80" , vfmaddsub213ps(zmm17, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E23D50A68AFCFDFFFF" , vfmaddsub213ps(zmm17, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6212A540B6C8" , vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A547B6C8" , k(k7).vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A5C7B6C8" , k(k7).z().vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A510B6C8" , rn_sae().vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A550B6C8" , ru_sae().vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A530B6C8" , rd_sae().vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6212A570B6C8" , rz_sae().vfmaddsub231pd(zmm9, zmm27, zmm24));
+ TEST_INSTRUCTION("6272A540B609" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232A540B68CF023010000" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272A550B609" , vfmaddsub231pd(zmm9, zmm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272A540B64A7F" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272A540B68A00200000" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272A540B64A80" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272A540B68AC0DFFFFF" , vfmaddsub231pd(zmm9, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272A550B64A7F" , vfmaddsub231pd(zmm9, zmm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272A550B68A00040000" , vfmaddsub231pd(zmm9, zmm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272A550B64A80" , vfmaddsub231pd(zmm9, zmm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272A550B68AF8FBFFFF" , vfmaddsub231pd(zmm9, zmm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62325540B6FB" , vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62325546B6FB" , k(k6).vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("623255C6B6FB" , k(k6).z().vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62325510B6FB" , rn_sae().vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62325550B6FB" , ru_sae().vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62325530B6FB" , rd_sae().vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62325570B6FB" , rz_sae().vfmaddsub231ps(zmm15, zmm21, zmm19));
+ TEST_INSTRUCTION("62725540B639" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62325540B6BCF023010000" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62725550B639" , vfmaddsub231ps(zmm15, zmm21, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62725540B67A7F" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62725540B6BA00200000" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62725540B67A80" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62725540B6BAC0DFFFFF" , vfmaddsub231ps(zmm15, zmm21, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62725550B67A7F" , vfmaddsub231ps(zmm15, zmm21, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62725550B6BA00020000" , vfmaddsub231ps(zmm15, zmm21, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62725550B67A80" , vfmaddsub231ps(zmm15, zmm21, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62725550B6BAFCFDFFFF" , vfmaddsub231ps(zmm15, zmm21, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62829D489AF3" , vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829D4A9AF3" , k(k2).vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829DCA9AF3" , k(k2).z().vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829D189AF3" , rn_sae().vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829D589AF3" , ru_sae().vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829D389AF3" , rd_sae().vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62829D789AF3" , rz_sae().vfmsub132pd(zmm22, zmm12, zmm27));
+ TEST_INSTRUCTION("62E29D489A31" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A29D489AB4F023010000" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E29D589A31" , vfmsub132pd(zmm22, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E29D489A727F" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E29D489AB200200000" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E29D489A7280" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E29D489AB2C0DFFFFF" , vfmsub132pd(zmm22, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E29D589A727F" , vfmsub132pd(zmm22, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E29D589AB200040000" , vfmsub132pd(zmm22, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E29D589A7280" , vfmsub132pd(zmm22, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E29D589AB2F8FBFFFF" , vfmsub132pd(zmm22, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B215489AC8" , vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B2154C9AC8" , k(k4).vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B215CC9AC8" , k(k4).z().vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B215189AC8" , rn_sae().vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B215589AC8" , ru_sae().vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B215389AC8" , rd_sae().vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62B215789AC8" , rz_sae().vfmsub132ps(zmm1, zmm13, zmm16));
+ TEST_INSTRUCTION("62F215489A09" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B215489A8CF023010000" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F215589A09" , vfmsub132ps(zmm1, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F215489A4A7F" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F215489A8A00200000" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F215489A4A80" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F215489A8AC0DFFFFF" , vfmsub132ps(zmm1, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F215589A4A7F" , vfmsub132ps(zmm1, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F215589A8A00020000" , vfmsub132ps(zmm1, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F215589A4A80" , vfmsub132ps(zmm1, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F215589A8AFCFDFFFF" , vfmsub132ps(zmm1, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6212BD089BE3" , vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD0B9BE3" , k(k3).vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD8B9BE3" , k(k3).z().vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD189BE3" , rn_sae().vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD589BE3" , ru_sae().vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD389BE3" , rd_sae().vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("6212BD789BE3" , rz_sae().vfmsub132sd(xmm12, xmm8, xmm27));
+ TEST_INSTRUCTION("C462B99B21" , vfmsub132sd(xmm12, xmm8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C422B99BA4F023010000" , vfmsub132sd(xmm12, xmm8, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C462B99BA2F8030000" , vfmsub132sd(xmm12, xmm8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C462B99BA200040000" , vfmsub132sd(xmm12, xmm8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C462B99BA200FCFFFF" , vfmsub132sd(xmm12, xmm8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C462B99BA2F8FBFFFF" , vfmsub132sd(xmm12, xmm8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62024D009BF3" , vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D039BF3" , k(k3).vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D839BF3" , k(k3).z().vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D109BF3" , rn_sae().vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D509BF3" , ru_sae().vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D309BF3" , rd_sae().vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62024D709BF3" , rz_sae().vfmsub132ss(xmm30, xmm22, xmm27));
+ TEST_INSTRUCTION("62624D009B31" , vfmsub132ss(xmm30, xmm22, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62224D009BB4F023010000" , vfmsub132ss(xmm30, xmm22, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62624D009B727F" , vfmsub132ss(xmm30, xmm22, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62624D009BB200020000" , vfmsub132ss(xmm30, xmm22, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62624D009B7280" , vfmsub132ss(xmm30, xmm22, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62624D009BB2FCFDFFFF" , vfmsub132ss(xmm30, xmm22, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F2AD48AAEC" , vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD49AAEC" , k(k1).vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2ADC9AAEC" , k(k1).z().vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD18AAEC" , rn_sae().vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD58AAEC" , ru_sae().vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD38AAEC" , rd_sae().vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD78AAEC" , rz_sae().vfmsub213pd(zmm5, zmm10, zmm4));
+ TEST_INSTRUCTION("62F2AD48AA29" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2AD48AAACF023010000" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2AD58AA29" , vfmsub213pd(zmm5, zmm10, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2AD48AA6A7F" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2AD48AAAA00200000" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2AD48AA6A80" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2AD48AAAAC0DFFFFF" , vfmsub213pd(zmm5, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2AD58AA6A7F" , vfmsub213pd(zmm5, zmm10, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2AD58AAAA00040000" , vfmsub213pd(zmm5, zmm10, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD58AA6A80" , vfmsub213pd(zmm5, zmm10, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD58AAAAF8FBFFFF" , vfmsub213pd(zmm5, zmm10, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C24D40AAF2" , vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24D46AAF2" , k(k6).vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24DC6AAF2" , k(k6).z().vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24D10AAF2" , rn_sae().vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24D50AAF2" , ru_sae().vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24D30AAF2" , rd_sae().vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62C24D70AAF2" , rz_sae().vfmsub213ps(zmm22, zmm22, zmm10));
+ TEST_INSTRUCTION("62E24D40AA31" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A24D40AAB4F023010000" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E24D50AA31" , vfmsub213ps(zmm22, zmm22, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E24D40AA727F" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E24D40AAB200200000" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E24D40AA7280" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E24D40AAB2C0DFFFFF" , vfmsub213ps(zmm22, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E24D50AA727F" , vfmsub213ps(zmm22, zmm22, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E24D50AAB200020000" , vfmsub213ps(zmm22, zmm22, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E24D50AA7280" , vfmsub213ps(zmm22, zmm22, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E24D50AAB2FCFDFFFF" , vfmsub213ps(zmm22, zmm22, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4C2B9ABF4" , vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD09ABF4" , k(k1).vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD89ABF4" , k(k1).z().vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD18ABF4" , rn_sae().vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD58ABF4" , ru_sae().vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD38ABF4" , rd_sae().vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("62D2BD78ABF4" , rz_sae().vfmsub213sd(xmm6, xmm8, xmm12));
+ TEST_INSTRUCTION("C4E2B9AB31" , vfmsub213sd(xmm6, xmm8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2B9ABB4F023010000" , vfmsub213sd(xmm6, xmm8, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C4E2B9ABB2F8030000" , vfmsub213sd(xmm6, xmm8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2B9ABB200040000" , vfmsub213sd(xmm6, xmm8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2B9ABB200FCFFFF" , vfmsub213sd(xmm6, xmm8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2B9ABB2F8FBFFFF" , vfmsub213sd(xmm6, xmm8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62021508ABF2" , vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021509ABF2" , k(k1).vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021589ABF2" , k(k1).z().vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021518ABF2" , rn_sae().vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021558ABF2" , ru_sae().vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021538ABF2" , rd_sae().vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62021578ABF2" , rz_sae().vfmsub213ss(xmm30, xmm13, xmm26));
+ TEST_INSTRUCTION("62621508AB31" , vfmsub213ss(xmm30, xmm13, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62221508ABB4F023010000" , vfmsub213ss(xmm30, xmm13, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62621508AB727F" , vfmsub213ss(xmm30, xmm13, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62621508ABB200020000" , vfmsub213ss(xmm30, xmm13, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62621508AB7280" , vfmsub213ss(xmm30, xmm13, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62621508ABB2FCFDFFFF" , vfmsub213ss(xmm30, xmm13, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62D29D48BAEB" , vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29D4ABAEB" , k(k2).vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29DCABAEB" , k(k2).z().vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29D18BAEB" , rn_sae().vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29D58BAEB" , ru_sae().vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29D38BAEB" , rd_sae().vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62D29D78BAEB" , rz_sae().vfmsub231pd(zmm5, zmm12, zmm11));
+ TEST_INSTRUCTION("62F29D48BA29" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B29D48BAACF023010000" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F29D58BA29" , vfmsub231pd(zmm5, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F29D48BA6A7F" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F29D48BAAA00200000" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F29D48BA6A80" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F29D48BAAAC0DFFFFF" , vfmsub231pd(zmm5, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F29D58BA6A7F" , vfmsub231pd(zmm5, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F29D58BAAA00040000" , vfmsub231pd(zmm5, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F29D58BA6A80" , vfmsub231pd(zmm5, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F29D58BAAAF8FBFFFF" , vfmsub231pd(zmm5, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62925540BAF3" , vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62925543BAF3" , k(k3).vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("629255C3BAF3" , k(k3).z().vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62925510BAF3" , rn_sae().vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62925550BAF3" , ru_sae().vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62925530BAF3" , rd_sae().vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62925570BAF3" , rz_sae().vfmsub231ps(zmm6, zmm21, zmm27));
+ TEST_INSTRUCTION("62F25540BA31" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B25540BAB4F023010000" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F25550BA31" , vfmsub231ps(zmm6, zmm21, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F25540BA727F" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F25540BAB200200000" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F25540BA7280" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F25540BAB2C0DFFFFF" , vfmsub231ps(zmm6, zmm21, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F25550BA727F" , vfmsub231ps(zmm6, zmm21, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F25550BAB200020000" , vfmsub231ps(zmm6, zmm21, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F25550BA7280" , vfmsub231ps(zmm6, zmm21, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F25550BAB2FCFDFFFF" , vfmsub231ps(zmm6, zmm21, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4E2A1BBDE" , vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A50FBBDE" , k(k7).vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A58FBBDE" , k(k7).z().vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A518BBDE" , rn_sae().vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A558BBDE" , ru_sae().vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A538BBDE" , rd_sae().vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("62F2A578BBDE" , rz_sae().vfmsub231sd(xmm3, xmm11, xmm6));
+ TEST_INSTRUCTION("C4E2A1BB19" , vfmsub231sd(xmm3, xmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2A1BB9CF023010000" , vfmsub231sd(xmm3, xmm11, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C4E2A1BB9AF8030000" , vfmsub231sd(xmm3, xmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2A1BB9A00040000" , vfmsub231sd(xmm3, xmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2A1BB9A00FCFFFF" , vfmsub231sd(xmm3, xmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2A1BB9AF8FBFFFF" , vfmsub231sd(xmm3, xmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62626508BBED" , vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("6262650EBBED" , k(k6).vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("6262658EBBED" , k(k6).z().vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("62626518BBED" , rn_sae().vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("62626558BBED" , ru_sae().vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("62626538BBED" , rd_sae().vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("62626578BBED" , rz_sae().vfmsub231ss(xmm29, xmm3, xmm5));
+ TEST_INSTRUCTION("62626508BB29" , vfmsub231ss(xmm29, xmm3, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62226508BBACF023010000" , vfmsub231ss(xmm29, xmm3, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62626508BB6A7F" , vfmsub231ss(xmm29, xmm3, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62626508BBAA00020000" , vfmsub231ss(xmm29, xmm3, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62626508BB6A80" , vfmsub231ss(xmm29, xmm3, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62626508BBAAFCFDFFFF" , vfmsub231ss(xmm29, xmm3, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62A29D4097EA" , vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29D4797EA" , k(k7).vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29DC797EA" , k(k7).z().vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29D1097EA" , rn_sae().vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29D5097EA" , ru_sae().vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29D3097EA" , rd_sae().vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62A29D7097EA" , rz_sae().vfmsubadd132pd(zmm21, zmm28, zmm18));
+ TEST_INSTRUCTION("62E29D409729" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A29D4097ACF023010000" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E29D509729" , vfmsubadd132pd(zmm21, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E29D40976A7F" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E29D4097AA00200000" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E29D40976A80" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E29D4097AAC0DFFFFF" , vfmsubadd132pd(zmm21, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E29D50976A7F" , vfmsubadd132pd(zmm21, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E29D5097AA00040000" , vfmsubadd132pd(zmm21, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E29D50976A80" , vfmsubadd132pd(zmm21, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E29D5097AAF8FBFFFF" , vfmsubadd132pd(zmm21, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B2154897D5" , vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B2154F97D5" , k(k7).vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B215CF97D5" , k(k7).z().vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B2151897D5" , rn_sae().vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B2155897D5" , ru_sae().vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B2153897D5" , rd_sae().vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62B2157897D5" , rz_sae().vfmsubadd132ps(zmm2, zmm13, zmm21));
+ TEST_INSTRUCTION("62F215489711" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B215489794F023010000" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F215589711" , vfmsubadd132ps(zmm2, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F2154897527F" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F21548979200200000" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F21548975280" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F215489792C0DFFFFF" , vfmsubadd132ps(zmm2, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2155897527F" , vfmsubadd132ps(zmm2, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F21558979200020000" , vfmsubadd132ps(zmm2, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F21558975280" , vfmsubadd132ps(zmm2, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F215589792FCFDFFFF" , vfmsubadd132ps(zmm2, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2C540A7D2" , vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C546A7D2" , k(k6).vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C5C6A7D2" , k(k6).z().vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C510A7D2" , rn_sae().vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C550A7D2" , ru_sae().vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C530A7D2" , rd_sae().vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C570A7D2" , rz_sae().vfmsubadd213pd(zmm2, zmm23, zmm2));
+ TEST_INSTRUCTION("62F2C540A711" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2C540A794F023010000" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2C550A711" , vfmsubadd213pd(zmm2, zmm23, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2C540A7527F" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2C540A79200200000" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2C540A75280" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2C540A792C0DFFFFF" , vfmsubadd213pd(zmm2, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2C550A7527F" , vfmsubadd213pd(zmm2, zmm23, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2C550A79200040000" , vfmsubadd213pd(zmm2, zmm23, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2C550A75280" , vfmsubadd213pd(zmm2, zmm23, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2C550A792F8FBFFFF" , vfmsubadd213pd(zmm2, zmm23, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C21D48A7F6" , vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21D4EA7F6" , k(k6).vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21DCEA7F6" , k(k6).z().vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21D18A7F6" , rn_sae().vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21D58A7F6" , ru_sae().vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21D38A7F6" , rd_sae().vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62C21D78A7F6" , rz_sae().vfmsubadd213ps(zmm22, zmm12, zmm14));
+ TEST_INSTRUCTION("62E21D48A731" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A21D48A7B4F023010000" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E21D58A731" , vfmsubadd213ps(zmm22, zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E21D48A7727F" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E21D48A7B200200000" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E21D48A77280" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E21D48A7B2C0DFFFFF" , vfmsubadd213ps(zmm22, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E21D58A7727F" , vfmsubadd213ps(zmm22, zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E21D58A7B200020000" , vfmsubadd213ps(zmm22, zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E21D58A77280" , vfmsubadd213ps(zmm22, zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E21D58A7B2FCFDFFFF" , vfmsubadd213ps(zmm22, zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2A540B7C5" , vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A542B7C5" , k(k2).vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A5C2B7C5" , k(k2).z().vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A510B7C5" , rn_sae().vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A550B7C5" , ru_sae().vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A530B7C5" , rd_sae().vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A570B7C5" , rz_sae().vfmsubadd231pd(zmm16, zmm27, zmm21));
+ TEST_INSTRUCTION("62E2A540B701" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2A540B784F023010000" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2A550B701" , vfmsubadd231pd(zmm16, zmm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2A540B7427F" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2A540B78200200000" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2A540B74280" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2A540B782C0DFFFFF" , vfmsubadd231pd(zmm16, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2A550B7427F" , vfmsubadd231pd(zmm16, zmm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2A550B78200040000" , vfmsubadd231pd(zmm16, zmm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2A550B74280" , vfmsubadd231pd(zmm16, zmm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2A550B782F8FBFFFF" , vfmsubadd231pd(zmm16, zmm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62726540B7C1" , vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726542B7C1" , k(k2).vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("627265C2B7C1" , k(k2).z().vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726510B7C1" , rn_sae().vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726550B7C1" , ru_sae().vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726530B7C1" , rd_sae().vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726570B7C1" , rz_sae().vfmsubadd231ps(zmm8, zmm19, zmm1));
+ TEST_INSTRUCTION("62726540B701" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62326540B784F023010000" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62726550B701" , vfmsubadd231ps(zmm8, zmm19, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62726540B7427F" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62726540B78200200000" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62726540B74280" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62726540B782C0DFFFFF" , vfmsubadd231ps(zmm8, zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62726550B7427F" , vfmsubadd231ps(zmm8, zmm19, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62726550B78200020000" , vfmsubadd231ps(zmm8, zmm19, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62726550B74280" , vfmsubadd231ps(zmm8, zmm19, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62726550B782FCFDFFFF" , vfmsubadd231ps(zmm8, zmm19, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62728D489CE1" , vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D4F9CE1" , k(k7).vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728DCF9CE1" , k(k7).z().vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D189CE1" , rn_sae().vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D589CE1" , ru_sae().vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D389CE1" , rd_sae().vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D789CE1" , rz_sae().vfnmadd132pd(zmm12, zmm14, zmm1));
+ TEST_INSTRUCTION("62728D489C21" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62328D489CA4F023010000" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62728D589C21" , vfnmadd132pd(zmm12, zmm14, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62728D489C627F" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62728D489CA200200000" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62728D489C6280" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62728D489CA2C0DFFFFF" , vfnmadd132pd(zmm12, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62728D589C627F" , vfnmadd132pd(zmm12, zmm14, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62728D589CA200040000" , vfnmadd132pd(zmm12, zmm14, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62728D589C6280" , vfnmadd132pd(zmm12, zmm14, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62728D589CA2F8FBFFFF" , vfnmadd132pd(zmm12, zmm14, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C27D409CEA" , vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27D459CEA" , k(k5).vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27DC59CEA" , k(k5).z().vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27D109CEA" , rn_sae().vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27D509CEA" , ru_sae().vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27D309CEA" , rd_sae().vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62C27D709CEA" , rz_sae().vfnmadd132ps(zmm21, zmm16, zmm10));
+ TEST_INSTRUCTION("62E27D409C29" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D409CACF023010000" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D509C29" , vfnmadd132ps(zmm21, zmm16, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E27D409C6A7F" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E27D409CAA00200000" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E27D409C6A80" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E27D409CAAC0DFFFFF" , vfnmadd132ps(zmm21, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E27D509C6A7F" , vfnmadd132ps(zmm21, zmm16, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E27D509CAA00020000" , vfnmadd132ps(zmm21, zmm16, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E27D509C6A80" , vfnmadd132ps(zmm21, zmm16, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E27D509CAAFCFDFFFF" , vfnmadd132ps(zmm21, zmm16, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C2E5089DDB" , vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E50A9DDB" , k(k2).vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E58A9DDB" , k(k2).z().vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E5189DDB" , rn_sae().vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E5589DDB" , ru_sae().vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E5389DDB" , rd_sae().vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62C2E5789DDB" , rz_sae().vfnmadd132sd(xmm19, xmm3, xmm11));
+ TEST_INSTRUCTION("62E2E5089D19" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2E5089D9CF023010000" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2E5089D5A7F" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E2E5089D9A00040000" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E2E5089D5A80" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E2E5089D9AF8FBFFFF" , vfnmadd132sd(xmm19, xmm3, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("622275089DCF" , vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("6222750B9DCF" , k(k3).vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("6222758B9DCF" , k(k3).z().vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("622275189DCF" , rn_sae().vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("622275589DCF" , ru_sae().vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("622275389DCF" , rd_sae().vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("622275789DCF" , rz_sae().vfnmadd132ss(xmm25, xmm1, xmm23));
+ TEST_INSTRUCTION("626275089D09" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("622275089D8CF023010000" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626275089D4A7F" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("626275089D8A00020000" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("626275089D4A80" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("626275089D8AFCFDFFFF" , vfnmadd132ss(xmm25, xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C2FD40ACC9" , vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FD44ACC9" , k(k4).vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FDC4ACC9" , k(k4).z().vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FD10ACC9" , rn_sae().vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FD50ACC9" , ru_sae().vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FD30ACC9" , rd_sae().vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C2FD70ACC9" , rz_sae().vfnmadd213pd(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62E2FD40AC09" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD40AC8CF023010000" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2FD50AC09" , vfnmadd213pd(zmm17, zmm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2FD40AC4A7F" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2FD40AC8A00200000" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2FD40AC4A80" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2FD40AC8AC0DFFFFF" , vfnmadd213pd(zmm17, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2FD50AC4A7F" , vfnmadd213pd(zmm17, zmm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2FD50AC8A00040000" , vfnmadd213pd(zmm17, zmm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD50AC4A80" , vfnmadd213pd(zmm17, zmm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD50AC8AF8FBFFFF" , vfnmadd213pd(zmm17, zmm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62622D48ACD6" , vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D4EACD6" , k(k6).vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622DCEACD6" , k(k6).z().vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D18ACD6" , rn_sae().vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D58ACD6" , ru_sae().vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D38ACD6" , rd_sae().vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D78ACD6" , rz_sae().vfnmadd213ps(zmm26, zmm10, zmm6));
+ TEST_INSTRUCTION("62622D48AC11" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62222D48AC94F023010000" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62622D58AC11" , vfnmadd213ps(zmm26, zmm10, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62622D48AC527F" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62622D48AC9200200000" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62622D48AC5280" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62622D48AC92C0DFFFFF" , vfnmadd213ps(zmm26, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62622D58AC527F" , vfnmadd213ps(zmm26, zmm10, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62622D58AC9200020000" , vfnmadd213ps(zmm26, zmm10, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62622D58AC5280" , vfnmadd213ps(zmm26, zmm10, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62622D58AC92FCFDFFFF" , vfnmadd213ps(zmm26, zmm10, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6272A500ADEA" , vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A507ADEA" , k(k7).vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A587ADEA" , k(k7).z().vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A510ADEA" , rn_sae().vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A550ADEA" , ru_sae().vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A530ADEA" , rd_sae().vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A570ADEA" , rz_sae().vfnmadd213sd(xmm13, xmm27, xmm2));
+ TEST_INSTRUCTION("6272A500AD29" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6232A500ADACF023010000" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272A500AD6A7F" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6272A500ADAA00040000" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6272A500AD6A80" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6272A500ADAAF8FBFFFF" , vfnmadd213sd(xmm13, xmm27, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62024508ADEC" , vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("6202450AADEC" , k(k2).vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("6202458AADEC" , k(k2).z().vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("62024518ADEC" , rn_sae().vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("62024558ADEC" , ru_sae().vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("62024538ADEC" , rd_sae().vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("62024578ADEC" , rz_sae().vfnmadd213ss(xmm29, xmm7, xmm28));
+ TEST_INSTRUCTION("62624508AD29" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62224508ADACF023010000" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62624508AD6A7F" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62624508ADAA00020000" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62624508AD6A80" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62624508ADAAFCFDFFFF" , vfnmadd213ss(xmm29, xmm7, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6232A548BCE0" , vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A54EBCE0" , k(k6).vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A5CEBCE0" , k(k6).z().vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A518BCE0" , rn_sae().vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A558BCE0" , ru_sae().vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A538BCE0" , rd_sae().vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6232A578BCE0" , rz_sae().vfnmadd231pd(zmm12, zmm11, zmm16));
+ TEST_INSTRUCTION("6272A548BC21" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232A548BCA4F023010000" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272A558BC21" , vfnmadd231pd(zmm12, zmm11, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272A548BC627F" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272A548BCA200200000" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272A548BC6280" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272A548BCA2C0DFFFFF" , vfnmadd231pd(zmm12, zmm11, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272A558BC627F" , vfnmadd231pd(zmm12, zmm11, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272A558BCA200040000" , vfnmadd231pd(zmm12, zmm11, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272A558BC6280" , vfnmadd231pd(zmm12, zmm11, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272A558BCA2F8FBFFFF" , vfnmadd231pd(zmm12, zmm11, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62124548BCF0" , vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("6212454DBCF0" , k(k5).vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("621245CDBCF0" , k(k5).z().vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("62124518BCF0" , rn_sae().vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("62124558BCF0" , ru_sae().vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("62124538BCF0" , rd_sae().vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("62124578BCF0" , rz_sae().vfnmadd231ps(zmm14, zmm7, zmm24));
+ TEST_INSTRUCTION("62724548BC31" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62324548BCB4F023010000" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62724558BC31" , vfnmadd231ps(zmm14, zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62724548BC727F" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62724548BCB200200000" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62724548BC7280" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62724548BCB2C0DFFFFF" , vfnmadd231ps(zmm14, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62724558BC727F" , vfnmadd231ps(zmm14, zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62724558BCB200020000" , vfnmadd231ps(zmm14, zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62724558BC7280" , vfnmadd231ps(zmm14, zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62724558BCB2FCFDFFFF" , vfnmadd231ps(zmm14, zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B2A508BDF2" , vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A50BBDF2" , k(k3).vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A58BBDF2" , k(k3).z().vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A518BDF2" , rn_sae().vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A558BDF2" , ru_sae().vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A538BDF2" , rd_sae().vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("62B2A578BDF2" , rz_sae().vfnmadd231sd(xmm6, xmm11, xmm18));
+ TEST_INSTRUCTION("C4E2A1BD31" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2A1BDB4F023010000" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C4E2A1BDB2F8030000" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2A1BDB200040000" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2A1BDB200FCFFFF" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2A1BDB2F8FBFFFF" , vfnmadd231sd(xmm6, xmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62226D08BDD9" , vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D09BDD9" , k(k1).vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D89BDD9" , k(k1).z().vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D18BDD9" , rn_sae().vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D58BDD9" , ru_sae().vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D38BDD9" , rd_sae().vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62226D78BDD9" , rz_sae().vfnmadd231ss(xmm27, xmm2, xmm17));
+ TEST_INSTRUCTION("62626D08BD19" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62226D08BD9CF023010000" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62626D08BD5A7F" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62626D08BD9A00020000" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62626D08BD5A80" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62626D08BD9AFCFDFFFF" , vfnmadd231ss(xmm27, xmm2, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6262D5489EE6" , vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D54A9EE6" , k(k2).vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5CA9EE6" , k(k2).z().vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5189EE6" , rn_sae().vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5589EE6" , ru_sae().vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5389EE6" , rd_sae().vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5789EE6" , rz_sae().vfnmsub132pd(zmm28, zmm5, zmm6));
+ TEST_INSTRUCTION("6262D5489E21" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222D5489EA4F023010000" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262D5589E21" , vfnmsub132pd(zmm28, zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262D5489E627F" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262D5489EA200200000" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262D5489E6280" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262D5489EA2C0DFFFFF" , vfnmsub132pd(zmm28, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262D5589E627F" , vfnmsub132pd(zmm28, zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262D5589EA200040000" , vfnmsub132pd(zmm28, zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262D5589E6280" , vfnmsub132pd(zmm28, zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262D5589EA2F8FBFFFF" , vfnmsub132pd(zmm28, zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F26D409EE6" , vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D429EE6" , k(k2).vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26DC29EE6" , k(k2).z().vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D109EE6" , rn_sae().vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D509EE6" , ru_sae().vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D309EE6" , rd_sae().vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D709EE6" , rz_sae().vfnmsub132ps(zmm4, zmm18, zmm6));
+ TEST_INSTRUCTION("62F26D409E21" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B26D409EA4F023010000" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F26D509E21" , vfnmsub132ps(zmm4, zmm18, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F26D409E627F" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F26D409EA200200000" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F26D409E6280" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F26D409EA2C0DFFFFF" , vfnmsub132ps(zmm4, zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F26D509E627F" , vfnmsub132ps(zmm4, zmm18, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F26D509EA200020000" , vfnmsub132ps(zmm4, zmm18, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F26D509E6280" , vfnmsub132ps(zmm4, zmm18, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F26D509EA2FCFDFFFF" , vfnmsub132ps(zmm4, zmm18, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6242A5089FD5" , vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A50E9FD5" , k(k6).vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A58E9FD5" , k(k6).z().vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A5189FD5" , rn_sae().vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A5589FD5" , ru_sae().vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A5389FD5" , rd_sae().vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6242A5789FD5" , rz_sae().vfnmsub132sd(xmm26, xmm11, xmm13));
+ TEST_INSTRUCTION("6262A5089F11" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222A5089F94F023010000" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262A5089F527F" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262A5089F9200040000" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262A5089F5280" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262A5089F92F8FBFFFF" , vfnmsub132sd(xmm26, xmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62824D009FF8" , vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D069FF8" , k(k6).vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D869FF8" , k(k6).z().vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D109FF8" , rn_sae().vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D509FF8" , ru_sae().vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D309FF8" , rd_sae().vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62824D709FF8" , rz_sae().vfnmsub132ss(xmm23, xmm22, xmm24));
+ TEST_INSTRUCTION("62E24D009F39" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A24D009FBCF023010000" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E24D009F7A7F" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E24D009FBA00020000" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E24D009F7A80" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E24D009FBAFCFDFFFF" , vfnmsub132ss(xmm23, xmm22, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C2ED40AEFB" , vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2ED42AEFB" , k(k2).vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2EDC2AEFB" , k(k2).z().vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2ED10AEFB" , rn_sae().vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2ED50AEFB" , ru_sae().vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2ED30AEFB" , rd_sae().vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62C2ED70AEFB" , rz_sae().vfnmsub213pd(zmm23, zmm18, zmm11));
+ TEST_INSTRUCTION("62E2ED40AE39" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2ED40AEBCF023010000" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2ED50AE39" , vfnmsub213pd(zmm23, zmm18, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2ED40AE7A7F" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2ED40AEBA00200000" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2ED40AE7A80" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2ED40AEBAC0DFFFFF" , vfnmsub213pd(zmm23, zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2ED50AE7A7F" , vfnmsub213pd(zmm23, zmm18, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2ED50AEBA00040000" , vfnmsub213pd(zmm23, zmm18, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED50AE7A80" , vfnmsub213pd(zmm23, zmm18, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED50AEBAF8FBFFFF" , vfnmsub213pd(zmm23, zmm18, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E21548AEEA" , vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E2154BAEEA" , k(k3).vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E215CBAEEA" , k(k3).z().vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E21518AEEA" , rn_sae().vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E21558AEEA" , ru_sae().vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E21538AEEA" , rd_sae().vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E21578AEEA" , rz_sae().vfnmsub213ps(zmm21, zmm13, zmm2));
+ TEST_INSTRUCTION("62E21548AE29" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A21548AEACF023010000" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E21558AE29" , vfnmsub213ps(zmm21, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E21548AE6A7F" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E21548AEAA00200000" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E21548AE6A80" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E21548AEAAC0DFFFFF" , vfnmsub213ps(zmm21, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E21558AE6A7F" , vfnmsub213ps(zmm21, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E21558AEAA00020000" , vfnmsub213ps(zmm21, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E21558AE6A80" , vfnmsub213ps(zmm21, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E21558AEAAFCFDFFFF" , vfnmsub213ps(zmm21, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6202C500AFEC" , vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C503AFEC" , k(k3).vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C583AFEC" , k(k3).z().vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C510AFEC" , rn_sae().vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C550AFEC" , ru_sae().vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C530AFEC" , rd_sae().vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6202C570AFEC" , rz_sae().vfnmsub213sd(xmm29, xmm23, xmm28));
+ TEST_INSTRUCTION("6262C500AF29" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222C500AFACF023010000" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262C500AF6A7F" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262C500AFAA00040000" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262C500AF6A80" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262C500AFAAF8FBFFFF" , vfnmsub213sd(xmm29, xmm23, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62521D00AFF4" , vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D04AFF4" , k(k4).vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D84AFF4" , k(k4).z().vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D10AFF4" , rn_sae().vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D50AFF4" , ru_sae().vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D30AFF4" , rd_sae().vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62521D70AFF4" , rz_sae().vfnmsub213ss(xmm14, xmm28, xmm12));
+ TEST_INSTRUCTION("62721D00AF31" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D00AFB4F023010000" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62721D00AF727F" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62721D00AFB200020000" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62721D00AF7280" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62721D00AFB2FCFDFFFF" , vfnmsub213ss(xmm14, xmm28, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6202DD48BEE8" , vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DD4FBEE8" , k(k7).vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DDCFBEE8" , k(k7).z().vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DD18BEE8" , rn_sae().vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DD58BEE8" , ru_sae().vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DD38BEE8" , rd_sae().vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6202DD78BEE8" , rz_sae().vfnmsub231pd(zmm29, zmm4, zmm24));
+ TEST_INSTRUCTION("6262DD48BE29" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222DD48BEACF023010000" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262DD58BE29" , vfnmsub231pd(zmm29, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262DD48BE6A7F" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262DD48BEAA00200000" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262DD48BE6A80" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262DD48BEAAC0DFFFFF" , vfnmsub231pd(zmm29, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262DD58BE6A7F" , vfnmsub231pd(zmm29, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262DD58BEAA00040000" , vfnmsub231pd(zmm29, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262DD58BE6A80" , vfnmsub231pd(zmm29, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262DD58BEAAF8FBFFFF" , vfnmsub231pd(zmm29, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62524D48BEC5" , vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524D4ABEC5" , k(k2).vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524DCABEC5" , k(k2).z().vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524D18BEC5" , rn_sae().vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524D58BEC5" , ru_sae().vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524D38BEC5" , rd_sae().vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62524D78BEC5" , rz_sae().vfnmsub231ps(zmm8, zmm6, zmm13));
+ TEST_INSTRUCTION("62724D48BE01" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62324D48BE84F023010000" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62724D58BE01" , vfnmsub231ps(zmm8, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62724D48BE427F" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62724D48BE8200200000" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62724D48BE4280" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62724D48BE82C0DFFFFF" , vfnmsub231ps(zmm8, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62724D58BE427F" , vfnmsub231ps(zmm8, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62724D58BE8200020000" , vfnmsub231ps(zmm8, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62724D58BE4280" , vfnmsub231ps(zmm8, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62724D58BE82FCFDFFFF" , vfnmsub231ps(zmm8, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D2DD00BFF6" , vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD01BFF6" , k(k1).vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD81BFF6" , k(k1).z().vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD10BFF6" , rn_sae().vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD50BFF6" , ru_sae().vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD30BFF6" , rd_sae().vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62D2DD70BFF6" , rz_sae().vfnmsub231sd(xmm6, xmm20, xmm14));
+ TEST_INSTRUCTION("62F2DD00BF31" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2DD00BFB4F023010000" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2DD00BF727F" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2DD00BFB200040000" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2DD00BF7280" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2DD00BFB2F8FBFFFF" , vfnmsub231sd(xmm6, xmm20, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62421508BFD2" , vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("6242150CBFD2" , k(k4).vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("6242158CBFD2" , k(k4).z().vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("62421518BFD2" , rn_sae().vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("62421558BFD2" , ru_sae().vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("62421538BFD2" , rd_sae().vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("62421578BFD2" , rz_sae().vfnmsub231ss(xmm26, xmm13, xmm10));
+ TEST_INSTRUCTION("62621508BF11" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62221508BF94F023010000" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62621508BF527F" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62621508BF9200020000" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62621508BF5280" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62621508BF92FCFDFFFF" , vfnmsub231ss(xmm26, xmm13, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6212FD4842F1" , vgetexppd(zmm14, zmm25));
+ TEST_INSTRUCTION("6212FD4D42F1" , k(k5).vgetexppd(zmm14, zmm25));
+ TEST_INSTRUCTION("6212FDCD42F1" , k(k5).z().vgetexppd(zmm14, zmm25));
+ TEST_INSTRUCTION("6212FD1842F1" , sae().vgetexppd(zmm14, zmm25));
+ TEST_INSTRUCTION("6272FD484231" , vgetexppd(zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232FD4842B4F023010000" , vgetexppd(zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272FD584231" , vgetexppd(zmm14, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272FD4842727F" , vgetexppd(zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272FD4842B200200000" , vgetexppd(zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272FD48427280" , vgetexppd(zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272FD4842B2C0DFFFFF" , vgetexppd(zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272FD5842727F" , vgetexppd(zmm14, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272FD5842B200040000" , vgetexppd(zmm14, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272FD58427280" , vgetexppd(zmm14, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272FD5842B2F8FBFFFF" , vgetexppd(zmm14, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F27D4842CE" , vgetexpps(zmm1, zmm6));
+ TEST_INSTRUCTION("62F27D4B42CE" , k(k3).vgetexpps(zmm1, zmm6));
+ TEST_INSTRUCTION("62F27DCB42CE" , k(k3).z().vgetexpps(zmm1, zmm6));
+ TEST_INSTRUCTION("62F27D1842CE" , sae().vgetexpps(zmm1, zmm6));
+ TEST_INSTRUCTION("62F27D484209" , vgetexpps(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D48428CF023010000" , vgetexpps(zmm1, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D584209" , vgetexpps(zmm1, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D48424A7F" , vgetexpps(zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D48428A00200000" , vgetexpps(zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D48424A80" , vgetexpps(zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D48428AC0DFFFFF" , vgetexpps(zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D58424A7F" , vgetexpps(zmm1, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D58428A00020000" , vgetexpps(zmm1, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D58424A80" , vgetexpps(zmm1, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D58428AFCFDFFFF" , vgetexpps(zmm1, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2C50843D2" , vgetexpsd(xmm2, xmm7, xmm2));
+ TEST_INSTRUCTION("62F2C50D43D2" , k(k5).vgetexpsd(xmm2, xmm7, xmm2));
+ TEST_INSTRUCTION("62F2C58D43D2" , k(k5).z().vgetexpsd(xmm2, xmm7, xmm2));
+ TEST_INSTRUCTION("62F2C51843D2" , sae().vgetexpsd(xmm2, xmm7, xmm2));
+ TEST_INSTRUCTION("62F2C5084311" , vgetexpsd(xmm2, xmm7, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2C5084394F023010000" , vgetexpsd(xmm2, xmm7, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2C50843527F" , vgetexpsd(xmm2, xmm7, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2C508439200040000" , vgetexpsd(xmm2, xmm7, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2C508435280" , vgetexpsd(xmm2, xmm7, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2C5084392F8FBFFFF" , vgetexpsd(xmm2, xmm7, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6282750843E2" , vgetexpss(xmm20, xmm1, xmm26));
+ TEST_INSTRUCTION("6282750F43E2" , k(k7).vgetexpss(xmm20, xmm1, xmm26));
+ TEST_INSTRUCTION("6282758F43E2" , k(k7).z().vgetexpss(xmm20, xmm1, xmm26));
+ TEST_INSTRUCTION("6282751843E2" , sae().vgetexpss(xmm20, xmm1, xmm26));
+ TEST_INSTRUCTION("62E275084321" , vgetexpss(xmm20, xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2750843A4F023010000" , vgetexpss(xmm20, xmm1, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2750843627F" , vgetexpss(xmm20, xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E2750843A200020000" , vgetexpss(xmm20, xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E27508436280" , vgetexpss(xmm20, xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E2750843A2FCFDFFFF" , vgetexpss(xmm20, xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6293FD4826D2AB" , vgetmantpd(zmm2, zmm26, 171));
+ TEST_INSTRUCTION("6293FD4F26D2AB" , k(k7).vgetmantpd(zmm2, zmm26, 171));
+ TEST_INSTRUCTION("6293FDCF26D2AB" , k(k7).z().vgetmantpd(zmm2, zmm26, 171));
+ TEST_INSTRUCTION("6293FD1826D2AB" , sae().vgetmantpd(zmm2, zmm26, 171));
+ TEST_INSTRUCTION("6293FD4826D27B" , vgetmantpd(zmm2, zmm26, 123));
+ TEST_INSTRUCTION("6293FD1826D27B" , sae().vgetmantpd(zmm2, zmm26, 123));
+ TEST_INSTRUCTION("62F3FD4826117B" , vgetmantpd(zmm2, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3FD482694F0230100007B" , vgetmantpd(zmm2, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3FD5826117B" , vgetmantpd(zmm2, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD4826527F7B" , vgetmantpd(zmm2, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F3FD482692002000007B" , vgetmantpd(zmm2, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F3FD482652807B" , vgetmantpd(zmm2, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F3FD482692C0DFFFFF7B" , vgetmantpd(zmm2, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F3FD5826527F7B" , vgetmantpd(zmm2, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD582692000400007B" , vgetmantpd(zmm2, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD582652807B" , vgetmantpd(zmm2, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD582692F8FBFFFF7B" , vgetmantpd(zmm2, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62837D4826F4AB" , vgetmantps(zmm22, zmm28, 171));
+ TEST_INSTRUCTION("62837D4B26F4AB" , k(k3).vgetmantps(zmm22, zmm28, 171));
+ TEST_INSTRUCTION("62837DCB26F4AB" , k(k3).z().vgetmantps(zmm22, zmm28, 171));
+ TEST_INSTRUCTION("62837D1826F4AB" , sae().vgetmantps(zmm22, zmm28, 171));
+ TEST_INSTRUCTION("62837D4826F47B" , vgetmantps(zmm22, zmm28, 123));
+ TEST_INSTRUCTION("62837D1826F47B" , sae().vgetmantps(zmm22, zmm28, 123));
+ TEST_INSTRUCTION("62E37D4826317B" , vgetmantps(zmm22, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A37D4826B4F0230100007B" , vgetmantps(zmm22, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62E37D5826317B" , vgetmantps(zmm22, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62E37D4826727F7B" , vgetmantps(zmm22, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E37D4826B2002000007B" , vgetmantps(zmm22, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E37D482672807B" , vgetmantps(zmm22, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E37D4826B2C0DFFFFF7B" , vgetmantps(zmm22, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E37D5826727F7B" , vgetmantps(zmm22, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62E37D5826B2000200007B" , vgetmantps(zmm22, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62E37D582672807B" , vgetmantps(zmm22, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62E37D5826B2FCFDFFFF7B" , vgetmantps(zmm22, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D3A50027D8AB" , vgetmantsd(xmm3, xmm27, xmm8, 171));
+ TEST_INSTRUCTION("62D3A50627D8AB" , k(k6).vgetmantsd(xmm3, xmm27, xmm8, 171));
+ TEST_INSTRUCTION("62D3A58627D8AB" , k(k6).z().vgetmantsd(xmm3, xmm27, xmm8, 171));
+ TEST_INSTRUCTION("62D3A51027D8AB" , sae().vgetmantsd(xmm3, xmm27, xmm8, 171));
+ TEST_INSTRUCTION("62D3A50027D87B" , vgetmantsd(xmm3, xmm27, xmm8, 123));
+ TEST_INSTRUCTION("62D3A51027D87B" , sae().vgetmantsd(xmm3, xmm27, xmm8, 123));
+ TEST_INSTRUCTION("62F3A50027197B" , vgetmantsd(xmm3, xmm27, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3A500279CF0230100007B" , vgetmantsd(xmm3, xmm27, qword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3A500275A7F7B" , vgetmantsd(xmm3, xmm27, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62F3A500279A000400007B" , vgetmantsd(xmm3, xmm27, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62F3A500275A807B" , vgetmantsd(xmm3, xmm27, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62F3A500279AF8FBFFFF7B" , vgetmantsd(xmm3, xmm27, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62D36D0827DCAB" , vgetmantss(xmm3, xmm2, xmm12, 171));
+ TEST_INSTRUCTION("62D36D0F27DCAB" , k(k7).vgetmantss(xmm3, xmm2, xmm12, 171));
+ TEST_INSTRUCTION("62D36D8F27DCAB" , k(k7).z().vgetmantss(xmm3, xmm2, xmm12, 171));
+ TEST_INSTRUCTION("62D36D1827DCAB" , sae().vgetmantss(xmm3, xmm2, xmm12, 171));
+ TEST_INSTRUCTION("62D36D0827DC7B" , vgetmantss(xmm3, xmm2, xmm12, 123));
+ TEST_INSTRUCTION("62D36D1827DC7B" , sae().vgetmantss(xmm3, xmm2, xmm12, 123));
+ TEST_INSTRUCTION("62F36D0827197B" , vgetmantss(xmm3, xmm2, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B36D08279CF0230100007B" , vgetmantss(xmm3, xmm2, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F36D08275A7F7B" , vgetmantss(xmm3, xmm2, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62F36D08279A000200007B" , vgetmantss(xmm3, xmm2, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62F36D08275A807B" , vgetmantss(xmm3, xmm2, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62F36D08279AFCFDFFFF7B" , vgetmantss(xmm3, xmm2, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62732D4018DBAB" , vinsertf32x4(zmm11, zmm26, xmm3, 171));
+ TEST_INSTRUCTION("62732D4118DBAB" , k(k1).vinsertf32x4(zmm11, zmm26, xmm3, 171));
+ TEST_INSTRUCTION("62732DC118DBAB" , k(k1).z().vinsertf32x4(zmm11, zmm26, xmm3, 171));
+ TEST_INSTRUCTION("62732D4018DB7B" , vinsertf32x4(zmm11, zmm26, xmm3, 123));
+ TEST_INSTRUCTION("62732D4018197B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62332D40189CF0230100007B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62732D40185A7F7B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rdx, 2032), 123));
+ TEST_INSTRUCTION("62732D40189A000800007B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rdx, 2048), 123));
+ TEST_INSTRUCTION("62732D40185A807B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rdx, -2048), 123));
+ TEST_INSTRUCTION("62732D40189AF0F7FFFF7B" , vinsertf32x4(zmm11, zmm26, xmmword_ptr(rdx, -2064), 123));
+ TEST_INSTRUCTION("62F3D5481ACFAB" , vinsertf64x4(zmm1, zmm5, ymm7, 171));
+ TEST_INSTRUCTION("62F3D5491ACFAB" , k(k1).vinsertf64x4(zmm1, zmm5, ymm7, 171));
+ TEST_INSTRUCTION("62F3D5C91ACFAB" , k(k1).z().vinsertf64x4(zmm1, zmm5, ymm7, 171));
+ TEST_INSTRUCTION("62F3D5481ACF7B" , vinsertf64x4(zmm1, zmm5, ymm7, 123));
+ TEST_INSTRUCTION("62F3D5481A097B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3D5481A8CF0230100007B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3D5481A4A7F7B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rdx, 4064), 123));
+ TEST_INSTRUCTION("62F3D5481A8A001000007B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rdx, 4096), 123));
+ TEST_INSTRUCTION("62F3D5481A4A807B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rdx, -4096), 123));
+ TEST_INSTRUCTION("62F3D5481A8AE0EFFFFF7B" , vinsertf64x4(zmm1, zmm5, ymmword_ptr(rdx, -4128), 123));
+ TEST_INSTRUCTION("62C3154838CAAB" , vinserti32x4(zmm17, zmm13, xmm10, 171));
+ TEST_INSTRUCTION("62C3154E38CAAB" , k(k6).vinserti32x4(zmm17, zmm13, xmm10, 171));
+ TEST_INSTRUCTION("62C315CE38CAAB" , k(k6).z().vinserti32x4(zmm17, zmm13, xmm10, 171));
+ TEST_INSTRUCTION("62C3154838CA7B" , vinserti32x4(zmm17, zmm13, xmm10, 123));
+ TEST_INSTRUCTION("62E3154838097B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A31548388CF0230100007B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62E31548384A7F7B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rdx, 2032), 123));
+ TEST_INSTRUCTION("62E31548388A000800007B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rdx, 2048), 123));
+ TEST_INSTRUCTION("62E31548384A807B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rdx, -2048), 123));
+ TEST_INSTRUCTION("62E31548388AF0F7FFFF7B" , vinserti32x4(zmm17, zmm13, xmmword_ptr(rdx, -2064), 123));
+ TEST_INSTRUCTION("62F3B5403AE4AB" , vinserti64x4(zmm4, zmm25, ymm4, 171));
+ TEST_INSTRUCTION("62F3B5413AE4AB" , k(k1).vinserti64x4(zmm4, zmm25, ymm4, 171));
+ TEST_INSTRUCTION("62F3B5C13AE4AB" , k(k1).z().vinserti64x4(zmm4, zmm25, ymm4, 171));
+ TEST_INSTRUCTION("62F3B5403AE47B" , vinserti64x4(zmm4, zmm25, ymm4, 123));
+ TEST_INSTRUCTION("62F3B5403A217B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3B5403AA4F0230100007B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3B5403A627F7B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rdx, 4064), 123));
+ TEST_INSTRUCTION("62F3B5403AA2001000007B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rdx, 4096), 123));
+ TEST_INSTRUCTION("62F3B5403A62807B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rdx, -4096), 123));
+ TEST_INSTRUCTION("62F3B5403AA2E0EFFFFF7B" , vinserti64x4(zmm4, zmm25, ymmword_ptr(rdx, -4128), 123));
+ TEST_INSTRUCTION("6263750021F5AB" , vinsertps(xmm30, xmm17, xmm5, 171));
+ TEST_INSTRUCTION("6263750021F57B" , vinsertps(xmm30, xmm17, xmm5, 123));
+ TEST_INSTRUCTION("6263750021317B" , vinsertps(xmm30, xmm17, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223750021B4F0230100007B" , vinsertps(xmm30, xmm17, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6263750021727F7B" , vinsertps(xmm30, xmm17, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("6263750021B2000200007B" , vinsertps(xmm30, xmm17, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("626375002172807B" , vinsertps(xmm30, xmm17, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("6263750021B2FCFDFFFF7B" , vinsertps(xmm30, xmm17, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62219D405FF4" , vmaxpd(zmm30, zmm28, zmm20));
+ TEST_INSTRUCTION("62219D415FF4" , k(k1).vmaxpd(zmm30, zmm28, zmm20));
+ TEST_INSTRUCTION("62219DC15FF4" , k(k1).z().vmaxpd(zmm30, zmm28, zmm20));
+ TEST_INSTRUCTION("62219D105FF4" , sae().vmaxpd(zmm30, zmm28, zmm20));
+ TEST_INSTRUCTION("62619D405F31" , vmaxpd(zmm30, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62219D405FB4F023010000" , vmaxpd(zmm30, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62619D505F31" , vmaxpd(zmm30, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62619D405F727F" , vmaxpd(zmm30, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62619D405FB200200000" , vmaxpd(zmm30, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62619D405F7280" , vmaxpd(zmm30, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62619D405FB2C0DFFFFF" , vmaxpd(zmm30, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62619D505F727F" , vmaxpd(zmm30, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62619D505FB200040000" , vmaxpd(zmm30, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62619D505F7280" , vmaxpd(zmm30, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62619D505FB2F8FBFFFF" , vmaxpd(zmm30, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62214C485FCC" , vmaxps(zmm25, zmm6, zmm20));
+ TEST_INSTRUCTION("62214C495FCC" , k(k1).vmaxps(zmm25, zmm6, zmm20));
+ TEST_INSTRUCTION("62214CC95FCC" , k(k1).z().vmaxps(zmm25, zmm6, zmm20));
+ TEST_INSTRUCTION("62214C185FCC" , sae().vmaxps(zmm25, zmm6, zmm20));
+ TEST_INSTRUCTION("62614C485F09" , vmaxps(zmm25, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62214C485F8CF023010000" , vmaxps(zmm25, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62614C585F09" , vmaxps(zmm25, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62614C485F4A7F" , vmaxps(zmm25, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62614C485F8A00200000" , vmaxps(zmm25, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62614C485F4A80" , vmaxps(zmm25, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62614C485F8AC0DFFFFF" , vmaxps(zmm25, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62614C585F4A7F" , vmaxps(zmm25, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62614C585F8A00020000" , vmaxps(zmm25, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62614C585F4A80" , vmaxps(zmm25, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62614C585F8AFCFDFFFF" , vmaxps(zmm25, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6281E7005FE1" , vmaxsd(xmm20, xmm19, xmm25));
+ TEST_INSTRUCTION("6281E7035FE1" , k(k3).vmaxsd(xmm20, xmm19, xmm25));
+ TEST_INSTRUCTION("6281E7835FE1" , k(k3).z().vmaxsd(xmm20, xmm19, xmm25));
+ TEST_INSTRUCTION("6281E7105FE1" , sae().vmaxsd(xmm20, xmm19, xmm25));
+ TEST_INSTRUCTION("62E1E7005F21" , vmaxsd(xmm20, xmm19, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1E7005FA4F023010000" , vmaxsd(xmm20, xmm19, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1E7005F627F" , vmaxsd(xmm20, xmm19, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1E7005FA200040000" , vmaxsd(xmm20, xmm19, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1E7005F6280" , vmaxsd(xmm20, xmm19, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1E7005FA2F8FBFFFF" , vmaxsd(xmm20, xmm19, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C55A5FC6" , vmaxss(xmm8, xmm4, xmm6));
+ TEST_INSTRUCTION("62715E0C5FC6" , k(k4).vmaxss(xmm8, xmm4, xmm6));
+ TEST_INSTRUCTION("62715E8C5FC6" , k(k4).z().vmaxss(xmm8, xmm4, xmm6));
+ TEST_INSTRUCTION("62715E185FC6" , sae().vmaxss(xmm8, xmm4, xmm6));
+ TEST_INSTRUCTION("C55A5F01" , vmaxss(xmm8, xmm4, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4215A5F84F023010000" , vmaxss(xmm8, xmm4, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C55A5F82FC010000" , vmaxss(xmm8, xmm4, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C55A5F8200020000" , vmaxss(xmm8, xmm4, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C55A5F8200FEFFFF" , vmaxss(xmm8, xmm4, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C55A5F82FCFDFFFF" , vmaxss(xmm8, xmm4, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B1CD485DF6" , vminpd(zmm6, zmm6, zmm22));
+ TEST_INSTRUCTION("62B1CD4F5DF6" , k(k7).vminpd(zmm6, zmm6, zmm22));
+ TEST_INSTRUCTION("62B1CDCF5DF6" , k(k7).z().vminpd(zmm6, zmm6, zmm22));
+ TEST_INSTRUCTION("62B1CD185DF6" , sae().vminpd(zmm6, zmm6, zmm22));
+ TEST_INSTRUCTION("62F1CD485D31" , vminpd(zmm6, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1CD485DB4F023010000" , vminpd(zmm6, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1CD585D31" , vminpd(zmm6, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1CD485D727F" , vminpd(zmm6, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1CD485DB200200000" , vminpd(zmm6, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1CD485D7280" , vminpd(zmm6, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1CD485DB2C0DFFFFF" , vminpd(zmm6, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1CD585D727F" , vminpd(zmm6, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1CD585DB200040000" , vminpd(zmm6, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1CD585D7280" , vminpd(zmm6, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1CD585DB2F8FBFFFF" , vminpd(zmm6, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F164485DDF" , vminps(zmm3, zmm3, zmm7));
+ TEST_INSTRUCTION("62F1644B5DDF" , k(k3).vminps(zmm3, zmm3, zmm7));
+ TEST_INSTRUCTION("62F164CB5DDF" , k(k3).z().vminps(zmm3, zmm3, zmm7));
+ TEST_INSTRUCTION("62F164185DDF" , sae().vminps(zmm3, zmm3, zmm7));
+ TEST_INSTRUCTION("62F164485D19" , vminps(zmm3, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B164485D9CF023010000" , vminps(zmm3, zmm3, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F164585D19" , vminps(zmm3, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F164485D5A7F" , vminps(zmm3, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F164485D9A00200000" , vminps(zmm3, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F164485D5A80" , vminps(zmm3, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F164485D9AC0DFFFFF" , vminps(zmm3, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F164585D5A7F" , vminps(zmm3, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F164585D9A00020000" , vminps(zmm3, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F164585D5A80" , vminps(zmm3, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F164585D9AFCFDFFFF" , vminps(zmm3, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6291B7005DEA" , vminsd(xmm5, xmm25, xmm26));
+ TEST_INSTRUCTION("6291B7035DEA" , k(k3).vminsd(xmm5, xmm25, xmm26));
+ TEST_INSTRUCTION("6291B7835DEA" , k(k3).z().vminsd(xmm5, xmm25, xmm26));
+ TEST_INSTRUCTION("6291B7105DEA" , sae().vminsd(xmm5, xmm25, xmm26));
+ TEST_INSTRUCTION("62F1B7005D29" , vminsd(xmm5, xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1B7005DACF023010000" , vminsd(xmm5, xmm25, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1B7005D6A7F" , vminsd(xmm5, xmm25, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1B7005DAA00040000" , vminsd(xmm5, xmm25, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1B7005D6A80" , vminsd(xmm5, xmm25, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1B7005DAAF8FBFFFF" , vminsd(xmm5, xmm25, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("623176005DD3" , vminss(xmm10, xmm17, xmm19));
+ TEST_INSTRUCTION("623176055DD3" , k(k5).vminss(xmm10, xmm17, xmm19));
+ TEST_INSTRUCTION("623176855DD3" , k(k5).z().vminss(xmm10, xmm17, xmm19));
+ TEST_INSTRUCTION("623176105DD3" , sae().vminss(xmm10, xmm17, xmm19));
+ TEST_INSTRUCTION("627176005D11" , vminss(xmm10, xmm17, dword_ptr(rcx)));
+ TEST_INSTRUCTION("623176005D94F023010000" , vminss(xmm10, xmm17, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("627176005D527F" , vminss(xmm10, xmm17, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("627176005D9200020000" , vminss(xmm10, xmm17, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("627176005D5280" , vminss(xmm10, xmm17, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("627176005D92FCFDFFFF" , vminss(xmm10, xmm17, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62D1FD4828FE" , vmovapd(zmm7, zmm14));
+ TEST_INSTRUCTION("62D1FD4D28FE" , k(k5).vmovapd(zmm7, zmm14));
+ TEST_INSTRUCTION("62D1FDCD28FE" , k(k5).z().vmovapd(zmm7, zmm14));
+ TEST_INSTRUCTION("62F1FD482839" , vmovapd(zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FD4828BCF023010000" , vmovapd(zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FD48287A7F" , vmovapd(zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FD4828BA00200000" , vmovapd(zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FD48287A80" , vmovapd(zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FD4828BAC0DFFFFF" , vmovapd(zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62D17C4828E9" , vmovaps(zmm5, zmm9));
+ TEST_INSTRUCTION("62D17C4928E9" , k(k1).vmovaps(zmm5, zmm9));
+ TEST_INSTRUCTION("62D17CC928E9" , k(k1).z().vmovaps(zmm5, zmm9));
+ TEST_INSTRUCTION("62F17C482829" , vmovaps(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17C4828ACF023010000" , vmovaps(zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17C48286A7F" , vmovaps(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17C4828AA00200000" , vmovaps(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17C48286A80" , vmovaps(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17C4828AAC0DFFFFF" , vmovaps(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62617D086ED0" , vmovd(xmm26, eax));
+ TEST_INSTRUCTION("62617D086ED5" , vmovd(xmm26, ebp));
+ TEST_INSTRUCTION("62417D086ED5" , vmovd(xmm26, r13d));
+ TEST_INSTRUCTION("62617D086E11" , vmovd(xmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62217D086E94F023010000" , vmovd(xmm26, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62617D086E527F" , vmovd(xmm26, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62617D086E9200020000" , vmovd(xmm26, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62617D086E5280" , vmovd(xmm26, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62617D086E92FCFDFFFF" , vmovd(xmm26, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C5F97E29" , vmovd(dword_ptr(rcx), xmm5));
+ TEST_INSTRUCTION("C4A1797EACF023010000" , vmovd(dword_ptr(rax, r14, 3, 291), xmm5));
+ TEST_INSTRUCTION("C5F97EAAFC010000" , vmovd(dword_ptr(rdx, 508), xmm5));
+ TEST_INSTRUCTION("C5F97EAA00020000" , vmovd(dword_ptr(rdx, 512), xmm5));
+ TEST_INSTRUCTION("C5F97EAA00FEFFFF" , vmovd(dword_ptr(rdx, -512), xmm5));
+ TEST_INSTRUCTION("C5F97EAAFCFDFFFF" , vmovd(dword_ptr(rdx, -516), xmm5));
+ TEST_INSTRUCTION("6291FF4812ED" , vmovddup(zmm5, zmm29));
+ TEST_INSTRUCTION("6291FF4C12ED" , k(k4).vmovddup(zmm5, zmm29));
+ TEST_INSTRUCTION("6291FFCC12ED" , k(k4).z().vmovddup(zmm5, zmm29));
+ TEST_INSTRUCTION("62F1FF481229" , vmovddup(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF4812ACF023010000" , vmovddup(zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FF48126A7F" , vmovddup(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FF4812AA00200000" , vmovddup(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FF48126A80" , vmovddup(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FF4812AAC0DFFFFF" , vmovddup(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62A17D486FF2" , vmovdqa32(zmm22, zmm18));
+ TEST_INSTRUCTION("62A17D4E6FF2" , k(k6).vmovdqa32(zmm22, zmm18));
+ TEST_INSTRUCTION("62A17DCE6FF2" , k(k6).z().vmovdqa32(zmm22, zmm18));
+ TEST_INSTRUCTION("62E17D486F31" , vmovdqa32(zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17D486FB4F023010000" , vmovdqa32(zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17D486F727F" , vmovdqa32(zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17D486FB200200000" , vmovdqa32(zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17D486F7280" , vmovdqa32(zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17D486FB2C0DFFFFF" , vmovdqa32(zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62C1FD486FF4" , vmovdqa64(zmm22, zmm12));
+ TEST_INSTRUCTION("62C1FD4D6FF4" , k(k5).vmovdqa64(zmm22, zmm12));
+ TEST_INSTRUCTION("62C1FDCD6FF4" , k(k5).z().vmovdqa64(zmm22, zmm12));
+ TEST_INSTRUCTION("62E1FD486F31" , vmovdqa64(zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD486FB4F023010000" , vmovdqa64(zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1FD486F727F" , vmovdqa64(zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD486FB200200000" , vmovdqa64(zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD486F7280" , vmovdqa64(zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD486FB2C0DFFFFF" , vmovdqa64(zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62917E486FE8" , vmovdqu32(zmm5, zmm24));
+ TEST_INSTRUCTION("62917E4D6FE8" , k(k5).vmovdqu32(zmm5, zmm24));
+ TEST_INSTRUCTION("62917ECD6FE8" , k(k5).z().vmovdqu32(zmm5, zmm24));
+ TEST_INSTRUCTION("62F17E486F29" , vmovdqu32(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E486FACF023010000" , vmovdqu32(zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17E486F6A7F" , vmovdqu32(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17E486FAA00200000" , vmovdqu32(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17E486F6A80" , vmovdqu32(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17E486FAAC0DFFFFF" , vmovdqu32(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62D1FE486FF7" , vmovdqu64(zmm6, zmm15));
+ TEST_INSTRUCTION("62D1FE4B6FF7" , k(k3).vmovdqu64(zmm6, zmm15));
+ TEST_INSTRUCTION("62D1FECB6FF7" , k(k3).z().vmovdqu64(zmm6, zmm15));
+ TEST_INSTRUCTION("62F1FE486F31" , vmovdqu64(zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FE486FB4F023010000" , vmovdqu64(zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FE486F727F" , vmovdqu64(zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FE486FB200200000" , vmovdqu64(zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FE486F7280" , vmovdqu64(zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FE486FB2C0DFFFFF" , vmovdqu64(zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62A1740812D7" , vmovhlps(xmm18, xmm1, xmm23));
+ TEST_INSTRUCTION("62E19D001619" , vmovhpd(xmm19, xmm28, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A19D00169CF023010000" , vmovhpd(xmm19, xmm28, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E19D00165A7F" , vmovhpd(xmm19, xmm28, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E19D00169A00040000" , vmovhpd(xmm19, xmm28, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E19D00165A80" , vmovhpd(xmm19, xmm28, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E19D00169AF8FBFFFF" , vmovhpd(xmm19, xmm28, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5791739" , vmovhpd(qword_ptr(rcx), xmm15));
+ TEST_INSTRUCTION("C4217917BCF023010000" , vmovhpd(qword_ptr(rax, r14, 3, 291), xmm15));
+ TEST_INSTRUCTION("C57917BAF8030000" , vmovhpd(qword_ptr(rdx, 1016), xmm15));
+ TEST_INSTRUCTION("C57917BA00040000" , vmovhpd(qword_ptr(rdx, 1024), xmm15));
+ TEST_INSTRUCTION("C57917BA00FCFFFF" , vmovhpd(qword_ptr(rdx, -1024), xmm15));
+ TEST_INSTRUCTION("C57917BAF8FBFFFF" , vmovhpd(qword_ptr(rdx, -1032), xmm15));
+ TEST_INSTRUCTION("62E174001621" , vmovhps(xmm20, xmm17, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1740016A4F023010000" , vmovhps(xmm20, xmm17, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1740016627F" , vmovhps(xmm20, xmm17, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1740016A200040000" , vmovhps(xmm20, xmm17, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E17400166280" , vmovhps(xmm20, xmm17, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1740016A2F8FBFFFF" , vmovhps(xmm20, xmm17, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E17C081711" , vmovhps(qword_ptr(rcx), xmm18));
+ TEST_INSTRUCTION("62A17C081794F023010000" , vmovhps(qword_ptr(rax, r14, 3, 291), xmm18));
+ TEST_INSTRUCTION("62E17C0817527F" , vmovhps(qword_ptr(rdx, 1016), xmm18));
+ TEST_INSTRUCTION("62E17C08179200040000" , vmovhps(qword_ptr(rdx, 1024), xmm18));
+ TEST_INSTRUCTION("62E17C08175280" , vmovhps(qword_ptr(rdx, -1024), xmm18));
+ TEST_INSTRUCTION("62E17C081792F8FBFFFF" , vmovhps(qword_ptr(rdx, -1032), xmm18));
+ TEST_INSTRUCTION("6211140816EC" , vmovlhps(xmm13, xmm13, xmm28));
+ TEST_INSTRUCTION("6261CD081229" , vmovlpd(xmm29, xmm6, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221CD0812ACF023010000" , vmovlpd(xmm29, xmm6, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261CD08126A7F" , vmovlpd(xmm29, xmm6, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261CD0812AA00040000" , vmovlpd(xmm29, xmm6, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261CD08126A80" , vmovlpd(xmm29, xmm6, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261CD0812AAF8FBFFFF" , vmovlpd(xmm29, xmm6, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5791339" , vmovlpd(qword_ptr(rcx), xmm15));
+ TEST_INSTRUCTION("C4217913BCF023010000" , vmovlpd(qword_ptr(rax, r14, 3, 291), xmm15));
+ TEST_INSTRUCTION("C57913BAF8030000" , vmovlpd(qword_ptr(rdx, 1016), xmm15));
+ TEST_INSTRUCTION("C57913BA00040000" , vmovlpd(qword_ptr(rdx, 1024), xmm15));
+ TEST_INSTRUCTION("C57913BA00FCFFFF" , vmovlpd(qword_ptr(rdx, -1024), xmm15));
+ TEST_INSTRUCTION("C57913BAF8FBFFFF" , vmovlpd(qword_ptr(rdx, -1032), xmm15));
+ TEST_INSTRUCTION("62F15C001239" , vmovlps(xmm7, xmm20, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B15C0012BCF023010000" , vmovlps(xmm7, xmm20, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F15C00127A7F" , vmovlps(xmm7, xmm20, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F15C0012BA00040000" , vmovlps(xmm7, xmm20, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F15C00127A80" , vmovlps(xmm7, xmm20, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F15C0012BAF8FBFFFF" , vmovlps(xmm7, xmm20, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62617C081319" , vmovlps(qword_ptr(rcx), xmm27));
+ TEST_INSTRUCTION("62217C08139CF023010000" , vmovlps(qword_ptr(rax, r14, 3, 291), xmm27));
+ TEST_INSTRUCTION("62617C08135A7F" , vmovlps(qword_ptr(rdx, 1016), xmm27));
+ TEST_INSTRUCTION("62617C08139A00040000" , vmovlps(qword_ptr(rdx, 1024), xmm27));
+ TEST_INSTRUCTION("62617C08135A80" , vmovlps(qword_ptr(rdx, -1024), xmm27));
+ TEST_INSTRUCTION("62617C08139AF8FBFFFF" , vmovlps(qword_ptr(rdx, -1032), xmm27));
+ TEST_INSTRUCTION("62617D48E701" , vmovntdq(zmmword_ptr(rcx), zmm24));
+ TEST_INSTRUCTION("62217D48E784F023010000" , vmovntdq(zmmword_ptr(rax, r14, 3, 291), zmm24));
+ TEST_INSTRUCTION("62617D48E7427F" , vmovntdq(zmmword_ptr(rdx, 8128), zmm24));
+ TEST_INSTRUCTION("62617D48E78200200000" , vmovntdq(zmmword_ptr(rdx, 8192), zmm24));
+ TEST_INSTRUCTION("62617D48E74280" , vmovntdq(zmmword_ptr(rdx, -8192), zmm24));
+ TEST_INSTRUCTION("62617D48E782C0DFFFFF" , vmovntdq(zmmword_ptr(rdx, -8256), zmm24));
+ TEST_INSTRUCTION("62E27D482A09" , vmovntdqa(zmm17, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D482A8CF023010000" , vmovntdqa(zmm17, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D482A4A7F" , vmovntdqa(zmm17, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E27D482A8A00200000" , vmovntdqa(zmm17, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E27D482A4A80" , vmovntdqa(zmm17, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E27D482A8AC0DFFFFF" , vmovntdqa(zmm17, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FD482B09" , vmovntpd(zmmword_ptr(rcx), zmm17));
+ TEST_INSTRUCTION("62A1FD482B8CF023010000" , vmovntpd(zmmword_ptr(rax, r14, 3, 291), zmm17));
+ TEST_INSTRUCTION("62E1FD482B4A7F" , vmovntpd(zmmword_ptr(rdx, 8128), zmm17));
+ TEST_INSTRUCTION("62E1FD482B8A00200000" , vmovntpd(zmmword_ptr(rdx, 8192), zmm17));
+ TEST_INSTRUCTION("62E1FD482B4A80" , vmovntpd(zmmword_ptr(rdx, -8192), zmm17));
+ TEST_INSTRUCTION("62E1FD482B8AC0DFFFFF" , vmovntpd(zmmword_ptr(rdx, -8256), zmm17));
+ TEST_INSTRUCTION("62F17C482B29" , vmovntps(zmmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62B17C482BACF023010000" , vmovntps(zmmword_ptr(rax, r14, 3, 291), zmm5));
+ TEST_INSTRUCTION("62F17C482B6A7F" , vmovntps(zmmword_ptr(rdx, 8128), zmm5));
+ TEST_INSTRUCTION("62F17C482BAA00200000" , vmovntps(zmmword_ptr(rdx, 8192), zmm5));
+ TEST_INSTRUCTION("62F17C482B6A80" , vmovntps(zmmword_ptr(rdx, -8192), zmm5));
+ TEST_INSTRUCTION("62F17C482BAAC0DFFFFF" , vmovntps(zmmword_ptr(rdx, -8256), zmm5));
+ TEST_INSTRUCTION("6261FF081009" , vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6261FF0B1009" , k(k3).vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6261FF8B1009" , k(k3).z().vmovsd(xmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FF08108CF023010000" , vmovsd(xmm25, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261FF08104A7F" , vmovsd(xmm25, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261FF08108A00040000" , vmovsd(xmm25, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261FF08104A80" , vmovsd(xmm25, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261FF08108AF8FBFFFF" , vmovsd(xmm25, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6261FF081109" , vmovsd(qword_ptr(rcx), xmm25));
+ TEST_INSTRUCTION("6261FF0A1109" , k(k2).vmovsd(qword_ptr(rcx), xmm25));
+ TEST_INSTRUCTION("6221FF08118CF023010000" , vmovsd(qword_ptr(rax, r14, 3, 291), xmm25));
+ TEST_INSTRUCTION("6261FF08114A7F" , vmovsd(qword_ptr(rdx, 1016), xmm25));
+ TEST_INSTRUCTION("6261FF08118A00040000" , vmovsd(qword_ptr(rdx, 1024), xmm25));
+ TEST_INSTRUCTION("6261FF08114A80" , vmovsd(qword_ptr(rdx, -1024), xmm25));
+ TEST_INSTRUCTION("6261FF08118AF8FBFFFF" , vmovsd(qword_ptr(rdx, -1032), xmm25));
+ TEST_INSTRUCTION("6221E70810DB" , vmovsd(xmm27, xmm3, xmm19));
+ TEST_INSTRUCTION("6221E70B10DB" , k(k3).vmovsd(xmm27, xmm3, xmm19));
+ TEST_INSTRUCTION("6221E78B10DB" , k(k3).z().vmovsd(xmm27, xmm3, xmm19));
+ TEST_INSTRUCTION("62817E4816C3" , vmovshdup(zmm16, zmm27));
+ TEST_INSTRUCTION("62817E4C16C3" , k(k4).vmovshdup(zmm16, zmm27));
+ TEST_INSTRUCTION("62817ECC16C3" , k(k4).z().vmovshdup(zmm16, zmm27));
+ TEST_INSTRUCTION("62E17E481601" , vmovshdup(zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E481684F023010000" , vmovshdup(zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17E4816427F" , vmovshdup(zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17E48168200200000" , vmovshdup(zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17E48164280" , vmovshdup(zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17E481682C0DFFFFF" , vmovshdup(zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62517E4812EE" , vmovsldup(zmm13, zmm14));
+ TEST_INSTRUCTION("62517E4E12EE" , k(k6).vmovsldup(zmm13, zmm14));
+ TEST_INSTRUCTION("62517ECE12EE" , k(k6).z().vmovsldup(zmm13, zmm14));
+ TEST_INSTRUCTION("62717E481229" , vmovsldup(zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E4812ACF023010000" , vmovsldup(zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717E48126A7F" , vmovsldup(zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717E4812AA00200000" , vmovsldup(zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717E48126A80" , vmovsldup(zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717E4812AAC0DFFFFF" , vmovsldup(zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("C5FA1011" , vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E0C1011" , k(k4).vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E8C1011" , k(k4).z().vmovss(xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A17A1094F023010000" , vmovss(xmm2, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5FA1092FC010000" , vmovss(xmm2, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5FA109200020000" , vmovss(xmm2, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5FA109200FEFFFF" , vmovss(xmm2, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5FA1092FCFDFFFF" , vmovss(xmm2, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C5FA1129" , vmovss(dword_ptr(rcx), xmm5));
+ TEST_INSTRUCTION("62F17E0E1129" , k(k6).vmovss(dword_ptr(rcx), xmm5));
+ TEST_INSTRUCTION("C4A17A11ACF023010000" , vmovss(dword_ptr(rax, r14, 3, 291), xmm5));
+ TEST_INSTRUCTION("C5FA11AAFC010000" , vmovss(dword_ptr(rdx, 508), xmm5));
+ TEST_INSTRUCTION("C5FA11AA00020000" , vmovss(dword_ptr(rdx, 512), xmm5));
+ TEST_INSTRUCTION("C5FA11AA00FEFFFF" , vmovss(dword_ptr(rdx, -512), xmm5));
+ TEST_INSTRUCTION("C5FA11AAFCFDFFFF" , vmovss(dword_ptr(rdx, -516), xmm5));
+ TEST_INSTRUCTION("6201360810E2" , vmovss(xmm28, xmm9, xmm26));
+ TEST_INSTRUCTION("6201360C10E2" , k(k4).vmovss(xmm28, xmm9, xmm26));
+ TEST_INSTRUCTION("6201368C10E2" , k(k4).z().vmovss(xmm28, xmm9, xmm26));
+ TEST_INSTRUCTION("6241FD4810D9" , vmovupd(zmm27, zmm9));
+ TEST_INSTRUCTION("6241FD4A10D9" , k(k2).vmovupd(zmm27, zmm9));
+ TEST_INSTRUCTION("6241FDCA10D9" , k(k2).z().vmovupd(zmm27, zmm9));
+ TEST_INSTRUCTION("6261FD481019" , vmovupd(zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FD48109CF023010000" , vmovupd(zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261FD48105A7F" , vmovupd(zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261FD48109A00200000" , vmovupd(zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261FD48105A80" , vmovupd(zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261FD48109AC0DFFFFF" , vmovupd(zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62A17C4810F6" , vmovups(zmm22, zmm22));
+ TEST_INSTRUCTION("62A17C4B10F6" , k(k3).vmovups(zmm22, zmm22));
+ TEST_INSTRUCTION("62A17CCB10F6" , k(k3).z().vmovups(zmm22, zmm22));
+ TEST_INSTRUCTION("62E17C481031" , vmovups(zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17C4810B4F023010000" , vmovups(zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17C4810727F" , vmovups(zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17C4810B200200000" , vmovups(zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17C48107280" , vmovups(zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17C4810B2C0DFFFFF" , vmovups(zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6221DD4859C7" , vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DD4E59C7" , k(k6).vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DDCE59C7" , k(k6).z().vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DD1859C7" , rn_sae().vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DD5859C7" , ru_sae().vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DD3859C7" , rd_sae().vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6221DD7859C7" , rz_sae().vmulpd(zmm24, zmm4, zmm23));
+ TEST_INSTRUCTION("6261DD485901" , vmulpd(zmm24, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221DD485984F023010000" , vmulpd(zmm24, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261DD585901" , vmulpd(zmm24, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261DD4859427F" , vmulpd(zmm24, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261DD48598200200000" , vmulpd(zmm24, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261DD48594280" , vmulpd(zmm24, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261DD485982C0DFFFFF" , vmulpd(zmm24, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261DD5859427F" , vmulpd(zmm24, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261DD58598200040000" , vmulpd(zmm24, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261DD58594280" , vmulpd(zmm24, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261DD585982F8FBFFFF" , vmulpd(zmm24, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62914C4859D8" , vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914C4C59D8" , k(k4).vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914CCC59D8" , k(k4).z().vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914C1859D8" , rn_sae().vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914C5859D8" , ru_sae().vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914C3859D8" , rd_sae().vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62914C7859D8" , rz_sae().vmulps(zmm3, zmm6, zmm24));
+ TEST_INSTRUCTION("62F14C485919" , vmulps(zmm3, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B14C48599CF023010000" , vmulps(zmm3, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F14C585919" , vmulps(zmm3, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F14C48595A7F" , vmulps(zmm3, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F14C48599A00200000" , vmulps(zmm3, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F14C48595A80" , vmulps(zmm3, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F14C48599AC0DFFFFF" , vmulps(zmm3, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F14C58595A7F" , vmulps(zmm3, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F14C58599A00020000" , vmulps(zmm3, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F14C58595A80" , vmulps(zmm3, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F14C58599AFCFDFFFF" , vmulps(zmm3, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6231DF0859EA" , vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF0A59EA" , k(k2).vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF8A59EA" , k(k2).z().vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF1859EA" , rn_sae().vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF5859EA" , ru_sae().vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF3859EA" , rd_sae().vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("6231DF7859EA" , rz_sae().vmulsd(xmm13, xmm4, xmm18));
+ TEST_INSTRUCTION("C55B5929" , vmulsd(xmm13, xmm4, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4215B59ACF023010000" , vmulsd(xmm13, xmm4, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C55B59AAF8030000" , vmulsd(xmm13, xmm4, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C55B59AA00040000" , vmulsd(xmm13, xmm4, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C55B59AA00FCFFFF" , vmulsd(xmm13, xmm4, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C55B59AAF8FBFFFF" , vmulsd(xmm13, xmm4, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C12E0859F6" , vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E0C59F6" , k(k4).vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E8C59F6" , k(k4).z().vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E1859F6" , rn_sae().vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E5859F6" , ru_sae().vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E3859F6" , rd_sae().vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62C12E7859F6" , rz_sae().vmulss(xmm22, xmm10, xmm14));
+ TEST_INSTRUCTION("62E12E085931" , vmulss(xmm22, xmm10, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A12E0859B4F023010000" , vmulss(xmm22, xmm10, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E12E0859727F" , vmulss(xmm22, xmm10, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E12E0859B200020000" , vmulss(xmm22, xmm10, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E12E08597280" , vmulss(xmm22, xmm10, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E12E0859B2FCFDFFFF" , vmulss(xmm22, xmm10, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62527D481EFE" , vpabsd(zmm15, zmm14));
+ TEST_INSTRUCTION("62527D4E1EFE" , k(k6).vpabsd(zmm15, zmm14));
+ TEST_INSTRUCTION("62527DCE1EFE" , k(k6).z().vpabsd(zmm15, zmm14));
+ TEST_INSTRUCTION("62727D481E39" , vpabsd(zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D481EBCF023010000" , vpabsd(zmm15, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62727D581E39" , vpabsd(zmm15, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62727D481E7A7F" , vpabsd(zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62727D481EBA00200000" , vpabsd(zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62727D481E7A80" , vpabsd(zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62727D481EBAC0DFFFFF" , vpabsd(zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62727D581E7A7F" , vpabsd(zmm15, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62727D581EBA00020000" , vpabsd(zmm15, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62727D581E7A80" , vpabsd(zmm15, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62727D581EBAFCFDFFFF" , vpabsd(zmm15, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6292FD481FE8" , vpabsq(zmm5, zmm24));
+ TEST_INSTRUCTION("6292FD4E1FE8" , k(k6).vpabsq(zmm5, zmm24));
+ TEST_INSTRUCTION("6292FDCE1FE8" , k(k6).z().vpabsq(zmm5, zmm24));
+ TEST_INSTRUCTION("62F2FD481F29" , vpabsq(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2FD481FACF023010000" , vpabsq(zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2FD581F29" , vpabsq(zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2FD481F6A7F" , vpabsq(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2FD481FAA00200000" , vpabsq(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2FD481F6A80" , vpabsq(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2FD481FAAC0DFFFFF" , vpabsq(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2FD581F6A7F" , vpabsq(zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2FD581FAA00040000" , vpabsq(zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2FD581F6A80" , vpabsq(zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2FD581FAAF8FBFFFF" , vpabsq(zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62215548FED4" , vpaddd(zmm26, zmm5, zmm20));
+ TEST_INSTRUCTION("62215549FED4" , k(k1).vpaddd(zmm26, zmm5, zmm20));
+ TEST_INSTRUCTION("622155C9FED4" , k(k1).z().vpaddd(zmm26, zmm5, zmm20));
+ TEST_INSTRUCTION("62615548FE11" , vpaddd(zmm26, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62215548FE94F023010000" , vpaddd(zmm26, zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62615558FE11" , vpaddd(zmm26, zmm5, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62615548FE527F" , vpaddd(zmm26, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62615548FE9200200000" , vpaddd(zmm26, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62615548FE5280" , vpaddd(zmm26, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62615548FE92C0DFFFFF" , vpaddd(zmm26, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62615558FE527F" , vpaddd(zmm26, zmm5, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62615558FE9200020000" , vpaddd(zmm26, zmm5, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62615558FE5280" , vpaddd(zmm26, zmm5, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62615558FE92FCFDFFFF" , vpaddd(zmm26, zmm5, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6251B540D4C6" , vpaddq(zmm8, zmm25, zmm14));
+ TEST_INSTRUCTION("6251B543D4C6" , k(k3).vpaddq(zmm8, zmm25, zmm14));
+ TEST_INSTRUCTION("6251B5C3D4C6" , k(k3).z().vpaddq(zmm8, zmm25, zmm14));
+ TEST_INSTRUCTION("6271B540D401" , vpaddq(zmm8, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231B540D484F023010000" , vpaddq(zmm8, zmm25, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271B550D401" , vpaddq(zmm8, zmm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271B540D4427F" , vpaddq(zmm8, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271B540D48200200000" , vpaddq(zmm8, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271B540D44280" , vpaddq(zmm8, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271B540D482C0DFFFFF" , vpaddq(zmm8, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271B550D4427F" , vpaddq(zmm8, zmm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271B550D48200040000" , vpaddq(zmm8, zmm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271B550D44280" , vpaddq(zmm8, zmm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271B550D482F8FBFFFF" , vpaddq(zmm8, zmm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62814D40DBD9" , vpandd(zmm19, zmm22, zmm25));
+ TEST_INSTRUCTION("62814D41DBD9" , k(k1).vpandd(zmm19, zmm22, zmm25));
+ TEST_INSTRUCTION("62814DC1DBD9" , k(k1).z().vpandd(zmm19, zmm22, zmm25));
+ TEST_INSTRUCTION("62E14D40DB19" , vpandd(zmm19, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A14D40DB9CF023010000" , vpandd(zmm19, zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E14D50DB19" , vpandd(zmm19, zmm22, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E14D40DB5A7F" , vpandd(zmm19, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E14D40DB9A00200000" , vpandd(zmm19, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E14D40DB5A80" , vpandd(zmm19, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E14D40DB9AC0DFFFFF" , vpandd(zmm19, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E14D50DB5A7F" , vpandd(zmm19, zmm22, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E14D50DB9A00020000" , vpandd(zmm19, zmm22, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E14D50DB5A80" , vpandd(zmm19, zmm22, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E14D50DB9AFCFDFFFF" , vpandd(zmm19, zmm22, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62411D40DFF7" , vpandnd(zmm30, zmm28, zmm15));
+ TEST_INSTRUCTION("62411D43DFF7" , k(k3).vpandnd(zmm30, zmm28, zmm15));
+ TEST_INSTRUCTION("62411DC3DFF7" , k(k3).z().vpandnd(zmm30, zmm28, zmm15));
+ TEST_INSTRUCTION("62611D40DF31" , vpandnd(zmm30, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62211D40DFB4F023010000" , vpandnd(zmm30, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62611D50DF31" , vpandnd(zmm30, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62611D40DF727F" , vpandnd(zmm30, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62611D40DFB200200000" , vpandnd(zmm30, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62611D40DF7280" , vpandnd(zmm30, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62611D40DFB2C0DFFFFF" , vpandnd(zmm30, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62611D50DF727F" , vpandnd(zmm30, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62611D50DFB200020000" , vpandnd(zmm30, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62611D50DF7280" , vpandnd(zmm30, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62611D50DFB2FCFDFFFF" , vpandnd(zmm30, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1C548DFE3" , vpandnq(zmm20, zmm7, zmm19));
+ TEST_INSTRUCTION("62A1C54DDFE3" , k(k5).vpandnq(zmm20, zmm7, zmm19));
+ TEST_INSTRUCTION("62A1C5CDDFE3" , k(k5).z().vpandnq(zmm20, zmm7, zmm19));
+ TEST_INSTRUCTION("62E1C548DF21" , vpandnq(zmm20, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1C548DFA4F023010000" , vpandnq(zmm20, zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1C558DF21" , vpandnq(zmm20, zmm7, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1C548DF627F" , vpandnq(zmm20, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1C548DFA200200000" , vpandnq(zmm20, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1C548DF6280" , vpandnq(zmm20, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1C548DFA2C0DFFFFF" , vpandnq(zmm20, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1C558DF627F" , vpandnq(zmm20, zmm7, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1C558DFA200040000" , vpandnq(zmm20, zmm7, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1C558DF6280" , vpandnq(zmm20, zmm7, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1C558DFA2F8FBFFFF" , vpandnq(zmm20, zmm7, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6281DD48DBCA" , vpandq(zmm17, zmm4, zmm26));
+ TEST_INSTRUCTION("6281DD4FDBCA" , k(k7).vpandq(zmm17, zmm4, zmm26));
+ TEST_INSTRUCTION("6281DDCFDBCA" , k(k7).z().vpandq(zmm17, zmm4, zmm26));
+ TEST_INSTRUCTION("62E1DD48DB09" , vpandq(zmm17, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1DD48DB8CF023010000" , vpandq(zmm17, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1DD58DB09" , vpandq(zmm17, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1DD48DB4A7F" , vpandq(zmm17, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1DD48DB8A00200000" , vpandq(zmm17, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1DD48DB4A80" , vpandq(zmm17, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1DD48DB8AC0DFFFFF" , vpandq(zmm17, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1DD58DB4A7F" , vpandq(zmm17, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1DD58DB8A00040000" , vpandq(zmm17, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1DD58DB4A80" , vpandq(zmm17, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1DD58DB8AF8FBFFFF" , vpandq(zmm17, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D2354064EB" , vpblendmd(zmm5, zmm25, zmm11));
+ TEST_INSTRUCTION("62D2354364EB" , k(k3).vpblendmd(zmm5, zmm25, zmm11));
+ TEST_INSTRUCTION("62D235C364EB" , k(k3).z().vpblendmd(zmm5, zmm25, zmm11));
+ TEST_INSTRUCTION("62F235406429" , vpblendmd(zmm5, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2354064ACF023010000" , vpblendmd(zmm5, zmm25, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F235506429" , vpblendmd(zmm5, zmm25, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23540646A7F" , vpblendmd(zmm5, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2354064AA00200000" , vpblendmd(zmm5, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23540646A80" , vpblendmd(zmm5, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2354064AAC0DFFFFF" , vpblendmd(zmm5, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23550646A7F" , vpblendmd(zmm5, zmm25, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F2355064AA00020000" , vpblendmd(zmm5, zmm25, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23550646A80" , vpblendmd(zmm5, zmm25, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F2355064AAFCFDFFFF" , vpblendmd(zmm5, zmm25, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62627D485811" , vpbroadcastd(zmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62627D4A5811" , k(k2).vpbroadcastd(zmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62627DCA5811" , k(k2).z().vpbroadcastd(zmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D485894F023010000" , vpbroadcastd(zmm26, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62627D4858527F" , vpbroadcastd(zmm26, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62627D48589200020000" , vpbroadcastd(zmm26, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62627D48585280" , vpbroadcastd(zmm26, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62627D485892FCFDFFFF" , vpbroadcastd(zmm26, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62327D4858D6" , vpbroadcastd(zmm10, xmm22));
+ TEST_INSTRUCTION("62327D4F58D6" , k(k7).vpbroadcastd(zmm10, xmm22));
+ TEST_INSTRUCTION("62327DCF58D6" , k(k7).z().vpbroadcastd(zmm10, xmm22));
+ TEST_INSTRUCTION("62727D487CD8" , vpbroadcastd(zmm11, eax));
+ TEST_INSTRUCTION("62727D4E7CD8" , k(k6).vpbroadcastd(zmm11, eax));
+ TEST_INSTRUCTION("62727DCE7CD8" , k(k6).z().vpbroadcastd(zmm11, eax));
+ TEST_INSTRUCTION("62727D487CDD" , vpbroadcastd(zmm11, ebp));
+ TEST_INSTRUCTION("62527D487CDD" , vpbroadcastd(zmm11, r13d));
+ TEST_INSTRUCTION("6262FD485909" , vpbroadcastq(zmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4A5909" , k(k2).vpbroadcastq(zmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCA5909" , k(k2).z().vpbroadcastq(zmm25, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD48598CF023010000" , vpbroadcastq(zmm25, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD48594A7F" , vpbroadcastq(zmm25, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262FD48598A00040000" , vpbroadcastq(zmm25, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262FD48594A80" , vpbroadcastq(zmm25, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262FD48598AF8FBFFFF" , vpbroadcastq(zmm25, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62F2FD4859DD" , vpbroadcastq(zmm3, xmm5));
+ TEST_INSTRUCTION("62F2FD4D59DD" , k(k5).vpbroadcastq(zmm3, xmm5));
+ TEST_INSTRUCTION("62F2FDCD59DD" , k(k5).z().vpbroadcastq(zmm3, xmm5));
+ TEST_INSTRUCTION("62F2FD487CC8" , vpbroadcastq(zmm1, rax));
+ TEST_INSTRUCTION("62F2FD4E7CC8" , k(k6).vpbroadcastq(zmm1, rax));
+ TEST_INSTRUCTION("62F2FDCE7CC8" , k(k6).z().vpbroadcastq(zmm1, rax));
+ TEST_INSTRUCTION("62D2FD487CC8" , vpbroadcastq(zmm1, r8));
+ TEST_INSTRUCTION("62D335401FEAAB" , vpcmpd(k5, zmm25, zmm10, 171));
+ TEST_INSTRUCTION("62D335431FEAAB" , k(k3).vpcmpd(k5, zmm25, zmm10, 171));
+ TEST_INSTRUCTION("62D335401FEA7B" , vpcmpd(k5, zmm25, zmm10, 123));
+ TEST_INSTRUCTION("62F335401F297B" , vpcmpd(k5, zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B335401FACF0230100007B" , vpcmpd(k5, zmm25, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F335501F297B" , vpcmpd(k5, zmm25, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F335401F6A7F7B" , vpcmpd(k5, zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F335401FAA002000007B" , vpcmpd(k5, zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F335401F6A807B" , vpcmpd(k5, zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F335401FAAC0DFFFFF7B" , vpcmpd(k5, zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F335501F6A7F7B" , vpcmpd(k5, zmm25, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501FAA000200007B" , vpcmpd(k5, zmm25, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501F6A807B" , vpcmpd(k5, zmm25, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501FAAFCFDFFFF7B" , vpcmpd(k5, zmm25, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D16D4876EA" , vpcmpeqd(k5, zmm2, zmm10));
+ TEST_INSTRUCTION("62D16D4F76EA" , k(k7).vpcmpeqd(k5, zmm2, zmm10));
+ TEST_INSTRUCTION("62F16D487629" , vpcmpeqd(k5, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B16D4876ACF023010000" , vpcmpeqd(k5, zmm2, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F16D587629" , vpcmpeqd(k5, zmm2, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F16D48766A7F" , vpcmpeqd(k5, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F16D4876AA00200000" , vpcmpeqd(k5, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F16D48766A80" , vpcmpeqd(k5, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F16D4876AAC0DFFFFF" , vpcmpeqd(k5, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F16D58766A7F" , vpcmpeqd(k5, zmm2, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F16D5876AA00020000" , vpcmpeqd(k5, zmm2, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F16D58766A80" , vpcmpeqd(k5, zmm2, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F16D5876AAFCFDFFFF" , vpcmpeqd(k5, zmm2, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2CD4029DA" , vpcmpeqq(k3, zmm22, zmm2));
+ TEST_INSTRUCTION("62F2CD4629DA" , k(k6).vpcmpeqq(k3, zmm22, zmm2));
+ TEST_INSTRUCTION("62F2CD402919" , vpcmpeqq(k3, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2CD40299CF023010000" , vpcmpeqq(k3, zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2CD502919" , vpcmpeqq(k3, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2CD40295A7F" , vpcmpeqq(k3, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2CD40299A00200000" , vpcmpeqq(k3, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2CD40295A80" , vpcmpeqq(k3, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2CD40299AC0DFFFFF" , vpcmpeqq(k3, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2CD50295A7F" , vpcmpeqq(k3, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2CD50299A00040000" , vpcmpeqq(k3, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD50295A80" , vpcmpeqq(k3, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD50299AF8FBFFFF" , vpcmpeqq(k3, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D1554066E8" , vpcmpgtd(k5, zmm21, zmm8));
+ TEST_INSTRUCTION("62D1554566E8" , k(k5).vpcmpgtd(k5, zmm21, zmm8));
+ TEST_INSTRUCTION("62F155406629" , vpcmpgtd(k5, zmm21, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1554066ACF023010000" , vpcmpgtd(k5, zmm21, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F155506629" , vpcmpgtd(k5, zmm21, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F15540666A7F" , vpcmpgtd(k5, zmm21, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1554066AA00200000" , vpcmpgtd(k5, zmm21, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F15540666A80" , vpcmpgtd(k5, zmm21, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1554066AAC0DFFFFF" , vpcmpgtd(k5, zmm21, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F15550666A7F" , vpcmpgtd(k5, zmm21, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F1555066AA00020000" , vpcmpgtd(k5, zmm21, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F15550666A80" , vpcmpgtd(k5, zmm21, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F1555066AAFCFDFFFF" , vpcmpgtd(k5, zmm21, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B2DD4037D1" , vpcmpgtq(k2, zmm20, zmm17));
+ TEST_INSTRUCTION("62B2DD4337D1" , k(k3).vpcmpgtq(k2, zmm20, zmm17));
+ TEST_INSTRUCTION("62F2DD403711" , vpcmpgtq(k2, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2DD403794F023010000" , vpcmpgtq(k2, zmm20, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2DD503711" , vpcmpgtq(k2, zmm20, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2DD4037527F" , vpcmpgtq(k2, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2DD40379200200000" , vpcmpgtq(k2, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2DD40375280" , vpcmpgtq(k2, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2DD403792C0DFFFFF" , vpcmpgtq(k2, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2DD5037527F" , vpcmpgtq(k2, zmm20, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2DD50379200040000" , vpcmpgtq(k2, zmm20, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2DD50375280" , vpcmpgtq(k2, zmm20, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2DD503792F8FBFFFF" , vpcmpgtq(k2, zmm20, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62939D401FECAB" , vpcmpq(k5, zmm28, zmm28, 171));
+ TEST_INSTRUCTION("62939D431FECAB" , k(k3).vpcmpq(k5, zmm28, zmm28, 171));
+ TEST_INSTRUCTION("62939D401FEC7B" , vpcmpq(k5, zmm28, zmm28, 123));
+ TEST_INSTRUCTION("62F39D401F297B" , vpcmpq(k5, zmm28, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B39D401FACF0230100007B" , vpcmpq(k5, zmm28, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F39D501F297B" , vpcmpq(k5, zmm28, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D401F6A7F7B" , vpcmpq(k5, zmm28, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F39D401FAA002000007B" , vpcmpq(k5, zmm28, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F39D401F6A807B" , vpcmpq(k5, zmm28, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F39D401FAAC0DFFFFF7B" , vpcmpq(k5, zmm28, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F39D501F6A7F7B" , vpcmpq(k5, zmm28, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D501FAA000400007B" , vpcmpq(k5, zmm28, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D501F6A807B" , vpcmpq(k5, zmm28, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D501FAAF8FBFFFF7B" , vpcmpq(k5, zmm28, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F335401ED7AB" , vpcmpud(k2, zmm25, zmm7, 171));
+ TEST_INSTRUCTION("62F335411ED7AB" , k(k1).vpcmpud(k2, zmm25, zmm7, 171));
+ TEST_INSTRUCTION("62F335401ED77B" , vpcmpud(k2, zmm25, zmm7, 123));
+ TEST_INSTRUCTION("62F335401E117B" , vpcmpud(k2, zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B335401E94F0230100007B" , vpcmpud(k2, zmm25, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F335501E117B" , vpcmpud(k2, zmm25, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F335401E527F7B" , vpcmpud(k2, zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F335401E92002000007B" , vpcmpud(k2, zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F335401E52807B" , vpcmpud(k2, zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F335401E92C0DFFFFF7B" , vpcmpud(k2, zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F335501E527F7B" , vpcmpud(k2, zmm25, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501E92000200007B" , vpcmpud(k2, zmm25, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501E52807B" , vpcmpud(k2, zmm25, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501E92FCFDFFFF7B" , vpcmpud(k2, zmm25, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D38D481ED8AB" , vpcmpuq(k3, zmm14, zmm8, 171));
+ TEST_INSTRUCTION("62D38D4A1ED8AB" , k(k2).vpcmpuq(k3, zmm14, zmm8, 171));
+ TEST_INSTRUCTION("62D38D481ED87B" , vpcmpuq(k3, zmm14, zmm8, 123));
+ TEST_INSTRUCTION("62F38D481E197B" , vpcmpuq(k3, zmm14, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B38D481E9CF0230100007B" , vpcmpuq(k3, zmm14, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F38D581E197B" , vpcmpuq(k3, zmm14, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D481E5A7F7B" , vpcmpuq(k3, zmm14, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F38D481E9A002000007B" , vpcmpuq(k3, zmm14, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F38D481E5A807B" , vpcmpuq(k3, zmm14, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F38D481E9AC0DFFFFF7B" , vpcmpuq(k3, zmm14, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F38D581E5A7F7B" , vpcmpuq(k3, zmm14, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E9A000400007B" , vpcmpuq(k3, zmm14, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E5A807B" , vpcmpuq(k3, zmm14, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E9AF8FBFFFF7B" , vpcmpuq(k3, zmm14, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62228D4864D9" , vpblendmq(zmm27, zmm14, zmm17));
+ TEST_INSTRUCTION("62228D4D64D9" , k(k5).vpblendmq(zmm27, zmm14, zmm17));
+ TEST_INSTRUCTION("62228DCD64D9" , k(k5).z().vpblendmq(zmm27, zmm14, zmm17));
+ TEST_INSTRUCTION("62628D486419" , vpblendmq(zmm27, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62228D48649CF023010000" , vpblendmq(zmm27, zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62628D586419" , vpblendmq(zmm27, zmm14, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62628D48645A7F" , vpblendmq(zmm27, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62628D48649A00200000" , vpblendmq(zmm27, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62628D48645A80" , vpblendmq(zmm27, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62628D48649AC0DFFFFF" , vpblendmq(zmm27, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62628D58645A7F" , vpblendmq(zmm27, zmm14, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62628D58649A00040000" , vpblendmq(zmm27, zmm14, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62628D58645A80" , vpblendmq(zmm27, zmm14, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62628D58649AF8FBFFFF" , vpblendmq(zmm27, zmm14, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E27D488B39" , vpcompressd(zmmword_ptr(rcx), zmm23));
+ TEST_INSTRUCTION("62E27D4F8B39" , k(k7).vpcompressd(zmmword_ptr(rcx), zmm23));
+ TEST_INSTRUCTION("62A27D488BBCF023010000" , vpcompressd(zmmword_ptr(rax, r14, 3, 291), zmm23));
+ TEST_INSTRUCTION("62E27D488B7A7F" , vpcompressd(zmmword_ptr(rdx, 508), zmm23));
+ TEST_INSTRUCTION("62E27D488BBA00020000" , vpcompressd(zmmword_ptr(rdx, 512), zmm23));
+ TEST_INSTRUCTION("62E27D488B7A80" , vpcompressd(zmmword_ptr(rdx, -512), zmm23));
+ TEST_INSTRUCTION("62E27D488BBAFCFDFFFF" , vpcompressd(zmmword_ptr(rdx, -516), zmm23));
+ TEST_INSTRUCTION("62A27D488BD0" , vpcompressd(zmm16, zmm18));
+ TEST_INSTRUCTION("62A27D4A8BD0" , k(k2).vpcompressd(zmm16, zmm18));
+ TEST_INSTRUCTION("62A27DCA8BD0" , k(k2).z().vpcompressd(zmm16, zmm18));
+ TEST_INSTRUCTION("62C21D4036F1" , vpermd(zmm22, zmm28, zmm9));
+ TEST_INSTRUCTION("62C21D4136F1" , k(k1).vpermd(zmm22, zmm28, zmm9));
+ TEST_INSTRUCTION("62C21DC136F1" , k(k1).z().vpermd(zmm22, zmm28, zmm9));
+ TEST_INSTRUCTION("62E21D403631" , vpermd(zmm22, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A21D4036B4F023010000" , vpermd(zmm22, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E21D503631" , vpermd(zmm22, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E21D4036727F" , vpermd(zmm22, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E21D4036B200200000" , vpermd(zmm22, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E21D40367280" , vpermd(zmm22, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E21D4036B2C0DFFFFF" , vpermd(zmm22, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E21D5036727F" , vpermd(zmm22, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E21D5036B200020000" , vpermd(zmm22, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E21D50367280" , vpermd(zmm22, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E21D5036B2FCFDFFFF" , vpermd(zmm22, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62E3FD4805DCAB" , vpermilpd(zmm19, zmm4, 171));
+ TEST_INSTRUCTION("62E3FD4905DCAB" , k(k1).vpermilpd(zmm19, zmm4, 171));
+ TEST_INSTRUCTION("62E3FDC905DCAB" , k(k1).z().vpermilpd(zmm19, zmm4, 171));
+ TEST_INSTRUCTION("62E3FD4805DC7B" , vpermilpd(zmm19, zmm4, 123));
+ TEST_INSTRUCTION("62E3FD4805197B" , vpermilpd(zmm19, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A3FD48059CF0230100007B" , vpermilpd(zmm19, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62E3FD5805197B" , vpermilpd(zmm19, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD48055A7F7B" , vpermilpd(zmm19, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E3FD48059A002000007B" , vpermilpd(zmm19, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E3FD48055A807B" , vpermilpd(zmm19, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E3FD48059AC0DFFFFF7B" , vpermilpd(zmm19, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E3FD58055A7F7B" , vpermilpd(zmm19, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD58059A000400007B" , vpermilpd(zmm19, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD58055A807B" , vpermilpd(zmm19, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD58059AF8FBFFFF7B" , vpermilpd(zmm19, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62B2AD400DCD" , vpermilpd(zmm1, zmm26, zmm21));
+ TEST_INSTRUCTION("62B2AD420DCD" , k(k2).vpermilpd(zmm1, zmm26, zmm21));
+ TEST_INSTRUCTION("62B2ADC20DCD" , k(k2).z().vpermilpd(zmm1, zmm26, zmm21));
+ TEST_INSTRUCTION("62F2AD400D09" , vpermilpd(zmm1, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2AD400D8CF023010000" , vpermilpd(zmm1, zmm26, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2AD500D09" , vpermilpd(zmm1, zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2AD400D4A7F" , vpermilpd(zmm1, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2AD400D8A00200000" , vpermilpd(zmm1, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2AD400D4A80" , vpermilpd(zmm1, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2AD400D8AC0DFFFFF" , vpermilpd(zmm1, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2AD500D4A7F" , vpermilpd(zmm1, zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2AD500D8A00040000" , vpermilpd(zmm1, zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD500D4A80" , vpermilpd(zmm1, zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD500D8AF8FBFFFF" , vpermilpd(zmm1, zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B37D4804D6AB" , vpermilps(zmm2, zmm22, 171));
+ TEST_INSTRUCTION("62B37D4A04D6AB" , k(k2).vpermilps(zmm2, zmm22, 171));
+ TEST_INSTRUCTION("62B37DCA04D6AB" , k(k2).z().vpermilps(zmm2, zmm22, 171));
+ TEST_INSTRUCTION("62B37D4804D67B" , vpermilps(zmm2, zmm22, 123));
+ TEST_INSTRUCTION("62F37D4804117B" , vpermilps(zmm2, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B37D480494F0230100007B" , vpermilps(zmm2, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F37D5804117B" , vpermilps(zmm2, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F37D4804527F7B" , vpermilps(zmm2, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F37D480492002000007B" , vpermilps(zmm2, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F37D480452807B" , vpermilps(zmm2, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F37D480492C0DFFFFF7B" , vpermilps(zmm2, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F37D5804527F7B" , vpermilps(zmm2, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F37D580492000200007B" , vpermilps(zmm2, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F37D580452807B" , vpermilps(zmm2, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F37D580492FCFDFFFF7B" , vpermilps(zmm2, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62725D400CEA" , vpermilps(zmm13, zmm20, zmm2));
+ TEST_INSTRUCTION("62725D410CEA" , k(k1).vpermilps(zmm13, zmm20, zmm2));
+ TEST_INSTRUCTION("62725DC10CEA" , k(k1).z().vpermilps(zmm13, zmm20, zmm2));
+ TEST_INSTRUCTION("62725D400C29" , vpermilps(zmm13, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62325D400CACF023010000" , vpermilps(zmm13, zmm20, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62725D500C29" , vpermilps(zmm13, zmm20, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62725D400C6A7F" , vpermilps(zmm13, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62725D400CAA00200000" , vpermilps(zmm13, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62725D400C6A80" , vpermilps(zmm13, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62725D400CAAC0DFFFFF" , vpermilps(zmm13, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62725D500C6A7F" , vpermilps(zmm13, zmm20, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62725D500CAA00020000" , vpermilps(zmm13, zmm20, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62725D500C6A80" , vpermilps(zmm13, zmm20, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62725D500CAAFCFDFFFF" , vpermilps(zmm13, zmm20, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6293FD4801DBAB" , vpermpd(zmm3, zmm27, 171));
+ TEST_INSTRUCTION("6293FD4A01DBAB" , k(k2).vpermpd(zmm3, zmm27, 171));
+ TEST_INSTRUCTION("6293FDCA01DBAB" , k(k2).z().vpermpd(zmm3, zmm27, 171));
+ TEST_INSTRUCTION("6293FD4801DB7B" , vpermpd(zmm3, zmm27, 123));
+ TEST_INSTRUCTION("62F3FD4801197B" , vpermpd(zmm3, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3FD48019CF0230100007B" , vpermpd(zmm3, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3FD5801197B" , vpermpd(zmm3, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD48015A7F7B" , vpermpd(zmm3, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F3FD48019A002000007B" , vpermpd(zmm3, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F3FD48015A807B" , vpermpd(zmm3, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F3FD48019AC0DFFFFF7B" , vpermpd(zmm3, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F3FD58015A7F7B" , vpermpd(zmm3, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD58019A000400007B" , vpermpd(zmm3, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD58015A807B" , vpermpd(zmm3, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD58019AF8FBFFFF7B" , vpermpd(zmm3, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62926D4816E0" , vpermps(zmm4, zmm2, zmm24));
+ TEST_INSTRUCTION("62926D4C16E0" , k(k4).vpermps(zmm4, zmm2, zmm24));
+ TEST_INSTRUCTION("62926DCC16E0" , k(k4).z().vpermps(zmm4, zmm2, zmm24));
+ TEST_INSTRUCTION("62F26D481621" , vpermps(zmm4, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B26D4816A4F023010000" , vpermps(zmm4, zmm2, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F26D581621" , vpermps(zmm4, zmm2, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F26D4816627F" , vpermps(zmm4, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F26D4816A200200000" , vpermps(zmm4, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F26D48166280" , vpermps(zmm4, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F26D4816A2C0DFFFFF" , vpermps(zmm4, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F26D5816627F" , vpermps(zmm4, zmm2, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F26D5816A200020000" , vpermps(zmm4, zmm2, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F26D58166280" , vpermps(zmm4, zmm2, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F26D5816A2FCFDFFFF" , vpermps(zmm4, zmm2, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6263FD4800CCAB" , vpermq(zmm25, zmm4, 171));
+ TEST_INSTRUCTION("6263FD4E00CCAB" , k(k6).vpermq(zmm25, zmm4, 171));
+ TEST_INSTRUCTION("6263FDCE00CCAB" , k(k6).z().vpermq(zmm25, zmm4, 171));
+ TEST_INSTRUCTION("6263FD4800CC7B" , vpermq(zmm25, zmm4, 123));
+ TEST_INSTRUCTION("6263FD4800097B" , vpermq(zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223FD48008CF0230100007B" , vpermq(zmm25, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6263FD5800097B" , vpermq(zmm25, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD48004A7F7B" , vpermq(zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6263FD48008A002000007B" , vpermq(zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6263FD48004A807B" , vpermq(zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6263FD48008AC0DFFFFF7B" , vpermq(zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6263FD58004A7F7B" , vpermq(zmm25, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD58008A000400007B" , vpermq(zmm25, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD58004A807B" , vpermq(zmm25, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD58008AF8FBFFFF7B" , vpermq(zmm25, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F27D488909" , vpexpandd(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D4F8909" , k(k7).vpexpandd(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DCF8909" , k(k7).z().vpexpandd(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D48898CF023010000" , vpexpandd(zmm1, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D48894A7F" , vpexpandd(zmm1, zmmword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F27D48898A00020000" , vpexpandd(zmm1, zmmword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F27D48894A80" , vpexpandd(zmm1, zmmword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F27D48898AFCFDFFFF" , vpexpandd(zmm1, zmmword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62827D4889D9" , vpexpandd(zmm19, zmm25));
+ TEST_INSTRUCTION("62827D4D89D9" , k(k5).vpexpandd(zmm19, zmm25));
+ TEST_INSTRUCTION("62827DCD89D9" , k(k5).z().vpexpandd(zmm19, zmm25));
+ TEST_INSTRUCTION("6262FD488901" , vpexpandq(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4F8901" , k(k7).vpexpandq(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCF8901" , k(k7).z().vpexpandq(zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD488984F023010000" , vpexpandq(zmm24, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262FD4889427F" , vpexpandq(zmm24, zmmword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262FD48898200040000" , vpexpandq(zmm24, zmmword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262FD48894280" , vpexpandq(zmm24, zmmword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262FD488982F8FBFFFF" , vpexpandq(zmm24, zmmword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6252FD4889F8" , vpexpandq(zmm15, zmm8));
+ TEST_INSTRUCTION("6252FD4F89F8" , k(k7).vpexpandq(zmm15, zmm8));
+ TEST_INSTRUCTION("6252FDCF89F8" , k(k7).z().vpexpandq(zmm15, zmm8));
+ TEST_INSTRUCTION("62B23D483DF0" , vpmaxsd(zmm6, zmm8, zmm16));
+ TEST_INSTRUCTION("62B23D4B3DF0" , k(k3).vpmaxsd(zmm6, zmm8, zmm16));
+ TEST_INSTRUCTION("62B23DCB3DF0" , k(k3).z().vpmaxsd(zmm6, zmm8, zmm16));
+ TEST_INSTRUCTION("62F23D483D31" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B23D483DB4F023010000" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F23D583D31" , vpmaxsd(zmm6, zmm8, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23D483D727F" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F23D483DB200200000" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23D483D7280" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F23D483DB2C0DFFFFF" , vpmaxsd(zmm6, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23D583D727F" , vpmaxsd(zmm6, zmm8, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F23D583DB200020000" , vpmaxsd(zmm6, zmm8, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23D583D7280" , vpmaxsd(zmm6, zmm8, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F23D583DB2FCFDFFFF" , vpmaxsd(zmm6, zmm8, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2CD483DF1" , vpmaxsq(zmm6, zmm6, zmm1));
+ TEST_INSTRUCTION("62F2CD4F3DF1" , k(k7).vpmaxsq(zmm6, zmm6, zmm1));
+ TEST_INSTRUCTION("62F2CDCF3DF1" , k(k7).z().vpmaxsq(zmm6, zmm6, zmm1));
+ TEST_INSTRUCTION("62F2CD483D31" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2CD483DB4F023010000" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2CD583D31" , vpmaxsq(zmm6, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2CD483D727F" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2CD483DB200200000" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2CD483D7280" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2CD483DB2C0DFFFFF" , vpmaxsq(zmm6, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2CD583D727F" , vpmaxsq(zmm6, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2CD583DB200040000" , vpmaxsq(zmm6, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD583D7280" , vpmaxsq(zmm6, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD583DB2F8FBFFFF" , vpmaxsq(zmm6, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("628245483FC9" , vpmaxud(zmm17, zmm7, zmm25));
+ TEST_INSTRUCTION("6282454D3FC9" , k(k5).vpmaxud(zmm17, zmm7, zmm25));
+ TEST_INSTRUCTION("628245CD3FC9" , k(k5).z().vpmaxud(zmm17, zmm7, zmm25));
+ TEST_INSTRUCTION("62E245483F09" , vpmaxud(zmm17, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A245483F8CF023010000" , vpmaxud(zmm17, zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E245583F09" , vpmaxud(zmm17, zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E245483F4A7F" , vpmaxud(zmm17, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E245483F8A00200000" , vpmaxud(zmm17, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E245483F4A80" , vpmaxud(zmm17, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E245483F8AC0DFFFFF" , vpmaxud(zmm17, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E245583F4A7F" , vpmaxud(zmm17, zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E245583F8A00020000" , vpmaxud(zmm17, zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E245583F4A80" , vpmaxud(zmm17, zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E245583F8AFCFDFFFF" , vpmaxud(zmm17, zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6202CD403FF1" , vpmaxuq(zmm30, zmm22, zmm25));
+ TEST_INSTRUCTION("6202CD413FF1" , k(k1).vpmaxuq(zmm30, zmm22, zmm25));
+ TEST_INSTRUCTION("6202CDC13FF1" , k(k1).z().vpmaxuq(zmm30, zmm22, zmm25));
+ TEST_INSTRUCTION("6262CD403F31" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222CD403FB4F023010000" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262CD503F31" , vpmaxuq(zmm30, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262CD403F727F" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262CD403FB200200000" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262CD403F7280" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262CD403FB2C0DFFFFF" , vpmaxuq(zmm30, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262CD503F727F" , vpmaxuq(zmm30, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262CD503FB200040000" , vpmaxuq(zmm30, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262CD503F7280" , vpmaxuq(zmm30, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262CD503FB2F8FBFFFF" , vpmaxuq(zmm30, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62927D4039D0" , vpminsd(zmm2, zmm16, zmm24));
+ TEST_INSTRUCTION("62927D4339D0" , k(k3).vpminsd(zmm2, zmm16, zmm24));
+ TEST_INSTRUCTION("62927DC339D0" , k(k3).z().vpminsd(zmm2, zmm16, zmm24));
+ TEST_INSTRUCTION("62F27D403911" , vpminsd(zmm2, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D403994F023010000" , vpminsd(zmm2, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D503911" , vpminsd(zmm2, zmm16, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D4039527F" , vpminsd(zmm2, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D40399200200000" , vpminsd(zmm2, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D40395280" , vpminsd(zmm2, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D403992C0DFFFFF" , vpminsd(zmm2, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D5039527F" , vpminsd(zmm2, zmm16, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D50399200020000" , vpminsd(zmm2, zmm16, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D50395280" , vpminsd(zmm2, zmm16, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D503992FCFDFFFF" , vpminsd(zmm2, zmm16, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2FD4039E1" , vpminsq(zmm20, zmm16, zmm17));
+ TEST_INSTRUCTION("62A2FD4639E1" , k(k6).vpminsq(zmm20, zmm16, zmm17));
+ TEST_INSTRUCTION("62A2FDC639E1" , k(k6).z().vpminsq(zmm20, zmm16, zmm17));
+ TEST_INSTRUCTION("62E2FD403921" , vpminsq(zmm20, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD4039A4F023010000" , vpminsq(zmm20, zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2FD503921" , vpminsq(zmm20, zmm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2FD4039627F" , vpminsq(zmm20, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2FD4039A200200000" , vpminsq(zmm20, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2FD40396280" , vpminsq(zmm20, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2FD4039A2C0DFFFFF" , vpminsq(zmm20, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2FD5039627F" , vpminsq(zmm20, zmm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2FD5039A200040000" , vpminsq(zmm20, zmm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD50396280" , vpminsq(zmm20, zmm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD5039A2F8FBFFFF" , vpminsq(zmm20, zmm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B245403BDC" , vpminud(zmm3, zmm23, zmm20));
+ TEST_INSTRUCTION("62B245433BDC" , k(k3).vpminud(zmm3, zmm23, zmm20));
+ TEST_INSTRUCTION("62B245C33BDC" , k(k3).z().vpminud(zmm3, zmm23, zmm20));
+ TEST_INSTRUCTION("62F245403B19" , vpminud(zmm3, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B245403B9CF023010000" , vpminud(zmm3, zmm23, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F245503B19" , vpminud(zmm3, zmm23, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F245403B5A7F" , vpminud(zmm3, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F245403B9A00200000" , vpminud(zmm3, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F245403B5A80" , vpminud(zmm3, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F245403B9AC0DFFFFF" , vpminud(zmm3, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F245503B5A7F" , vpminud(zmm3, zmm23, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F245503B9A00020000" , vpminud(zmm3, zmm23, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F245503B5A80" , vpminud(zmm3, zmm23, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F245503B9AFCFDFFFF" , vpminud(zmm3, zmm23, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6272AD403BDF" , vpminuq(zmm11, zmm26, zmm7));
+ TEST_INSTRUCTION("6272AD453BDF" , k(k5).vpminuq(zmm11, zmm26, zmm7));
+ TEST_INSTRUCTION("6272ADC53BDF" , k(k5).z().vpminuq(zmm11, zmm26, zmm7));
+ TEST_INSTRUCTION("6272AD403B19" , vpminuq(zmm11, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232AD403B9CF023010000" , vpminuq(zmm11, zmm26, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272AD503B19" , vpminuq(zmm11, zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272AD403B5A7F" , vpminuq(zmm11, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272AD403B9A00200000" , vpminuq(zmm11, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272AD403B5A80" , vpminuq(zmm11, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272AD403B9AC0DFFFFF" , vpminuq(zmm11, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272AD503B5A7F" , vpminuq(zmm11, zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272AD503B9A00040000" , vpminuq(zmm11, zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272AD503B5A80" , vpminuq(zmm11, zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272AD503B9AF8FBFFFF" , vpminuq(zmm11, zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62627D4821DF" , vpmovsxbd(zmm27, xmm7));
+ TEST_INSTRUCTION("62627D4D21DF" , k(k5).vpmovsxbd(zmm27, xmm7));
+ TEST_INSTRUCTION("62627DCD21DF" , k(k5).z().vpmovsxbd(zmm27, xmm7));
+ TEST_INSTRUCTION("62627D482119" , vpmovsxbd(zmm27, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D48219CF023010000" , vpmovsxbd(zmm27, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62627D48215A7F" , vpmovsxbd(zmm27, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62627D48219A00080000" , vpmovsxbd(zmm27, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62627D48215A80" , vpmovsxbd(zmm27, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62627D48219AF0F7FFFF" , vpmovsxbd(zmm27, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62527D4822DB" , vpmovsxbq(zmm11, xmm11));
+ TEST_INSTRUCTION("62527D4D22DB" , k(k5).vpmovsxbq(zmm11, xmm11));
+ TEST_INSTRUCTION("62527DCD22DB" , k(k5).z().vpmovsxbq(zmm11, xmm11));
+ TEST_INSTRUCTION("62727D482219" , vpmovsxbq(zmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D48229CF023010000" , vpmovsxbq(zmm11, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62727D48225A7F" , vpmovsxbq(zmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62727D48229A00040000" , vpmovsxbq(zmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62727D48225A80" , vpmovsxbq(zmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62727D48229AF8FBFFFF" , vpmovsxbq(zmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62027D4825D5" , vpmovsxdq(zmm26, ymm29));
+ TEST_INSTRUCTION("62027D4925D5" , k(k1).vpmovsxdq(zmm26, ymm29));
+ TEST_INSTRUCTION("62027DC925D5" , k(k1).z().vpmovsxdq(zmm26, ymm29));
+ TEST_INSTRUCTION("62627D482511" , vpmovsxdq(zmm26, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D482594F023010000" , vpmovsxdq(zmm26, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62627D4825527F" , vpmovsxdq(zmm26, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62627D48259200100000" , vpmovsxdq(zmm26, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62627D48255280" , vpmovsxdq(zmm26, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62627D482592E0EFFFFF" , vpmovsxdq(zmm26, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62C27D4823FB" , vpmovsxwd(zmm23, ymm11));
+ TEST_INSTRUCTION("62C27D4A23FB" , k(k2).vpmovsxwd(zmm23, ymm11));
+ TEST_INSTRUCTION("62C27DCA23FB" , k(k2).z().vpmovsxwd(zmm23, ymm11));
+ TEST_INSTRUCTION("62E27D482339" , vpmovsxwd(zmm23, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D4823BCF023010000" , vpmovsxwd(zmm23, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D48237A7F" , vpmovsxwd(zmm23, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E27D4823BA00100000" , vpmovsxwd(zmm23, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E27D48237A80" , vpmovsxwd(zmm23, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E27D4823BAE0EFFFFF" , vpmovsxwd(zmm23, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62027D4824C9" , vpmovsxwq(zmm25, xmm25));
+ TEST_INSTRUCTION("62027D4C24C9" , k(k4).vpmovsxwq(zmm25, xmm25));
+ TEST_INSTRUCTION("62027DCC24C9" , k(k4).z().vpmovsxwq(zmm25, xmm25));
+ TEST_INSTRUCTION("62627D482409" , vpmovsxwq(zmm25, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D48248CF023010000" , vpmovsxwq(zmm25, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62627D48244A7F" , vpmovsxwq(zmm25, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62627D48248A00080000" , vpmovsxwq(zmm25, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62627D48244A80" , vpmovsxwq(zmm25, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62627D48248AF0F7FFFF" , vpmovsxwq(zmm25, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62827D4831D1" , vpmovzxbd(zmm18, xmm25));
+ TEST_INSTRUCTION("62827D4F31D1" , k(k7).vpmovzxbd(zmm18, xmm25));
+ TEST_INSTRUCTION("62827DCF31D1" , k(k7).z().vpmovzxbd(zmm18, xmm25));
+ TEST_INSTRUCTION("62E27D483111" , vpmovzxbd(zmm18, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D483194F023010000" , vpmovzxbd(zmm18, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D4831527F" , vpmovzxbd(zmm18, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E27D48319200080000" , vpmovzxbd(zmm18, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E27D48315280" , vpmovzxbd(zmm18, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E27D483192F0F7FFFF" , vpmovzxbd(zmm18, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62D27D4832EF" , vpmovzxbq(zmm5, xmm15));
+ TEST_INSTRUCTION("62D27D4932EF" , k(k1).vpmovzxbq(zmm5, xmm15));
+ TEST_INSTRUCTION("62D27DC932EF" , k(k1).z().vpmovzxbq(zmm5, xmm15));
+ TEST_INSTRUCTION("62F27D483229" , vpmovzxbq(zmm5, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D4832ACF023010000" , vpmovzxbq(zmm5, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D48326A7F" , vpmovzxbq(zmm5, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F27D4832AA00040000" , vpmovzxbq(zmm5, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F27D48326A80" , vpmovzxbq(zmm5, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F27D4832AAF8FBFFFF" , vpmovzxbq(zmm5, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E27D4835E4" , vpmovzxdq(zmm20, ymm4));
+ TEST_INSTRUCTION("62E27D4B35E4" , k(k3).vpmovzxdq(zmm20, ymm4));
+ TEST_INSTRUCTION("62E27DCB35E4" , k(k3).z().vpmovzxdq(zmm20, ymm4));
+ TEST_INSTRUCTION("62E27D483521" , vpmovzxdq(zmm20, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D4835A4F023010000" , vpmovzxdq(zmm20, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D4835627F" , vpmovzxdq(zmm20, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E27D4835A200100000" , vpmovzxdq(zmm20, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E27D48356280" , vpmovzxdq(zmm20, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E27D4835A2E0EFFFFF" , vpmovzxdq(zmm20, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62727D4833C6" , vpmovzxwd(zmm8, ymm6));
+ TEST_INSTRUCTION("62727D4F33C6" , k(k7).vpmovzxwd(zmm8, ymm6));
+ TEST_INSTRUCTION("62727DCF33C6" , k(k7).z().vpmovzxwd(zmm8, ymm6));
+ TEST_INSTRUCTION("62727D483301" , vpmovzxwd(zmm8, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D483384F023010000" , vpmovzxwd(zmm8, ymmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62727D4833427F" , vpmovzxwd(zmm8, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D48338200100000" , vpmovzxwd(zmm8, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48334280" , vpmovzxwd(zmm8, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D483382E0EFFFFF" , vpmovzxwd(zmm8, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62D27D4834EF" , vpmovzxwq(zmm5, xmm15));
+ TEST_INSTRUCTION("62D27D4F34EF" , k(k7).vpmovzxwq(zmm5, xmm15));
+ TEST_INSTRUCTION("62D27DCF34EF" , k(k7).z().vpmovzxwq(zmm5, xmm15));
+ TEST_INSTRUCTION("62F27D483429" , vpmovzxwq(zmm5, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D4834ACF023010000" , vpmovzxwq(zmm5, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F27D48346A7F" , vpmovzxwq(zmm5, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62F27D4834AA00080000" , vpmovzxwq(zmm5, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62F27D48346A80" , vpmovzxwq(zmm5, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62F27D4834AAF0F7FFFF" , vpmovzxwq(zmm5, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6242B54828E9" , vpmuldq(zmm29, zmm9, zmm9));
+ TEST_INSTRUCTION("6242B54D28E9" , k(k5).vpmuldq(zmm29, zmm9, zmm9));
+ TEST_INSTRUCTION("6242B5CD28E9" , k(k5).z().vpmuldq(zmm29, zmm9, zmm9));
+ TEST_INSTRUCTION("6262B5482829" , vpmuldq(zmm29, zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222B54828ACF023010000" , vpmuldq(zmm29, zmm9, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262B5582829" , vpmuldq(zmm29, zmm9, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262B548286A7F" , vpmuldq(zmm29, zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262B54828AA00200000" , vpmuldq(zmm29, zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262B548286A80" , vpmuldq(zmm29, zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262B54828AAC0DFFFFF" , vpmuldq(zmm29, zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262B558286A7F" , vpmuldq(zmm29, zmm9, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262B55828AA00040000" , vpmuldq(zmm29, zmm9, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262B558286A80" , vpmuldq(zmm29, zmm9, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262B55828AAF8FBFFFF" , vpmuldq(zmm29, zmm9, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6272654840E2" , vpmulld(zmm12, zmm3, zmm2));
+ TEST_INSTRUCTION("6272654E40E2" , k(k6).vpmulld(zmm12, zmm3, zmm2));
+ TEST_INSTRUCTION("627265CE40E2" , k(k6).z().vpmulld(zmm12, zmm3, zmm2));
+ TEST_INSTRUCTION("627265484021" , vpmulld(zmm12, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232654840A4F023010000" , vpmulld(zmm12, zmm3, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("627265584021" , vpmulld(zmm12, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("6272654840627F" , vpmulld(zmm12, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272654840A200200000" , vpmulld(zmm12, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62726548406280" , vpmulld(zmm12, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272654840A2C0DFFFFF" , vpmulld(zmm12, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272655840627F" , vpmulld(zmm12, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("6272655840A200020000" , vpmulld(zmm12, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62726558406280" , vpmulld(zmm12, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("6272655840A2FCFDFFFF" , vpmulld(zmm12, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C1D548F4F9" , vpmuludq(zmm23, zmm5, zmm9));
+ TEST_INSTRUCTION("62C1D54CF4F9" , k(k4).vpmuludq(zmm23, zmm5, zmm9));
+ TEST_INSTRUCTION("62C1D5CCF4F9" , k(k4).z().vpmuludq(zmm23, zmm5, zmm9));
+ TEST_INSTRUCTION("62E1D548F439" , vpmuludq(zmm23, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1D548F4BCF023010000" , vpmuludq(zmm23, zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1D558F439" , vpmuludq(zmm23, zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1D548F47A7F" , vpmuludq(zmm23, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1D548F4BA00200000" , vpmuludq(zmm23, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1D548F47A80" , vpmuludq(zmm23, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1D548F4BAC0DFFFFF" , vpmuludq(zmm23, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1D558F47A7F" , vpmuludq(zmm23, zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1D558F4BA00040000" , vpmuludq(zmm23, zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1D558F47A80" , vpmuludq(zmm23, zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1D558F4BAF8FBFFFF" , vpmuludq(zmm23, zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62A16D48EBFC" , vpord(zmm23, zmm2, zmm20));
+ TEST_INSTRUCTION("62A16D4AEBFC" , k(k2).vpord(zmm23, zmm2, zmm20));
+ TEST_INSTRUCTION("62A16DCAEBFC" , k(k2).z().vpord(zmm23, zmm2, zmm20));
+ TEST_INSTRUCTION("62E16D48EB39" , vpord(zmm23, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A16D48EBBCF023010000" , vpord(zmm23, zmm2, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E16D58EB39" , vpord(zmm23, zmm2, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E16D48EB7A7F" , vpord(zmm23, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E16D48EBBA00200000" , vpord(zmm23, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E16D48EB7A80" , vpord(zmm23, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E16D48EBBAC0DFFFFF" , vpord(zmm23, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E16D58EB7A7F" , vpord(zmm23, zmm2, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E16D58EBBA00020000" , vpord(zmm23, zmm2, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E16D58EB7A80" , vpord(zmm23, zmm2, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E16D58EBBAFCFDFFFF" , vpord(zmm23, zmm2, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F1AD48EBCE" , vporq(zmm1, zmm10, zmm6));
+ TEST_INSTRUCTION("62F1AD4AEBCE" , k(k2).vporq(zmm1, zmm10, zmm6));
+ TEST_INSTRUCTION("62F1ADCAEBCE" , k(k2).z().vporq(zmm1, zmm10, zmm6));
+ TEST_INSTRUCTION("62F1AD48EB09" , vporq(zmm1, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1AD48EB8CF023010000" , vporq(zmm1, zmm10, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1AD58EB09" , vporq(zmm1, zmm10, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1AD48EB4A7F" , vporq(zmm1, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1AD48EB8A00200000" , vporq(zmm1, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1AD48EB4A80" , vporq(zmm1, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1AD48EB8AC0DFFFFF" , vporq(zmm1, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1AD58EB4A7F" , vporq(zmm1, zmm10, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1AD58EB8A00040000" , vporq(zmm1, zmm10, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1AD58EB4A80" , vporq(zmm1, zmm10, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1AD58EB8AF8FBFFFF" , vporq(zmm1, zmm10, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62817D4870D9AB" , vpshufd(zmm19, zmm25, 171));
+ TEST_INSTRUCTION("62817D4E70D9AB" , k(k6).vpshufd(zmm19, zmm25, 171));
+ TEST_INSTRUCTION("62817DCE70D9AB" , k(k6).z().vpshufd(zmm19, zmm25, 171));
+ TEST_INSTRUCTION("62817D4870D97B" , vpshufd(zmm19, zmm25, 123));
+ TEST_INSTRUCTION("62E17D4870197B" , vpshufd(zmm19, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A17D48709CF0230100007B" , vpshufd(zmm19, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62E17D5870197B" , vpshufd(zmm19, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62E17D48705A7F7B" , vpshufd(zmm19, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E17D48709A002000007B" , vpshufd(zmm19, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E17D48705A807B" , vpshufd(zmm19, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E17D48709AC0DFFFFF7B" , vpshufd(zmm19, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E17D58705A7F7B" , vpshufd(zmm19, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62E17D58709A000200007B" , vpshufd(zmm19, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62E17D58705A807B" , vpshufd(zmm19, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62E17D58709AFCFDFFFF7B" , vpshufd(zmm19, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62E14D48F2CB" , vpslld(zmm17, zmm6, xmm3));
+ TEST_INSTRUCTION("62E14D4BF2CB" , k(k3).vpslld(zmm17, zmm6, xmm3));
+ TEST_INSTRUCTION("62E14DCBF2CB" , k(k3).z().vpslld(zmm17, zmm6, xmm3));
+ TEST_INSTRUCTION("62E14D48F209" , vpslld(zmm17, zmm6, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A14D48F28CF023010000" , vpslld(zmm17, zmm6, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E14D48F24A7F" , vpslld(zmm17, zmm6, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E14D48F28A00080000" , vpslld(zmm17, zmm6, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E14D48F24A80" , vpslld(zmm17, zmm6, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E14D48F28AF0F7FFFF" , vpslld(zmm17, zmm6, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6221F540F3D7" , vpsllq(zmm26, zmm17, xmm23));
+ TEST_INSTRUCTION("6221F546F3D7" , k(k6).vpsllq(zmm26, zmm17, xmm23));
+ TEST_INSTRUCTION("6221F5C6F3D7" , k(k6).z().vpsllq(zmm26, zmm17, xmm23));
+ TEST_INSTRUCTION("6261F540F311" , vpsllq(zmm26, zmm17, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221F540F394F023010000" , vpsllq(zmm26, zmm17, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261F540F3527F" , vpsllq(zmm26, zmm17, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("6261F540F39200080000" , vpsllq(zmm26, zmm17, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("6261F540F35280" , vpsllq(zmm26, zmm17, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("6261F540F392F0F7FFFF" , vpsllq(zmm26, zmm17, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62321D4847D6" , vpsllvd(zmm10, zmm12, zmm22));
+ TEST_INSTRUCTION("62321D4E47D6" , k(k6).vpsllvd(zmm10, zmm12, zmm22));
+ TEST_INSTRUCTION("62321DCE47D6" , k(k6).z().vpsllvd(zmm10, zmm12, zmm22));
+ TEST_INSTRUCTION("62721D484711" , vpsllvd(zmm10, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D484794F023010000" , vpsllvd(zmm10, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62721D584711" , vpsllvd(zmm10, zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62721D4847527F" , vpsllvd(zmm10, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62721D48479200200000" , vpsllvd(zmm10, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62721D48475280" , vpsllvd(zmm10, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62721D484792C0DFFFFF" , vpsllvd(zmm10, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62721D5847527F" , vpsllvd(zmm10, zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62721D58479200020000" , vpsllvd(zmm10, zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62721D58475280" , vpsllvd(zmm10, zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62721D584792FCFDFFFF" , vpsllvd(zmm10, zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6282D54847C2" , vpsllvq(zmm16, zmm5, zmm26));
+ TEST_INSTRUCTION("6282D54D47C2" , k(k5).vpsllvq(zmm16, zmm5, zmm26));
+ TEST_INSTRUCTION("6282D5CD47C2" , k(k5).z().vpsllvq(zmm16, zmm5, zmm26));
+ TEST_INSTRUCTION("62E2D5484701" , vpsllvq(zmm16, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2D5484784F023010000" , vpsllvq(zmm16, zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2D5584701" , vpsllvq(zmm16, zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2D54847427F" , vpsllvq(zmm16, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2D548478200200000" , vpsllvq(zmm16, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2D548474280" , vpsllvq(zmm16, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2D5484782C0DFFFFF" , vpsllvq(zmm16, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2D55847427F" , vpsllvq(zmm16, zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2D558478200040000" , vpsllvq(zmm16, zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2D558474280" , vpsllvq(zmm16, zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2D5584782F8FBFFFF" , vpsllvq(zmm16, zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E10D48E2D6" , vpsrad(zmm18, zmm14, xmm6));
+ TEST_INSTRUCTION("62E10D49E2D6" , k(k1).vpsrad(zmm18, zmm14, xmm6));
+ TEST_INSTRUCTION("62E10DC9E2D6" , k(k1).z().vpsrad(zmm18, zmm14, xmm6));
+ TEST_INSTRUCTION("62E10D48E211" , vpsrad(zmm18, zmm14, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A10D48E294F023010000" , vpsrad(zmm18, zmm14, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E10D48E2527F" , vpsrad(zmm18, zmm14, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E10D48E29200080000" , vpsrad(zmm18, zmm14, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E10D48E25280" , vpsrad(zmm18, zmm14, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E10D48E292F0F7FFFF" , vpsrad(zmm18, zmm14, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62A1F540E2EE" , vpsraq(zmm21, zmm17, xmm22));
+ TEST_INSTRUCTION("62A1F543E2EE" , k(k3).vpsraq(zmm21, zmm17, xmm22));
+ TEST_INSTRUCTION("62A1F5C3E2EE" , k(k3).z().vpsraq(zmm21, zmm17, xmm22));
+ TEST_INSTRUCTION("62E1F540E229" , vpsraq(zmm21, zmm17, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1F540E2ACF023010000" , vpsraq(zmm21, zmm17, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1F540E26A7F" , vpsraq(zmm21, zmm17, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E1F540E2AA00080000" , vpsraq(zmm21, zmm17, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E1F540E26A80" , vpsraq(zmm21, zmm17, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E1F540E2AAF0F7FFFF" , vpsraq(zmm21, zmm17, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6222154046E9" , vpsravd(zmm29, zmm29, zmm17));
+ TEST_INSTRUCTION("6222154246E9" , k(k2).vpsravd(zmm29, zmm29, zmm17));
+ TEST_INSTRUCTION("622215C246E9" , k(k2).z().vpsravd(zmm29, zmm29, zmm17));
+ TEST_INSTRUCTION("626215404629" , vpsravd(zmm29, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222154046ACF023010000" , vpsravd(zmm29, zmm29, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626215504629" , vpsravd(zmm29, zmm29, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62621540466A7F" , vpsravd(zmm29, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262154046AA00200000" , vpsravd(zmm29, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62621540466A80" , vpsravd(zmm29, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262154046AAC0DFFFFF" , vpsravd(zmm29, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62621550466A7F" , vpsravd(zmm29, zmm29, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("6262155046AA00020000" , vpsravd(zmm29, zmm29, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62621550466A80" , vpsravd(zmm29, zmm29, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("6262155046AAFCFDFFFF" , vpsravd(zmm29, zmm29, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62E2DD4046F2" , vpsravq(zmm22, zmm20, zmm2));
+ TEST_INSTRUCTION("62E2DD4246F2" , k(k2).vpsravq(zmm22, zmm20, zmm2));
+ TEST_INSTRUCTION("62E2DDC246F2" , k(k2).z().vpsravq(zmm22, zmm20, zmm2));
+ TEST_INSTRUCTION("62E2DD404631" , vpsravq(zmm22, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2DD4046B4F023010000" , vpsravq(zmm22, zmm20, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2DD504631" , vpsravq(zmm22, zmm20, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2DD4046727F" , vpsravq(zmm22, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2DD4046B200200000" , vpsravq(zmm22, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2DD40467280" , vpsravq(zmm22, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2DD4046B2C0DFFFFF" , vpsravq(zmm22, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2DD5046727F" , vpsravq(zmm22, zmm20, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2DD5046B200040000" , vpsravq(zmm22, zmm20, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2DD50467280" , vpsravq(zmm22, zmm20, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2DD5046B2F8FBFFFF" , vpsravq(zmm22, zmm20, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62917540D2C9" , vpsrld(zmm1, zmm17, xmm25));
+ TEST_INSTRUCTION("62917544D2C9" , k(k4).vpsrld(zmm1, zmm17, xmm25));
+ TEST_INSTRUCTION("629175C4D2C9" , k(k4).z().vpsrld(zmm1, zmm17, xmm25));
+ TEST_INSTRUCTION("62F17540D209" , vpsrld(zmm1, zmm17, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17540D28CF023010000" , vpsrld(zmm1, zmm17, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17540D24A7F" , vpsrld(zmm1, zmm17, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62F17540D28A00080000" , vpsrld(zmm1, zmm17, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62F17540D24A80" , vpsrld(zmm1, zmm17, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62F17540D28AF0F7FFFF" , vpsrld(zmm1, zmm17, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6271A548D3CB" , vpsrlq(zmm9, zmm11, xmm3));
+ TEST_INSTRUCTION("6271A54DD3CB" , k(k5).vpsrlq(zmm9, zmm11, xmm3));
+ TEST_INSTRUCTION("6271A5CDD3CB" , k(k5).z().vpsrlq(zmm9, zmm11, xmm3));
+ TEST_INSTRUCTION("6271A548D309" , vpsrlq(zmm9, zmm11, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231A548D38CF023010000" , vpsrlq(zmm9, zmm11, xmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271A548D34A7F" , vpsrlq(zmm9, zmm11, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("6271A548D38A00080000" , vpsrlq(zmm9, zmm11, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("6271A548D34A80" , vpsrlq(zmm9, zmm11, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("6271A548D38AF0F7FFFF" , vpsrlq(zmm9, zmm11, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62120D4845C4" , vpsrlvd(zmm8, zmm14, zmm28));
+ TEST_INSTRUCTION("62120D4C45C4" , k(k4).vpsrlvd(zmm8, zmm14, zmm28));
+ TEST_INSTRUCTION("62120DCC45C4" , k(k4).z().vpsrlvd(zmm8, zmm14, zmm28));
+ TEST_INSTRUCTION("62720D484501" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62320D484584F023010000" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62720D584501" , vpsrlvd(zmm8, zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62720D4845427F" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62720D48458200200000" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62720D48454280" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62720D484582C0DFFFFF" , vpsrlvd(zmm8, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62720D5845427F" , vpsrlvd(zmm8, zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62720D58458200020000" , vpsrlvd(zmm8, zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62720D58454280" , vpsrlvd(zmm8, zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62720D584582FCFDFFFF" , vpsrlvd(zmm8, zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6282C54845E2" , vpsrlvq(zmm20, zmm7, zmm26));
+ TEST_INSTRUCTION("6282C54D45E2" , k(k5).vpsrlvq(zmm20, zmm7, zmm26));
+ TEST_INSTRUCTION("6282C5CD45E2" , k(k5).z().vpsrlvq(zmm20, zmm7, zmm26));
+ TEST_INSTRUCTION("62E2C5484521" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2C54845A4F023010000" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2C5584521" , vpsrlvq(zmm20, zmm7, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2C54845627F" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2C54845A200200000" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2C548456280" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2C54845A2C0DFFFFF" , vpsrlvq(zmm20, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2C55845627F" , vpsrlvq(zmm20, zmm7, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2C55845A200040000" , vpsrlvq(zmm20, zmm7, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2C558456280" , vpsrlvq(zmm20, zmm7, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2C55845A2F8FBFFFF" , vpsrlvq(zmm20, zmm7, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F1654872D5AB" , vpsrld(zmm3, zmm5, 171));
+ TEST_INSTRUCTION("62F1654C72D5AB" , k(k4).vpsrld(zmm3, zmm5, 171));
+ TEST_INSTRUCTION("62F165CC72D5AB" , k(k4).z().vpsrld(zmm3, zmm5, 171));
+ TEST_INSTRUCTION("62F1654872D57B" , vpsrld(zmm3, zmm5, 123));
+ TEST_INSTRUCTION("62F1654872117B" , vpsrld(zmm3, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B165487294F0230100007B" , vpsrld(zmm3, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1655872117B" , vpsrld(zmm3, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1654872527F7B" , vpsrld(zmm3, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F165487292002000007B" , vpsrld(zmm3, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F165487252807B" , vpsrld(zmm3, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F165487292C0DFFFFF7B" , vpsrld(zmm3, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1655872527F7B" , vpsrld(zmm3, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F165587292000200007B" , vpsrld(zmm3, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F165587252807B" , vpsrld(zmm3, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F165587292FCFDFFFF7B" , vpsrld(zmm3, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6291ED4073D1AB" , vpsrlq(zmm18, zmm25, 171));
+ TEST_INSTRUCTION("6291ED4173D1AB" , k(k1).vpsrlq(zmm18, zmm25, 171));
+ TEST_INSTRUCTION("6291EDC173D1AB" , k(k1).z().vpsrlq(zmm18, zmm25, 171));
+ TEST_INSTRUCTION("6291ED4073D17B" , vpsrlq(zmm18, zmm25, 123));
+ TEST_INSTRUCTION("62F1ED4073117B" , vpsrlq(zmm18, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1ED407394F0230100007B" , vpsrlq(zmm18, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1ED5073117B" , vpsrlq(zmm18, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1ED4073527F7B" , vpsrlq(zmm18, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1ED407392002000007B" , vpsrlq(zmm18, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1ED407352807B" , vpsrlq(zmm18, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1ED407392C0DFFFFF7B" , vpsrlq(zmm18, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1ED5073527F7B" , vpsrlq(zmm18, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1ED507392000400007B" , vpsrlq(zmm18, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1ED507352807B" , vpsrlq(zmm18, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1ED507392F8FBFFFF7B" , vpsrlq(zmm18, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F11D40FAFF" , vpsubd(zmm7, zmm28, zmm7));
+ TEST_INSTRUCTION("62F11D43FAFF" , k(k3).vpsubd(zmm7, zmm28, zmm7));
+ TEST_INSTRUCTION("62F11DC3FAFF" , k(k3).z().vpsubd(zmm7, zmm28, zmm7));
+ TEST_INSTRUCTION("62F11D40FA39" , vpsubd(zmm7, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B11D40FABCF023010000" , vpsubd(zmm7, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F11D50FA39" , vpsubd(zmm7, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F11D40FA7A7F" , vpsubd(zmm7, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F11D40FABA00200000" , vpsubd(zmm7, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F11D40FA7A80" , vpsubd(zmm7, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F11D40FABAC0DFFFFF" , vpsubd(zmm7, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F11D50FA7A7F" , vpsubd(zmm7, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F11D50FABA00020000" , vpsubd(zmm7, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F11D50FA7A80" , vpsubd(zmm7, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F11D50FABAFCFDFFFF" , vpsubd(zmm7, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62219D40FBE9" , vpsubq(zmm29, zmm28, zmm17));
+ TEST_INSTRUCTION("62219D42FBE9" , k(k2).vpsubq(zmm29, zmm28, zmm17));
+ TEST_INSTRUCTION("62219DC2FBE9" , k(k2).z().vpsubq(zmm29, zmm28, zmm17));
+ TEST_INSTRUCTION("62619D40FB29" , vpsubq(zmm29, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62219D40FBACF023010000" , vpsubq(zmm29, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62619D50FB29" , vpsubq(zmm29, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62619D40FB6A7F" , vpsubq(zmm29, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62619D40FBAA00200000" , vpsubq(zmm29, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62619D40FB6A80" , vpsubq(zmm29, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62619D40FBAAC0DFFFFF" , vpsubq(zmm29, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62619D50FB6A7F" , vpsubq(zmm29, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62619D50FBAA00040000" , vpsubq(zmm29, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62619D50FB6A80" , vpsubq(zmm29, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62619D50FBAAF8FBFFFF" , vpsubq(zmm29, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B21D4827D0" , vptestmd(k2, zmm12, zmm16));
+ TEST_INSTRUCTION("62B21D4927D0" , k(k1).vptestmd(k2, zmm12, zmm16));
+ TEST_INSTRUCTION("62F21D482711" , vptestmd(k2, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B21D482794F023010000" , vptestmd(k2, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F21D582711" , vptestmd(k2, zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F21D4827527F" , vptestmd(k2, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F21D48279200200000" , vptestmd(k2, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F21D48275280" , vptestmd(k2, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F21D482792C0DFFFFF" , vptestmd(k2, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F21D5827527F" , vptestmd(k2, zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F21D58279200020000" , vptestmd(k2, zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F21D58275280" , vptestmd(k2, zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F21D582792FCFDFFFF" , vptestmd(k2, zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B2CD4827ED" , vptestmq(k5, zmm6, zmm21));
+ TEST_INSTRUCTION("62B2CD4D27ED" , k(k5).vptestmq(k5, zmm6, zmm21));
+ TEST_INSTRUCTION("62F2CD482729" , vptestmq(k5, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2CD4827ACF023010000" , vptestmq(k5, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2CD582729" , vptestmq(k5, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2CD48276A7F" , vptestmq(k5, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2CD4827AA00200000" , vptestmq(k5, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2CD48276A80" , vptestmq(k5, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2CD4827AAC0DFFFFF" , vptestmq(k5, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2CD58276A7F" , vptestmq(k5, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2CD5827AA00040000" , vptestmq(k5, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD58276A80" , vptestmq(k5, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD5827AAF8FBFFFF" , vptestmq(k5, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D15D486AF5" , vpunpckhdq(zmm6, zmm4, zmm13));
+ TEST_INSTRUCTION("62D15D4D6AF5" , k(k5).vpunpckhdq(zmm6, zmm4, zmm13));
+ TEST_INSTRUCTION("62D15DCD6AF5" , k(k5).z().vpunpckhdq(zmm6, zmm4, zmm13));
+ TEST_INSTRUCTION("62F15D486A31" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B15D486AB4F023010000" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F15D586A31" , vpunpckhdq(zmm6, zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F15D486A727F" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F15D486AB200200000" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F15D486A7280" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F15D486AB2C0DFFFFF" , vpunpckhdq(zmm6, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F15D586A727F" , vpunpckhdq(zmm6, zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F15D586AB200020000" , vpunpckhdq(zmm6, zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F15D586A7280" , vpunpckhdq(zmm6, zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F15D586AB2FCFDFFFF" , vpunpckhdq(zmm6, zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("622185486DD8" , vpunpckhqdq(zmm27, zmm15, zmm16));
+ TEST_INSTRUCTION("6221854B6DD8" , k(k3).vpunpckhqdq(zmm27, zmm15, zmm16));
+ TEST_INSTRUCTION("622185CB6DD8" , k(k3).z().vpunpckhqdq(zmm27, zmm15, zmm16));
+ TEST_INSTRUCTION("626185486D19" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622185486D9CF023010000" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626185586D19" , vpunpckhqdq(zmm27, zmm15, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("626185486D5A7F" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("626185486D9A00200000" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("626185486D5A80" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626185486D9AC0DFFFFF" , vpunpckhqdq(zmm27, zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("626185586D5A7F" , vpunpckhqdq(zmm27, zmm15, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("626185586D9A00040000" , vpunpckhqdq(zmm27, zmm15, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("626185586D5A80" , vpunpckhqdq(zmm27, zmm15, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("626185586D9AF8FBFFFF" , vpunpckhqdq(zmm27, zmm15, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6221654862C1" , vpunpckldq(zmm24, zmm3, zmm17));
+ TEST_INSTRUCTION("6221654B62C1" , k(k3).vpunpckldq(zmm24, zmm3, zmm17));
+ TEST_INSTRUCTION("622165CB62C1" , k(k3).z().vpunpckldq(zmm24, zmm3, zmm17));
+ TEST_INSTRUCTION("626165486201" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622165486284F023010000" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626165586201" , vpunpckldq(zmm24, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("6261654862427F" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62616548628200200000" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62616548624280" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626165486282C0DFFFFF" , vpunpckldq(zmm24, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261655862427F" , vpunpckldq(zmm24, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62616558628200020000" , vpunpckldq(zmm24, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62616558624280" , vpunpckldq(zmm24, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("626165586282FCFDFFFF" , vpunpckldq(zmm24, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B1DD486CD9" , vpunpcklqdq(zmm3, zmm4, zmm17));
+ TEST_INSTRUCTION("62B1DD496CD9" , k(k1).vpunpcklqdq(zmm3, zmm4, zmm17));
+ TEST_INSTRUCTION("62B1DDC96CD9" , k(k1).z().vpunpcklqdq(zmm3, zmm4, zmm17));
+ TEST_INSTRUCTION("62F1DD486C19" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1DD486C9CF023010000" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1DD586C19" , vpunpcklqdq(zmm3, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1DD486C5A7F" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1DD486C9A00200000" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1DD486C5A80" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1DD486C9AC0DFFFFF" , vpunpcklqdq(zmm3, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1DD586C5A7F" , vpunpcklqdq(zmm3, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1DD586C9A00040000" , vpunpcklqdq(zmm3, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1DD586C5A80" , vpunpcklqdq(zmm3, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1DD586C9AF8FBFFFF" , vpunpcklqdq(zmm3, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62111D48EFC0" , vpxord(zmm8, zmm12, zmm24));
+ TEST_INSTRUCTION("62111D4EEFC0" , k(k6).vpxord(zmm8, zmm12, zmm24));
+ TEST_INSTRUCTION("62111DCEEFC0" , k(k6).z().vpxord(zmm8, zmm12, zmm24));
+ TEST_INSTRUCTION("62711D48EF01" , vpxord(zmm8, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62311D48EF84F023010000" , vpxord(zmm8, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62711D58EF01" , vpxord(zmm8, zmm12, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62711D48EF427F" , vpxord(zmm8, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62711D48EF8200200000" , vpxord(zmm8, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62711D48EF4280" , vpxord(zmm8, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62711D48EF82C0DFFFFF" , vpxord(zmm8, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62711D58EF427F" , vpxord(zmm8, zmm12, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62711D58EF8200020000" , vpxord(zmm8, zmm12, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62711D58EF4280" , vpxord(zmm8, zmm12, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62711D58EF82FCFDFFFF" , vpxord(zmm8, zmm12, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D1CD40EFFA" , vpxorq(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D1CD46EFFA" , k(k6).vpxorq(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D1CDC6EFFA" , k(k6).z().vpxorq(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62F1CD40EF39" , vpxorq(zmm7, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1CD40EFBCF023010000" , vpxorq(zmm7, zmm22, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1CD50EF39" , vpxorq(zmm7, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1CD40EF7A7F" , vpxorq(zmm7, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1CD40EFBA00200000" , vpxorq(zmm7, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1CD40EF7A80" , vpxorq(zmm7, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1CD40EFBAC0DFFFFF" , vpxorq(zmm7, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1CD50EF7A7F" , vpxorq(zmm7, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1CD50EFBA00040000" , vpxorq(zmm7, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1CD50EF7A80" , vpxorq(zmm7, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1CD50EFBAF8FBFFFF" , vpxorq(zmm7, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6272FD484CEC" , vrcp14pd(zmm13, zmm4));
+ TEST_INSTRUCTION("6272FD4D4CEC" , k(k5).vrcp14pd(zmm13, zmm4));
+ TEST_INSTRUCTION("6272FDCD4CEC" , k(k5).z().vrcp14pd(zmm13, zmm4));
+ TEST_INSTRUCTION("6272FD484C29" , vrcp14pd(zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232FD484CACF023010000" , vrcp14pd(zmm13, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272FD584C29" , vrcp14pd(zmm13, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272FD484C6A7F" , vrcp14pd(zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272FD484CAA00200000" , vrcp14pd(zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272FD484C6A80" , vrcp14pd(zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272FD484CAAC0DFFFFF" , vrcp14pd(zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272FD584C6A7F" , vrcp14pd(zmm13, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272FD584CAA00040000" , vrcp14pd(zmm13, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272FD584C6A80" , vrcp14pd(zmm13, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272FD584CAAF8FBFFFF" , vrcp14pd(zmm13, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62127D484CD1" , vrcp14ps(zmm10, zmm25));
+ TEST_INSTRUCTION("62127D494CD1" , k(k1).vrcp14ps(zmm10, zmm25));
+ TEST_INSTRUCTION("62127DC94CD1" , k(k1).z().vrcp14ps(zmm10, zmm25));
+ TEST_INSTRUCTION("62727D484C11" , vrcp14ps(zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D484C94F023010000" , vrcp14ps(zmm10, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62727D584C11" , vrcp14ps(zmm10, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62727D484C527F" , vrcp14ps(zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62727D484C9200200000" , vrcp14ps(zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62727D484C5280" , vrcp14ps(zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62727D484C92C0DFFFFF" , vrcp14ps(zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62727D584C527F" , vrcp14ps(zmm10, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62727D584C9200020000" , vrcp14ps(zmm10, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62727D584C5280" , vrcp14ps(zmm10, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62727D584C92FCFDFFFF" , vrcp14ps(zmm10, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6252CD004DE6" , vrcp14sd(xmm12, xmm22, xmm14));
+ TEST_INSTRUCTION("6252CD024DE6" , k(k2).vrcp14sd(xmm12, xmm22, xmm14));
+ TEST_INSTRUCTION("6252CD824DE6" , k(k2).z().vrcp14sd(xmm12, xmm22, xmm14));
+ TEST_INSTRUCTION("6272CD004D21" , vrcp14sd(xmm12, xmm22, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6232CD004DA4F023010000" , vrcp14sd(xmm12, xmm22, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272CD004D627F" , vrcp14sd(xmm12, xmm22, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6272CD004DA200040000" , vrcp14sd(xmm12, xmm22, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6272CD004D6280" , vrcp14sd(xmm12, xmm22, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6272CD004DA2F8FBFFFF" , vrcp14sd(xmm12, xmm22, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62723D084DC3" , vrcp14ss(xmm8, xmm8, xmm3));
+ TEST_INSTRUCTION("62723D0F4DC3" , k(k7).vrcp14ss(xmm8, xmm8, xmm3));
+ TEST_INSTRUCTION("62723D8F4DC3" , k(k7).z().vrcp14ss(xmm8, xmm8, xmm3));
+ TEST_INSTRUCTION("62723D084D01" , vrcp14ss(xmm8, xmm8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62323D084D84F023010000" , vrcp14ss(xmm8, xmm8, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62723D084D427F" , vrcp14ss(xmm8, xmm8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62723D084D8200020000" , vrcp14ss(xmm8, xmm8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62723D084D4280" , vrcp14ss(xmm8, xmm8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62723D084D82FCFDFFFF" , vrcp14ss(xmm8, xmm8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C2FD484EDE" , vrsqrt14pd(zmm19, zmm14));
+ TEST_INSTRUCTION("62C2FD494EDE" , k(k1).vrsqrt14pd(zmm19, zmm14));
+ TEST_INSTRUCTION("62C2FDC94EDE" , k(k1).z().vrsqrt14pd(zmm19, zmm14));
+ TEST_INSTRUCTION("62E2FD484E19" , vrsqrt14pd(zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD484E9CF023010000" , vrsqrt14pd(zmm19, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2FD584E19" , vrsqrt14pd(zmm19, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2FD484E5A7F" , vrsqrt14pd(zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2FD484E9A00200000" , vrsqrt14pd(zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2FD484E5A80" , vrsqrt14pd(zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2FD484E9AC0DFFFFF" , vrsqrt14pd(zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2FD584E5A7F" , vrsqrt14pd(zmm19, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2FD584E9A00040000" , vrsqrt14pd(zmm19, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD584E5A80" , vrsqrt14pd(zmm19, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD584E9AF8FBFFFF" , vrsqrt14pd(zmm19, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C27D484EC1" , vrsqrt14ps(zmm16, zmm9));
+ TEST_INSTRUCTION("62C27D4D4EC1" , k(k5).vrsqrt14ps(zmm16, zmm9));
+ TEST_INSTRUCTION("62C27DCD4EC1" , k(k5).z().vrsqrt14ps(zmm16, zmm9));
+ TEST_INSTRUCTION("62E27D484E01" , vrsqrt14ps(zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D484E84F023010000" , vrsqrt14ps(zmm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E27D584E01" , vrsqrt14ps(zmm16, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E27D484E427F" , vrsqrt14ps(zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E27D484E8200200000" , vrsqrt14ps(zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E27D484E4280" , vrsqrt14ps(zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E27D484E82C0DFFFFF" , vrsqrt14ps(zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E27D584E427F" , vrsqrt14ps(zmm16, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E27D584E8200020000" , vrsqrt14ps(zmm16, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E27D584E4280" , vrsqrt14ps(zmm16, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E27D584E82FCFDFFFF" , vrsqrt14ps(zmm16, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6242CD084FD2" , vrsqrt14sd(xmm26, xmm6, xmm10));
+ TEST_INSTRUCTION("6242CD0D4FD2" , k(k5).vrsqrt14sd(xmm26, xmm6, xmm10));
+ TEST_INSTRUCTION("6242CD8D4FD2" , k(k5).z().vrsqrt14sd(xmm26, xmm6, xmm10));
+ TEST_INSTRUCTION("6262CD084F11" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222CD084F94F023010000" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262CD084F527F" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262CD084F9200040000" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262CD084F5280" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262CD084F92F8FBFFFF" , vrsqrt14sd(xmm26, xmm6, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62520D084FF1" , vrsqrt14ss(xmm14, xmm14, xmm9));
+ TEST_INSTRUCTION("62520D094FF1" , k(k1).vrsqrt14ss(xmm14, xmm14, xmm9));
+ TEST_INSTRUCTION("62520D894FF1" , k(k1).z().vrsqrt14ss(xmm14, xmm14, xmm9));
+ TEST_INSTRUCTION("62720D084F31" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62320D084FB4F023010000" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62720D084F727F" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62720D084FB200020000" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62720D084F7280" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62720D084FB2FCFDFFFF" , vrsqrt14ss(xmm14, xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6221BD48C6E6AB" , vshufpd(zmm28, zmm8, zmm22, 171));
+ TEST_INSTRUCTION("6221BD4AC6E6AB" , k(k2).vshufpd(zmm28, zmm8, zmm22, 171));
+ TEST_INSTRUCTION("6221BDCAC6E6AB" , k(k2).z().vshufpd(zmm28, zmm8, zmm22, 171));
+ TEST_INSTRUCTION("6221BD48C6E67B" , vshufpd(zmm28, zmm8, zmm22, 123));
+ TEST_INSTRUCTION("6261BD48C6217B" , vshufpd(zmm28, zmm8, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6221BD48C6A4F0230100007B" , vshufpd(zmm28, zmm8, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6261BD58C6217B" , vshufpd(zmm28, zmm8, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6261BD48C6627F7B" , vshufpd(zmm28, zmm8, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6261BD48C6A2002000007B" , vshufpd(zmm28, zmm8, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6261BD48C662807B" , vshufpd(zmm28, zmm8, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6261BD48C6A2C0DFFFFF7B" , vshufpd(zmm28, zmm8, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6261BD58C6627F7B" , vshufpd(zmm28, zmm8, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6261BD58C6A2000400007B" , vshufpd(zmm28, zmm8, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6261BD58C662807B" , vshufpd(zmm28, zmm8, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6261BD58C6A2F8FBFFFF7B" , vshufpd(zmm28, zmm8, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62D14C48C6E9AB" , vshufps(zmm5, zmm6, zmm9, 171));
+ TEST_INSTRUCTION("62D14C4EC6E9AB" , k(k6).vshufps(zmm5, zmm6, zmm9, 171));
+ TEST_INSTRUCTION("62D14CCEC6E9AB" , k(k6).z().vshufps(zmm5, zmm6, zmm9, 171));
+ TEST_INSTRUCTION("62D14C48C6E97B" , vshufps(zmm5, zmm6, zmm9, 123));
+ TEST_INSTRUCTION("62F14C48C6297B" , vshufps(zmm5, zmm6, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B14C48C6ACF0230100007B" , vshufps(zmm5, zmm6, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F14C58C6297B" , vshufps(zmm5, zmm6, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F14C48C66A7F7B" , vshufps(zmm5, zmm6, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F14C48C6AA002000007B" , vshufps(zmm5, zmm6, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F14C48C66A807B" , vshufps(zmm5, zmm6, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F14C48C6AAC0DFFFFF7B" , vshufps(zmm5, zmm6, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F14C58C66A7F7B" , vshufps(zmm5, zmm6, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F14C58C6AA000200007B" , vshufps(zmm5, zmm6, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F14C58C66A807B" , vshufps(zmm5, zmm6, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F14C58C6AAFCFDFFFF7B" , vshufps(zmm5, zmm6, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62A1FD4851DB" , vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FD4D51DB" , k(k5).vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FDCD51DB" , k(k5).z().vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FD1851DB" , rn_sae().vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FD5851DB" , ru_sae().vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FD3851DB" , rd_sae().vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62A1FD7851DB" , rz_sae().vsqrtpd(zmm19, zmm19));
+ TEST_INSTRUCTION("62E1FD485119" , vsqrtpd(zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD48519CF023010000" , vsqrtpd(zmm19, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1FD585119" , vsqrtpd(zmm19, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1FD48515A7F" , vsqrtpd(zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD48519A00200000" , vsqrtpd(zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD48515A80" , vsqrtpd(zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD48519AC0DFFFFF" , vsqrtpd(zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FD58515A7F" , vsqrtpd(zmm19, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1FD58519A00040000" , vsqrtpd(zmm19, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD58515A80" , vsqrtpd(zmm19, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD58519AF8FBFFFF" , vsqrtpd(zmm19, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62017C4851E5" , vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017C4B51E5" , k(k3).vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017CCB51E5" , k(k3).z().vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017C1851E5" , rn_sae().vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017C5851E5" , ru_sae().vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017C3851E5" , rd_sae().vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62017C7851E5" , rz_sae().vsqrtps(zmm28, zmm29));
+ TEST_INSTRUCTION("62617C485121" , vsqrtps(zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62217C4851A4F023010000" , vsqrtps(zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62617C585121" , vsqrtps(zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62617C4851627F" , vsqrtps(zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62617C4851A200200000" , vsqrtps(zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62617C48516280" , vsqrtps(zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62617C4851A2C0DFFFFF" , vsqrtps(zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62617C5851627F" , vsqrtps(zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62617C5851A200020000" , vsqrtps(zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62617C58516280" , vsqrtps(zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62617C5851A2FCFDFFFF" , vsqrtps(zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4C16B51F4" , vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF0F51F4" , k(k7).vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF8F51F4" , k(k7).z().vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF1851F4" , rn_sae().vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF5851F4" , ru_sae().vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF3851F4" , rd_sae().vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("62D1EF7851F4" , rz_sae().vsqrtsd(xmm6, xmm2, xmm12));
+ TEST_INSTRUCTION("C5EB5131" , vsqrtsd(xmm6, xmm2, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A16B51B4F023010000" , vsqrtsd(xmm6, xmm2, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5EB51B2F8030000" , vsqrtsd(xmm6, xmm2, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C5EB51B200040000" , vsqrtsd(xmm6, xmm2, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C5EB51B200FCFFFF" , vsqrtsd(xmm6, xmm2, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C5EB51B2F8FBFFFF" , vsqrtsd(xmm6, xmm2, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C1660051F0" , vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1660151F0" , k(k1).vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1668151F0" , k(k1).z().vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1661051F0" , rn_sae().vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1665051F0" , ru_sae().vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1663051F0" , rd_sae().vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62C1667051F0" , rz_sae().vsqrtss(xmm22, xmm19, xmm8));
+ TEST_INSTRUCTION("62E166005131" , vsqrtss(xmm22, xmm19, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1660051B4F023010000" , vsqrtss(xmm22, xmm19, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1660051727F" , vsqrtss(xmm22, xmm19, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E1660051B200020000" , vsqrtss(xmm22, xmm19, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E16600517280" , vsqrtss(xmm22, xmm19, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E1660051B2FCFDFFFF" , vsqrtss(xmm22, xmm19, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62519D485CC9" , vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519D4F5CC9" , k(k7).vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519DCF5CC9" , k(k7).z().vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519D185CC9" , rn_sae().vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519D585CC9" , ru_sae().vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519D385CC9" , rd_sae().vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62519D785CC9" , rz_sae().vsubpd(zmm9, zmm12, zmm9));
+ TEST_INSTRUCTION("62719D485C09" , vsubpd(zmm9, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62319D485C8CF023010000" , vsubpd(zmm9, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62719D585C09" , vsubpd(zmm9, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62719D485C4A7F" , vsubpd(zmm9, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62719D485C8A00200000" , vsubpd(zmm9, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62719D485C4A80" , vsubpd(zmm9, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62719D485C8AC0DFFFFF" , vsubpd(zmm9, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62719D585C4A7F" , vsubpd(zmm9, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62719D585C8A00040000" , vsubpd(zmm9, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62719D585C4A80" , vsubpd(zmm9, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62719D585C8AF8FBFFFF" , vsubpd(zmm9, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("623124405CF5" , vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124455CF5" , k(k5).vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124C55CF5" , k(k5).z().vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124105CF5" , rn_sae().vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124505CF5" , ru_sae().vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124305CF5" , rd_sae().vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("623124705CF5" , rz_sae().vsubps(zmm14, zmm27, zmm21));
+ TEST_INSTRUCTION("627124405C31" , vsubps(zmm14, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("623124405CB4F023010000" , vsubps(zmm14, zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("627124505C31" , vsubps(zmm14, zmm27, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("627124405C727F" , vsubps(zmm14, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("627124405CB200200000" , vsubps(zmm14, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("627124405C7280" , vsubps(zmm14, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("627124405CB2C0DFFFFF" , vsubps(zmm14, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("627124505C727F" , vsubps(zmm14, zmm27, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("627124505CB200020000" , vsubps(zmm14, zmm27, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("627124505C7280" , vsubps(zmm14, zmm27, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("627124505CB2FCFDFFFF" , vsubps(zmm14, zmm27, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C1A7005CE7" , vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7055CE7" , k(k5).vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7855CE7" , k(k5).z().vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7105CE7" , rn_sae().vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7505CE7" , ru_sae().vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7305CE7" , rd_sae().vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62C1A7705CE7" , rz_sae().vsubsd(xmm20, xmm27, xmm15));
+ TEST_INSTRUCTION("62E1A7005C21" , vsubsd(xmm20, xmm27, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1A7005CA4F023010000" , vsubsd(xmm20, xmm27, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1A7005C627F" , vsubsd(xmm20, xmm27, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1A7005CA200040000" , vsubsd(xmm20, xmm27, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1A7005C6280" , vsubsd(xmm20, xmm27, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1A7005CA2F8FBFFFF" , vsubsd(xmm20, xmm27, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62D136005CE9" , vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136035CE9" , k(k3).vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136835CE9" , k(k3).z().vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136105CE9" , rn_sae().vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136505CE9" , ru_sae().vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136305CE9" , rd_sae().vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62D136705CE9" , rz_sae().vsubss(xmm5, xmm25, xmm9));
+ TEST_INSTRUCTION("62F136005C29" , vsubss(xmm5, xmm25, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B136005CACF023010000" , vsubss(xmm5, xmm25, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F136005C6A7F" , vsubss(xmm5, xmm25, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F136005CAA00020000" , vsubss(xmm5, xmm25, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F136005C6A80" , vsubss(xmm5, xmm25, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F136005CAAFCFDFFFF" , vsubss(xmm5, xmm25, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C441792EDA" , vucomisd(xmm11, xmm10));
+ TEST_INSTRUCTION("6251FD182EDA" , sae().vucomisd(xmm11, xmm10));
+ TEST_INSTRUCTION("C5792E19" , vucomisd(xmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C421792E9CF023010000" , vucomisd(xmm11, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5792E9AF8030000" , vucomisd(xmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C5792E9A00040000" , vucomisd(xmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C5792E9A00FCFFFF" , vucomisd(xmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C5792E9AF8FBFFFF" , vucomisd(xmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C17C082EF3" , vucomiss(xmm22, xmm11));
+ TEST_INSTRUCTION("62C17C182EF3" , sae().vucomiss(xmm22, xmm11));
+ TEST_INSTRUCTION("62E17C082E31" , vucomiss(xmm22, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17C082EB4F023010000" , vucomiss(xmm22, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E17C082E727F" , vucomiss(xmm22, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E17C082EB200020000" , vucomiss(xmm22, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E17C082E7280" , vucomiss(xmm22, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E17C082EB2FCFDFFFF" , vucomiss(xmm22, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6201E54015CA" , vunpckhpd(zmm25, zmm19, zmm26));
+ TEST_INSTRUCTION("6201E54515CA" , k(k5).vunpckhpd(zmm25, zmm19, zmm26));
+ TEST_INSTRUCTION("6201E5C515CA" , k(k5).z().vunpckhpd(zmm25, zmm19, zmm26));
+ TEST_INSTRUCTION("6261E5401509" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221E540158CF023010000" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6261E5501509" , vunpckhpd(zmm25, zmm19, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261E540154A7F" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261E540158A00200000" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261E540154A80" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261E540158AC0DFFFFF" , vunpckhpd(zmm25, zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261E550154A7F" , vunpckhpd(zmm25, zmm19, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261E550158A00040000" , vunpckhpd(zmm25, zmm19, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261E550154A80" , vunpckhpd(zmm25, zmm19, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261E550158AF8FBFFFF" , vunpckhpd(zmm25, zmm19, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B10C4815E8" , vunpckhps(zmm5, zmm14, zmm16));
+ TEST_INSTRUCTION("62B10C4E15E8" , k(k6).vunpckhps(zmm5, zmm14, zmm16));
+ TEST_INSTRUCTION("62B10CCE15E8" , k(k6).z().vunpckhps(zmm5, zmm14, zmm16));
+ TEST_INSTRUCTION("62F10C481529" , vunpckhps(zmm5, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B10C4815ACF023010000" , vunpckhps(zmm5, zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F10C581529" , vunpckhps(zmm5, zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F10C48156A7F" , vunpckhps(zmm5, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F10C4815AA00200000" , vunpckhps(zmm5, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F10C48156A80" , vunpckhps(zmm5, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F10C4815AAC0DFFFFF" , vunpckhps(zmm5, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F10C58156A7F" , vunpckhps(zmm5, zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F10C5815AA00020000" , vunpckhps(zmm5, zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F10C58156A80" , vunpckhps(zmm5, zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F10C5815AAFCFDFFFF" , vunpckhps(zmm5, zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1954014D5" , vunpcklpd(zmm18, zmm29, zmm21));
+ TEST_INSTRUCTION("62A1954614D5" , k(k6).vunpcklpd(zmm18, zmm29, zmm21));
+ TEST_INSTRUCTION("62A195C614D5" , k(k6).z().vunpcklpd(zmm18, zmm29, zmm21));
+ TEST_INSTRUCTION("62E195401411" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A195401494F023010000" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E195501411" , vunpcklpd(zmm18, zmm29, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1954014527F" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E19540149200200000" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E19540145280" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E195401492C0DFFFFF" , vunpcklpd(zmm18, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1955014527F" , vunpcklpd(zmm18, zmm29, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E19550149200040000" , vunpcklpd(zmm18, zmm29, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E19550145280" , vunpcklpd(zmm18, zmm29, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E195501492F8FBFFFF" , vunpcklpd(zmm18, zmm29, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F1644814CA" , vunpcklps(zmm1, zmm3, zmm2));
+ TEST_INSTRUCTION("62F1644B14CA" , k(k3).vunpcklps(zmm1, zmm3, zmm2));
+ TEST_INSTRUCTION("62F164CB14CA" , k(k3).z().vunpcklps(zmm1, zmm3, zmm2));
+ TEST_INSTRUCTION("62F164481409" , vunpcklps(zmm1, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B16448148CF023010000" , vunpcklps(zmm1, zmm3, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F164581409" , vunpcklps(zmm1, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F16448144A7F" , vunpcklps(zmm1, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F16448148A00200000" , vunpcklps(zmm1, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F16448144A80" , vunpcklps(zmm1, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F16448148AC0DFFFFF" , vunpcklps(zmm1, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F16458144A7F" , vunpcklps(zmm1, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F16458148A00020000" , vunpcklps(zmm1, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F16458144A80" , vunpcklps(zmm1, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F16458148AFCFDFFFF" , vunpcklps(zmm1, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62330D4825E4AB" , vpternlogd(zmm12, zmm14, zmm20, 171));
+ TEST_INSTRUCTION("62330D4F25E4AB" , k(k7).vpternlogd(zmm12, zmm14, zmm20, 171));
+ TEST_INSTRUCTION("62330DCF25E4AB" , k(k7).z().vpternlogd(zmm12, zmm14, zmm20, 171));
+ TEST_INSTRUCTION("62330D4825E47B" , vpternlogd(zmm12, zmm14, zmm20, 123));
+ TEST_INSTRUCTION("62730D4825217B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62330D4825A4F0230100007B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62730D5825217B" , vpternlogd(zmm12, zmm14, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62730D4825627F7B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62730D4825A2002000007B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62730D482562807B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62730D4825A2C0DFFFFF7B" , vpternlogd(zmm12, zmm14, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62730D5825627F7B" , vpternlogd(zmm12, zmm14, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62730D5825A2000200007B" , vpternlogd(zmm12, zmm14, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62730D582562807B" , vpternlogd(zmm12, zmm14, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62730D5825A2FCFDFFFF7B" , vpternlogd(zmm12, zmm14, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6233ED4825FDAB" , vpternlogq(zmm15, zmm2, zmm21, 171));
+ TEST_INSTRUCTION("6233ED4B25FDAB" , k(k3).vpternlogq(zmm15, zmm2, zmm21, 171));
+ TEST_INSTRUCTION("6233EDCB25FDAB" , k(k3).z().vpternlogq(zmm15, zmm2, zmm21, 171));
+ TEST_INSTRUCTION("6233ED4825FD7B" , vpternlogq(zmm15, zmm2, zmm21, 123));
+ TEST_INSTRUCTION("6273ED4825397B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233ED4825BCF0230100007B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6273ED5825397B" , vpternlogq(zmm15, zmm2, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273ED48257A7F7B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273ED4825BA002000007B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273ED48257A807B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273ED4825BAC0DFFFFF7B" , vpternlogq(zmm15, zmm2, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273ED58257A7F7B" , vpternlogq(zmm15, zmm2, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273ED5825BA000400007B" , vpternlogq(zmm15, zmm2, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273ED58257A807B" , vpternlogq(zmm15, zmm2, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273ED5825BAF8FBFFFF7B" , vpternlogq(zmm15, zmm2, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F27E4832D3" , vpmovqb(xmm3, zmm2));
+ TEST_INSTRUCTION("62F27E4932D3" , k(k1).vpmovqb(xmm3, zmm2));
+ TEST_INSTRUCTION("62F27EC932D3" , k(k1).z().vpmovqb(xmm3, zmm2));
+ TEST_INSTRUCTION("62027E4822EE" , vpmovsqb(xmm30, zmm29));
+ TEST_INSTRUCTION("62027E4D22EE" , k(k5).vpmovsqb(xmm30, zmm29));
+ TEST_INSTRUCTION("62027ECD22EE" , k(k5).z().vpmovsqb(xmm30, zmm29));
+ TEST_INSTRUCTION("62027E4812E0" , vpmovusqb(xmm24, zmm28));
+ TEST_INSTRUCTION("62027E4F12E0" , k(k7).vpmovusqb(xmm24, zmm28));
+ TEST_INSTRUCTION("62027ECF12E0" , k(k7).z().vpmovusqb(xmm24, zmm28));
+ TEST_INSTRUCTION("62E27E4834D6" , vpmovqw(xmm6, zmm18));
+ TEST_INSTRUCTION("62E27E4934D6" , k(k1).vpmovqw(xmm6, zmm18));
+ TEST_INSTRUCTION("62E27EC934D6" , k(k1).z().vpmovqw(xmm6, zmm18));
+ TEST_INSTRUCTION("62827E4824DB" , vpmovsqw(xmm27, zmm19));
+ TEST_INSTRUCTION("62827E4E24DB" , k(k6).vpmovsqw(xmm27, zmm19));
+ TEST_INSTRUCTION("62827ECE24DB" , k(k6).z().vpmovsqw(xmm27, zmm19));
+ TEST_INSTRUCTION("62127E4814D4" , vpmovusqw(xmm28, zmm10));
+ TEST_INSTRUCTION("62127E4F14D4" , k(k7).vpmovusqw(xmm28, zmm10));
+ TEST_INSTRUCTION("62127ECF14D4" , k(k7).z().vpmovusqw(xmm28, zmm10));
+ TEST_INSTRUCTION("62627E4835CE" , vpmovqd(ymm6, zmm25));
+ TEST_INSTRUCTION("62627E4D35CE" , k(k5).vpmovqd(ymm6, zmm25));
+ TEST_INSTRUCTION("62627ECD35CE" , k(k5).z().vpmovqd(ymm6, zmm25));
+ TEST_INSTRUCTION("62D27E4825D7" , vpmovsqd(ymm15, zmm2));
+ TEST_INSTRUCTION("62D27E4A25D7" , k(k2).vpmovsqd(ymm15, zmm2));
+ TEST_INSTRUCTION("62D27ECA25D7" , k(k2).z().vpmovsqd(ymm15, zmm2));
+ TEST_INSTRUCTION("62D27E4815E0" , vpmovusqd(ymm8, zmm4));
+ TEST_INSTRUCTION("62D27E4C15E0" , k(k4).vpmovusqd(ymm8, zmm4));
+ TEST_INSTRUCTION("62D27ECC15E0" , k(k4).z().vpmovusqd(ymm8, zmm4));
+ TEST_INSTRUCTION("62F27E4831EA" , vpmovdb(xmm2, zmm5));
+ TEST_INSTRUCTION("62F27E4D31EA" , k(k5).vpmovdb(xmm2, zmm5));
+ TEST_INSTRUCTION("62F27ECD31EA" , k(k5).z().vpmovdb(xmm2, zmm5));
+ TEST_INSTRUCTION("62B27E4821D5" , vpmovsdb(xmm21, zmm2));
+ TEST_INSTRUCTION("62B27E4C21D5" , k(k4).vpmovsdb(xmm21, zmm2));
+ TEST_INSTRUCTION("62B27ECC21D5" , k(k4).z().vpmovsdb(xmm21, zmm2));
+ TEST_INSTRUCTION("62B27E4811D4" , vpmovusdb(xmm20, zmm2));
+ TEST_INSTRUCTION("62B27E4B11D4" , k(k3).vpmovusdb(xmm20, zmm2));
+ TEST_INSTRUCTION("62B27ECB11D4" , k(k3).z().vpmovusdb(xmm20, zmm2));
+ TEST_INSTRUCTION("62227E4833EE" , vpmovdw(ymm22, zmm29));
+ TEST_INSTRUCTION("62227E4D33EE" , k(k5).vpmovdw(ymm22, zmm29));
+ TEST_INSTRUCTION("62227ECD33EE" , k(k5).z().vpmovdw(ymm22, zmm29));
+ TEST_INSTRUCTION("62127E4823F1" , vpmovsdw(ymm25, zmm14));
+ TEST_INSTRUCTION("62127E4C23F1" , k(k4).vpmovsdw(ymm25, zmm14));
+ TEST_INSTRUCTION("62127ECC23F1" , k(k4).z().vpmovsdw(ymm25, zmm14));
+ TEST_INSTRUCTION("62D27E4813F8" , vpmovusdw(ymm8, zmm7));
+ TEST_INSTRUCTION("62D27E4913F8" , k(k1).vpmovusdw(ymm8, zmm7));
+ TEST_INSTRUCTION("62D27EC913F8" , k(k1).z().vpmovusdw(ymm8, zmm7));
+ TEST_INSTRUCTION("62F33D4023F3AB" , vshuff32x4(zmm6, zmm24, zmm3, 171));
+ TEST_INSTRUCTION("62F33D4223F3AB" , k(k2).vshuff32x4(zmm6, zmm24, zmm3, 171));
+ TEST_INSTRUCTION("62F33DC223F3AB" , k(k2).z().vshuff32x4(zmm6, zmm24, zmm3, 171));
+ TEST_INSTRUCTION("62F33D4023F37B" , vshuff32x4(zmm6, zmm24, zmm3, 123));
+ TEST_INSTRUCTION("62F33D4023317B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B33D4023B4F0230100007B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F33D5023317B" , vshuff32x4(zmm6, zmm24, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D4023727F7B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F33D4023B2002000007B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F33D402372807B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F33D4023B2C0DFFFFF7B" , vshuff32x4(zmm6, zmm24, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F33D5023727F7B" , vshuff32x4(zmm6, zmm24, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D5023B2000200007B" , vshuff32x4(zmm6, zmm24, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D502372807B" , vshuff32x4(zmm6, zmm24, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D5023B2FCFDFFFF7B" , vshuff32x4(zmm6, zmm24, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6253B54023FBAB" , vshuff64x2(zmm15, zmm25, zmm11, 171));
+ TEST_INSTRUCTION("6253B54223FBAB" , k(k2).vshuff64x2(zmm15, zmm25, zmm11, 171));
+ TEST_INSTRUCTION("6253B5C223FBAB" , k(k2).z().vshuff64x2(zmm15, zmm25, zmm11, 171));
+ TEST_INSTRUCTION("6253B54023FB7B" , vshuff64x2(zmm15, zmm25, zmm11, 123));
+ TEST_INSTRUCTION("6273B54023397B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233B54023BCF0230100007B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6273B55023397B" , vshuff64x2(zmm15, zmm25, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273B540237A7F7B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273B54023BA002000007B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273B540237A807B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273B54023BAC0DFFFFF7B" , vshuff64x2(zmm15, zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273B550237A7F7B" , vshuff64x2(zmm15, zmm25, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273B55023BA000400007B" , vshuff64x2(zmm15, zmm25, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273B550237A807B" , vshuff64x2(zmm15, zmm25, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273B55023BAF8FBFFFF7B" , vshuff64x2(zmm15, zmm25, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62931D4043C9AB" , vshufi32x4(zmm1, zmm28, zmm25, 171));
+ TEST_INSTRUCTION("62931D4443C9AB" , k(k4).vshufi32x4(zmm1, zmm28, zmm25, 171));
+ TEST_INSTRUCTION("62931DC443C9AB" , k(k4).z().vshufi32x4(zmm1, zmm28, zmm25, 171));
+ TEST_INSTRUCTION("62931D4043C97B" , vshufi32x4(zmm1, zmm28, zmm25, 123));
+ TEST_INSTRUCTION("62F31D4043097B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B31D40438CF0230100007B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F31D5043097B" , vshufi32x4(zmm1, zmm28, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F31D40434A7F7B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F31D40438A002000007B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F31D40434A807B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F31D40438AC0DFFFFF7B" , vshufi32x4(zmm1, zmm28, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F31D50434A7F7B" , vshufi32x4(zmm1, zmm28, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F31D50438A000200007B" , vshufi32x4(zmm1, zmm28, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F31D50434A807B" , vshufi32x4(zmm1, zmm28, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F31D50438AFCFDFFFF7B" , vshufi32x4(zmm1, zmm28, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62B3FD4043DBAB" , vshufi64x2(zmm3, zmm16, zmm19, 171));
+ TEST_INSTRUCTION("62B3FD4743DBAB" , k(k7).vshufi64x2(zmm3, zmm16, zmm19, 171));
+ TEST_INSTRUCTION("62B3FDC743DBAB" , k(k7).z().vshufi64x2(zmm3, zmm16, zmm19, 171));
+ TEST_INSTRUCTION("62B3FD4043DB7B" , vshufi64x2(zmm3, zmm16, zmm19, 123));
+ TEST_INSTRUCTION("62F3FD4043197B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3FD40439CF0230100007B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F3FD5043197B" , vshufi64x2(zmm3, zmm16, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD40435A7F7B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F3FD40439A002000007B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F3FD40435A807B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F3FD40439AC0DFFFFF7B" , vshufi64x2(zmm3, zmm16, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F3FD50435A7F7B" , vshufi64x2(zmm3, zmm16, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD50439A000400007B" , vshufi64x2(zmm3, zmm16, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD50435A807B" , vshufi64x2(zmm3, zmm16, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3FD50439AF8FBFFFF7B" , vshufi64x2(zmm3, zmm16, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62A2C54036EE" , vpermq(zmm21, zmm23, zmm22));
+ TEST_INSTRUCTION("62A2C54136EE" , k(k1).vpermq(zmm21, zmm23, zmm22));
+ TEST_INSTRUCTION("62A2C5C136EE" , k(k1).z().vpermq(zmm21, zmm23, zmm22));
+ TEST_INSTRUCTION("62E2C5403629" , vpermq(zmm21, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2C54036ACF023010000" , vpermq(zmm21, zmm23, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2C5503629" , vpermq(zmm21, zmm23, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2C540366A7F" , vpermq(zmm21, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2C54036AA00200000" , vpermq(zmm21, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2C540366A80" , vpermq(zmm21, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2C54036AAC0DFFFFF" , vpermq(zmm21, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2C550366A7F" , vpermq(zmm21, zmm23, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2C55036AA00040000" , vpermq(zmm21, zmm23, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2C550366A80" , vpermq(zmm21, zmm23, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2C55036AAF8FBFFFF" , vpermq(zmm21, zmm23, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6222954016D2" , vpermpd(zmm26, zmm29, zmm18));
+ TEST_INSTRUCTION("6222954616D2" , k(k6).vpermpd(zmm26, zmm29, zmm18));
+ TEST_INSTRUCTION("622295C616D2" , k(k6).z().vpermpd(zmm26, zmm29, zmm18));
+ TEST_INSTRUCTION("626295401611" , vpermpd(zmm26, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622295401694F023010000" , vpermpd(zmm26, zmm29, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626295501611" , vpermpd(zmm26, zmm29, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262954016527F" , vpermpd(zmm26, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62629540169200200000" , vpermpd(zmm26, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62629540165280" , vpermpd(zmm26, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626295401692C0DFFFFF" , vpermpd(zmm26, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262955016527F" , vpermpd(zmm26, zmm29, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62629550169200040000" , vpermpd(zmm26, zmm29, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62629550165280" , vpermpd(zmm26, zmm29, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("626295501692F8FBFFFF" , vpermpd(zmm26, zmm29, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62724D487EEE" , vpermt2d(zmm13, zmm6, zmm6));
+ TEST_INSTRUCTION("62724D4E7EEE" , k(k6).vpermt2d(zmm13, zmm6, zmm6));
+ TEST_INSTRUCTION("62724DCE7EEE" , k(k6).z().vpermt2d(zmm13, zmm6, zmm6));
+ TEST_INSTRUCTION("62724D487E29" , vpermt2d(zmm13, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62324D487EACF023010000" , vpermt2d(zmm13, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62724D587E29" , vpermt2d(zmm13, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62724D487E6A7F" , vpermt2d(zmm13, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62724D487EAA00200000" , vpermt2d(zmm13, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62724D487E6A80" , vpermt2d(zmm13, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62724D487EAAC0DFFFFF" , vpermt2d(zmm13, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62724D587E6A7F" , vpermt2d(zmm13, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62724D587EAA00020000" , vpermt2d(zmm13, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62724D587E6A80" , vpermt2d(zmm13, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62724D587EAAFCFDFFFF" , vpermt2d(zmm13, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A29D487EE8" , vpermt2q(zmm21, zmm12, zmm16));
+ TEST_INSTRUCTION("62A29D4A7EE8" , k(k2).vpermt2q(zmm21, zmm12, zmm16));
+ TEST_INSTRUCTION("62A29DCA7EE8" , k(k2).z().vpermt2q(zmm21, zmm12, zmm16));
+ TEST_INSTRUCTION("62E29D487E29" , vpermt2q(zmm21, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A29D487EACF023010000" , vpermt2q(zmm21, zmm12, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E29D587E29" , vpermt2q(zmm21, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E29D487E6A7F" , vpermt2q(zmm21, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E29D487EAA00200000" , vpermt2q(zmm21, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E29D487E6A80" , vpermt2q(zmm21, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E29D487EAAC0DFFFFF" , vpermt2q(zmm21, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E29D587E6A7F" , vpermt2q(zmm21, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E29D587EAA00040000" , vpermt2q(zmm21, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E29D587E6A80" , vpermt2q(zmm21, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E29D587EAAF8FBFFFF" , vpermt2q(zmm21, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62721D407FDA" , vpermt2ps(zmm11, zmm28, zmm2));
+ TEST_INSTRUCTION("62721D417FDA" , k(k1).vpermt2ps(zmm11, zmm28, zmm2));
+ TEST_INSTRUCTION("62721DC17FDA" , k(k1).z().vpermt2ps(zmm11, zmm28, zmm2));
+ TEST_INSTRUCTION("62721D407F19" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D407F9CF023010000" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62721D507F19" , vpermt2ps(zmm11, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62721D407F5A7F" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62721D407F9A00200000" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62721D407F5A80" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62721D407F9AC0DFFFFF" , vpermt2ps(zmm11, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62721D507F5A7F" , vpermt2ps(zmm11, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62721D507F9A00020000" , vpermt2ps(zmm11, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62721D507F5A80" , vpermt2ps(zmm11, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62721D507F9AFCFDFFFF" , vpermt2ps(zmm11, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D2A5407FDB" , vpermt2pd(zmm3, zmm27, zmm11));
+ TEST_INSTRUCTION("62D2A5427FDB" , k(k2).vpermt2pd(zmm3, zmm27, zmm11));
+ TEST_INSTRUCTION("62D2A5C27FDB" , k(k2).z().vpermt2pd(zmm3, zmm27, zmm11));
+ TEST_INSTRUCTION("62F2A5407F19" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2A5407F9CF023010000" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F2A5507F19" , vpermt2pd(zmm3, zmm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2A5407F5A7F" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2A5407F9A00200000" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2A5407F5A80" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2A5407F9AC0DFFFFF" , vpermt2pd(zmm3, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2A5507F5A7F" , vpermt2pd(zmm3, zmm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2A5507F9A00040000" , vpermt2pd(zmm3, zmm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2A5507F5A80" , vpermt2pd(zmm3, zmm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2A5507F9AF8FBFFFF" , vpermt2pd(zmm3, zmm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6223DD4803E7AB" , valignq(zmm28, zmm4, zmm23, 171));
+ TEST_INSTRUCTION("6223DD4B03E7AB" , k(k3).valignq(zmm28, zmm4, zmm23, 171));
+ TEST_INSTRUCTION("6223DDCB03E7AB" , k(k3).z().valignq(zmm28, zmm4, zmm23, 171));
+ TEST_INSTRUCTION("6223DD4803E77B" , valignq(zmm28, zmm4, zmm23, 123));
+ TEST_INSTRUCTION("6263DD4803217B" , valignq(zmm28, zmm4, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223DD4803A4F0230100007B" , valignq(zmm28, zmm4, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6263DD5803217B" , valignq(zmm28, zmm4, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6263DD4803627F7B" , valignq(zmm28, zmm4, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6263DD4803A2002000007B" , valignq(zmm28, zmm4, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6263DD480362807B" , valignq(zmm28, zmm4, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6263DD4803A2C0DFFFFF7B" , valignq(zmm28, zmm4, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6263DD5803627F7B" , valignq(zmm28, zmm4, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6263DD5803A2000400007B" , valignq(zmm28, zmm4, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263DD580362807B" , valignq(zmm28, zmm4, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263DD5803A2F8FBFFFF7B" , valignq(zmm28, zmm4, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62917F0879C6" , vcvtsd2usi(eax, xmm30));
+ TEST_INSTRUCTION("62917F1879C6" , rn_sae().vcvtsd2usi(eax, xmm30));
+ TEST_INSTRUCTION("62917F5879C6" , ru_sae().vcvtsd2usi(eax, xmm30));
+ TEST_INSTRUCTION("62917F3879C6" , rd_sae().vcvtsd2usi(eax, xmm30));
+ TEST_INSTRUCTION("62917F7879C6" , rz_sae().vcvtsd2usi(eax, xmm30));
+ TEST_INSTRUCTION("62F17F087901" , vcvtsd2usi(eax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F087984F023010000" , vcvtsd2usi(eax, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17F0879427F" , vcvtsd2usi(eax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F08798200040000" , vcvtsd2usi(eax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08794280" , vcvtsd2usi(eax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F087982F8FBFFFF" , vcvtsd2usi(eax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62917F0879EE" , vcvtsd2usi(ebp, xmm30));
+ TEST_INSTRUCTION("62917F1879EE" , rn_sae().vcvtsd2usi(ebp, xmm30));
+ TEST_INSTRUCTION("62917F5879EE" , ru_sae().vcvtsd2usi(ebp, xmm30));
+ TEST_INSTRUCTION("62917F3879EE" , rd_sae().vcvtsd2usi(ebp, xmm30));
+ TEST_INSTRUCTION("62917F7879EE" , rz_sae().vcvtsd2usi(ebp, xmm30));
+ TEST_INSTRUCTION("62F17F087929" , vcvtsd2usi(ebp, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F0879ACF023010000" , vcvtsd2usi(ebp, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17F08796A7F" , vcvtsd2usi(ebp, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F0879AA00040000" , vcvtsd2usi(ebp, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08796A80" , vcvtsd2usi(ebp, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F0879AAF8FBFFFF" , vcvtsd2usi(ebp, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62117F0879EE" , vcvtsd2usi(r13d, xmm30));
+ TEST_INSTRUCTION("62117F1879EE" , rn_sae().vcvtsd2usi(r13d, xmm30));
+ TEST_INSTRUCTION("62117F5879EE" , ru_sae().vcvtsd2usi(r13d, xmm30));
+ TEST_INSTRUCTION("62117F3879EE" , rd_sae().vcvtsd2usi(r13d, xmm30));
+ TEST_INSTRUCTION("62117F7879EE" , rz_sae().vcvtsd2usi(r13d, xmm30));
+ TEST_INSTRUCTION("62717F087929" , vcvtsd2usi(r13d, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62317F0879ACF023010000" , vcvtsd2usi(r13d, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717F08796A7F" , vcvtsd2usi(r13d, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62717F0879AA00040000" , vcvtsd2usi(r13d, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62717F08796A80" , vcvtsd2usi(r13d, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62717F0879AAF8FBFFFF" , vcvtsd2usi(r13d, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B1FF0879C2" , vcvtsd2usi(rax, xmm18));
+ TEST_INSTRUCTION("62B1FF1879C2" , rn_sae().vcvtsd2usi(rax, xmm18));
+ TEST_INSTRUCTION("62B1FF5879C2" , ru_sae().vcvtsd2usi(rax, xmm18));
+ TEST_INSTRUCTION("62B1FF3879C2" , rd_sae().vcvtsd2usi(rax, xmm18));
+ TEST_INSTRUCTION("62B1FF7879C2" , rz_sae().vcvtsd2usi(rax, xmm18));
+ TEST_INSTRUCTION("62F1FF087901" , vcvtsd2usi(rax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF087984F023010000" , vcvtsd2usi(rax, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FF0879427F" , vcvtsd2usi(rax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1FF08798200040000" , vcvtsd2usi(rax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1FF08794280" , vcvtsd2usi(rax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1FF087982F8FBFFFF" , vcvtsd2usi(rax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6231FF0879C2" , vcvtsd2usi(r8, xmm18));
+ TEST_INSTRUCTION("6231FF1879C2" , rn_sae().vcvtsd2usi(r8, xmm18));
+ TEST_INSTRUCTION("6231FF5879C2" , ru_sae().vcvtsd2usi(r8, xmm18));
+ TEST_INSTRUCTION("6231FF3879C2" , rd_sae().vcvtsd2usi(r8, xmm18));
+ TEST_INSTRUCTION("6231FF7879C2" , rz_sae().vcvtsd2usi(r8, xmm18));
+ TEST_INSTRUCTION("6271FF087901" , vcvtsd2usi(r8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FF087984F023010000" , vcvtsd2usi(r8, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271FF0879427F" , vcvtsd2usi(r8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271FF08798200040000" , vcvtsd2usi(r8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271FF08794280" , vcvtsd2usi(r8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271FF087982F8FBFFFF" , vcvtsd2usi(r8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62917E0879C4" , vcvtss2usi(eax, xmm28));
+ TEST_INSTRUCTION("62917E1879C4" , rn_sae().vcvtss2usi(eax, xmm28));
+ TEST_INSTRUCTION("62917E5879C4" , ru_sae().vcvtss2usi(eax, xmm28));
+ TEST_INSTRUCTION("62917E3879C4" , rd_sae().vcvtss2usi(eax, xmm28));
+ TEST_INSTRUCTION("62917E7879C4" , rz_sae().vcvtss2usi(eax, xmm28));
+ TEST_INSTRUCTION("62F17E087901" , vcvtss2usi(eax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E087984F023010000" , vcvtss2usi(eax, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17E0879427F" , vcvtss2usi(eax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E08798200020000" , vcvtss2usi(eax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08794280" , vcvtss2usi(eax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E087982FCFDFFFF" , vcvtss2usi(eax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62917E0879EC" , vcvtss2usi(ebp, xmm28));
+ TEST_INSTRUCTION("62917E1879EC" , rn_sae().vcvtss2usi(ebp, xmm28));
+ TEST_INSTRUCTION("62917E5879EC" , ru_sae().vcvtss2usi(ebp, xmm28));
+ TEST_INSTRUCTION("62917E3879EC" , rd_sae().vcvtss2usi(ebp, xmm28));
+ TEST_INSTRUCTION("62917E7879EC" , rz_sae().vcvtss2usi(ebp, xmm28));
+ TEST_INSTRUCTION("62F17E087929" , vcvtss2usi(ebp, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E0879ACF023010000" , vcvtss2usi(ebp, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17E08796A7F" , vcvtss2usi(ebp, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E0879AA00020000" , vcvtss2usi(ebp, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08796A80" , vcvtss2usi(ebp, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E0879AAFCFDFFFF" , vcvtss2usi(ebp, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62117E0879EC" , vcvtss2usi(r13d, xmm28));
+ TEST_INSTRUCTION("62117E1879EC" , rn_sae().vcvtss2usi(r13d, xmm28));
+ TEST_INSTRUCTION("62117E5879EC" , ru_sae().vcvtss2usi(r13d, xmm28));
+ TEST_INSTRUCTION("62117E3879EC" , rd_sae().vcvtss2usi(r13d, xmm28));
+ TEST_INSTRUCTION("62117E7879EC" , rz_sae().vcvtss2usi(r13d, xmm28));
+ TEST_INSTRUCTION("62717E087929" , vcvtss2usi(r13d, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E0879ACF023010000" , vcvtss2usi(r13d, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717E08796A7F" , vcvtss2usi(r13d, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62717E0879AA00020000" , vcvtss2usi(r13d, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62717E08796A80" , vcvtss2usi(r13d, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62717E0879AAFCFDFFFF" , vcvtss2usi(r13d, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B1FE0879C7" , vcvtss2usi(rax, xmm23));
+ TEST_INSTRUCTION("62B1FE1879C7" , rn_sae().vcvtss2usi(rax, xmm23));
+ TEST_INSTRUCTION("62B1FE5879C7" , ru_sae().vcvtss2usi(rax, xmm23));
+ TEST_INSTRUCTION("62B1FE3879C7" , rd_sae().vcvtss2usi(rax, xmm23));
+ TEST_INSTRUCTION("62B1FE7879C7" , rz_sae().vcvtss2usi(rax, xmm23));
+ TEST_INSTRUCTION("62F1FE087901" , vcvtss2usi(rax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FE087984F023010000" , vcvtss2usi(rax, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FE0879427F" , vcvtss2usi(rax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F1FE08798200020000" , vcvtss2usi(rax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F1FE08794280" , vcvtss2usi(rax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F1FE087982FCFDFFFF" , vcvtss2usi(rax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6231FE0879C7" , vcvtss2usi(r8, xmm23));
+ TEST_INSTRUCTION("6231FE1879C7" , rn_sae().vcvtss2usi(r8, xmm23));
+ TEST_INSTRUCTION("6231FE5879C7" , ru_sae().vcvtss2usi(r8, xmm23));
+ TEST_INSTRUCTION("6231FE3879C7" , rd_sae().vcvtss2usi(r8, xmm23));
+ TEST_INSTRUCTION("6231FE7879C7" , rz_sae().vcvtss2usi(r8, xmm23));
+ TEST_INSTRUCTION("6271FE087901" , vcvtss2usi(r8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FE087984F023010000" , vcvtss2usi(r8, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271FE0879427F" , vcvtss2usi(r8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("6271FE08798200020000" , vcvtss2usi(r8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("6271FE08794280" , vcvtss2usi(r8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("6271FE087982FCFDFFFF" , vcvtss2usi(r8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62E177087BD8" , vcvtusi2sd(xmm19, xmm1, eax));
+ TEST_INSTRUCTION("62E177087BDD" , vcvtusi2sd(xmm19, xmm1, ebp));
+ TEST_INSTRUCTION("62C177087BDD" , vcvtusi2sd(xmm19, xmm1, r13d));
+ TEST_INSTRUCTION("62E177087B19" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A177087B9CF023010000" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E177087B5A7F" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E177087B9A00020000" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E177087B5A80" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E177087B9AFCFDFFFF" , vcvtusi2sd(xmm19, xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6271AF007BF0" , vcvtusi2sd(xmm14, xmm26, rax));
+ TEST_INSTRUCTION("6271AF107BF0" , rn_sae().vcvtusi2sd(xmm14, xmm26, rax));
+ TEST_INSTRUCTION("6271AF507BF0" , ru_sae().vcvtusi2sd(xmm14, xmm26, rax));
+ TEST_INSTRUCTION("6271AF307BF0" , rd_sae().vcvtusi2sd(xmm14, xmm26, rax));
+ TEST_INSTRUCTION("6271AF707BF0" , rz_sae().vcvtusi2sd(xmm14, xmm26, rax));
+ TEST_INSTRUCTION("6251AF007BF0" , vcvtusi2sd(xmm14, xmm26, r8));
+ TEST_INSTRUCTION("6251AF107BF0" , rn_sae().vcvtusi2sd(xmm14, xmm26, r8));
+ TEST_INSTRUCTION("6251AF507BF0" , ru_sae().vcvtusi2sd(xmm14, xmm26, r8));
+ TEST_INSTRUCTION("6251AF307BF0" , rd_sae().vcvtusi2sd(xmm14, xmm26, r8));
+ TEST_INSTRUCTION("6251AF707BF0" , rz_sae().vcvtusi2sd(xmm14, xmm26, r8));
+ TEST_INSTRUCTION("6271AF007B31" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231AF007BB4F023010000" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271AF007B727F" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271AF007BB200040000" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271AF007B7280" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271AF007BB2F8FBFFFF" , vcvtusi2sd(xmm14, xmm26, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62F12E007BE8" , vcvtusi2ss(xmm5, xmm26, eax));
+ TEST_INSTRUCTION("62F12E107BE8" , rn_sae().vcvtusi2ss(xmm5, xmm26, eax));
+ TEST_INSTRUCTION("62F12E507BE8" , ru_sae().vcvtusi2ss(xmm5, xmm26, eax));
+ TEST_INSTRUCTION("62F12E307BE8" , rd_sae().vcvtusi2ss(xmm5, xmm26, eax));
+ TEST_INSTRUCTION("62F12E707BE8" , rz_sae().vcvtusi2ss(xmm5, xmm26, eax));
+ TEST_INSTRUCTION("62F12E007BED" , vcvtusi2ss(xmm5, xmm26, ebp));
+ TEST_INSTRUCTION("62F12E107BED" , rn_sae().vcvtusi2ss(xmm5, xmm26, ebp));
+ TEST_INSTRUCTION("62F12E507BED" , ru_sae().vcvtusi2ss(xmm5, xmm26, ebp));
+ TEST_INSTRUCTION("62F12E307BED" , rd_sae().vcvtusi2ss(xmm5, xmm26, ebp));
+ TEST_INSTRUCTION("62F12E707BED" , rz_sae().vcvtusi2ss(xmm5, xmm26, ebp));
+ TEST_INSTRUCTION("62D12E007BED" , vcvtusi2ss(xmm5, xmm26, r13d));
+ TEST_INSTRUCTION("62D12E107BED" , rn_sae().vcvtusi2ss(xmm5, xmm26, r13d));
+ TEST_INSTRUCTION("62D12E507BED" , ru_sae().vcvtusi2ss(xmm5, xmm26, r13d));
+ TEST_INSTRUCTION("62D12E307BED" , rd_sae().vcvtusi2ss(xmm5, xmm26, r13d));
+ TEST_INSTRUCTION("62D12E707BED" , rz_sae().vcvtusi2ss(xmm5, xmm26, r13d));
+ TEST_INSTRUCTION("62F12E007B29" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B12E007BACF023010000" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F12E007B6A7F" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F12E007BAA00020000" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F12E007B6A80" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F12E007BAAFCFDFFFF" , vcvtusi2ss(xmm5, xmm26, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6271CE007BF0" , vcvtusi2ss(xmm14, xmm22, rax));
+ TEST_INSTRUCTION("6271CE107BF0" , rn_sae().vcvtusi2ss(xmm14, xmm22, rax));
+ TEST_INSTRUCTION("6271CE507BF0" , ru_sae().vcvtusi2ss(xmm14, xmm22, rax));
+ TEST_INSTRUCTION("6271CE307BF0" , rd_sae().vcvtusi2ss(xmm14, xmm22, rax));
+ TEST_INSTRUCTION("6271CE707BF0" , rz_sae().vcvtusi2ss(xmm14, xmm22, rax));
+ TEST_INSTRUCTION("6251CE007BF0" , vcvtusi2ss(xmm14, xmm22, r8));
+ TEST_INSTRUCTION("6251CE107BF0" , rn_sae().vcvtusi2ss(xmm14, xmm22, r8));
+ TEST_INSTRUCTION("6251CE507BF0" , ru_sae().vcvtusi2ss(xmm14, xmm22, r8));
+ TEST_INSTRUCTION("6251CE307BF0" , rd_sae().vcvtusi2ss(xmm14, xmm22, r8));
+ TEST_INSTRUCTION("6251CE707BF0" , rz_sae().vcvtusi2ss(xmm14, xmm22, r8));
+ TEST_INSTRUCTION("6271CE007B31" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231CE007BB4F023010000" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271CE007B727F" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271CE007BB200040000" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271CE007B7280" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271CE007BB2F8FBFFFF" , vcvtusi2ss(xmm14, xmm22, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6202AD402CD4" , vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202AD452CD4" , k(k5).vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202ADC52CD4" , k(k5).z().vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202AD102CD4" , rn_sae().vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202AD502CD4" , ru_sae().vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202AD302CD4" , rd_sae().vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6202AD702CD4" , rz_sae().vscalefpd(zmm26, zmm26, zmm28));
+ TEST_INSTRUCTION("6262AD402C11" , vscalefpd(zmm26, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222AD402C94F023010000" , vscalefpd(zmm26, zmm26, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262AD502C11" , vscalefpd(zmm26, zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262AD402C527F" , vscalefpd(zmm26, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262AD402C9200200000" , vscalefpd(zmm26, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262AD402C5280" , vscalefpd(zmm26, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262AD402C92C0DFFFFF" , vscalefpd(zmm26, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262AD502C527F" , vscalefpd(zmm26, zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262AD502C9200040000" , vscalefpd(zmm26, zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262AD502C5280" , vscalefpd(zmm26, zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262AD502C92F8FBFFFF" , vscalefpd(zmm26, zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62A24D482CDA" , vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24D4E2CDA" , k(k6).vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24DCE2CDA" , k(k6).z().vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24D182CDA" , rn_sae().vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24D582CDA" , ru_sae().vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24D382CDA" , rd_sae().vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62A24D782CDA" , rz_sae().vscalefps(zmm19, zmm6, zmm18));
+ TEST_INSTRUCTION("62E24D482C19" , vscalefps(zmm19, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A24D482C9CF023010000" , vscalefps(zmm19, zmm6, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E24D582C19" , vscalefps(zmm19, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E24D482C5A7F" , vscalefps(zmm19, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E24D482C9A00200000" , vscalefps(zmm19, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E24D482C5A80" , vscalefps(zmm19, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E24D482C9AC0DFFFFF" , vscalefps(zmm19, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E24D582C5A7F" , vscalefps(zmm19, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E24D582C9A00020000" , vscalefps(zmm19, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E24D582C5A80" , vscalefps(zmm19, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E24D582C9AFCFDFFFF" , vscalefps(zmm19, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2CD002DED" , vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD022DED" , k(k2).vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD822DED" , k(k2).z().vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD102DED" , rn_sae().vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD502DED" , ru_sae().vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD302DED" , rd_sae().vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62A2CD702DED" , rz_sae().vscalefsd(xmm21, xmm22, xmm21));
+ TEST_INSTRUCTION("62E2CD002D29" , vscalefsd(xmm21, xmm22, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD002DACF023010000" , vscalefsd(xmm21, xmm22, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2CD002D6A7F" , vscalefsd(xmm21, xmm22, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E2CD002DAA00040000" , vscalefsd(xmm21, xmm22, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E2CD002D6A80" , vscalefsd(xmm21, xmm22, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E2CD002DAAF8FBFFFF" , vscalefsd(xmm21, xmm22, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("623205082DEF" , vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("6232050B2DEF" , k(k3).vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("6232058B2DEF" , k(k3).z().vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("623205182DEF" , rn_sae().vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("623205582DEF" , ru_sae().vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("623205382DEF" , rd_sae().vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("623205782DEF" , rz_sae().vscalefss(xmm13, xmm15, xmm23));
+ TEST_INSTRUCTION("627205082D29" , vscalefss(xmm13, xmm15, dword_ptr(rcx)));
+ TEST_INSTRUCTION("623205082DACF023010000" , vscalefss(xmm13, xmm15, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("627205082D6A7F" , vscalefss(xmm13, xmm15, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("627205082DAA00020000" , vscalefss(xmm13, xmm15, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("627205082D6A80" , vscalefss(xmm13, xmm15, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("627205082DAAFCFDFFFF" , vscalefss(xmm13, xmm15, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62732D4054FAAB" , vfixupimmps(zmm15, zmm26, zmm2, 171));
+ TEST_INSTRUCTION("62732D4454FAAB" , k(k4).vfixupimmps(zmm15, zmm26, zmm2, 171));
+ TEST_INSTRUCTION("62732DC454FAAB" , k(k4).z().vfixupimmps(zmm15, zmm26, zmm2, 171));
+ TEST_INSTRUCTION("62732D1054FAAB" , sae().vfixupimmps(zmm15, zmm26, zmm2, 171));
+ TEST_INSTRUCTION("62732D4054FA7B" , vfixupimmps(zmm15, zmm26, zmm2, 123));
+ TEST_INSTRUCTION("62732D1054FA7B" , sae().vfixupimmps(zmm15, zmm26, zmm2, 123));
+ TEST_INSTRUCTION("62732D4054397B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62332D4054BCF0230100007B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62732D5054397B" , vfixupimmps(zmm15, zmm26, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62732D40547A7F7B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62732D4054BA002000007B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62732D40547A807B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62732D4054BAC0DFFFFF7B" , vfixupimmps(zmm15, zmm26, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62732D50547A7F7B" , vfixupimmps(zmm15, zmm26, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62732D5054BA000200007B" , vfixupimmps(zmm15, zmm26, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62732D50547A807B" , vfixupimmps(zmm15, zmm26, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62732D5054BAFCFDFFFF7B" , vfixupimmps(zmm15, zmm26, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6233D54054CBAB" , vfixupimmpd(zmm9, zmm21, zmm19, 171));
+ TEST_INSTRUCTION("6233D54254CBAB" , k(k2).vfixupimmpd(zmm9, zmm21, zmm19, 171));
+ TEST_INSTRUCTION("6233D5C254CBAB" , k(k2).z().vfixupimmpd(zmm9, zmm21, zmm19, 171));
+ TEST_INSTRUCTION("6233D51054CBAB" , sae().vfixupimmpd(zmm9, zmm21, zmm19, 171));
+ TEST_INSTRUCTION("6233D54054CB7B" , vfixupimmpd(zmm9, zmm21, zmm19, 123));
+ TEST_INSTRUCTION("6233D51054CB7B" , sae().vfixupimmpd(zmm9, zmm21, zmm19, 123));
+ TEST_INSTRUCTION("6273D54054097B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233D540548CF0230100007B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6273D55054097B" , vfixupimmpd(zmm9, zmm21, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273D540544A7F7B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273D540548A002000007B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273D540544A807B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273D540548AC0DFFFFF7B" , vfixupimmpd(zmm9, zmm21, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273D550544A7F7B" , vfixupimmpd(zmm9, zmm21, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273D550548A000400007B" , vfixupimmpd(zmm9, zmm21, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273D550544A807B" , vfixupimmpd(zmm9, zmm21, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273D550548AF8FBFFFF7B" , vfixupimmpd(zmm9, zmm21, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62136D0055FCAB" , vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D0555FCAB" , k(k5).vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D8555FCAB" , k(k5).z().vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D1055FCAB" , sae().vfixupimmss(xmm15, xmm18, xmm28, 171));
+ TEST_INSTRUCTION("62136D0055FC7B" , vfixupimmss(xmm15, xmm18, xmm28, 123));
+ TEST_INSTRUCTION("62136D1055FC7B" , sae().vfixupimmss(xmm15, xmm18, xmm28, 123));
+ TEST_INSTRUCTION("62736D0055397B" , vfixupimmss(xmm15, xmm18, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62336D0055BCF0230100007B" , vfixupimmss(xmm15, xmm18, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62736D00557A7F7B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62736D0055BA000200007B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62736D00557A807B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62736D0055BAFCFDFFFF7B" , vfixupimmss(xmm15, xmm18, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("6273AD0055EDAB" , vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD0655EDAB" , k(k6).vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD8655EDAB" , k(k6).z().vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD1055EDAB" , sae().vfixupimmsd(xmm13, xmm26, xmm5, 171));
+ TEST_INSTRUCTION("6273AD0055ED7B" , vfixupimmsd(xmm13, xmm26, xmm5, 123));
+ TEST_INSTRUCTION("6273AD1055ED7B" , sae().vfixupimmsd(xmm13, xmm26, xmm5, 123));
+ TEST_INSTRUCTION("6273AD0055297B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233AD0055ACF0230100007B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("6273AD00556A7F7B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("6273AD0055AA000400007B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("6273AD00556A807B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("6273AD0055AAF8FBFFFF7B" , vfixupimmsd(xmm13, xmm26, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("6291154072F0AB" , vpslld(zmm29, zmm24, 171));
+ TEST_INSTRUCTION("6291154672F0AB" , k(k6).vpslld(zmm29, zmm24, 171));
+ TEST_INSTRUCTION("629115C672F0AB" , k(k6).z().vpslld(zmm29, zmm24, 171));
+ TEST_INSTRUCTION("6291154072F07B" , vpslld(zmm29, zmm24, 123));
+ TEST_INSTRUCTION("62F1154072317B" , vpslld(zmm29, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1154072B4F0230100007B" , vpslld(zmm29, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1155072317B" , vpslld(zmm29, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1154072727F7B" , vpslld(zmm29, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1154072B2002000007B" , vpslld(zmm29, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F115407272807B" , vpslld(zmm29, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1154072B2C0DFFFFF7B" , vpslld(zmm29, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1155072727F7B" , vpslld(zmm29, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F1155072B2000200007B" , vpslld(zmm29, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F115507272807B" , vpslld(zmm29, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F1155072B2FCFDFFFF7B" , vpslld(zmm29, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D1CD4873F3AB" , vpsllq(zmm6, zmm11, 171));
+ TEST_INSTRUCTION("62D1CD4A73F3AB" , k(k2).vpsllq(zmm6, zmm11, 171));
+ TEST_INSTRUCTION("62D1CDCA73F3AB" , k(k2).z().vpsllq(zmm6, zmm11, 171));
+ TEST_INSTRUCTION("62D1CD4873F37B" , vpsllq(zmm6, zmm11, 123));
+ TEST_INSTRUCTION("62F1CD4873317B" , vpsllq(zmm6, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1CD4873B4F0230100007B" , vpsllq(zmm6, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1CD5873317B" , vpsllq(zmm6, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD4873727F7B" , vpsllq(zmm6, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1CD4873B2002000007B" , vpsllq(zmm6, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1CD487372807B" , vpsllq(zmm6, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1CD4873B2C0DFFFFF7B" , vpsllq(zmm6, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1CD5873727F7B" , vpsllq(zmm6, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD5873B2000400007B" , vpsllq(zmm6, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD587372807B" , vpsllq(zmm6, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD5873B2F8FBFFFF7B" , vpsllq(zmm6, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F1254072E5AB" , vpsrad(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F1254572E5AB" , k(k5).vpsrad(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F125C572E5AB" , k(k5).z().vpsrad(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F1254072E57B" , vpsrad(zmm27, zmm5, 123));
+ TEST_INSTRUCTION("62F1254072217B" , vpsrad(zmm27, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1254072A4F0230100007B" , vpsrad(zmm27, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1255072217B" , vpsrad(zmm27, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1254072627F7B" , vpsrad(zmm27, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1254072A2002000007B" , vpsrad(zmm27, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F125407262807B" , vpsrad(zmm27, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1254072A2C0DFFFFF7B" , vpsrad(zmm27, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1255072627F7B" , vpsrad(zmm27, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F1255072A2000200007B" , vpsrad(zmm27, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F125507262807B" , vpsrad(zmm27, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F1255072A2FCFDFFFF7B" , vpsrad(zmm27, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62F1954072E5AB" , vpsraq(zmm29, zmm5, 171));
+ TEST_INSTRUCTION("62F1954472E5AB" , k(k4).vpsraq(zmm29, zmm5, 171));
+ TEST_INSTRUCTION("62F195C472E5AB" , k(k4).z().vpsraq(zmm29, zmm5, 171));
+ TEST_INSTRUCTION("62F1954072E57B" , vpsraq(zmm29, zmm5, 123));
+ TEST_INSTRUCTION("62F1954072217B" , vpsraq(zmm29, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1954072A4F0230100007B" , vpsraq(zmm29, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1955072217B" , vpsraq(zmm29, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1954072627F7B" , vpsraq(zmm29, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1954072A2002000007B" , vpsraq(zmm29, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F195407262807B" , vpsraq(zmm29, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1954072A2C0DFFFFF7B" , vpsraq(zmm29, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1955072627F7B" , vpsraq(zmm29, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1955072A2000400007B" , vpsraq(zmm29, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F195507262807B" , vpsraq(zmm29, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1955072A2F8FBFFFF7B" , vpsraq(zmm29, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62B2154015F0" , vprolvd(zmm6, zmm29, zmm16));
+ TEST_INSTRUCTION("62B2154215F0" , k(k2).vprolvd(zmm6, zmm29, zmm16));
+ TEST_INSTRUCTION("62B215C215F0" , k(k2).z().vprolvd(zmm6, zmm29, zmm16));
+ TEST_INSTRUCTION("62F215401531" , vprolvd(zmm6, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2154015B4F023010000" , vprolvd(zmm6, zmm29, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F215501531" , vprolvd(zmm6, zmm29, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F2154015727F" , vprolvd(zmm6, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2154015B200200000" , vprolvd(zmm6, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F21540157280" , vprolvd(zmm6, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2154015B2C0DFFFFF" , vprolvd(zmm6, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2155015727F" , vprolvd(zmm6, zmm29, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F2155015B200020000" , vprolvd(zmm6, zmm29, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F21550157280" , vprolvd(zmm6, zmm29, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F2155015B2FCFDFFFF" , vprolvd(zmm6, zmm29, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F12D4872CDAB" , vprold(zmm10, zmm5, 171));
+ TEST_INSTRUCTION("62F12D4F72CDAB" , k(k7).vprold(zmm10, zmm5, 171));
+ TEST_INSTRUCTION("62F12DCF72CDAB" , k(k7).z().vprold(zmm10, zmm5, 171));
+ TEST_INSTRUCTION("62F12D4872CD7B" , vprold(zmm10, zmm5, 123));
+ TEST_INSTRUCTION("62F12D4872097B" , vprold(zmm10, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B12D48728CF0230100007B" , vprold(zmm10, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F12D5872097B" , vprold(zmm10, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F12D48724A7F7B" , vprold(zmm10, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F12D48728A002000007B" , vprold(zmm10, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F12D48724A807B" , vprold(zmm10, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F12D48728AC0DFFFFF7B" , vprold(zmm10, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F12D58724A7F7B" , vprold(zmm10, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F12D58728A000200007B" , vprold(zmm10, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F12D58724A807B" , vprold(zmm10, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F12D58728AFCFDFFFF7B" , vprold(zmm10, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6262DD4815DE" , vprolvq(zmm27, zmm4, zmm6));
+ TEST_INSTRUCTION("6262DD4D15DE" , k(k5).vprolvq(zmm27, zmm4, zmm6));
+ TEST_INSTRUCTION("6262DDCD15DE" , k(k5).z().vprolvq(zmm27, zmm4, zmm6));
+ TEST_INSTRUCTION("6262DD481519" , vprolvq(zmm27, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222DD48159CF023010000" , vprolvq(zmm27, zmm4, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6262DD581519" , vprolvq(zmm27, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262DD48155A7F" , vprolvq(zmm27, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262DD48159A00200000" , vprolvq(zmm27, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262DD48155A80" , vprolvq(zmm27, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262DD48159AC0DFFFFF" , vprolvq(zmm27, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262DD58155A7F" , vprolvq(zmm27, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262DD58159A00040000" , vprolvq(zmm27, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262DD58155A80" , vprolvq(zmm27, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262DD58159AF8FBFFFF" , vprolvq(zmm27, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B1E54072CAAB" , vprolq(zmm19, zmm18, 171));
+ TEST_INSTRUCTION("62B1E54372CAAB" , k(k3).vprolq(zmm19, zmm18, 171));
+ TEST_INSTRUCTION("62B1E5C372CAAB" , k(k3).z().vprolq(zmm19, zmm18, 171));
+ TEST_INSTRUCTION("62B1E54072CA7B" , vprolq(zmm19, zmm18, 123));
+ TEST_INSTRUCTION("62F1E54072097B" , vprolq(zmm19, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1E540728CF0230100007B" , vprolq(zmm19, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1E55072097B" , vprolq(zmm19, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E540724A7F7B" , vprolq(zmm19, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1E540728A002000007B" , vprolq(zmm19, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1E540724A807B" , vprolq(zmm19, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1E540728AC0DFFFFF7B" , vprolq(zmm19, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1E550724A7F7B" , vprolq(zmm19, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E550728A000400007B" , vprolq(zmm19, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E550724A807B" , vprolq(zmm19, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E550728AF8FBFFFF7B" , vprolq(zmm19, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62125D4014DC" , vprorvd(zmm11, zmm20, zmm28));
+ TEST_INSTRUCTION("62125D4214DC" , k(k2).vprorvd(zmm11, zmm20, zmm28));
+ TEST_INSTRUCTION("62125DC214DC" , k(k2).z().vprorvd(zmm11, zmm20, zmm28));
+ TEST_INSTRUCTION("62725D401419" , vprorvd(zmm11, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62325D40149CF023010000" , vprorvd(zmm11, zmm20, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62725D501419" , vprorvd(zmm11, zmm20, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62725D40145A7F" , vprorvd(zmm11, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62725D40149A00200000" , vprorvd(zmm11, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62725D40145A80" , vprorvd(zmm11, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62725D40149AC0DFFFFF" , vprorvd(zmm11, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62725D50145A7F" , vprorvd(zmm11, zmm20, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62725D50149A00020000" , vprorvd(zmm11, zmm20, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62725D50145A80" , vprorvd(zmm11, zmm20, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62725D50149AFCFDFFFF" , vprorvd(zmm11, zmm20, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D1354872C2AB" , vprord(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("62D1354F72C2AB" , k(k7).vprord(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("62D135CF72C2AB" , k(k7).z().vprord(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("62D1354872C27B" , vprord(zmm9, zmm10, 123));
+ TEST_INSTRUCTION("62F1354872017B" , vprord(zmm9, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B135487284F0230100007B" , vprord(zmm9, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1355872017B" , vprord(zmm9, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1354872427F7B" , vprord(zmm9, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F135487282002000007B" , vprord(zmm9, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F135487242807B" , vprord(zmm9, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F135487282C0DFFFFF7B" , vprord(zmm9, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1355872427F7B" , vprord(zmm9, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F135587282000200007B" , vprord(zmm9, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F135587242807B" , vprord(zmm9, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F135587282FCFDFFFF7B" , vprord(zmm9, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6272BD4014F1" , vprorvq(zmm14, zmm24, zmm1));
+ TEST_INSTRUCTION("6272BD4714F1" , k(k7).vprorvq(zmm14, zmm24, zmm1));
+ TEST_INSTRUCTION("6272BDC714F1" , k(k7).z().vprorvq(zmm14, zmm24, zmm1));
+ TEST_INSTRUCTION("6272BD401431" , vprorvq(zmm14, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232BD4014B4F023010000" , vprorvq(zmm14, zmm24, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6272BD501431" , vprorvq(zmm14, zmm24, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272BD4014727F" , vprorvq(zmm14, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272BD4014B200200000" , vprorvq(zmm14, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272BD40147280" , vprorvq(zmm14, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272BD4014B2C0DFFFFF" , vprorvq(zmm14, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272BD5014727F" , vprorvq(zmm14, zmm24, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272BD5014B200040000" , vprorvq(zmm14, zmm24, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272BD50147280" , vprorvq(zmm14, zmm24, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272BD5014B2F8FBFFFF" , vprorvq(zmm14, zmm24, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6291D54072C1AB" , vprorq(zmm21, zmm25, 171));
+ TEST_INSTRUCTION("6291D54672C1AB" , k(k6).vprorq(zmm21, zmm25, 171));
+ TEST_INSTRUCTION("6291D5C672C1AB" , k(k6).z().vprorq(zmm21, zmm25, 171));
+ TEST_INSTRUCTION("6291D54072C17B" , vprorq(zmm21, zmm25, 123));
+ TEST_INSTRUCTION("62F1D54072017B" , vprorq(zmm21, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1D5407284F0230100007B" , vprorq(zmm21, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62F1D55072017B" , vprorq(zmm21, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1D54072427F7B" , vprorq(zmm21, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1D5407282002000007B" , vprorq(zmm21, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1D5407242807B" , vprorq(zmm21, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1D5407282C0DFFFFF7B" , vprorq(zmm21, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1D55072427F7B" , vprorq(zmm21, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1D5507282000400007B" , vprorq(zmm21, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1D5507242807B" , vprorq(zmm21, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1D5507282F8FBFFFF7B" , vprorq(zmm21, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD4809F7AB" , vrndscalepd(zmm22, zmm7, 171));
+ TEST_INSTRUCTION("62E3FD4909F7AB" , k(k1).vrndscalepd(zmm22, zmm7, 171));
+ TEST_INSTRUCTION("62E3FDC909F7AB" , k(k1).z().vrndscalepd(zmm22, zmm7, 171));
+ TEST_INSTRUCTION("62E3FD1809F7AB" , sae().vrndscalepd(zmm22, zmm7, 171));
+ TEST_INSTRUCTION("62E3FD4809F77B" , vrndscalepd(zmm22, zmm7, 123));
+ TEST_INSTRUCTION("62E3FD1809F77B" , sae().vrndscalepd(zmm22, zmm7, 123));
+ TEST_INSTRUCTION("62E3FD4809317B" , vrndscalepd(zmm22, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A3FD4809B4F0230100007B" , vrndscalepd(zmm22, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62E3FD5809317B" , vrndscalepd(zmm22, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD4809727F7B" , vrndscalepd(zmm22, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E3FD4809B2002000007B" , vrndscalepd(zmm22, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E3FD480972807B" , vrndscalepd(zmm22, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E3FD4809B2C0DFFFFF7B" , vrndscalepd(zmm22, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E3FD5809727F7B" , vrndscalepd(zmm22, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD5809B2000400007B" , vrndscalepd(zmm22, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD580972807B" , vrndscalepd(zmm22, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E3FD5809B2F8FBFFFF7B" , vrndscalepd(zmm22, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62737D4808EFAB" , vrndscaleps(zmm13, zmm7, 171));
+ TEST_INSTRUCTION("62737D4908EFAB" , k(k1).vrndscaleps(zmm13, zmm7, 171));
+ TEST_INSTRUCTION("62737DC908EFAB" , k(k1).z().vrndscaleps(zmm13, zmm7, 171));
+ TEST_INSTRUCTION("62737D1808EFAB" , sae().vrndscaleps(zmm13, zmm7, 171));
+ TEST_INSTRUCTION("62737D4808EF7B" , vrndscaleps(zmm13, zmm7, 123));
+ TEST_INSTRUCTION("62737D1808EF7B" , sae().vrndscaleps(zmm13, zmm7, 123));
+ TEST_INSTRUCTION("62737D4808297B" , vrndscaleps(zmm13, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62337D4808ACF0230100007B" , vrndscaleps(zmm13, zmmword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62737D5808297B" , vrndscaleps(zmm13, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62737D48086A7F7B" , vrndscaleps(zmm13, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62737D4808AA002000007B" , vrndscaleps(zmm13, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62737D48086A807B" , vrndscaleps(zmm13, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62737D4808AAC0DFFFFF7B" , vrndscaleps(zmm13, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62737D58086A7F7B" , vrndscaleps(zmm13, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62737D5808AA000200007B" , vrndscaleps(zmm13, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62737D58086A807B" , vrndscaleps(zmm13, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62737D5808AAFCFDFFFF7B" , vrndscaleps(zmm13, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62439D080BCFAB" , vrndscalesd(xmm25, xmm12, xmm15, 171));
+ TEST_INSTRUCTION("62439D0E0BCFAB" , k(k6).vrndscalesd(xmm25, xmm12, xmm15, 171));
+ TEST_INSTRUCTION("62439D8E0BCFAB" , k(k6).z().vrndscalesd(xmm25, xmm12, xmm15, 171));
+ TEST_INSTRUCTION("62439D180BCFAB" , sae().vrndscalesd(xmm25, xmm12, xmm15, 171));
+ TEST_INSTRUCTION("62439D080BCF7B" , vrndscalesd(xmm25, xmm12, xmm15, 123));
+ TEST_INSTRUCTION("62439D180BCF7B" , sae().vrndscalesd(xmm25, xmm12, xmm15, 123));
+ TEST_INSTRUCTION("62639D080B097B" , vrndscalesd(xmm25, xmm12, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62239D080B8CF0230100007B" , vrndscalesd(xmm25, xmm12, qword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("62639D080B4A7F7B" , vrndscalesd(xmm25, xmm12, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62639D080B8A000400007B" , vrndscalesd(xmm25, xmm12, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62639D080B4A807B" , vrndscalesd(xmm25, xmm12, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62639D080B8AF8FBFFFF7B" , vrndscalesd(xmm25, xmm12, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("623325080AD9AB" , vrndscaless(xmm11, xmm11, xmm17, 171));
+ TEST_INSTRUCTION("6233250B0AD9AB" , k(k3).vrndscaless(xmm11, xmm11, xmm17, 171));
+ TEST_INSTRUCTION("6233258B0AD9AB" , k(k3).z().vrndscaless(xmm11, xmm11, xmm17, 171));
+ TEST_INSTRUCTION("623325180AD9AB" , sae().vrndscaless(xmm11, xmm11, xmm17, 171));
+ TEST_INSTRUCTION("623325080AD97B" , vrndscaless(xmm11, xmm11, xmm17, 123));
+ TEST_INSTRUCTION("623325180AD97B" , sae().vrndscaless(xmm11, xmm11, xmm17, 123));
+ TEST_INSTRUCTION("627325080A197B" , vrndscaless(xmm11, xmm11, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("623325080A9CF0230100007B" , vrndscaless(xmm11, xmm11, dword_ptr(rax, r14, 3, 291), 123));
+ TEST_INSTRUCTION("627325080A5A7F7B" , vrndscaless(xmm11, xmm11, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("627325080A9A000200007B" , vrndscaless(xmm11, xmm11, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("627325080A5A807B" , vrndscaless(xmm11, xmm11, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("627325080A9AFCFDFFFF7B" , vrndscaless(xmm11, xmm11, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("6272FD488B19" , vpcompressq(zmmword_ptr(rcx), zmm11));
+ TEST_INSTRUCTION("6272FD4F8B19" , k(k7).vpcompressq(zmmword_ptr(rcx), zmm11));
+ TEST_INSTRUCTION("6232FD488B9CF023010000" , vpcompressq(zmmword_ptr(rax, r14, 3, 291), zmm11));
+ TEST_INSTRUCTION("6272FD488B5A7F" , vpcompressq(zmmword_ptr(rdx, 1016), zmm11));
+ TEST_INSTRUCTION("6272FD488B9A00040000" , vpcompressq(zmmword_ptr(rdx, 1024), zmm11));
+ TEST_INSTRUCTION("6272FD488B5A80" , vpcompressq(zmmword_ptr(rdx, -1024), zmm11));
+ TEST_INSTRUCTION("6272FD488B9AF8FBFFFF" , vpcompressq(zmmword_ptr(rdx, -1032), zmm11));
+ TEST_INSTRUCTION("62A2FD488BD9" , vpcompressq(zmm17, zmm19));
+ TEST_INSTRUCTION("62A2FD4A8BD9" , k(k2).vpcompressq(zmm17, zmm19));
+ TEST_INSTRUCTION("62A2FDCA8BD9" , k(k2).z().vpcompressq(zmm17, zmm19));
+ TEST_INSTRUCTION("C5D441D6" , kandw(k2, k5, k6));
+ TEST_INSTRUCTION("C5CC42E7" , kandnw(k4, k6, k7));
+ TEST_INSTRUCTION("C5CC45E7" , korw(k4, k6, k7));
+ TEST_INSTRUCTION("C5D446DD" , kxnorw(k3, k5, k5));
+ TEST_INSTRUCTION("C5CC47D7" , kxorw(k2, k6, k7));
+ TEST_INSTRUCTION("C5F844DE" , knotw(k3, k6));
+ TEST_INSTRUCTION("C5F898D6" , kortestw(k2, k6));
+ TEST_INSTRUCTION("C4E3F930E4AB" , kshiftrw(k4, k4, 171));
+ TEST_INSTRUCTION("C4E3F930E47B" , kshiftrw(k4, k4, 123));
+ TEST_INSTRUCTION("C4E3F932D5AB" , kshiftlw(k2, k5, 171));
+ TEST_INSTRUCTION("C4E3F932D57B" , kshiftlw(k2, k5, 123));
+ TEST_INSTRUCTION("C5F890E5" , kmovw(k4, k5));
+ TEST_INSTRUCTION("C5F89021" , kmovw(k4, word_ptr(rcx)));
+ TEST_INSTRUCTION("C4A17890A4F023010000" , kmovw(k4, word_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("C5F89121" , kmovw(word_ptr(rcx), k4));
+ TEST_INSTRUCTION("C4A17891A4F023010000" , kmovw(word_ptr(rax, r14, 3, 291), k4));
+ TEST_INSTRUCTION("C5F892D8" , kmovw(k3, eax));
+ TEST_INSTRUCTION("C5F892DD" , kmovw(k3, ebp));
+ TEST_INSTRUCTION("C4C17892DD" , kmovw(k3, r13d));
+ TEST_INSTRUCTION("C5F893C2" , kmovw(eax, k2));
+ TEST_INSTRUCTION("C5F893EA" , kmovw(ebp, k2));
+ TEST_INSTRUCTION("C57893EA" , kmovw(r13d, k2));
+ TEST_INSTRUCTION("C5D54BEE" , kunpckbw(k5, k5, k6));
+ TEST_INSTRUCTION("62E37D481D19AB" , vcvtps2ph(ymmword_ptr(rcx), zmm19, 171));
+ TEST_INSTRUCTION("62E37D4E1D19AB" , k(k6).vcvtps2ph(ymmword_ptr(rcx), zmm19, 171));
+ TEST_INSTRUCTION("62E37D481D197B" , vcvtps2ph(ymmword_ptr(rcx), zmm19, 123));
+ TEST_INSTRUCTION("62A37D481D9CF0230100007B" , vcvtps2ph(ymmword_ptr(rax, r14, 3, 291), zmm19, 123));
+ TEST_INSTRUCTION("62E37D481D5A7F7B" , vcvtps2ph(ymmword_ptr(rdx, 4064), zmm19, 123));
+ TEST_INSTRUCTION("62E37D481D9A001000007B" , vcvtps2ph(ymmword_ptr(rdx, 4096), zmm19, 123));
+ TEST_INSTRUCTION("62E37D481D5A807B" , vcvtps2ph(ymmword_ptr(rdx, -4096), zmm19, 123));
+ TEST_INSTRUCTION("62E37D481D9AE0EFFFFF7B" , vcvtps2ph(ymmword_ptr(rdx, -4128), zmm19, 123));
+ TEST_INSTRUCTION("62E37D481921AB" , vextractf32x4(xmmword_ptr(rcx), zmm20, 171));
+ TEST_INSTRUCTION("62E37D4F1921AB" , k(k7).vextractf32x4(xmmword_ptr(rcx), zmm20, 171));
+ TEST_INSTRUCTION("62E37D4819217B" , vextractf32x4(xmmword_ptr(rcx), zmm20, 123));
+ TEST_INSTRUCTION("62A37D4819A4F0230100007B" , vextractf32x4(xmmword_ptr(rax, r14, 3, 291), zmm20, 123));
+ TEST_INSTRUCTION("62E37D4819627F7B" , vextractf32x4(xmmword_ptr(rdx, 2032), zmm20, 123));
+ TEST_INSTRUCTION("62E37D4819A2000800007B" , vextractf32x4(xmmword_ptr(rdx, 2048), zmm20, 123));
+ TEST_INSTRUCTION("62E37D481962807B" , vextractf32x4(xmmword_ptr(rdx, -2048), zmm20, 123));
+ TEST_INSTRUCTION("62E37D4819A2F0F7FFFF7B" , vextractf32x4(xmmword_ptr(rdx, -2064), zmm20, 123));
+ TEST_INSTRUCTION("62F3FD481B29AB" , vextractf64x4(ymmword_ptr(rcx), zmm5, 171));
+ TEST_INSTRUCTION("62F3FD4C1B29AB" , k(k4).vextractf64x4(ymmword_ptr(rcx), zmm5, 171));
+ TEST_INSTRUCTION("62F3FD481B297B" , vextractf64x4(ymmword_ptr(rcx), zmm5, 123));
+ TEST_INSTRUCTION("62B3FD481BACF0230100007B" , vextractf64x4(ymmword_ptr(rax, r14, 3, 291), zmm5, 123));
+ TEST_INSTRUCTION("62F3FD481B6A7F7B" , vextractf64x4(ymmword_ptr(rdx, 4064), zmm5, 123));
+ TEST_INSTRUCTION("62F3FD481BAA001000007B" , vextractf64x4(ymmword_ptr(rdx, 4096), zmm5, 123));
+ TEST_INSTRUCTION("62F3FD481B6A807B" , vextractf64x4(ymmword_ptr(rdx, -4096), zmm5, 123));
+ TEST_INSTRUCTION("62F3FD481BAAE0EFFFFF7B" , vextractf64x4(ymmword_ptr(rdx, -4128), zmm5, 123));
+ TEST_INSTRUCTION("62637D483929AB" , vextracti32x4(xmmword_ptr(rcx), zmm29, 171));
+ TEST_INSTRUCTION("62637D4A3929AB" , k(k2).vextracti32x4(xmmword_ptr(rcx), zmm29, 171));
+ TEST_INSTRUCTION("62637D4839297B" , vextracti32x4(xmmword_ptr(rcx), zmm29, 123));
+ TEST_INSTRUCTION("62237D4839ACF0230100007B" , vextracti32x4(xmmword_ptr(rax, r14, 3, 291), zmm29, 123));
+ TEST_INSTRUCTION("62637D48396A7F7B" , vextracti32x4(xmmword_ptr(rdx, 2032), zmm29, 123));
+ TEST_INSTRUCTION("62637D4839AA000800007B" , vextracti32x4(xmmword_ptr(rdx, 2048), zmm29, 123));
+ TEST_INSTRUCTION("62637D48396A807B" , vextracti32x4(xmmword_ptr(rdx, -2048), zmm29, 123));
+ TEST_INSTRUCTION("62637D4839AAF0F7FFFF7B" , vextracti32x4(xmmword_ptr(rdx, -2064), zmm29, 123));
+ TEST_INSTRUCTION("6263FD483B31AB" , vextracti64x4(ymmword_ptr(rcx), zmm30, 171));
+ TEST_INSTRUCTION("6263FD4C3B31AB" , k(k4).vextracti64x4(ymmword_ptr(rcx), zmm30, 171));
+ TEST_INSTRUCTION("6263FD483B317B" , vextracti64x4(ymmword_ptr(rcx), zmm30, 123));
+ TEST_INSTRUCTION("6223FD483BB4F0230100007B" , vextracti64x4(ymmword_ptr(rax, r14, 3, 291), zmm30, 123));
+ TEST_INSTRUCTION("6263FD483B727F7B" , vextracti64x4(ymmword_ptr(rdx, 4064), zmm30, 123));
+ TEST_INSTRUCTION("6263FD483BB2001000007B" , vextracti64x4(ymmword_ptr(rdx, 4096), zmm30, 123));
+ TEST_INSTRUCTION("6263FD483B72807B" , vextracti64x4(ymmword_ptr(rdx, -4096), zmm30, 123));
+ TEST_INSTRUCTION("6263FD483BB2E0EFFFFF7B" , vextracti64x4(ymmword_ptr(rdx, -4128), zmm30, 123));
+ TEST_INSTRUCTION("62E1FD482911" , vmovapd(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E1FD4E2911" , k(k6).vmovapd(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A1FD482994F023010000" , vmovapd(zmmword_ptr(rax, r14, 3, 291), zmm18));
+ TEST_INSTRUCTION("62E1FD4829527F" , vmovapd(zmmword_ptr(rdx, 8128), zmm18));
+ TEST_INSTRUCTION("62E1FD48299200200000" , vmovapd(zmmword_ptr(rdx, 8192), zmm18));
+ TEST_INSTRUCTION("62E1FD48295280" , vmovapd(zmmword_ptr(rdx, -8192), zmm18));
+ TEST_INSTRUCTION("62E1FD482992C0DFFFFF" , vmovapd(zmmword_ptr(rdx, -8256), zmm18));
+ TEST_INSTRUCTION("62717C482909" , vmovaps(zmmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("62717C4B2909" , k(k3).vmovaps(zmmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("62317C48298CF023010000" , vmovaps(zmmword_ptr(rax, r14, 3, 291), zmm9));
+ TEST_INSTRUCTION("62717C48294A7F" , vmovaps(zmmword_ptr(rdx, 8128), zmm9));
+ TEST_INSTRUCTION("62717C48298A00200000" , vmovaps(zmmword_ptr(rdx, 8192), zmm9));
+ TEST_INSTRUCTION("62717C48294A80" , vmovaps(zmmword_ptr(rdx, -8192), zmm9));
+ TEST_INSTRUCTION("62717C48298AC0DFFFFF" , vmovaps(zmmword_ptr(rdx, -8256), zmm9));
+ TEST_INSTRUCTION("62E17D487F11" , vmovdqa32(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E17D4C7F11" , k(k4).vmovdqa32(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A17D487F94F023010000" , vmovdqa32(zmmword_ptr(rax, r14, 3, 291), zmm18));
+ TEST_INSTRUCTION("62E17D487F527F" , vmovdqa32(zmmword_ptr(rdx, 8128), zmm18));
+ TEST_INSTRUCTION("62E17D487F9200200000" , vmovdqa32(zmmword_ptr(rdx, 8192), zmm18));
+ TEST_INSTRUCTION("62E17D487F5280" , vmovdqa32(zmmword_ptr(rdx, -8192), zmm18));
+ TEST_INSTRUCTION("62E17D487F92C0DFFFFF" , vmovdqa32(zmmword_ptr(rdx, -8256), zmm18));
+ TEST_INSTRUCTION("62E1FD487F19" , vmovdqa64(zmmword_ptr(rcx), zmm19));
+ TEST_INSTRUCTION("62E1FD4D7F19" , k(k5).vmovdqa64(zmmword_ptr(rcx), zmm19));
+ TEST_INSTRUCTION("62A1FD487F9CF023010000" , vmovdqa64(zmmword_ptr(rax, r14, 3, 291), zmm19));
+ TEST_INSTRUCTION("62E1FD487F5A7F" , vmovdqa64(zmmword_ptr(rdx, 8128), zmm19));
+ TEST_INSTRUCTION("62E1FD487F9A00200000" , vmovdqa64(zmmword_ptr(rdx, 8192), zmm19));
+ TEST_INSTRUCTION("62E1FD487F5A80" , vmovdqa64(zmmword_ptr(rdx, -8192), zmm19));
+ TEST_INSTRUCTION("62E1FD487F9AC0DFFFFF" , vmovdqa64(zmmword_ptr(rdx, -8256), zmm19));
+ TEST_INSTRUCTION("62E17E487F31" , vmovdqu32(zmmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62E17E497F31" , k(k1).vmovdqu32(zmmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62A17E487FB4F023010000" , vmovdqu32(zmmword_ptr(rax, r14, 3, 291), zmm22));
+ TEST_INSTRUCTION("62E17E487F727F" , vmovdqu32(zmmword_ptr(rdx, 8128), zmm22));
+ TEST_INSTRUCTION("62E17E487FB200200000" , vmovdqu32(zmmword_ptr(rdx, 8192), zmm22));
+ TEST_INSTRUCTION("62E17E487F7280" , vmovdqu32(zmmword_ptr(rdx, -8192), zmm22));
+ TEST_INSTRUCTION("62E17E487FB2C0DFFFFF" , vmovdqu32(zmmword_ptr(rdx, -8256), zmm22));
+ TEST_INSTRUCTION("6261FE487F01" , vmovdqu64(zmmword_ptr(rcx), zmm24));
+ TEST_INSTRUCTION("6261FE4D7F01" , k(k5).vmovdqu64(zmmword_ptr(rcx), zmm24));
+ TEST_INSTRUCTION("6221FE487F84F023010000" , vmovdqu64(zmmword_ptr(rax, r14, 3, 291), zmm24));
+ TEST_INSTRUCTION("6261FE487F427F" , vmovdqu64(zmmword_ptr(rdx, 8128), zmm24));
+ TEST_INSTRUCTION("6261FE487F8200200000" , vmovdqu64(zmmword_ptr(rdx, 8192), zmm24));
+ TEST_INSTRUCTION("6261FE487F4280" , vmovdqu64(zmmword_ptr(rdx, -8192), zmm24));
+ TEST_INSTRUCTION("6261FE487F82C0DFFFFF" , vmovdqu64(zmmword_ptr(rdx, -8256), zmm24));
+ TEST_INSTRUCTION("6271FD481111" , vmovupd(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("6271FD4F1111" , k(k7).vmovupd(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("6231FD481194F023010000" , vmovupd(zmmword_ptr(rax, r14, 3, 291), zmm10));
+ TEST_INSTRUCTION("6271FD4811527F" , vmovupd(zmmword_ptr(rdx, 8128), zmm10));
+ TEST_INSTRUCTION("6271FD48119200200000" , vmovupd(zmmword_ptr(rdx, 8192), zmm10));
+ TEST_INSTRUCTION("6271FD48115280" , vmovupd(zmmword_ptr(rdx, -8192), zmm10));
+ TEST_INSTRUCTION("6271FD481192C0DFFFFF" , vmovupd(zmmword_ptr(rdx, -8256), zmm10));
+ TEST_INSTRUCTION("62617C481101" , vmovups(zmmword_ptr(rcx), zmm24));
+ TEST_INSTRUCTION("62617C4F1101" , k(k7).vmovups(zmmword_ptr(rcx), zmm24));
+ TEST_INSTRUCTION("62217C481184F023010000" , vmovups(zmmword_ptr(rax, r14, 3, 291), zmm24));
+ TEST_INSTRUCTION("62617C4811427F" , vmovups(zmmword_ptr(rdx, 8128), zmm24));
+ TEST_INSTRUCTION("62617C48118200200000" , vmovups(zmmword_ptr(rdx, 8192), zmm24));
+ TEST_INSTRUCTION("62617C48114280" , vmovups(zmmword_ptr(rdx, -8192), zmm24));
+ TEST_INSTRUCTION("62617C481182C0DFFFFF" , vmovups(zmmword_ptr(rdx, -8256), zmm24));
+ TEST_INSTRUCTION("62F27E483219" , vpmovqb(qword_ptr(rcx), zmm3));
+ TEST_INSTRUCTION("62F27E4F3219" , k(k7).vpmovqb(qword_ptr(rcx), zmm3));
+ TEST_INSTRUCTION("62B27E48329CF023010000" , vpmovqb(qword_ptr(rax, r14, 3, 291), zmm3));
+ TEST_INSTRUCTION("62F27E48325A7F" , vpmovqb(qword_ptr(rdx, 1016), zmm3));
+ TEST_INSTRUCTION("62F27E48329A00040000" , vpmovqb(qword_ptr(rdx, 1024), zmm3));
+ TEST_INSTRUCTION("62F27E48325A80" , vpmovqb(qword_ptr(rdx, -1024), zmm3));
+ TEST_INSTRUCTION("62F27E48329AF8FBFFFF" , vpmovqb(qword_ptr(rdx, -1032), zmm3));
+ TEST_INSTRUCTION("62E27E482201" , vpmovsqb(qword_ptr(rcx), zmm16));
+ TEST_INSTRUCTION("62E27E4A2201" , k(k2).vpmovsqb(qword_ptr(rcx), zmm16));
+ TEST_INSTRUCTION("62A27E482284F023010000" , vpmovsqb(qword_ptr(rax, r14, 3, 291), zmm16));
+ TEST_INSTRUCTION("62E27E4822427F" , vpmovsqb(qword_ptr(rdx, 1016), zmm16));
+ TEST_INSTRUCTION("62E27E48228200040000" , vpmovsqb(qword_ptr(rdx, 1024), zmm16));
+ TEST_INSTRUCTION("62E27E48224280" , vpmovsqb(qword_ptr(rdx, -1024), zmm16));
+ TEST_INSTRUCTION("62E27E482282F8FBFFFF" , vpmovsqb(qword_ptr(rdx, -1032), zmm16));
+ TEST_INSTRUCTION("62627E481221" , vpmovusqb(qword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62627E491221" , k(k1).vpmovusqb(qword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62227E4812A4F023010000" , vpmovusqb(qword_ptr(rax, r14, 3, 291), zmm28));
+ TEST_INSTRUCTION("62627E4812627F" , vpmovusqb(qword_ptr(rdx, 1016), zmm28));
+ TEST_INSTRUCTION("62627E4812A200040000" , vpmovusqb(qword_ptr(rdx, 1024), zmm28));
+ TEST_INSTRUCTION("62627E48126280" , vpmovusqb(qword_ptr(rdx, -1024), zmm28));
+ TEST_INSTRUCTION("62627E4812A2F8FBFFFF" , vpmovusqb(qword_ptr(rdx, -1032), zmm28));
+ TEST_INSTRUCTION("62F27E483439" , vpmovqw(xmmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62F27E4E3439" , k(k6).vpmovqw(xmmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62B27E4834BCF023010000" , vpmovqw(xmmword_ptr(rax, r14, 3, 291), zmm7));
+ TEST_INSTRUCTION("62F27E48347A7F" , vpmovqw(xmmword_ptr(rdx, 2032), zmm7));
+ TEST_INSTRUCTION("62F27E4834BA00080000" , vpmovqw(xmmword_ptr(rdx, 2048), zmm7));
+ TEST_INSTRUCTION("62F27E48347A80" , vpmovqw(xmmword_ptr(rdx, -2048), zmm7));
+ TEST_INSTRUCTION("62F27E4834BAF0F7FFFF" , vpmovqw(xmmword_ptr(rdx, -2064), zmm7));
+ TEST_INSTRUCTION("62F27E482409" , vpmovsqw(xmmword_ptr(rcx), zmm1));
+ TEST_INSTRUCTION("62F27E4D2409" , k(k5).vpmovsqw(xmmword_ptr(rcx), zmm1));
+ TEST_INSTRUCTION("62B27E48248CF023010000" , vpmovsqw(xmmword_ptr(rax, r14, 3, 291), zmm1));
+ TEST_INSTRUCTION("62F27E48244A7F" , vpmovsqw(xmmword_ptr(rdx, 2032), zmm1));
+ TEST_INSTRUCTION("62F27E48248A00080000" , vpmovsqw(xmmword_ptr(rdx, 2048), zmm1));
+ TEST_INSTRUCTION("62F27E48244A80" , vpmovsqw(xmmword_ptr(rdx, -2048), zmm1));
+ TEST_INSTRUCTION("62F27E48248AF0F7FFFF" , vpmovsqw(xmmword_ptr(rdx, -2064), zmm1));
+ TEST_INSTRUCTION("62627E481409" , vpmovusqw(xmmword_ptr(rcx), zmm25));
+ TEST_INSTRUCTION("62627E4B1409" , k(k3).vpmovusqw(xmmword_ptr(rcx), zmm25));
+ TEST_INSTRUCTION("62227E48148CF023010000" , vpmovusqw(xmmword_ptr(rax, r14, 3, 291), zmm25));
+ TEST_INSTRUCTION("62627E48144A7F" , vpmovusqw(xmmword_ptr(rdx, 2032), zmm25));
+ TEST_INSTRUCTION("62627E48148A00080000" , vpmovusqw(xmmword_ptr(rdx, 2048), zmm25));
+ TEST_INSTRUCTION("62627E48144A80" , vpmovusqw(xmmword_ptr(rdx, -2048), zmm25));
+ TEST_INSTRUCTION("62627E48148AF0F7FFFF" , vpmovusqw(xmmword_ptr(rdx, -2064), zmm25));
+ TEST_INSTRUCTION("62627E483521" , vpmovqd(ymmword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62627E4D3521" , k(k5).vpmovqd(ymmword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62227E4835A4F023010000" , vpmovqd(ymmword_ptr(rax, r14, 3, 291), zmm28));
+ TEST_INSTRUCTION("62627E4835627F" , vpmovqd(ymmword_ptr(rdx, 4064), zmm28));
+ TEST_INSTRUCTION("62627E4835A200100000" , vpmovqd(ymmword_ptr(rdx, 4096), zmm28));
+ TEST_INSTRUCTION("62627E48356280" , vpmovqd(ymmword_ptr(rdx, -4096), zmm28));
+ TEST_INSTRUCTION("62627E4835A2E0EFFFFF" , vpmovqd(ymmword_ptr(rdx, -4128), zmm28));
+ TEST_INSTRUCTION("62727E482509" , vpmovsqd(ymmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("62727E4F2509" , k(k7).vpmovsqd(ymmword_ptr(rcx), zmm9));
+ TEST_INSTRUCTION("62327E48258CF023010000" , vpmovsqd(ymmword_ptr(rax, r14, 3, 291), zmm9));
+ TEST_INSTRUCTION("62727E48254A7F" , vpmovsqd(ymmword_ptr(rdx, 4064), zmm9));
+ TEST_INSTRUCTION("62727E48258A00100000" , vpmovsqd(ymmword_ptr(rdx, 4096), zmm9));
+ TEST_INSTRUCTION("62727E48254A80" , vpmovsqd(ymmword_ptr(rdx, -4096), zmm9));
+ TEST_INSTRUCTION("62727E48258AE0EFFFFF" , vpmovsqd(ymmword_ptr(rdx, -4128), zmm9));
+ TEST_INSTRUCTION("62E27E481531" , vpmovusqd(ymmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62E27E491531" , k(k1).vpmovusqd(ymmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62A27E4815B4F023010000" , vpmovusqd(ymmword_ptr(rax, r14, 3, 291), zmm22));
+ TEST_INSTRUCTION("62E27E4815727F" , vpmovusqd(ymmword_ptr(rdx, 4064), zmm22));
+ TEST_INSTRUCTION("62E27E4815B200100000" , vpmovusqd(ymmword_ptr(rdx, 4096), zmm22));
+ TEST_INSTRUCTION("62E27E48157280" , vpmovusqd(ymmword_ptr(rdx, -4096), zmm22));
+ TEST_INSTRUCTION("62E27E4815B2E0EFFFFF" , vpmovusqd(ymmword_ptr(rdx, -4128), zmm22));
+ TEST_INSTRUCTION("62727E483121" , vpmovdb(xmmword_ptr(rcx), zmm12));
+ TEST_INSTRUCTION("62727E4B3121" , k(k3).vpmovdb(xmmword_ptr(rcx), zmm12));
+ TEST_INSTRUCTION("62327E4831A4F023010000" , vpmovdb(xmmword_ptr(rax, r14, 3, 291), zmm12));
+ TEST_INSTRUCTION("62727E4831627F" , vpmovdb(xmmword_ptr(rdx, 2032), zmm12));
+ TEST_INSTRUCTION("62727E4831A200080000" , vpmovdb(xmmword_ptr(rdx, 2048), zmm12));
+ TEST_INSTRUCTION("62727E48316280" , vpmovdb(xmmword_ptr(rdx, -2048), zmm12));
+ TEST_INSTRUCTION("62727E4831A2F0F7FFFF" , vpmovdb(xmmword_ptr(rdx, -2064), zmm12));
+ TEST_INSTRUCTION("62F27E482131" , vpmovsdb(xmmword_ptr(rcx), zmm6));
+ TEST_INSTRUCTION("62F27E492131" , k(k1).vpmovsdb(xmmword_ptr(rcx), zmm6));
+ TEST_INSTRUCTION("62B27E4821B4F023010000" , vpmovsdb(xmmword_ptr(rax, r14, 3, 291), zmm6));
+ TEST_INSTRUCTION("62F27E4821727F" , vpmovsdb(xmmword_ptr(rdx, 2032), zmm6));
+ TEST_INSTRUCTION("62F27E4821B200080000" , vpmovsdb(xmmword_ptr(rdx, 2048), zmm6));
+ TEST_INSTRUCTION("62F27E48217280" , vpmovsdb(xmmword_ptr(rdx, -2048), zmm6));
+ TEST_INSTRUCTION("62F27E4821B2F0F7FFFF" , vpmovsdb(xmmword_ptr(rdx, -2064), zmm6));
+ TEST_INSTRUCTION("62E27E481139" , vpmovusdb(xmmword_ptr(rcx), zmm23));
+ TEST_INSTRUCTION("62E27E4B1139" , k(k3).vpmovusdb(xmmword_ptr(rcx), zmm23));
+ TEST_INSTRUCTION("62A27E4811BCF023010000" , vpmovusdb(xmmword_ptr(rax, r14, 3, 291), zmm23));
+ TEST_INSTRUCTION("62E27E48117A7F" , vpmovusdb(xmmword_ptr(rdx, 2032), zmm23));
+ TEST_INSTRUCTION("62E27E4811BA00080000" , vpmovusdb(xmmword_ptr(rdx, 2048), zmm23));
+ TEST_INSTRUCTION("62E27E48117A80" , vpmovusdb(xmmword_ptr(rdx, -2048), zmm23));
+ TEST_INSTRUCTION("62E27E4811BAF0F7FFFF" , vpmovusdb(xmmword_ptr(rdx, -2064), zmm23));
+ TEST_INSTRUCTION("62F27E483339" , vpmovdw(ymmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62F27E4F3339" , k(k7).vpmovdw(ymmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62B27E4833BCF023010000" , vpmovdw(ymmword_ptr(rax, r14, 3, 291), zmm7));
+ TEST_INSTRUCTION("62F27E48337A7F" , vpmovdw(ymmword_ptr(rdx, 4064), zmm7));
+ TEST_INSTRUCTION("62F27E4833BA00100000" , vpmovdw(ymmword_ptr(rdx, 4096), zmm7));
+ TEST_INSTRUCTION("62F27E48337A80" , vpmovdw(ymmword_ptr(rdx, -4096), zmm7));
+ TEST_INSTRUCTION("62F27E4833BAE0EFFFFF" , vpmovdw(ymmword_ptr(rdx, -4128), zmm7));
+ TEST_INSTRUCTION("62727E482331" , vpmovsdw(ymmword_ptr(rcx), zmm14));
+ TEST_INSTRUCTION("62727E4E2331" , k(k6).vpmovsdw(ymmword_ptr(rcx), zmm14));
+ TEST_INSTRUCTION("62327E4823B4F023010000" , vpmovsdw(ymmword_ptr(rax, r14, 3, 291), zmm14));
+ TEST_INSTRUCTION("62727E4823727F" , vpmovsdw(ymmword_ptr(rdx, 4064), zmm14));
+ TEST_INSTRUCTION("62727E4823B200100000" , vpmovsdw(ymmword_ptr(rdx, 4096), zmm14));
+ TEST_INSTRUCTION("62727E48237280" , vpmovsdw(ymmword_ptr(rdx, -4096), zmm14));
+ TEST_INSTRUCTION("62727E4823B2E0EFFFFF" , vpmovsdw(ymmword_ptr(rdx, -4128), zmm14));
+ TEST_INSTRUCTION("62F27E481329" , vpmovusdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62F27E4B1329" , k(k3).vpmovusdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62B27E4813ACF023010000" , vpmovusdw(ymmword_ptr(rax, r14, 3, 291), zmm5));
+ TEST_INSTRUCTION("62F27E48136A7F" , vpmovusdw(ymmword_ptr(rdx, 4064), zmm5));
+ TEST_INSTRUCTION("62F27E4813AA00100000" , vpmovusdw(ymmword_ptr(rdx, 4096), zmm5));
+ TEST_INSTRUCTION("62F27E48136A80" , vpmovusdw(ymmword_ptr(rdx, -4096), zmm5));
+ TEST_INSTRUCTION("62F27E4813AAE0EFFFFF" , vpmovusdw(ymmword_ptr(rdx, -4128), zmm5));
+ TEST_INSTRUCTION("62A1FC4878C4" , vcvttpd2udq(ymm16, zmm20));
+ TEST_INSTRUCTION("62A1FC4F78C4" , k(k7).vcvttpd2udq(ymm16, zmm20));
+ TEST_INSTRUCTION("62A1FCCF78C4" , k(k7).z().vcvttpd2udq(ymm16, zmm20));
+ TEST_INSTRUCTION("62A1FC1878C4" , sae().vcvttpd2udq(ymm16, zmm20));
+ TEST_INSTRUCTION("62E1FC487801" , vcvttpd2udq(ymm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FC487884F023010000" , vcvttpd2udq(ymm16, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E1FC587801" , vcvttpd2udq(ymm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1FC4878427F" , vcvttpd2udq(ymm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FC48788200200000" , vcvttpd2udq(ymm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FC48784280" , vcvttpd2udq(ymm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FC487882C0DFFFFF" , vcvttpd2udq(ymm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FC5878427F" , vcvttpd2udq(ymm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1FC58788200040000" , vcvttpd2udq(ymm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1FC58784280" , vcvttpd2udq(ymm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1FC587882F8FBFFFF" , vcvttpd2udq(ymm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62117C4878F4" , vcvttps2udq(zmm14, zmm28));
+ TEST_INSTRUCTION("62117C4978F4" , k(k1).vcvttps2udq(zmm14, zmm28));
+ TEST_INSTRUCTION("62117CC978F4" , k(k1).z().vcvttps2udq(zmm14, zmm28));
+ TEST_INSTRUCTION("62117C1878F4" , sae().vcvttps2udq(zmm14, zmm28));
+ TEST_INSTRUCTION("62717C487831" , vcvttps2udq(zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317C4878B4F023010000" , vcvttps2udq(zmm14, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717C587831" , vcvttps2udq(zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62717C4878727F" , vcvttps2udq(zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717C4878B200200000" , vcvttps2udq(zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717C48787280" , vcvttps2udq(zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717C4878B2C0DFFFFF" , vcvttps2udq(zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62717C5878727F" , vcvttps2udq(zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62717C5878B200020000" , vcvttps2udq(zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62717C58787280" , vcvttps2udq(zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62717C5878B2FCFDFFFF" , vcvttps2udq(zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B17F0878C5" , vcvttsd2usi(eax, xmm21));
+ TEST_INSTRUCTION("62B17F1878C5" , sae().vcvttsd2usi(eax, xmm21));
+ TEST_INSTRUCTION("62F17F087801" , vcvttsd2usi(eax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F087884F023010000" , vcvttsd2usi(eax, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17F0878427F" , vcvttsd2usi(eax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F08788200040000" , vcvttsd2usi(eax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08784280" , vcvttsd2usi(eax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F087882F8FBFFFF" , vcvttsd2usi(eax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B17F0878ED" , vcvttsd2usi(ebp, xmm21));
+ TEST_INSTRUCTION("62B17F1878ED" , sae().vcvttsd2usi(ebp, xmm21));
+ TEST_INSTRUCTION("62F17F087829" , vcvttsd2usi(ebp, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F0878ACF023010000" , vcvttsd2usi(ebp, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17F08786A7F" , vcvttsd2usi(ebp, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F0878AA00040000" , vcvttsd2usi(ebp, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08786A80" , vcvttsd2usi(ebp, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F0878AAF8FBFFFF" , vcvttsd2usi(ebp, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62317F0878ED" , vcvttsd2usi(r13d, xmm21));
+ TEST_INSTRUCTION("62317F1878ED" , sae().vcvttsd2usi(r13d, xmm21));
+ TEST_INSTRUCTION("62717F087829" , vcvttsd2usi(r13d, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62317F0878ACF023010000" , vcvttsd2usi(r13d, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717F08786A7F" , vcvttsd2usi(r13d, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62717F0878AA00040000" , vcvttsd2usi(r13d, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62717F08786A80" , vcvttsd2usi(r13d, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62717F0878AAF8FBFFFF" , vcvttsd2usi(r13d, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62F1FF0878C7" , vcvttsd2usi(rax, xmm7));
+ TEST_INSTRUCTION("62F1FF1878C7" , sae().vcvttsd2usi(rax, xmm7));
+ TEST_INSTRUCTION("62F1FF087801" , vcvttsd2usi(rax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF087884F023010000" , vcvttsd2usi(rax, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FF0878427F" , vcvttsd2usi(rax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1FF08788200040000" , vcvttsd2usi(rax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1FF08784280" , vcvttsd2usi(rax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1FF087882F8FBFFFF" , vcvttsd2usi(rax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6271FF0878C7" , vcvttsd2usi(r8, xmm7));
+ TEST_INSTRUCTION("6271FF1878C7" , sae().vcvttsd2usi(r8, xmm7));
+ TEST_INSTRUCTION("6271FF087801" , vcvttsd2usi(r8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FF087884F023010000" , vcvttsd2usi(r8, qword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271FF0878427F" , vcvttsd2usi(r8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271FF08788200040000" , vcvttsd2usi(r8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271FF08784280" , vcvttsd2usi(r8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271FF087882F8FBFFFF" , vcvttsd2usi(r8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B17E0878C2" , vcvttss2usi(eax, xmm18));
+ TEST_INSTRUCTION("62B17E1878C2" , sae().vcvttss2usi(eax, xmm18));
+ TEST_INSTRUCTION("62F17E087801" , vcvttss2usi(eax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E087884F023010000" , vcvttss2usi(eax, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17E0878427F" , vcvttss2usi(eax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E08788200020000" , vcvttss2usi(eax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08784280" , vcvttss2usi(eax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E087882FCFDFFFF" , vcvttss2usi(eax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B17E0878EA" , vcvttss2usi(ebp, xmm18));
+ TEST_INSTRUCTION("62B17E1878EA" , sae().vcvttss2usi(ebp, xmm18));
+ TEST_INSTRUCTION("62F17E087829" , vcvttss2usi(ebp, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E0878ACF023010000" , vcvttss2usi(ebp, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F17E08786A7F" , vcvttss2usi(ebp, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E0878AA00020000" , vcvttss2usi(ebp, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08786A80" , vcvttss2usi(ebp, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E0878AAFCFDFFFF" , vcvttss2usi(ebp, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62317E0878EA" , vcvttss2usi(r13d, xmm18));
+ TEST_INSTRUCTION("62317E1878EA" , sae().vcvttss2usi(r13d, xmm18));
+ TEST_INSTRUCTION("62717E087829" , vcvttss2usi(r13d, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E0878ACF023010000" , vcvttss2usi(r13d, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62717E08786A7F" , vcvttss2usi(r13d, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62717E0878AA00020000" , vcvttss2usi(r13d, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62717E08786A80" , vcvttss2usi(r13d, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62717E0878AAFCFDFFFF" , vcvttss2usi(r13d, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6291FE0878C3" , vcvttss2usi(rax, xmm27));
+ TEST_INSTRUCTION("6291FE1878C3" , sae().vcvttss2usi(rax, xmm27));
+ TEST_INSTRUCTION("62F1FE087801" , vcvttss2usi(rax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FE087884F023010000" , vcvttss2usi(rax, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62F1FE0878427F" , vcvttss2usi(rax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F1FE08788200020000" , vcvttss2usi(rax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F1FE08784280" , vcvttss2usi(rax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F1FE087882FCFDFFFF" , vcvttss2usi(rax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6211FE0878C3" , vcvttss2usi(r8, xmm27));
+ TEST_INSTRUCTION("6211FE1878C3" , sae().vcvttss2usi(r8, xmm27));
+ TEST_INSTRUCTION("6271FE087801" , vcvttss2usi(r8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FE087884F023010000" , vcvttss2usi(r8, dword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("6271FE0878427F" , vcvttss2usi(r8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("6271FE08788200020000" , vcvttss2usi(r8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("6271FE08784280" , vcvttss2usi(r8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("6271FE087882FCFDFFFF" , vcvttss2usi(r8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62721D4076D4" , vpermi2d(zmm10, zmm28, zmm4));
+ TEST_INSTRUCTION("62721D4576D4" , k(k5).vpermi2d(zmm10, zmm28, zmm4));
+ TEST_INSTRUCTION("62721DC576D4" , k(k5).z().vpermi2d(zmm10, zmm28, zmm4));
+ TEST_INSTRUCTION("62721D407611" , vpermi2d(zmm10, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D407694F023010000" , vpermi2d(zmm10, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62721D507611" , vpermi2d(zmm10, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62721D4076527F" , vpermi2d(zmm10, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62721D40769200200000" , vpermi2d(zmm10, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62721D40765280" , vpermi2d(zmm10, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62721D407692C0DFFFFF" , vpermi2d(zmm10, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62721D5076527F" , vpermi2d(zmm10, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62721D50769200020000" , vpermi2d(zmm10, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62721D50765280" , vpermi2d(zmm10, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62721D507692FCFDFFFF" , vpermi2d(zmm10, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62829D4076D4" , vpermi2q(zmm18, zmm28, zmm28));
+ TEST_INSTRUCTION("62829D4276D4" , k(k2).vpermi2q(zmm18, zmm28, zmm28));
+ TEST_INSTRUCTION("62829DC276D4" , k(k2).z().vpermi2q(zmm18, zmm28, zmm28));
+ TEST_INSTRUCTION("62E29D407611" , vpermi2q(zmm18, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A29D407694F023010000" , vpermi2q(zmm18, zmm28, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E29D507611" , vpermi2q(zmm18, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E29D4076527F" , vpermi2q(zmm18, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E29D40769200200000" , vpermi2q(zmm18, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E29D40765280" , vpermi2q(zmm18, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E29D407692C0DFFFFF" , vpermi2q(zmm18, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E29D5076527F" , vpermi2q(zmm18, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E29D50769200040000" , vpermi2q(zmm18, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E29D50765280" , vpermi2q(zmm18, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E29D507692F8FBFFFF" , vpermi2q(zmm18, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6242454077C0" , vpermi2ps(zmm24, zmm23, zmm8));
+ TEST_INSTRUCTION("6242454277C0" , k(k2).vpermi2ps(zmm24, zmm23, zmm8));
+ TEST_INSTRUCTION("624245C277C0" , k(k2).z().vpermi2ps(zmm24, zmm23, zmm8));
+ TEST_INSTRUCTION("626245407701" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622245407784F023010000" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("626245507701" , vpermi2ps(zmm24, zmm23, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("6262454077427F" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62624540778200200000" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62624540774280" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626245407782C0DFFFFF" , vpermi2ps(zmm24, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262455077427F" , vpermi2ps(zmm24, zmm23, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62624550778200020000" , vpermi2ps(zmm24, zmm23, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62624550774280" , vpermi2ps(zmm24, zmm23, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("626245507782FCFDFFFF" , vpermi2ps(zmm24, zmm23, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2D54877E4" , vpermi2pd(zmm20, zmm5, zmm20));
+ TEST_INSTRUCTION("62A2D54B77E4" , k(k3).vpermi2pd(zmm20, zmm5, zmm20));
+ TEST_INSTRUCTION("62A2D5CB77E4" , k(k3).z().vpermi2pd(zmm20, zmm5, zmm20));
+ TEST_INSTRUCTION("62E2D5487721" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2D54877A4F023010000" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rax, r14, 3, 291)));
+ TEST_INSTRUCTION("62E2D5587721" , vpermi2pd(zmm20, zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2D54877627F" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2D54877A200200000" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2D548776280" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2D54877A2C0DFFFFF" , vpermi2pd(zmm20, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2D55877627F" , vpermi2pd(zmm20, zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2D55877A200040000" , vpermi2pd(zmm20, zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2D558776280" , vpermi2pd(zmm20, zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2D55877A2F8FBFFFF" , vpermi2pd(zmm20, zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E1A54858CA" , vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A54958CA" , k(k1).vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A5C958CA" , k(k1).z().vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A51858CA" , rn_sae().vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A55858CA" , ru_sae().vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A53858CA" , rd_sae().vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A57858CA" , rz_sae().vaddpd(zmm17, zmm11, zmm2));
+ TEST_INSTRUCTION("62E1A5485809" , vaddpd(zmm17, zmm11, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1A548588CF034120000" , vaddpd(zmm17, zmm11, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1A5585809" , vaddpd(zmm17, zmm11, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1A548584A7F" , vaddpd(zmm17, zmm11, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1A548588A00200000" , vaddpd(zmm17, zmm11, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1A548584A80" , vaddpd(zmm17, zmm11, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1A548588AC0DFFFFF" , vaddpd(zmm17, zmm11, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1A558584A7F" , vaddpd(zmm17, zmm11, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1A558588A00040000" , vaddpd(zmm17, zmm11, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1A558584A80" , vaddpd(zmm17, zmm11, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1A558588AF8FBFFFF" , vaddpd(zmm17, zmm11, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F14C4858DD" , vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C4958DD" , k(k1).vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14CC958DD" , k(k1).z().vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C1858DD" , rn_sae().vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C5858DD" , ru_sae().vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C3858DD" , rd_sae().vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C7858DD" , rz_sae().vaddps(zmm3, zmm6, zmm5));
+ TEST_INSTRUCTION("62F14C485819" , vaddps(zmm3, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B14C48589CF034120000" , vaddps(zmm3, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F14C585819" , vaddps(zmm3, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F14C48585A7F" , vaddps(zmm3, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F14C48589A00200000" , vaddps(zmm3, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F14C48585A80" , vaddps(zmm3, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F14C48589AC0DFFFFF" , vaddps(zmm3, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F14C58585A7F" , vaddps(zmm3, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F14C58589A00020000" , vaddps(zmm3, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F14C58585A80" , vaddps(zmm3, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F14C58589AFCFDFFFF" , vaddps(zmm3, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6291EF0058CB" , vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF0358CB" , k(k3).vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF8358CB" , k(k3).z().vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF1058CB" , rn_sae().vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF5058CB" , ru_sae().vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF3058CB" , rd_sae().vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("6291EF7058CB" , rz_sae().vaddsd(xmm1, xmm18, xmm27));
+ TEST_INSTRUCTION("62F1EF005809" , vaddsd(xmm1, xmm18, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1EF00588CF034120000" , vaddsd(xmm1, xmm18, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1EF00584A7F" , vaddsd(xmm1, xmm18, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1EF00588A00040000" , vaddsd(xmm1, xmm18, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1EF00584A80" , vaddsd(xmm1, xmm18, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1EF00588AF8FBFFFF" , vaddsd(xmm1, xmm18, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C10E0858CF" , vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E0C58CF" , k(k4).vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E8C58CF" , k(k4).z().vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E1858CF" , rn_sae().vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E5858CF" , ru_sae().vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E3858CF" , rd_sae().vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62C10E7858CF" , rz_sae().vaddss(xmm17, xmm14, xmm15));
+ TEST_INSTRUCTION("62E10E085809" , vaddss(xmm17, xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A10E08588CF034120000" , vaddss(xmm17, xmm14, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E10E08584A7F" , vaddss(xmm17, xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E10E08588A00020000" , vaddss(xmm17, xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E10E08584A80" , vaddss(xmm17, xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E10E08588AFCFDFFFF" , vaddss(xmm17, xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6273454803FDAB" , valignd(zmm15, zmm7, zmm5, 171));
+ TEST_INSTRUCTION("6273454A03FDAB" , k(k2).valignd(zmm15, zmm7, zmm5, 171));
+ TEST_INSTRUCTION("627345CA03FDAB" , k(k2).z().valignd(zmm15, zmm7, zmm5, 171));
+ TEST_INSTRUCTION("6273454803FD7B" , valignd(zmm15, zmm7, zmm5, 123));
+ TEST_INSTRUCTION("6273454803397B" , valignd(zmm15, zmm7, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233454803BCF0341200007B" , valignd(zmm15, zmm7, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273455803397B" , valignd(zmm15, zmm7, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62734548037A7F7B" , valignd(zmm15, zmm7, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273454803BA002000007B" , valignd(zmm15, zmm7, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62734548037A807B" , valignd(zmm15, zmm7, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273454803BAC0DFFFFF7B" , valignd(zmm15, zmm7, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62734558037A7F7B" , valignd(zmm15, zmm7, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("6273455803BA000200007B" , valignd(zmm15, zmm7, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62734558037A807B" , valignd(zmm15, zmm7, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("6273455803BAFCFDFFFF7B" , valignd(zmm15, zmm7, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62C2ED4865F8" , vblendmpd(zmm23, zmm2, zmm8));
+ TEST_INSTRUCTION("62C2ED4F65F8" , k(k7).vblendmpd(zmm23, zmm2, zmm8));
+ TEST_INSTRUCTION("62C2EDCF65F8" , k(k7).z().vblendmpd(zmm23, zmm2, zmm8));
+ TEST_INSTRUCTION("62E2ED486539" , vblendmpd(zmm23, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2ED4865BCF034120000" , vblendmpd(zmm23, zmm2, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2ED586539" , vblendmpd(zmm23, zmm2, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2ED48657A7F" , vblendmpd(zmm23, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2ED4865BA00200000" , vblendmpd(zmm23, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2ED48657A80" , vblendmpd(zmm23, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2ED4865BAC0DFFFFF" , vblendmpd(zmm23, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2ED58657A7F" , vblendmpd(zmm23, zmm2, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2ED5865BA00040000" , vblendmpd(zmm23, zmm2, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED58657A80" , vblendmpd(zmm23, zmm2, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED5865BAF8FBFFFF" , vblendmpd(zmm23, zmm2, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E2354865FF" , vblendmps(zmm23, zmm9, zmm7));
+ TEST_INSTRUCTION("62E2354F65FF" , k(k7).vblendmps(zmm23, zmm9, zmm7));
+ TEST_INSTRUCTION("62E235CF65FF" , k(k7).z().vblendmps(zmm23, zmm9, zmm7));
+ TEST_INSTRUCTION("62E235486539" , vblendmps(zmm23, zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2354865BCF034120000" , vblendmps(zmm23, zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E235586539" , vblendmps(zmm23, zmm9, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E23548657A7F" , vblendmps(zmm23, zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2354865BA00200000" , vblendmps(zmm23, zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E23548657A80" , vblendmps(zmm23, zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2354865BAC0DFFFFF" , vblendmps(zmm23, zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E23558657A7F" , vblendmps(zmm23, zmm9, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E2355865BA00020000" , vblendmps(zmm23, zmm9, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E23558657A80" , vblendmps(zmm23, zmm9, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E2355865BAFCFDFFFF" , vblendmps(zmm23, zmm9, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62727D481A39" , vbroadcastf32x4(zmm15, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62727D4B1A39" , k(k3).vbroadcastf32x4(zmm15, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62727DCB1A39" , k(k3).z().vbroadcastf32x4(zmm15, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D481ABCF034120000" , vbroadcastf32x4(zmm15, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D481A7A7F" , vbroadcastf32x4(zmm15, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62727D481ABA00080000" , vbroadcastf32x4(zmm15, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62727D481A7A80" , vbroadcastf32x4(zmm15, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62727D481ABAF0F7FFFF" , vbroadcastf32x4(zmm15, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6262FD481B11" , vbroadcastf64x4(zmm26, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD491B11" , k(k1).vbroadcastf64x4(zmm26, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDC91B11" , k(k1).z().vbroadcastf64x4(zmm26, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD481B94F034120000" , vbroadcastf64x4(zmm26, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262FD481B527F" , vbroadcastf64x4(zmm26, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("6262FD481B9200100000" , vbroadcastf64x4(zmm26, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("6262FD481B5280" , vbroadcastf64x4(zmm26, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("6262FD481B92E0EFFFFF" , vbroadcastf64x4(zmm26, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62F27D485A11" , vbroadcasti32x4(zmm2, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D4D5A11" , k(k5).vbroadcasti32x4(zmm2, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DCD5A11" , k(k5).z().vbroadcasti32x4(zmm2, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D485A94F034120000" , vbroadcasti32x4(zmm2, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D485A527F" , vbroadcasti32x4(zmm2, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62F27D485A9200080000" , vbroadcasti32x4(zmm2, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62F27D485A5280" , vbroadcasti32x4(zmm2, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62F27D485A92F0F7FFFF" , vbroadcasti32x4(zmm2, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62E2FD485B09" , vbroadcasti64x4(zmm17, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62E2FD4A5B09" , k(k2).vbroadcasti64x4(zmm17, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62E2FDCA5B09" , k(k2).z().vbroadcasti64x4(zmm17, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD485B8CF034120000" , vbroadcasti64x4(zmm17, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2FD485B4A7F" , vbroadcasti64x4(zmm17, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E2FD485B8A00100000" , vbroadcasti64x4(zmm17, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E2FD485B4A80" , vbroadcasti64x4(zmm17, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E2FD485B8AE0EFFFFF" , vbroadcasti64x4(zmm17, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("6262FD481919" , vbroadcastsd(zmm27, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FD4F1919" , k(k7).vbroadcastsd(zmm27, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6262FDCF1919" , k(k7).z().vbroadcastsd(zmm27, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD48199CF034120000" , vbroadcastsd(zmm27, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262FD48195A7F" , vbroadcastsd(zmm27, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262FD48199A00040000" , vbroadcastsd(zmm27, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262FD48195A80" , vbroadcastsd(zmm27, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262FD48199AF8FBFFFF" , vbroadcastsd(zmm27, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6282FD4819D9" , vbroadcastsd(zmm19, xmm25));
+ TEST_INSTRUCTION("6282FD4B19D9" , k(k3).vbroadcastsd(zmm19, xmm25));
+ TEST_INSTRUCTION("6282FDCB19D9" , k(k3).z().vbroadcastsd(zmm19, xmm25));
+ TEST_INSTRUCTION("62F27D481811" , vbroadcastss(zmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27D491811" , k(k1).vbroadcastss(zmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F27DC91811" , k(k1).z().vbroadcastss(zmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D481894F034120000" , vbroadcastss(zmm2, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D4818527F" , vbroadcastss(zmm2, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F27D48189200020000" , vbroadcastss(zmm2, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F27D48185280" , vbroadcastss(zmm2, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F27D481892FCFDFFFF" , vbroadcastss(zmm2, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C27D4818FF" , vbroadcastss(zmm23, xmm15));
+ TEST_INSTRUCTION("62C27D4C18FF" , k(k4).vbroadcastss(zmm23, xmm15));
+ TEST_INSTRUCTION("62C27DCC18FF" , k(k4).z().vbroadcastss(zmm23, xmm15));
+ TEST_INSTRUCTION("62B18548C2E8AB" , vcmppd(k5, zmm15, zmm16, 171));
+ TEST_INSTRUCTION("62B1854DC2E8AB" , k(k5).vcmppd(k5, zmm15, zmm16, 171));
+ TEST_INSTRUCTION("62B18518C2E8AB" , sae().vcmppd(k5, zmm15, zmm16, 171));
+ TEST_INSTRUCTION("62B18548C2E87B" , vcmppd(k5, zmm15, zmm16, 123));
+ TEST_INSTRUCTION("62B18518C2E87B" , sae().vcmppd(k5, zmm15, zmm16, 123));
+ TEST_INSTRUCTION("62F18548C2297B" , vcmppd(k5, zmm15, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B18548C2ACF0341200007B" , vcmppd(k5, zmm15, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F18558C2297B" , vcmppd(k5, zmm15, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F18548C26A7F7B" , vcmppd(k5, zmm15, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F18548C2AA002000007B" , vcmppd(k5, zmm15, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F18548C26A807B" , vcmppd(k5, zmm15, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F18548C2AAC0DFFFFF7B" , vcmppd(k5, zmm15, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F18558C26A7F7B" , vcmppd(k5, zmm15, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F18558C2AA000400007B" , vcmppd(k5, zmm15, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F18558C26A807B" , vcmppd(k5, zmm15, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F18558C2AAF8FBFFFF7B" , vcmppd(k5, zmm15, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62916448C2D5AB" , vcmpps(k2, zmm3, zmm29, 171));
+ TEST_INSTRUCTION("6291644DC2D5AB" , k(k5).vcmpps(k2, zmm3, zmm29, 171));
+ TEST_INSTRUCTION("62916418C2D5AB" , sae().vcmpps(k2, zmm3, zmm29, 171));
+ TEST_INSTRUCTION("62916448C2D57B" , vcmpps(k2, zmm3, zmm29, 123));
+ TEST_INSTRUCTION("62916418C2D57B" , sae().vcmpps(k2, zmm3, zmm29, 123));
+ TEST_INSTRUCTION("62F16448C2117B" , vcmpps(k2, zmm3, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B16448C294F0341200007B" , vcmpps(k2, zmm3, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F16458C2117B" , vcmpps(k2, zmm3, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F16448C2527F7B" , vcmpps(k2, zmm3, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F16448C292002000007B" , vcmpps(k2, zmm3, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F16448C252807B" , vcmpps(k2, zmm3, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F16448C292C0DFFFFF7B" , vcmpps(k2, zmm3, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F16458C2527F7B" , vcmpps(k2, zmm3, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F16458C292000200007B" , vcmpps(k2, zmm3, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F16458C252807B" , vcmpps(k2, zmm3, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F16458C292FCFDFFFF7B" , vcmpps(k2, zmm3, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62F1D708C2E6AB" , vcmpsd(k4, xmm5, xmm6, 171));
+ TEST_INSTRUCTION("62F1D70DC2E6AB" , k(k5).vcmpsd(k4, xmm5, xmm6, 171));
+ TEST_INSTRUCTION("62F1D718C2E6AB" , sae().vcmpsd(k4, xmm5, xmm6, 171));
+ TEST_INSTRUCTION("62F1D708C2E67B" , vcmpsd(k4, xmm5, xmm6, 123));
+ TEST_INSTRUCTION("62F1D718C2E67B" , sae().vcmpsd(k4, xmm5, xmm6, 123));
+ TEST_INSTRUCTION("62F1D708C2217B" , vcmpsd(k4, xmm5, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1D708C2A4F0341200007B" , vcmpsd(k4, xmm5, qword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1D708C2627F7B" , vcmpsd(k4, xmm5, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62F1D708C2A2000400007B" , vcmpsd(k4, xmm5, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62F1D708C262807B" , vcmpsd(k4, xmm5, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62F1D708C2A2F8FBFFFF7B" , vcmpsd(k4, xmm5, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62916600C2D0AB" , vcmpss(k2, xmm19, xmm24, 171));
+ TEST_INSTRUCTION("62916601C2D0AB" , k(k1).vcmpss(k2, xmm19, xmm24, 171));
+ TEST_INSTRUCTION("62916610C2D0AB" , sae().vcmpss(k2, xmm19, xmm24, 171));
+ TEST_INSTRUCTION("62916600C2D07B" , vcmpss(k2, xmm19, xmm24, 123));
+ TEST_INSTRUCTION("62916610C2D07B" , sae().vcmpss(k2, xmm19, xmm24, 123));
+ TEST_INSTRUCTION("62F16600C2117B" , vcmpss(k2, xmm19, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B16600C294F0341200007B" , vcmpss(k2, xmm19, dword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F16600C2527F7B" , vcmpss(k2, xmm19, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62F16600C292000200007B" , vcmpss(k2, xmm19, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62F16600C252807B" , vcmpss(k2, xmm19, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62F16600C292FCFDFFFF7B" , vcmpss(k2, xmm19, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("C441792FEB" , vcomisd(xmm13, xmm11));
+ TEST_INSTRUCTION("6251FD182FEB" , sae().vcomisd(xmm13, xmm11));
+ TEST_INSTRUCTION("C5792F29" , vcomisd(xmm13, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C421792FACF034120000" , vcomisd(xmm13, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5792FAAF8030000" , vcomisd(xmm13, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C5792FAA00040000" , vcomisd(xmm13, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C5792FAA00FCFFFF" , vcomisd(xmm13, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C5792FAAF8FBFFFF" , vcomisd(xmm13, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C441782FC7" , vcomiss(xmm8, xmm15));
+ TEST_INSTRUCTION("62517C182FC7" , sae().vcomiss(xmm8, xmm15));
+ TEST_INSTRUCTION("C5782F01" , vcomiss(xmm8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C421782F84F034120000" , vcomiss(xmm8, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5782F82FC010000" , vcomiss(xmm8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5782F8200020000" , vcomiss(xmm8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5782F8200FEFFFF" , vcomiss(xmm8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5782F82FCFDFFFF" , vcomiss(xmm8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6262FD488A31" , vcompresspd(zmmword_ptr(rcx), zmm30));
+ TEST_INSTRUCTION("6262FD4F8A31" , k(k7).vcompresspd(zmmword_ptr(rcx), zmm30));
+ TEST_INSTRUCTION("6222FD488AB4F034120000" , vcompresspd(zmmword_ptr(rax, r14, 3, 4660), zmm30));
+ TEST_INSTRUCTION("6262FD488A727F" , vcompresspd(zmmword_ptr(rdx, 1016), zmm30));
+ TEST_INSTRUCTION("6262FD488AB200040000" , vcompresspd(zmmword_ptr(rdx, 1024), zmm30));
+ TEST_INSTRUCTION("6262FD488A7280" , vcompresspd(zmmword_ptr(rdx, -1024), zmm30));
+ TEST_INSTRUCTION("6262FD488AB2F8FBFFFF" , vcompresspd(zmmword_ptr(rdx, -1032), zmm30));
+ TEST_INSTRUCTION("6262FD488AC9" , vcompresspd(zmm1, zmm25));
+ TEST_INSTRUCTION("6262FD4C8AC9" , k(k4).vcompresspd(zmm1, zmm25));
+ TEST_INSTRUCTION("6262FDCC8AC9" , k(k4).z().vcompresspd(zmm1, zmm25));
+ TEST_INSTRUCTION("62727D488A11" , vcompressps(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62727D4C8A11" , k(k4).vcompressps(zmmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62327D488A94F034120000" , vcompressps(zmmword_ptr(rax, r14, 3, 4660), zmm10));
+ TEST_INSTRUCTION("62727D488A527F" , vcompressps(zmmword_ptr(rdx, 508), zmm10));
+ TEST_INSTRUCTION("62727D488A9200020000" , vcompressps(zmmword_ptr(rdx, 512), zmm10));
+ TEST_INSTRUCTION("62727D488A5280" , vcompressps(zmmword_ptr(rdx, -512), zmm10));
+ TEST_INSTRUCTION("62727D488A92FCFDFFFF" , vcompressps(zmmword_ptr(rdx, -516), zmm10));
+ TEST_INSTRUCTION("62B27D488AFB" , vcompressps(zmm19, zmm7));
+ TEST_INSTRUCTION("62B27D4B8AFB" , k(k3).vcompressps(zmm19, zmm7));
+ TEST_INSTRUCTION("62B27DCB8AFB" , k(k3).z().vcompressps(zmm19, zmm7));
+ TEST_INSTRUCTION("62217E48E6E4" , vcvtdq2pd(zmm28, ymm20));
+ TEST_INSTRUCTION("62217E4AE6E4" , k(k2).vcvtdq2pd(zmm28, ymm20));
+ TEST_INSTRUCTION("62217ECAE6E4" , k(k2).z().vcvtdq2pd(zmm28, ymm20));
+ TEST_INSTRUCTION("62617E48E621" , vcvtdq2pd(zmm28, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62217E48E6A4F034120000" , vcvtdq2pd(zmm28, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62617E58E621" , vcvtdq2pd(zmm28, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62617E48E6627F" , vcvtdq2pd(zmm28, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62617E48E6A200100000" , vcvtdq2pd(zmm28, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62617E48E66280" , vcvtdq2pd(zmm28, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62617E48E6A2E0EFFFFF" , vcvtdq2pd(zmm28, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62617E58E6627F" , vcvtdq2pd(zmm28, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62617E58E6A200020000" , vcvtdq2pd(zmm28, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62617E58E66280" , vcvtdq2pd(zmm28, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62617E58E6A2FCFDFFFF" , vcvtdq2pd(zmm28, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62E17C485BDC" , vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C4D5BDC" , k(k5).vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17CCD5BDC" , k(k5).z().vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C185BDC" , rn_sae().vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C585BDC" , ru_sae().vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C385BDC" , rd_sae().vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C785BDC" , rz_sae().vcvtdq2ps(zmm19, zmm4));
+ TEST_INSTRUCTION("62E17C485B19" , vcvtdq2ps(zmm19, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17C485B9CF034120000" , vcvtdq2ps(zmm19, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17C585B19" , vcvtdq2ps(zmm19, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E17C485B5A7F" , vcvtdq2ps(zmm19, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17C485B9A00200000" , vcvtdq2ps(zmm19, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17C485B5A80" , vcvtdq2ps(zmm19, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17C485B9AC0DFFFFF" , vcvtdq2ps(zmm19, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17C585B5A7F" , vcvtdq2ps(zmm19, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E17C585B9A00020000" , vcvtdq2ps(zmm19, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E17C585B5A80" , vcvtdq2ps(zmm19, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E17C585B9AFCFDFFFF" , vcvtdq2ps(zmm19, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F1FF48E6F2" , vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF4EE6F2" , k(k6).vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FFCEE6F2" , k(k6).z().vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF18E6F2" , rn_sae().vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF58E6F2" , ru_sae().vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF38E6F2" , rd_sae().vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF78E6F2" , rz_sae().vcvtpd2dq(ymm6, zmm2));
+ TEST_INSTRUCTION("62F1FF48E631" , vcvtpd2dq(ymm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF48E6B4F034120000" , vcvtpd2dq(ymm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FF58E631" , vcvtpd2dq(ymm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1FF48E6727F" , vcvtpd2dq(ymm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FF48E6B200200000" , vcvtpd2dq(ymm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FF48E67280" , vcvtpd2dq(ymm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FF48E6B2C0DFFFFF" , vcvtpd2dq(ymm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1FF58E6727F" , vcvtpd2dq(ymm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1FF58E6B200040000" , vcvtpd2dq(ymm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1FF58E67280" , vcvtpd2dq(ymm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1FF58E6B2F8FBFFFF" , vcvtpd2dq(ymm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C1FD485AC2" , vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FD4A5AC2" , k(k2).vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FDCA5AC2" , k(k2).z().vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FD185AC2" , rn_sae().vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FD585AC2" , ru_sae().vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FD385AC2" , rd_sae().vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62C1FD785AC2" , rz_sae().vcvtpd2ps(ymm16, zmm10));
+ TEST_INSTRUCTION("62E1FD485A01" , vcvtpd2ps(ymm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD485A84F034120000" , vcvtpd2ps(ymm16, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FD585A01" , vcvtpd2ps(ymm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1FD485A427F" , vcvtpd2ps(ymm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD485A8200200000" , vcvtpd2ps(ymm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD485A4280" , vcvtpd2ps(ymm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD485A82C0DFFFFF" , vcvtpd2ps(ymm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FD585A427F" , vcvtpd2ps(ymm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1FD585A8200040000" , vcvtpd2ps(ymm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD585A4280" , vcvtpd2ps(ymm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD585A82F8FBFFFF" , vcvtpd2ps(ymm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6201FC4879C9" , vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FC4979C9" , k(k1).vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FCC979C9" , k(k1).z().vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FC1879C9" , rn_sae().vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FC5879C9" , ru_sae().vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FC3879C9" , rd_sae().vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6201FC7879C9" , rz_sae().vcvtpd2udq(ymm25, zmm25));
+ TEST_INSTRUCTION("6261FC487909" , vcvtpd2udq(ymm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FC48798CF034120000" , vcvtpd2udq(ymm25, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261FC587909" , vcvtpd2udq(ymm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261FC48794A7F" , vcvtpd2udq(ymm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261FC48798A00200000" , vcvtpd2udq(ymm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261FC48794A80" , vcvtpd2udq(ymm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261FC48798AC0DFFFFF" , vcvtpd2udq(ymm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261FC58794A7F" , vcvtpd2udq(ymm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261FC58798A00040000" , vcvtpd2udq(ymm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261FC58794A80" , vcvtpd2udq(ymm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261FC58798AF8FBFFFF" , vcvtpd2udq(ymm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62327D4813CD" , vcvtph2ps(zmm9, ymm21));
+ TEST_INSTRUCTION("62327D4B13CD" , k(k3).vcvtph2ps(zmm9, ymm21));
+ TEST_INSTRUCTION("62327DCB13CD" , k(k3).z().vcvtph2ps(zmm9, ymm21));
+ TEST_INSTRUCTION("62327D1813CD" , sae().vcvtph2ps(zmm9, ymm21));
+ TEST_INSTRUCTION("62727D481309" , vcvtph2ps(zmm9, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D48138CF034120000" , vcvtph2ps(zmm9, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D48134A7F" , vcvtph2ps(zmm9, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D48138A00100000" , vcvtph2ps(zmm9, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48134A80" , vcvtph2ps(zmm9, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D48138AE0EFFFFF" , vcvtph2ps(zmm9, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62E17D485BC6" , vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D4A5BC6" , k(k2).vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17DCA5BC6" , k(k2).z().vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D185BC6" , rn_sae().vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D585BC6" , ru_sae().vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D385BC6" , rd_sae().vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D785BC6" , rz_sae().vcvtps2dq(zmm16, zmm6));
+ TEST_INSTRUCTION("62E17D485B01" , vcvtps2dq(zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17D485B84F034120000" , vcvtps2dq(zmm16, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17D585B01" , vcvtps2dq(zmm16, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E17D485B427F" , vcvtps2dq(zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17D485B8200200000" , vcvtps2dq(zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17D485B4280" , vcvtps2dq(zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17D485B82C0DFFFFF" , vcvtps2dq(zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17D585B427F" , vcvtps2dq(zmm16, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E17D585B8200020000" , vcvtps2dq(zmm16, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E17D585B4280" , vcvtps2dq(zmm16, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E17D585B82FCFDFFFF" , vcvtps2dq(zmm16, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62117C485AD8" , vcvtps2pd(zmm11, ymm24));
+ TEST_INSTRUCTION("62117C4B5AD8" , k(k3).vcvtps2pd(zmm11, ymm24));
+ TEST_INSTRUCTION("62117CCB5AD8" , k(k3).z().vcvtps2pd(zmm11, ymm24));
+ TEST_INSTRUCTION("62117C185AD8" , sae().vcvtps2pd(zmm11, ymm24));
+ TEST_INSTRUCTION("62717C485A19" , vcvtps2pd(zmm11, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317C485A9CF034120000" , vcvtps2pd(zmm11, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717C585A19" , vcvtps2pd(zmm11, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62717C485A5A7F" , vcvtps2pd(zmm11, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62717C485A9A00100000" , vcvtps2pd(zmm11, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62717C485A5A80" , vcvtps2pd(zmm11, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62717C485A9AE0EFFFFF" , vcvtps2pd(zmm11, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62717C585A5A7F" , vcvtps2pd(zmm11, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62717C585A9A00020000" , vcvtps2pd(zmm11, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62717C585A5A80" , vcvtps2pd(zmm11, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62717C585A9AFCFDFFFF" , vcvtps2pd(zmm11, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62C37D481DF1AB" , vcvtps2ph(ymm9, zmm22, 171));
+ TEST_INSTRUCTION("62C37D4F1DF1AB" , k(k7).vcvtps2ph(ymm9, zmm22, 171));
+ TEST_INSTRUCTION("62C37DCF1DF1AB" , k(k7).z().vcvtps2ph(ymm9, zmm22, 171));
+ TEST_INSTRUCTION("62C37D181DF1AB" , sae().vcvtps2ph(ymm9, zmm22, 171));
+ TEST_INSTRUCTION("62C37D481DF17B" , vcvtps2ph(ymm9, zmm22, 123));
+ TEST_INSTRUCTION("62C37D181DF17B" , sae().vcvtps2ph(ymm9, zmm22, 123));
+ TEST_INSTRUCTION("62F17C4879EC" , vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C4D79EC" , k(k5).vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17CCD79EC" , k(k5).z().vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C1879EC" , rn_sae().vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C5879EC" , ru_sae().vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C3879EC" , rd_sae().vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C7879EC" , rz_sae().vcvtps2udq(zmm5, zmm4));
+ TEST_INSTRUCTION("62F17C487929" , vcvtps2udq(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17C4879ACF034120000" , vcvtps2udq(zmm5, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17C587929" , vcvtps2udq(zmm5, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F17C48796A7F" , vcvtps2udq(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17C4879AA00200000" , vcvtps2udq(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17C48796A80" , vcvtps2udq(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17C4879AAC0DFFFFF" , vcvtps2udq(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F17C58796A7F" , vcvtps2udq(zmm5, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F17C5879AA00020000" , vcvtps2udq(zmm5, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F17C58796A80" , vcvtps2udq(zmm5, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F17C5879AAFCFDFFFF" , vcvtps2udq(zmm5, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F17F182DC4" , rn_sae().vcvtsd2si(eax, xmm4));
+ TEST_INSTRUCTION("62F17F582DC4" , ru_sae().vcvtsd2si(eax, xmm4));
+ TEST_INSTRUCTION("62F17F382DC4" , rd_sae().vcvtsd2si(eax, xmm4));
+ TEST_INSTRUCTION("62F17F782DC4" , rz_sae().vcvtsd2si(eax, xmm4));
+ TEST_INSTRUCTION("62F17F182DEC" , rn_sae().vcvtsd2si(ebp, xmm4));
+ TEST_INSTRUCTION("62F17F582DEC" , ru_sae().vcvtsd2si(ebp, xmm4));
+ TEST_INSTRUCTION("62F17F382DEC" , rd_sae().vcvtsd2si(ebp, xmm4));
+ TEST_INSTRUCTION("62F17F782DEC" , rz_sae().vcvtsd2si(ebp, xmm4));
+ TEST_INSTRUCTION("62717F182DEC" , rn_sae().vcvtsd2si(r13d, xmm4));
+ TEST_INSTRUCTION("62717F582DEC" , ru_sae().vcvtsd2si(r13d, xmm4));
+ TEST_INSTRUCTION("62717F382DEC" , rd_sae().vcvtsd2si(r13d, xmm4));
+ TEST_INSTRUCTION("62717F782DEC" , rz_sae().vcvtsd2si(r13d, xmm4));
+ TEST_INSTRUCTION("6291FF182DC3" , rn_sae().vcvtsd2si(rax, xmm27));
+ TEST_INSTRUCTION("6291FF582DC3" , ru_sae().vcvtsd2si(rax, xmm27));
+ TEST_INSTRUCTION("6291FF382DC3" , rd_sae().vcvtsd2si(rax, xmm27));
+ TEST_INSTRUCTION("6291FF782DC3" , rz_sae().vcvtsd2si(rax, xmm27));
+ TEST_INSTRUCTION("6211FF182DC3" , rn_sae().vcvtsd2si(r8, xmm27));
+ TEST_INSTRUCTION("6211FF582DC3" , ru_sae().vcvtsd2si(r8, xmm27));
+ TEST_INSTRUCTION("6211FF382DC3" , rd_sae().vcvtsd2si(r8, xmm27));
+ TEST_INSTRUCTION("6211FF782DC3" , rz_sae().vcvtsd2si(r8, xmm27));
+ TEST_INSTRUCTION("C5B32AE0" , vcvtsi2sd(xmm4, xmm9, eax));
+ TEST_INSTRUCTION("C5B32AE5" , vcvtsi2sd(xmm4, xmm9, ebp));
+ TEST_INSTRUCTION("C4C1332AE5" , vcvtsi2sd(xmm4, xmm9, r13d));
+ TEST_INSTRUCTION("C5B32A21" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A1332AA4F034120000" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5B32AA2FC010000" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5B32AA200020000" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5B32AA200FEFFFF" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5B32AA2FCFDFFFF" , vcvtsi2sd(xmm4, xmm9, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6261F7002AC0" , vcvtsi2sd(xmm24, xmm17, rax));
+ TEST_INSTRUCTION("6261F7102AC0" , rn_sae().vcvtsi2sd(xmm24, xmm17, rax));
+ TEST_INSTRUCTION("6261F7502AC0" , ru_sae().vcvtsi2sd(xmm24, xmm17, rax));
+ TEST_INSTRUCTION("6261F7302AC0" , rd_sae().vcvtsi2sd(xmm24, xmm17, rax));
+ TEST_INSTRUCTION("6261F7702AC0" , rz_sae().vcvtsi2sd(xmm24, xmm17, rax));
+ TEST_INSTRUCTION("6241F7002AC0" , vcvtsi2sd(xmm24, xmm17, r8));
+ TEST_INSTRUCTION("6241F7102AC0" , rn_sae().vcvtsi2sd(xmm24, xmm17, r8));
+ TEST_INSTRUCTION("6241F7502AC0" , ru_sae().vcvtsi2sd(xmm24, xmm17, r8));
+ TEST_INSTRUCTION("6241F7302AC0" , rd_sae().vcvtsi2sd(xmm24, xmm17, r8));
+ TEST_INSTRUCTION("6241F7702AC0" , rz_sae().vcvtsi2sd(xmm24, xmm17, r8));
+ TEST_INSTRUCTION("6261F7002A01" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221F7002A84F034120000" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261F7002A427F" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261F7002A8200040000" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261F7002A4280" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261F7002A82F8FBFFFF" , vcvtsi2sd(xmm24, xmm17, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62611E002AC8" , vcvtsi2ss(xmm25, xmm28, eax));
+ TEST_INSTRUCTION("62611E102AC8" , rn_sae().vcvtsi2ss(xmm25, xmm28, eax));
+ TEST_INSTRUCTION("62611E502AC8" , ru_sae().vcvtsi2ss(xmm25, xmm28, eax));
+ TEST_INSTRUCTION("62611E302AC8" , rd_sae().vcvtsi2ss(xmm25, xmm28, eax));
+ TEST_INSTRUCTION("62611E702AC8" , rz_sae().vcvtsi2ss(xmm25, xmm28, eax));
+ TEST_INSTRUCTION("62611E002ACD" , vcvtsi2ss(xmm25, xmm28, ebp));
+ TEST_INSTRUCTION("62611E102ACD" , rn_sae().vcvtsi2ss(xmm25, xmm28, ebp));
+ TEST_INSTRUCTION("62611E502ACD" , ru_sae().vcvtsi2ss(xmm25, xmm28, ebp));
+ TEST_INSTRUCTION("62611E302ACD" , rd_sae().vcvtsi2ss(xmm25, xmm28, ebp));
+ TEST_INSTRUCTION("62611E702ACD" , rz_sae().vcvtsi2ss(xmm25, xmm28, ebp));
+ TEST_INSTRUCTION("62411E002ACD" , vcvtsi2ss(xmm25, xmm28, r13d));
+ TEST_INSTRUCTION("62411E102ACD" , rn_sae().vcvtsi2ss(xmm25, xmm28, r13d));
+ TEST_INSTRUCTION("62411E502ACD" , ru_sae().vcvtsi2ss(xmm25, xmm28, r13d));
+ TEST_INSTRUCTION("62411E302ACD" , rd_sae().vcvtsi2ss(xmm25, xmm28, r13d));
+ TEST_INSTRUCTION("62411E702ACD" , rz_sae().vcvtsi2ss(xmm25, xmm28, r13d));
+ TEST_INSTRUCTION("62611E002A09" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62211E002A8CF034120000" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62611E002A4A7F" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62611E002A8A00020000" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62611E002A4A80" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62611E002A8AFCFDFFFF" , vcvtsi2ss(xmm25, xmm28, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C4E1BA2AE0" , vcvtsi2ss(xmm4, xmm8, rax));
+ TEST_INSTRUCTION("62F1BE182AE0" , rn_sae().vcvtsi2ss(xmm4, xmm8, rax));
+ TEST_INSTRUCTION("62F1BE582AE0" , ru_sae().vcvtsi2ss(xmm4, xmm8, rax));
+ TEST_INSTRUCTION("62F1BE382AE0" , rd_sae().vcvtsi2ss(xmm4, xmm8, rax));
+ TEST_INSTRUCTION("62F1BE782AE0" , rz_sae().vcvtsi2ss(xmm4, xmm8, rax));
+ TEST_INSTRUCTION("C4C1BA2AE0" , vcvtsi2ss(xmm4, xmm8, r8));
+ TEST_INSTRUCTION("62D1BE182AE0" , rn_sae().vcvtsi2ss(xmm4, xmm8, r8));
+ TEST_INSTRUCTION("62D1BE582AE0" , ru_sae().vcvtsi2ss(xmm4, xmm8, r8));
+ TEST_INSTRUCTION("62D1BE382AE0" , rd_sae().vcvtsi2ss(xmm4, xmm8, r8));
+ TEST_INSTRUCTION("62D1BE782AE0" , rz_sae().vcvtsi2ss(xmm4, xmm8, r8));
+ TEST_INSTRUCTION("C4E1BA2A21" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A1BA2AA4F034120000" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C4E1BA2AA2F8030000" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E1BA2AA200040000" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E1BA2AA200FCFFFF" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E1BA2AA2F8FBFFFF" , vcvtsi2ss(xmm4, xmm8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62D17E182DC0" , rn_sae().vcvtss2si(eax, xmm8));
+ TEST_INSTRUCTION("62D17E582DC0" , ru_sae().vcvtss2si(eax, xmm8));
+ TEST_INSTRUCTION("62D17E382DC0" , rd_sae().vcvtss2si(eax, xmm8));
+ TEST_INSTRUCTION("62D17E782DC0" , rz_sae().vcvtss2si(eax, xmm8));
+ TEST_INSTRUCTION("62D17E182DE8" , rn_sae().vcvtss2si(ebp, xmm8));
+ TEST_INSTRUCTION("62D17E582DE8" , ru_sae().vcvtss2si(ebp, xmm8));
+ TEST_INSTRUCTION("62D17E382DE8" , rd_sae().vcvtss2si(ebp, xmm8));
+ TEST_INSTRUCTION("62D17E782DE8" , rz_sae().vcvtss2si(ebp, xmm8));
+ TEST_INSTRUCTION("62517E182DE8" , rn_sae().vcvtss2si(r13d, xmm8));
+ TEST_INSTRUCTION("62517E582DE8" , ru_sae().vcvtss2si(r13d, xmm8));
+ TEST_INSTRUCTION("62517E382DE8" , rd_sae().vcvtss2si(r13d, xmm8));
+ TEST_INSTRUCTION("62517E782DE8" , rz_sae().vcvtss2si(r13d, xmm8));
+ TEST_INSTRUCTION("62F1FE182DC6" , rn_sae().vcvtss2si(rax, xmm6));
+ TEST_INSTRUCTION("62F1FE582DC6" , ru_sae().vcvtss2si(rax, xmm6));
+ TEST_INSTRUCTION("62F1FE382DC6" , rd_sae().vcvtss2si(rax, xmm6));
+ TEST_INSTRUCTION("62F1FE782DC6" , rz_sae().vcvtss2si(rax, xmm6));
+ TEST_INSTRUCTION("6271FE182DC6" , rn_sae().vcvtss2si(r8, xmm6));
+ TEST_INSTRUCTION("6271FE582DC6" , ru_sae().vcvtss2si(r8, xmm6));
+ TEST_INSTRUCTION("6271FE382DC6" , rd_sae().vcvtss2si(r8, xmm6));
+ TEST_INSTRUCTION("6271FE782DC6" , rz_sae().vcvtss2si(r8, xmm6));
+ TEST_INSTRUCTION("62F1FD48E6E1" , vcvttpd2dq(ymm4, zmm1));
+ TEST_INSTRUCTION("62F1FD4EE6E1" , k(k6).vcvttpd2dq(ymm4, zmm1));
+ TEST_INSTRUCTION("62F1FDCEE6E1" , k(k6).z().vcvttpd2dq(ymm4, zmm1));
+ TEST_INSTRUCTION("62F1FD18E6E1" , sae().vcvttpd2dq(ymm4, zmm1));
+ TEST_INSTRUCTION("62F1FD48E621" , vcvttpd2dq(ymm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FD48E6A4F034120000" , vcvttpd2dq(ymm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FD58E621" , vcvttpd2dq(ymm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1FD48E6627F" , vcvttpd2dq(ymm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FD48E6A200200000" , vcvttpd2dq(ymm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FD48E66280" , vcvttpd2dq(ymm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FD48E6A2C0DFFFFF" , vcvttpd2dq(ymm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1FD58E6627F" , vcvttpd2dq(ymm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1FD58E6A200040000" , vcvttpd2dq(ymm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1FD58E66280" , vcvttpd2dq(ymm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1FD58E6A2F8FBFFFF" , vcvttpd2dq(ymm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62817E485BFC" , vcvttps2dq(zmm23, zmm28));
+ TEST_INSTRUCTION("62817E4B5BFC" , k(k3).vcvttps2dq(zmm23, zmm28));
+ TEST_INSTRUCTION("62817ECB5BFC" , k(k3).z().vcvttps2dq(zmm23, zmm28));
+ TEST_INSTRUCTION("62817E185BFC" , sae().vcvttps2dq(zmm23, zmm28));
+ TEST_INSTRUCTION("62E17E485B39" , vcvttps2dq(zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E485BBCF034120000" , vcvttps2dq(zmm23, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17E585B39" , vcvttps2dq(zmm23, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E17E485B7A7F" , vcvttps2dq(zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17E485BBA00200000" , vcvttps2dq(zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17E485B7A80" , vcvttps2dq(zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17E485BBAC0DFFFFF" , vcvttps2dq(zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17E585B7A7F" , vcvttps2dq(zmm23, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E17E585BBA00020000" , vcvttps2dq(zmm23, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E17E585B7A80" , vcvttps2dq(zmm23, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E17E585BBAFCFDFFFF" , vcvttps2dq(zmm23, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F17F182CC5" , sae().vcvttsd2si(eax, xmm5));
+ TEST_INSTRUCTION("62F17F182CED" , sae().vcvttsd2si(ebp, xmm5));
+ TEST_INSTRUCTION("62717F182CED" , sae().vcvttsd2si(r13d, xmm5));
+ TEST_INSTRUCTION("62F1FF182CC7" , sae().vcvttsd2si(rax, xmm7));
+ TEST_INSTRUCTION("6271FF182CC7" , sae().vcvttsd2si(r8, xmm7));
+ TEST_INSTRUCTION("62F17E182CC4" , sae().vcvttss2si(eax, xmm4));
+ TEST_INSTRUCTION("62F17E182CEC" , sae().vcvttss2si(ebp, xmm4));
+ TEST_INSTRUCTION("62717E182CEC" , sae().vcvttss2si(r13d, xmm4));
+ TEST_INSTRUCTION("6291FE182CC3" , sae().vcvttss2si(rax, xmm27));
+ TEST_INSTRUCTION("6211FE182CC3" , sae().vcvttss2si(r8, xmm27));
+ TEST_INSTRUCTION("62817E487AD4" , vcvtudq2pd(zmm18, ymm28));
+ TEST_INSTRUCTION("62817E497AD4" , k(k1).vcvtudq2pd(zmm18, ymm28));
+ TEST_INSTRUCTION("62817EC97AD4" , k(k1).z().vcvtudq2pd(zmm18, ymm28));
+ TEST_INSTRUCTION("62E17E487A11" , vcvtudq2pd(zmm18, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E487A94F034120000" , vcvtudq2pd(zmm18, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17E587A11" , vcvtudq2pd(zmm18, dword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E17E487A527F" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62E17E487A9200100000" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62E17E487A5280" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62E17E487A92E0EFFFFF" , vcvtudq2pd(zmm18, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62E17E587A527F" , vcvtudq2pd(zmm18, dword_ptr(rdx, 508)._1to8()));
+ TEST_INSTRUCTION("62E17E587A9200020000" , vcvtudq2pd(zmm18, dword_ptr(rdx, 512)._1to8()));
+ TEST_INSTRUCTION("62E17E587A5280" , vcvtudq2pd(zmm18, dword_ptr(rdx, -512)._1to8()));
+ TEST_INSTRUCTION("62E17E587A92FCFDFFFF" , vcvtudq2pd(zmm18, dword_ptr(rdx, -516)._1to8()));
+ TEST_INSTRUCTION("62917F487AF8" , vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917F4F7AF8" , k(k7).vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917FCF7AF8" , k(k7).z().vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917F187AF8" , rn_sae().vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917F587AF8" , ru_sae().vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917F387AF8" , rd_sae().vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62917F787AF8" , rz_sae().vcvtudq2ps(zmm7, zmm24));
+ TEST_INSTRUCTION("62F17F487A39" , vcvtudq2ps(zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F487ABCF034120000" , vcvtudq2ps(zmm7, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17F587A39" , vcvtudq2ps(zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F17F487A7A7F" , vcvtudq2ps(zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17F487ABA00200000" , vcvtudq2ps(zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17F487A7A80" , vcvtudq2ps(zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17F487ABAC0DFFFFF" , vcvtudq2ps(zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F17F587A7A7F" , vcvtudq2ps(zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F17F587ABA00020000" , vcvtudq2ps(zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F17F587A7A80" , vcvtudq2ps(zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F17F587ABAFCFDFFFF" , vcvtudq2ps(zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1DD485ED3" , vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DD4D5ED3" , k(k5).vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DDCD5ED3" , k(k5).z().vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DD185ED3" , rn_sae().vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DD585ED3" , ru_sae().vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DD385ED3" , rd_sae().vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62A1DD785ED3" , rz_sae().vdivpd(zmm18, zmm4, zmm19));
+ TEST_INSTRUCTION("62E1DD485E11" , vdivpd(zmm18, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1DD485E94F034120000" , vdivpd(zmm18, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1DD585E11" , vdivpd(zmm18, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1DD485E527F" , vdivpd(zmm18, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1DD485E9200200000" , vdivpd(zmm18, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1DD485E5280" , vdivpd(zmm18, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1DD485E92C0DFFFFF" , vdivpd(zmm18, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1DD585E527F" , vdivpd(zmm18, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1DD585E9200040000" , vdivpd(zmm18, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1DD585E5280" , vdivpd(zmm18, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1DD585E92F8FBFFFF" , vdivpd(zmm18, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F114405EF4" , vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114465EF4" , k(k6).vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114C65EF4" , k(k6).z().vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114105EF4" , rn_sae().vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114505EF4" , ru_sae().vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114305EF4" , rd_sae().vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114705EF4" , rz_sae().vdivps(zmm6, zmm29, zmm4));
+ TEST_INSTRUCTION("62F114405E31" , vdivps(zmm6, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B114405EB4F034120000" , vdivps(zmm6, zmm29, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F114505E31" , vdivps(zmm6, zmm29, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F114405E727F" , vdivps(zmm6, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F114405EB200200000" , vdivps(zmm6, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F114405E7280" , vdivps(zmm6, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F114405EB2C0DFFFFF" , vdivps(zmm6, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F114505E727F" , vdivps(zmm6, zmm29, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F114505EB200020000" , vdivps(zmm6, zmm29, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F114505E7280" , vdivps(zmm6, zmm29, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F114505EB2FCFDFFFF" , vdivps(zmm6, zmm29, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6231DF085EFE" , vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF0B5EFE" , k(k3).vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF8B5EFE" , k(k3).z().vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF185EFE" , rn_sae().vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF585EFE" , ru_sae().vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF385EFE" , rd_sae().vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("6231DF785EFE" , rz_sae().vdivsd(xmm15, xmm4, xmm22));
+ TEST_INSTRUCTION("C55B5E39" , vdivsd(xmm15, xmm4, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4215B5EBCF034120000" , vdivsd(xmm15, xmm4, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C55B5EBAF8030000" , vdivsd(xmm15, xmm4, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C55B5EBA00040000" , vdivsd(xmm15, xmm4, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C55B5EBA00FCFFFF" , vdivsd(xmm15, xmm4, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C55B5EBAF8FBFFFF" , vdivsd(xmm15, xmm4, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62216E085EDC" , vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E0D5EDC" , k(k5).vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E8D5EDC" , k(k5).z().vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E185EDC" , rn_sae().vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E585EDC" , ru_sae().vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E385EDC" , rd_sae().vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62216E785EDC" , rz_sae().vdivss(xmm27, xmm2, xmm20));
+ TEST_INSTRUCTION("62616E085E19" , vdivss(xmm27, xmm2, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62216E085E9CF034120000" , vdivss(xmm27, xmm2, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62616E085E5A7F" , vdivss(xmm27, xmm2, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62616E085E9A00020000" , vdivss(xmm27, xmm2, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62616E085E5A80" , vdivss(xmm27, xmm2, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62616E085E9AFCFDFFFF" , vdivss(xmm27, xmm2, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F2FD488821" , vexpandpd(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F2FD4F8821" , k(k7).vexpandpd(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F2FDCF8821" , k(k7).z().vexpandpd(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2FD4888A4F034120000" , vexpandpd(zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2FD4888627F" , vexpandpd(zmm4, zmmword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2FD4888A200040000" , vexpandpd(zmm4, zmmword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2FD48886280" , vexpandpd(zmm4, zmmword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2FD4888A2F8FBFFFF" , vexpandpd(zmm4, zmmword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62C2FD4888D1" , vexpandpd(zmm18, zmm9));
+ TEST_INSTRUCTION("62C2FD4A88D1" , k(k2).vexpandpd(zmm18, zmm9));
+ TEST_INSTRUCTION("62C2FDCA88D1" , k(k2).z().vexpandpd(zmm18, zmm9));
+ TEST_INSTRUCTION("62627D488821" , vexpandps(zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62627D4F8821" , k(k7).vexpandps(zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62627DCF8821" , k(k7).z().vexpandps(zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D4888A4F034120000" , vexpandps(zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62627D4888627F" , vexpandps(zmm28, zmmword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62627D4888A200020000" , vexpandps(zmm28, zmmword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62627D48886280" , vexpandps(zmm28, zmmword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62627D4888A2FCFDFFFF" , vexpandps(zmm28, zmmword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62A27D4888CA" , vexpandps(zmm17, zmm18));
+ TEST_INSTRUCTION("62A27D4988CA" , k(k1).vexpandps(zmm17, zmm18));
+ TEST_INSTRUCTION("62A27DC988CA" , k(k1).z().vexpandps(zmm17, zmm18));
+ TEST_INSTRUCTION("62337D4819D5AB" , vextractf32x4(xmm21, zmm10, 171));
+ TEST_INSTRUCTION("62337D4A19D5AB" , k(k2).vextractf32x4(xmm21, zmm10, 171));
+ TEST_INSTRUCTION("62337DCA19D5AB" , k(k2).z().vextractf32x4(xmm21, zmm10, 171));
+ TEST_INSTRUCTION("62337D4819D57B" , vextractf32x4(xmm21, zmm10, 123));
+ TEST_INSTRUCTION("62D3FD481BEEAB" , vextractf64x4(ymm14, zmm5, 171));
+ TEST_INSTRUCTION("62D3FD4B1BEEAB" , k(k3).vextractf64x4(ymm14, zmm5, 171));
+ TEST_INSTRUCTION("62D3FDCB1BEEAB" , k(k3).z().vextractf64x4(ymm14, zmm5, 171));
+ TEST_INSTRUCTION("62D3FD481BEE7B" , vextractf64x4(ymm14, zmm5, 123));
+ TEST_INSTRUCTION("62137D4839E5AB" , vextracti32x4(xmm29, zmm12, 171));
+ TEST_INSTRUCTION("62137D4D39E5AB" , k(k5).vextracti32x4(xmm29, zmm12, 171));
+ TEST_INSTRUCTION("62137DCD39E5AB" , k(k5).z().vextracti32x4(xmm29, zmm12, 171));
+ TEST_INSTRUCTION("62137D4839E57B" , vextracti32x4(xmm29, zmm12, 123));
+ TEST_INSTRUCTION("62E3FD483BF5AB" , vextracti64x4(ymm5, zmm22, 171));
+ TEST_INSTRUCTION("62E3FD4E3BF5AB" , k(k6).vextracti64x4(ymm5, zmm22, 171));
+ TEST_INSTRUCTION("62E3FDCE3BF5AB" , k(k6).z().vextracti64x4(ymm5, zmm22, 171));
+ TEST_INSTRUCTION("62E3FD483BF57B" , vextracti64x4(ymm5, zmm22, 123));
+ TEST_INSTRUCTION("62C2854898FB" , vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C2854F98FB" , k(k7).vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C285CF98FB" , k(k7).z().vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C2851898FB" , rn_sae().vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C2855898FB" , ru_sae().vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C2853898FB" , rd_sae().vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62C2857898FB" , rz_sae().vfmadd132pd(zmm23, zmm15, zmm11));
+ TEST_INSTRUCTION("62E285489839" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2854898BCF034120000" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E285589839" , vfmadd132pd(zmm23, zmm15, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E28548987A7F" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2854898BA00200000" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E28548987A80" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2854898BAC0DFFFFF" , vfmadd132pd(zmm23, zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E28558987A7F" , vfmadd132pd(zmm23, zmm15, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2855898BA00040000" , vfmadd132pd(zmm23, zmm15, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E28558987A80" , vfmadd132pd(zmm23, zmm15, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2855898BAF8FBFFFF" , vfmadd132pd(zmm23, zmm15, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62A2354098D9" , vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A2354698D9" , k(k6).vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A235C698D9" , k(k6).z().vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A2351098D9" , rn_sae().vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A2355098D9" , ru_sae().vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A2353098D9" , rd_sae().vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62A2357098D9" , rz_sae().vfmadd132ps(zmm19, zmm25, zmm17));
+ TEST_INSTRUCTION("62E235409819" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A23540989CF034120000" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E235509819" , vfmadd132ps(zmm19, zmm25, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E23540985A7F" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E23540989A00200000" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E23540985A80" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E23540989AC0DFFFFF" , vfmadd132ps(zmm19, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E23550985A7F" , vfmadd132ps(zmm19, zmm25, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E23550989A00020000" , vfmadd132ps(zmm19, zmm25, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E23550985A80" , vfmadd132ps(zmm19, zmm25, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E23550989AFCFDFFFF" , vfmadd132ps(zmm19, zmm25, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C2CD0099D3" , vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD0699D3" , k(k6).vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD8699D3" , k(k6).z().vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD1099D3" , rn_sae().vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD5099D3" , ru_sae().vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD3099D3" , rd_sae().vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62C2CD7099D3" , rz_sae().vfmadd132sd(xmm18, xmm22, xmm11));
+ TEST_INSTRUCTION("62E2CD009911" , vfmadd132sd(xmm18, xmm22, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD009994F034120000" , vfmadd132sd(xmm18, xmm22, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2CD0099527F" , vfmadd132sd(xmm18, xmm22, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E2CD00999200040000" , vfmadd132sd(xmm18, xmm22, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E2CD00995280" , vfmadd132sd(xmm18, xmm22, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E2CD009992F8FBFFFF" , vfmadd132sd(xmm18, xmm22, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62625D0099D7" , vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D0799D7" , k(k7).vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D8799D7" , k(k7).z().vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D1099D7" , rn_sae().vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D5099D7" , ru_sae().vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D3099D7" , rd_sae().vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D7099D7" , rz_sae().vfmadd132ss(xmm26, xmm20, xmm7));
+ TEST_INSTRUCTION("62625D009911" , vfmadd132ss(xmm26, xmm20, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62225D009994F034120000" , vfmadd132ss(xmm26, xmm20, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62625D0099527F" , vfmadd132ss(xmm26, xmm20, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62625D00999200020000" , vfmadd132ss(xmm26, xmm20, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62625D00995280" , vfmadd132ss(xmm26, xmm20, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62625D009992FCFDFFFF" , vfmadd132ss(xmm26, xmm20, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F2F540A8F1" , vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F546A8F1" , k(k6).vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F5C6A8F1" , k(k6).z().vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F510A8F1" , rn_sae().vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F550A8F1" , ru_sae().vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F530A8F1" , rd_sae().vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F570A8F1" , rz_sae().vfmadd213pd(zmm6, zmm17, zmm1));
+ TEST_INSTRUCTION("62F2F540A831" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2F540A8B4F034120000" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2F550A831" , vfmadd213pd(zmm6, zmm17, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2F540A8727F" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2F540A8B200200000" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2F540A87280" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2F540A8B2C0DFFFFF" , vfmadd213pd(zmm6, zmm17, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2F550A8727F" , vfmadd213pd(zmm6, zmm17, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2F550A8B200040000" , vfmadd213pd(zmm6, zmm17, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2F550A87280" , vfmadd213pd(zmm6, zmm17, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2F550A8B2F8FBFFFF" , vfmadd213pd(zmm6, zmm17, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62923D40A8E8" , vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D46A8E8" , k(k6).vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923DC6A8E8" , k(k6).z().vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D10A8E8" , rn_sae().vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D50A8E8" , ru_sae().vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D30A8E8" , rd_sae().vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D70A8E8" , rz_sae().vfmadd213ps(zmm5, zmm24, zmm24));
+ TEST_INSTRUCTION("62F23D40A829" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B23D40A8ACF034120000" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F23D50A829" , vfmadd213ps(zmm5, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23D40A86A7F" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F23D40A8AA00200000" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23D40A86A80" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F23D40A8AAC0DFFFFF" , vfmadd213ps(zmm5, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23D50A86A7F" , vfmadd213ps(zmm5, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F23D50A8AA00020000" , vfmadd213ps(zmm5, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23D50A86A80" , vfmadd213ps(zmm5, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F23D50A8AAFCFDFFFF" , vfmadd213ps(zmm5, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62028D08A9F4" , vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D0DA9F4" , k(k5).vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D8DA9F4" , k(k5).z().vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D18A9F4" , rn_sae().vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D58A9F4" , ru_sae().vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D38A9F4" , rd_sae().vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62028D78A9F4" , rz_sae().vfmadd213sd(xmm30, xmm14, xmm28));
+ TEST_INSTRUCTION("62628D08A931" , vfmadd213sd(xmm30, xmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62228D08A9B4F034120000" , vfmadd213sd(xmm30, xmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62628D08A9727F" , vfmadd213sd(xmm30, xmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62628D08A9B200040000" , vfmadd213sd(xmm30, xmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62628D08A97280" , vfmadd213sd(xmm30, xmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62628D08A9B2F8FBFFFF" , vfmadd213sd(xmm30, xmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62823500A9D1" , vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823501A9D1" , k(k1).vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823581A9D1" , k(k1).z().vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823510A9D1" , rn_sae().vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823550A9D1" , ru_sae().vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823530A9D1" , rd_sae().vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62823570A9D1" , rz_sae().vfmadd213ss(xmm18, xmm25, xmm25));
+ TEST_INSTRUCTION("62E23500A911" , vfmadd213ss(xmm18, xmm25, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A23500A994F034120000" , vfmadd213ss(xmm18, xmm25, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E23500A9527F" , vfmadd213ss(xmm18, xmm25, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E23500A99200020000" , vfmadd213ss(xmm18, xmm25, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E23500A95280" , vfmadd213ss(xmm18, xmm25, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E23500A992FCFDFFFF" , vfmadd213ss(xmm18, xmm25, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B29548B8EB" , vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B29549B8EB" , k(k1).vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B295C9B8EB" , k(k1).z().vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B29518B8EB" , rn_sae().vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B29558B8EB" , ru_sae().vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B29538B8EB" , rd_sae().vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62B29578B8EB" , rz_sae().vfmadd231pd(zmm5, zmm13, zmm19));
+ TEST_INSTRUCTION("62F29548B829" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B29548B8ACF034120000" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F29558B829" , vfmadd231pd(zmm5, zmm13, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F29548B86A7F" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F29548B8AA00200000" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F29548B86A80" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F29548B8AAC0DFFFFF" , vfmadd231pd(zmm5, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F29558B86A7F" , vfmadd231pd(zmm5, zmm13, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F29558B8AA00040000" , vfmadd231pd(zmm5, zmm13, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F29558B86A80" , vfmadd231pd(zmm5, zmm13, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F29558B8AAF8FBFFFF" , vfmadd231pd(zmm5, zmm13, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B27548B8D2" , vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B2754AB8D2" , k(k2).vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B275CAB8D2" , k(k2).z().vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B27518B8D2" , rn_sae().vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B27558B8D2" , ru_sae().vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B27538B8D2" , rd_sae().vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62B27578B8D2" , rz_sae().vfmadd231ps(zmm2, zmm1, zmm18));
+ TEST_INSTRUCTION("62F27548B811" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27548B894F034120000" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27558B811" , vfmadd231ps(zmm2, zmm1, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27548B8527F" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27548B89200200000" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27548B85280" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27548B892C0DFFFFF" , vfmadd231ps(zmm2, zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27558B8527F" , vfmadd231ps(zmm2, zmm1, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27558B89200020000" , vfmadd231ps(zmm2, zmm1, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27558B85280" , vfmadd231ps(zmm2, zmm1, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27558B892FCFDFFFF" , vfmadd231ps(zmm2, zmm1, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4C289B9F6" , vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D0AB9F6" , k(k2).vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D8AB9F6" , k(k2).z().vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D18B9F6" , rn_sae().vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D58B9F6" , ru_sae().vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D38B9F6" , rd_sae().vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("62D28D78B9F6" , rz_sae().vfmadd231sd(xmm6, xmm14, xmm14));
+ TEST_INSTRUCTION("C4E289B931" , vfmadd231sd(xmm6, xmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A289B9B4F034120000" , vfmadd231sd(xmm6, xmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C4E289B9B2F8030000" , vfmadd231sd(xmm6, xmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E289B9B200040000" , vfmadd231sd(xmm6, xmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E289B9B200FCFFFF" , vfmadd231sd(xmm6, xmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E289B9B2F8FBFFFF" , vfmadd231sd(xmm6, xmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62220D08B9D3" , vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D0CB9D3" , k(k4).vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D8CB9D3" , k(k4).z().vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D18B9D3" , rn_sae().vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D58B9D3" , ru_sae().vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D38B9D3" , rd_sae().vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62220D78B9D3" , rz_sae().vfmadd231ss(xmm26, xmm14, xmm19));
+ TEST_INSTRUCTION("62620D08B911" , vfmadd231ss(xmm26, xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62220D08B994F034120000" , vfmadd231ss(xmm26, xmm14, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62620D08B9527F" , vfmadd231ss(xmm26, xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62620D08B99200020000" , vfmadd231ss(xmm26, xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62620D08B95280" , vfmadd231ss(xmm26, xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62620D08B992FCFDFFFF" , vfmadd231ss(xmm26, xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62E2CD4896E2" , vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD4E96E2" , k(k6).vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CDCE96E2" , k(k6).z().vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD1896E2" , rn_sae().vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD5896E2" , ru_sae().vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD3896E2" , rd_sae().vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD7896E2" , rz_sae().vfmaddsub132pd(zmm20, zmm6, zmm2));
+ TEST_INSTRUCTION("62E2CD489621" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD4896A4F034120000" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2CD589621" , vfmaddsub132pd(zmm20, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2CD4896627F" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2CD4896A200200000" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2CD48966280" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2CD4896A2C0DFFFFF" , vfmaddsub132pd(zmm20, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2CD5896627F" , vfmaddsub132pd(zmm20, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2CD5896A200040000" , vfmaddsub132pd(zmm20, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD58966280" , vfmaddsub132pd(zmm20, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD5896A2F8FBFFFF" , vfmaddsub132pd(zmm20, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6242454896EC" , vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("6242454F96EC" , k(k7).vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("624245CF96EC" , k(k7).z().vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("6242451896EC" , rn_sae().vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("6242455896EC" , ru_sae().vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("6242453896EC" , rd_sae().vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("6242457896EC" , rz_sae().vfmaddsub132ps(zmm29, zmm7, zmm12));
+ TEST_INSTRUCTION("626245489629" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222454896ACF034120000" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626245589629" , vfmaddsub132ps(zmm29, zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62624548966A7F" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262454896AA00200000" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62624548966A80" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262454896AAC0DFFFFF" , vfmaddsub132ps(zmm29, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62624558966A7F" , vfmaddsub132ps(zmm29, zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("6262455896AA00020000" , vfmaddsub132ps(zmm29, zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62624558966A80" , vfmaddsub132ps(zmm29, zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("6262455896AAFCFDFFFF" , vfmaddsub132ps(zmm29, zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6242DD40A6DF" , vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DD43A6DF" , k(k3).vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DDC3A6DF" , k(k3).z().vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DD10A6DF" , rn_sae().vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DD50A6DF" , ru_sae().vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DD30A6DF" , rd_sae().vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6242DD70A6DF" , rz_sae().vfmaddsub213pd(zmm27, zmm20, zmm15));
+ TEST_INSTRUCTION("6262DD40A619" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222DD40A69CF034120000" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262DD50A619" , vfmaddsub213pd(zmm27, zmm20, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262DD40A65A7F" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262DD40A69A00200000" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262DD40A65A80" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262DD40A69AC0DFFFFF" , vfmaddsub213pd(zmm27, zmm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262DD50A65A7F" , vfmaddsub213pd(zmm27, zmm20, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262DD50A69A00040000" , vfmaddsub213pd(zmm27, zmm20, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262DD50A65A80" , vfmaddsub213pd(zmm27, zmm20, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262DD50A69AF8FBFFFF" , vfmaddsub213pd(zmm27, zmm20, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C21548A6F2" , vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C2154DA6F2" , k(k5).vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C215CDA6F2" , k(k5).z().vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C21518A6F2" , rn_sae().vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C21558A6F2" , ru_sae().vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C21538A6F2" , rd_sae().vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62C21578A6F2" , rz_sae().vfmaddsub213ps(zmm22, zmm13, zmm10));
+ TEST_INSTRUCTION("62E21548A631" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A21548A6B4F034120000" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E21558A631" , vfmaddsub213ps(zmm22, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E21548A6727F" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E21548A6B200200000" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E21548A67280" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E21548A6B2C0DFFFFF" , vfmaddsub213ps(zmm22, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E21558A6727F" , vfmaddsub213ps(zmm22, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E21558A6B200020000" , vfmaddsub213ps(zmm22, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E21558A67280" , vfmaddsub213ps(zmm22, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E21558A6B2FCFDFFFF" , vfmaddsub213ps(zmm22, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6292B540B6E4" , vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B546B6E4" , k(k6).vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B5C6B6E4" , k(k6).z().vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B510B6E4" , rn_sae().vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B550B6E4" , ru_sae().vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B530B6E4" , rd_sae().vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("6292B570B6E4" , rz_sae().vfmaddsub231pd(zmm4, zmm25, zmm28));
+ TEST_INSTRUCTION("62F2B540B621" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2B540B6A4F034120000" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2B550B621" , vfmaddsub231pd(zmm4, zmm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2B540B6627F" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2B540B6A200200000" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2B540B66280" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2B540B6A2C0DFFFFF" , vfmaddsub231pd(zmm4, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2B550B6627F" , vfmaddsub231pd(zmm4, zmm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2B550B6A200040000" , vfmaddsub231pd(zmm4, zmm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2B550B66280" , vfmaddsub231pd(zmm4, zmm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2B550B6A2F8FBFFFF" , vfmaddsub231pd(zmm4, zmm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D24D40B6FA" , vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24D46B6FA" , k(k6).vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24DC6B6FA" , k(k6).z().vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24D10B6FA" , rn_sae().vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24D50B6FA" , ru_sae().vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24D30B6FA" , rd_sae().vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62D24D70B6FA" , rz_sae().vfmaddsub231ps(zmm7, zmm22, zmm10));
+ TEST_INSTRUCTION("62F24D40B639" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B24D40B6BCF034120000" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F24D50B639" , vfmaddsub231ps(zmm7, zmm22, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F24D40B67A7F" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F24D40B6BA00200000" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F24D40B67A80" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F24D40B6BAC0DFFFFF" , vfmaddsub231ps(zmm7, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F24D50B67A7F" , vfmaddsub231ps(zmm7, zmm22, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F24D50B6BA00020000" , vfmaddsub231ps(zmm7, zmm22, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F24D50B67A80" , vfmaddsub231ps(zmm7, zmm22, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F24D50B6BAFCFDFFFF" , vfmaddsub231ps(zmm7, zmm22, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("622295409ACB" , vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295449ACB" , k(k4).vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295C49ACB" , k(k4).z().vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295109ACB" , rn_sae().vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295509ACB" , ru_sae().vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295309ACB" , rd_sae().vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("622295709ACB" , rz_sae().vfmsub132pd(zmm25, zmm29, zmm19));
+ TEST_INSTRUCTION("626295409A09" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622295409A8CF034120000" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626295509A09" , vfmsub132pd(zmm25, zmm29, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("626295409A4A7F" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("626295409A8A00200000" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("626295409A4A80" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626295409A8AC0DFFFFF" , vfmsub132pd(zmm25, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("626295509A4A7F" , vfmsub132pd(zmm25, zmm29, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("626295509A8A00040000" , vfmsub132pd(zmm25, zmm29, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("626295509A4A80" , vfmsub132pd(zmm25, zmm29, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("626295509A8AF8FBFFFF" , vfmsub132pd(zmm25, zmm29, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62224D489ADA" , vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224D4C9ADA" , k(k4).vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224DCC9ADA" , k(k4).z().vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224D189ADA" , rn_sae().vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224D589ADA" , ru_sae().vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224D389ADA" , rd_sae().vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62224D789ADA" , rz_sae().vfmsub132ps(zmm27, zmm6, zmm18));
+ TEST_INSTRUCTION("62624D489A19" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62224D489A9CF034120000" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62624D589A19" , vfmsub132ps(zmm27, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62624D489A5A7F" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62624D489A9A00200000" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62624D489A5A80" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62624D489A9AC0DFFFFF" , vfmsub132ps(zmm27, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62624D589A5A7F" , vfmsub132ps(zmm27, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62624D589A9A00020000" , vfmsub132ps(zmm27, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62624D589A5A80" , vfmsub132ps(zmm27, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62624D589A9AFCFDFFFF" , vfmsub132ps(zmm27, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6282DD009BFC" , vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD019BFC" , k(k1).vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD819BFC" , k(k1).z().vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD109BFC" , rn_sae().vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD509BFC" , ru_sae().vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD309BFC" , rd_sae().vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("6282DD709BFC" , rz_sae().vfmsub132sd(xmm23, xmm20, xmm28));
+ TEST_INSTRUCTION("62E2DD009B39" , vfmsub132sd(xmm23, xmm20, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2DD009BBCF034120000" , vfmsub132sd(xmm23, xmm20, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2DD009B7A7F" , vfmsub132sd(xmm23, xmm20, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E2DD009BBA00040000" , vfmsub132sd(xmm23, xmm20, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E2DD009B7A80" , vfmsub132sd(xmm23, xmm20, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E2DD009BBAF8FBFFFF" , vfmsub132sd(xmm23, xmm20, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("620235089BD1" , vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("6202350F9BD1" , k(k7).vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("6202358F9BD1" , k(k7).z().vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("620235189BD1" , rn_sae().vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("620235589BD1" , ru_sae().vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("620235389BD1" , rd_sae().vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("620235789BD1" , rz_sae().vfmsub132ss(xmm26, xmm9, xmm25));
+ TEST_INSTRUCTION("626235089B11" , vfmsub132ss(xmm26, xmm9, dword_ptr(rcx)));
+ TEST_INSTRUCTION("622235089B94F034120000" , vfmsub132ss(xmm26, xmm9, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626235089B527F" , vfmsub132ss(xmm26, xmm9, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("626235089B9200020000" , vfmsub132ss(xmm26, xmm9, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("626235089B5280" , vfmsub132ss(xmm26, xmm9, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("626235089B92FCFDFFFF" , vfmsub132ss(xmm26, xmm9, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B2ED40AAFB" , vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2ED44AAFB" , k(k4).vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2EDC4AAFB" , k(k4).z().vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2ED10AAFB" , rn_sae().vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2ED50AAFB" , ru_sae().vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2ED30AAFB" , rd_sae().vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62B2ED70AAFB" , rz_sae().vfmsub213pd(zmm7, zmm18, zmm19));
+ TEST_INSTRUCTION("62F2ED40AA39" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2ED40AABCF034120000" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2ED50AA39" , vfmsub213pd(zmm7, zmm18, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2ED40AA7A7F" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2ED40AABA00200000" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2ED40AA7A80" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2ED40AABAC0DFFFFF" , vfmsub213pd(zmm7, zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2ED50AA7A7F" , vfmsub213pd(zmm7, zmm18, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2ED50AABA00040000" , vfmsub213pd(zmm7, zmm18, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2ED50AA7A80" , vfmsub213pd(zmm7, zmm18, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2ED50AABAF8FBFFFF" , vfmsub213pd(zmm7, zmm18, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62727D40AACE" , vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D46AACE" , k(k6).vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727DC6AACE" , k(k6).z().vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D10AACE" , rn_sae().vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D50AACE" , ru_sae().vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D30AACE" , rd_sae().vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D70AACE" , rz_sae().vfmsub213ps(zmm9, zmm16, zmm6));
+ TEST_INSTRUCTION("62727D40AA09" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D40AA8CF034120000" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D50AA09" , vfmsub213ps(zmm9, zmm16, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62727D40AA4A7F" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62727D40AA8A00200000" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62727D40AA4A80" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62727D40AA8AC0DFFFFF" , vfmsub213ps(zmm9, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62727D50AA4A7F" , vfmsub213ps(zmm9, zmm16, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62727D50AA8A00020000" , vfmsub213ps(zmm9, zmm16, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62727D50AA4A80" , vfmsub213ps(zmm9, zmm16, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62727D50AA8AFCFDFFFF" , vfmsub213ps(zmm9, zmm16, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6232ED00ABE4" , vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED04ABE4" , k(k4).vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED84ABE4" , k(k4).z().vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED10ABE4" , rn_sae().vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED50ABE4" , ru_sae().vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED30ABE4" , rd_sae().vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6232ED70ABE4" , rz_sae().vfmsub213sd(xmm12, xmm18, xmm20));
+ TEST_INSTRUCTION("6272ED00AB21" , vfmsub213sd(xmm12, xmm18, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6232ED00ABA4F034120000" , vfmsub213sd(xmm12, xmm18, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272ED00AB627F" , vfmsub213sd(xmm12, xmm18, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6272ED00ABA200040000" , vfmsub213sd(xmm12, xmm18, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6272ED00AB6280" , vfmsub213sd(xmm12, xmm18, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6272ED00ABA2F8FBFFFF" , vfmsub213sd(xmm12, xmm18, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C4C271ABD1" , vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D2750FABD1" , k(k7).vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D2758FABD1" , k(k7).z().vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D27518ABD1" , rn_sae().vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D27558ABD1" , ru_sae().vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D27538ABD1" , rd_sae().vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("62D27578ABD1" , rz_sae().vfmsub213ss(xmm2, xmm1, xmm9));
+ TEST_INSTRUCTION("C4E271AB11" , vfmsub213ss(xmm2, xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A271AB94F034120000" , vfmsub213ss(xmm2, xmm1, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C4E271AB92FC010000" , vfmsub213ss(xmm2, xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C4E271AB9200020000" , vfmsub213ss(xmm2, xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C4E271AB9200FEFFFF" , vfmsub213ss(xmm2, xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C4E271AB92FCFDFFFF" , vfmsub213ss(xmm2, xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C2ED48BACE" , vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2ED4ABACE" , k(k2).vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2EDCABACE" , k(k2).z().vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2ED18BACE" , rn_sae().vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2ED58BACE" , ru_sae().vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2ED38BACE" , rd_sae().vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62C2ED78BACE" , rz_sae().vfmsub231pd(zmm17, zmm2, zmm14));
+ TEST_INSTRUCTION("62E2ED48BA09" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2ED48BA8CF034120000" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2ED58BA09" , vfmsub231pd(zmm17, zmm2, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2ED48BA4A7F" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2ED48BA8A00200000" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2ED48BA4A80" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2ED48BA8AC0DFFFFF" , vfmsub231pd(zmm17, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2ED58BA4A7F" , vfmsub231pd(zmm17, zmm2, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2ED58BA8A00040000" , vfmsub231pd(zmm17, zmm2, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED58BA4A80" , vfmsub231pd(zmm17, zmm2, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED58BA8AF8FBFFFF" , vfmsub231pd(zmm17, zmm2, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B25D48BAEC" , vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25D49BAEC" , k(k1).vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25DC9BAEC" , k(k1).z().vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25D18BAEC" , rn_sae().vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25D58BAEC" , ru_sae().vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25D38BAEC" , rd_sae().vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62B25D78BAEC" , rz_sae().vfmsub231ps(zmm5, zmm4, zmm20));
+ TEST_INSTRUCTION("62F25D48BA29" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B25D48BAACF034120000" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F25D58BA29" , vfmsub231ps(zmm5, zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F25D48BA6A7F" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F25D48BAAA00200000" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F25D48BA6A80" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F25D48BAAAC0DFFFFF" , vfmsub231ps(zmm5, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F25D58BA6A7F" , vfmsub231ps(zmm5, zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F25D58BAAA00020000" , vfmsub231ps(zmm5, zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F25D58BA6A80" , vfmsub231ps(zmm5, zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F25D58BAAAFCFDFFFF" , vfmsub231ps(zmm5, zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C4E2E9BBFE" , vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED0CBBFE" , k(k4).vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED8CBBFE" , k(k4).z().vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED18BBFE" , rn_sae().vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED58BBFE" , ru_sae().vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED38BBFE" , rd_sae().vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("62F2ED78BBFE" , rz_sae().vfmsub231sd(xmm7, xmm2, xmm6));
+ TEST_INSTRUCTION("C4E2E9BB39" , vfmsub231sd(xmm7, xmm2, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2E9BBBCF034120000" , vfmsub231sd(xmm7, xmm2, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C4E2E9BBBAF8030000" , vfmsub231sd(xmm7, xmm2, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2E9BBBA00040000" , vfmsub231sd(xmm7, xmm2, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2E9BBBA00FCFFFF" , vfmsub231sd(xmm7, xmm2, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2E9BBBAF8FBFFFF" , vfmsub231sd(xmm7, xmm2, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A26D00BBD2" , vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D07BBD2" , k(k7).vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D87BBD2" , k(k7).z().vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D10BBD2" , rn_sae().vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D50BBD2" , ru_sae().vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D30BBD2" , rd_sae().vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62A26D70BBD2" , rz_sae().vfmsub231ss(xmm18, xmm18, xmm18));
+ TEST_INSTRUCTION("62E26D00BB11" , vfmsub231ss(xmm18, xmm18, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A26D00BB94F034120000" , vfmsub231ss(xmm18, xmm18, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E26D00BB527F" , vfmsub231ss(xmm18, xmm18, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E26D00BB9200020000" , vfmsub231ss(xmm18, xmm18, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E26D00BB5280" , vfmsub231ss(xmm18, xmm18, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E26D00BB92FCFDFFFF" , vfmsub231ss(xmm18, xmm18, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62E2DD4897EF" , vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD4D97EF" , k(k5).vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DDCD97EF" , k(k5).z().vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD1897EF" , rn_sae().vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD5897EF" , ru_sae().vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD3897EF" , rd_sae().vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD7897EF" , rz_sae().vfmsubadd132pd(zmm21, zmm4, zmm7));
+ TEST_INSTRUCTION("62E2DD489729" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2DD4897ACF034120000" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2DD589729" , vfmsubadd132pd(zmm21, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2DD48976A7F" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2DD4897AA00200000" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2DD48976A80" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2DD4897AAC0DFFFFF" , vfmsubadd132pd(zmm21, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2DD58976A7F" , vfmsubadd132pd(zmm21, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2DD5897AA00040000" , vfmsubadd132pd(zmm21, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2DD58976A80" , vfmsubadd132pd(zmm21, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2DD5897AAF8FBFFFF" , vfmsubadd132pd(zmm21, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B23D4097F0" , vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23D4797F0" , k(k7).vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23DC797F0" , k(k7).z().vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23D1097F0" , rn_sae().vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23D5097F0" , ru_sae().vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23D3097F0" , rd_sae().vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62B23D7097F0" , rz_sae().vfmsubadd132ps(zmm6, zmm24, zmm16));
+ TEST_INSTRUCTION("62F23D409731" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B23D4097B4F034120000" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F23D509731" , vfmsubadd132ps(zmm6, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23D4097727F" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F23D4097B200200000" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23D40977280" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F23D4097B2C0DFFFFF" , vfmsubadd132ps(zmm6, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23D5097727F" , vfmsubadd132ps(zmm6, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F23D5097B200020000" , vfmsubadd132ps(zmm6, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23D50977280" , vfmsubadd132ps(zmm6, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F23D5097B2FCFDFFFF" , vfmsubadd132ps(zmm6, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6252CD40A7DB" , vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CD44A7DB" , k(k4).vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CDC4A7DB" , k(k4).z().vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CD10A7DB" , rn_sae().vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CD50A7DB" , ru_sae().vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CD30A7DB" , rd_sae().vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6252CD70A7DB" , rz_sae().vfmsubadd213pd(zmm11, zmm22, zmm11));
+ TEST_INSTRUCTION("6272CD40A719" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232CD40A79CF034120000" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272CD50A719" , vfmsubadd213pd(zmm11, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272CD40A75A7F" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272CD40A79A00200000" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272CD40A75A80" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272CD40A79AC0DFFFFF" , vfmsubadd213pd(zmm11, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272CD50A75A7F" , vfmsubadd213pd(zmm11, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272CD50A79A00040000" , vfmsubadd213pd(zmm11, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272CD50A75A80" , vfmsubadd213pd(zmm11, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272CD50A79AF8FBFFFF" , vfmsubadd213pd(zmm11, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62523548A7E2" , vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("6252354FA7E2" , k(k7).vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("625235CFA7E2" , k(k7).z().vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("62523518A7E2" , rn_sae().vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("62523558A7E2" , ru_sae().vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("62523538A7E2" , rd_sae().vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("62523578A7E2" , rz_sae().vfmsubadd213ps(zmm12, zmm9, zmm10));
+ TEST_INSTRUCTION("62723548A721" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62323548A7A4F034120000" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62723558A721" , vfmsubadd213ps(zmm12, zmm9, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62723548A7627F" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62723548A7A200200000" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62723548A76280" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62723548A7A2C0DFFFFF" , vfmsubadd213ps(zmm12, zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62723558A7627F" , vfmsubadd213ps(zmm12, zmm9, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62723558A7A200020000" , vfmsubadd213ps(zmm12, zmm9, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62723558A76280" , vfmsubadd213ps(zmm12, zmm9, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62723558A7A2FCFDFFFF" , vfmsubadd213ps(zmm12, zmm9, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C2ED48B7E9" , vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2ED4EB7E9" , k(k6).vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2EDCEB7E9" , k(k6).z().vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2ED18B7E9" , rn_sae().vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2ED58B7E9" , ru_sae().vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2ED38B7E9" , rd_sae().vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62C2ED78B7E9" , rz_sae().vfmsubadd231pd(zmm21, zmm2, zmm9));
+ TEST_INSTRUCTION("62E2ED48B729" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2ED48B7ACF034120000" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2ED58B729" , vfmsubadd231pd(zmm21, zmm2, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2ED48B76A7F" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2ED48B7AA00200000" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2ED48B76A80" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2ED48B7AAC0DFFFFF" , vfmsubadd231pd(zmm21, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2ED58B76A7F" , vfmsubadd231pd(zmm21, zmm2, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2ED58B7AA00040000" , vfmsubadd231pd(zmm21, zmm2, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED58B76A80" , vfmsubadd231pd(zmm21, zmm2, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2ED58B7AAF8FBFFFF" , vfmsubadd231pd(zmm21, zmm2, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62025540B7D8" , vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62025546B7D8" , k(k6).vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("620255C6B7D8" , k(k6).z().vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62025510B7D8" , rn_sae().vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62025550B7D8" , ru_sae().vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62025530B7D8" , rd_sae().vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62025570B7D8" , rz_sae().vfmsubadd231ps(zmm27, zmm21, zmm24));
+ TEST_INSTRUCTION("62625540B719" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62225540B79CF034120000" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62625550B719" , vfmsubadd231ps(zmm27, zmm21, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62625540B75A7F" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62625540B79A00200000" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62625540B75A80" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62625540B79AC0DFFFFF" , vfmsubadd231ps(zmm27, zmm21, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62625550B75A7F" , vfmsubadd231ps(zmm27, zmm21, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62625550B79A00020000" , vfmsubadd231ps(zmm27, zmm21, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62625550B75A80" , vfmsubadd231ps(zmm27, zmm21, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62625550B79AFCFDFFFF" , vfmsubadd231ps(zmm27, zmm21, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("623295409CDB" , vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295429CDB" , k(k2).vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295C29CDB" , k(k2).z().vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295109CDB" , rn_sae().vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295509CDB" , ru_sae().vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295309CDB" , rd_sae().vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("623295709CDB" , rz_sae().vfnmadd132pd(zmm11, zmm29, zmm19));
+ TEST_INSTRUCTION("627295409C19" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("623295409C9CF034120000" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("627295509C19" , vfnmadd132pd(zmm11, zmm29, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("627295409C5A7F" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("627295409C9A00200000" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("627295409C5A80" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("627295409C9AC0DFFFFF" , vfnmadd132pd(zmm11, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("627295509C5A7F" , vfnmadd132pd(zmm11, zmm29, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("627295509C9A00040000" , vfnmadd132pd(zmm11, zmm29, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("627295509C5A80" , vfnmadd132pd(zmm11, zmm29, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("627295509C9AF8FBFFFF" , vfnmadd132pd(zmm11, zmm29, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C265489CCF" , vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C2654D9CCF" , k(k5).vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C265CD9CCF" , k(k5).z().vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C265189CCF" , rn_sae().vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C265589CCF" , ru_sae().vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C265389CCF" , rd_sae().vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62C265789CCF" , rz_sae().vfnmadd132ps(zmm17, zmm3, zmm15));
+ TEST_INSTRUCTION("62E265489C09" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A265489C8CF034120000" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E265589C09" , vfnmadd132ps(zmm17, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E265489C4A7F" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E265489C8A00200000" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E265489C4A80" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E265489C8AC0DFFFFF" , vfnmadd132ps(zmm17, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E265589C4A7F" , vfnmadd132ps(zmm17, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E265589C8A00020000" , vfnmadd132ps(zmm17, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E265589C4A80" , vfnmadd132ps(zmm17, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E265589C8AFCFDFFFF" , vfnmadd132ps(zmm17, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2BD009DD1" , vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD049DD1" , k(k4).vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD849DD1" , k(k4).z().vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD109DD1" , rn_sae().vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD509DD1" , ru_sae().vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD309DD1" , rd_sae().vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD709DD1" , rz_sae().vfnmadd132sd(xmm2, xmm24, xmm1));
+ TEST_INSTRUCTION("62F2BD009D11" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2BD009D94F034120000" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2BD009D527F" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2BD009D9200040000" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2BD009D5280" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2BD009D92F8FBFFFF" , vfnmadd132sd(xmm2, xmm24, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("625265009DED" , vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265049DED" , k(k4).vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265849DED" , k(k4).z().vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265109DED" , rn_sae().vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265509DED" , ru_sae().vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265309DED" , rd_sae().vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("625265709DED" , rz_sae().vfnmadd132ss(xmm13, xmm19, xmm13));
+ TEST_INSTRUCTION("627265009D29" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rcx)));
+ TEST_INSTRUCTION("623265009DACF034120000" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("627265009D6A7F" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("627265009DAA00020000" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("627265009D6A80" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("627265009DAAFCFDFFFF" , vfnmadd132ss(xmm13, xmm19, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6232F548ACFE" , vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F54BACFE" , k(k3).vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F5CBACFE" , k(k3).z().vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F518ACFE" , rn_sae().vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F558ACFE" , ru_sae().vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F538ACFE" , rd_sae().vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6232F578ACFE" , rz_sae().vfnmadd213pd(zmm15, zmm1, zmm22));
+ TEST_INSTRUCTION("6272F548AC39" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232F548ACBCF034120000" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272F558AC39" , vfnmadd213pd(zmm15, zmm1, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272F548AC7A7F" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272F548ACBA00200000" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272F548AC7A80" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272F548ACBAC0DFFFFF" , vfnmadd213pd(zmm15, zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272F558AC7A7F" , vfnmadd213pd(zmm15, zmm1, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272F558ACBA00040000" , vfnmadd213pd(zmm15, zmm1, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272F558AC7A80" , vfnmadd213pd(zmm15, zmm1, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272F558ACBAF8FBFFFF" , vfnmadd213pd(zmm15, zmm1, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62725D48ACDC" , vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D4CACDC" , k(k4).vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725DCCACDC" , k(k4).z().vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D18ACDC" , rn_sae().vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D58ACDC" , ru_sae().vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D38ACDC" , rd_sae().vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D78ACDC" , rz_sae().vfnmadd213ps(zmm11, zmm4, zmm4));
+ TEST_INSTRUCTION("62725D48AC19" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62325D48AC9CF034120000" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62725D58AC19" , vfnmadd213ps(zmm11, zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62725D48AC5A7F" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62725D48AC9A00200000" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62725D48AC5A80" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62725D48AC9AC0DFFFFF" , vfnmadd213ps(zmm11, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62725D58AC5A7F" , vfnmadd213ps(zmm11, zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62725D58AC9A00020000" , vfnmadd213ps(zmm11, zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62725D58AC5A80" , vfnmadd213ps(zmm11, zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62725D58AC9AFCFDFFFF" , vfnmadd213ps(zmm11, zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62428D08ADF3" , vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D0CADF3" , k(k4).vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D8CADF3" , k(k4).z().vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D18ADF3" , rn_sae().vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D58ADF3" , ru_sae().vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D38ADF3" , rd_sae().vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62428D78ADF3" , rz_sae().vfnmadd213sd(xmm30, xmm14, xmm11));
+ TEST_INSTRUCTION("62628D08AD31" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62228D08ADB4F034120000" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62628D08AD727F" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62628D08ADB200040000" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62628D08AD7280" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62628D08ADB2F8FBFFFF" , vfnmadd213sd(xmm30, xmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62226508ADE4" , vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("6222650BADE4" , k(k3).vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("6222658BADE4" , k(k3).z().vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("62226518ADE4" , rn_sae().vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("62226558ADE4" , ru_sae().vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("62226538ADE4" , rd_sae().vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("62226578ADE4" , rz_sae().vfnmadd213ss(xmm28, xmm3, xmm20));
+ TEST_INSTRUCTION("62626508AD21" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62226508ADA4F034120000" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62626508AD627F" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62626508ADA200020000" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62626508AD6280" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62626508ADA2FCFDFFFF" , vfnmadd213ss(xmm28, xmm3, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6232D548BCFE" , vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D54FBCFE" , k(k7).vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D5CFBCFE" , k(k7).z().vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D518BCFE" , rn_sae().vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D558BCFE" , ru_sae().vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D538BCFE" , rd_sae().vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6232D578BCFE" , rz_sae().vfnmadd231pd(zmm15, zmm5, zmm22));
+ TEST_INSTRUCTION("6272D548BC39" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232D548BCBCF034120000" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272D558BC39" , vfnmadd231pd(zmm15, zmm5, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272D548BC7A7F" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272D548BCBA00200000" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272D548BC7A80" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272D548BCBAC0DFFFFF" , vfnmadd231pd(zmm15, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272D558BC7A7F" , vfnmadd231pd(zmm15, zmm5, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272D558BCBA00040000" , vfnmadd231pd(zmm15, zmm5, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272D558BC7A80" , vfnmadd231pd(zmm15, zmm5, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272D558BCBAF8FBFFFF" , vfnmadd231pd(zmm15, zmm5, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62521D40BCE9" , vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521D43BCE9" , k(k3).vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521DC3BCE9" , k(k3).z().vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521D10BCE9" , rn_sae().vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521D50BCE9" , ru_sae().vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521D30BCE9" , rd_sae().vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62521D70BCE9" , rz_sae().vfnmadd231ps(zmm13, zmm28, zmm9));
+ TEST_INSTRUCTION("62721D40BC29" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62321D40BCACF034120000" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62721D50BC29" , vfnmadd231ps(zmm13, zmm28, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62721D40BC6A7F" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62721D40BCAA00200000" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62721D40BC6A80" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62721D40BCAAC0DFFFFF" , vfnmadd231ps(zmm13, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62721D50BC6A7F" , vfnmadd231ps(zmm13, zmm28, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62721D50BCAA00020000" , vfnmadd231ps(zmm13, zmm28, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62721D50BC6A80" , vfnmadd231ps(zmm13, zmm28, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62721D50BCAAFCFDFFFF" , vfnmadd231ps(zmm13, zmm28, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("C462D1BDF5" , vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D50FBDF5" , k(k7).vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D58FBDF5" , k(k7).z().vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D518BDF5" , rn_sae().vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D558BDF5" , ru_sae().vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D538BDF5" , rd_sae().vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("6272D578BDF5" , rz_sae().vfnmadd231sd(xmm14, xmm5, xmm5));
+ TEST_INSTRUCTION("C462D1BD31" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C422D1BDB4F034120000" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C462D1BDB2F8030000" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C462D1BDB200040000" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C462D1BDB200FCFFFF" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C462D1BDB2F8FBFFFF" , vfnmadd231sd(xmm14, xmm5, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62027D00BDC9" , vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D06BDC9" , k(k6).vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D86BDC9" , k(k6).z().vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D10BDC9" , rn_sae().vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D50BDC9" , ru_sae().vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D30BDC9" , rd_sae().vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62027D70BDC9" , rz_sae().vfnmadd231ss(xmm25, xmm16, xmm25));
+ TEST_INSTRUCTION("62627D00BD09" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D00BD8CF034120000" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62627D00BD4A7F" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62627D00BD8A00020000" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62627D00BD4A80" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62627D00BD8AFCFDFFFF" , vfnmadd231ss(xmm25, xmm16, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6242BD489ED9" , vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BD4C9ED9" , k(k4).vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BDCC9ED9" , k(k4).z().vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BD189ED9" , rn_sae().vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BD589ED9" , ru_sae().vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BD389ED9" , rd_sae().vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6242BD789ED9" , rz_sae().vfnmsub132pd(zmm27, zmm8, zmm9));
+ TEST_INSTRUCTION("6262BD489E19" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222BD489E9CF034120000" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262BD589E19" , vfnmsub132pd(zmm27, zmm8, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262BD489E5A7F" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262BD489E9A00200000" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262BD489E5A80" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262BD489E9AC0DFFFFF" , vfnmsub132pd(zmm27, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262BD589E5A7F" , vfnmsub132pd(zmm27, zmm8, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262BD589E9A00040000" , vfnmsub132pd(zmm27, zmm8, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262BD589E5A80" , vfnmsub132pd(zmm27, zmm8, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262BD589E9AF8FBFFFF" , vfnmsub132pd(zmm27, zmm8, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("624225489ED1" , vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("6242254C9ED1" , k(k4).vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("624225CC9ED1" , k(k4).z().vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("624225189ED1" , rn_sae().vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("624225589ED1" , ru_sae().vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("624225389ED1" , rd_sae().vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("624225789ED1" , rz_sae().vfnmsub132ps(zmm26, zmm11, zmm9));
+ TEST_INSTRUCTION("626225489E11" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622225489E94F034120000" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626225589E11" , vfnmsub132ps(zmm26, zmm11, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("626225489E527F" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("626225489E9200200000" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("626225489E5280" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626225489E92C0DFFFFF" , vfnmsub132ps(zmm26, zmm11, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("626225589E527F" , vfnmsub132ps(zmm26, zmm11, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("626225589E9200020000" , vfnmsub132ps(zmm26, zmm11, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("626225589E5280" , vfnmsub132ps(zmm26, zmm11, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("626225589E92FCFDFFFF" , vfnmsub132ps(zmm26, zmm11, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B2BD089FDB" , vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD0B9FDB" , k(k3).vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD8B9FDB" , k(k3).z().vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD189FDB" , rn_sae().vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD589FDB" , ru_sae().vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD389FDB" , rd_sae().vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("62B2BD789FDB" , rz_sae().vfnmsub132sd(xmm3, xmm8, xmm19));
+ TEST_INSTRUCTION("C4E2B99F19" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A2B99F9CF034120000" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C4E2B99F9AF8030000" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C4E2B99F9A00040000" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C4E2B99F9A00FCFFFF" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C4E2B99F9AF8FBFFFF" , vfnmsub132sd(xmm3, xmm8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E275009FDE" , vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275019FDE" , k(k1).vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275819FDE" , k(k1).z().vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275109FDE" , rn_sae().vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275509FDE" , ru_sae().vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275309FDE" , rd_sae().vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275709FDE" , rz_sae().vfnmsub132ss(xmm19, xmm17, xmm6));
+ TEST_INSTRUCTION("62E275009F19" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A275009F9CF034120000" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E275009F5A7F" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E275009F9A00020000" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E275009F5A80" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E275009F9AFCFDFFFF" , vfnmsub132ss(xmm19, xmm17, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F2BD48AEFF" , vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD4DAEFF" , k(k5).vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BDCDAEFF" , k(k5).z().vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD18AEFF" , rn_sae().vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD58AEFF" , ru_sae().vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD38AEFF" , rd_sae().vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD78AEFF" , rz_sae().vfnmsub213pd(zmm7, zmm8, zmm7));
+ TEST_INSTRUCTION("62F2BD48AE39" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2BD48AEBCF034120000" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2BD58AE39" , vfnmsub213pd(zmm7, zmm8, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2BD48AE7A7F" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2BD48AEBA00200000" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2BD48AE7A80" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2BD48AEBAC0DFFFFF" , vfnmsub213pd(zmm7, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2BD58AE7A7F" , vfnmsub213pd(zmm7, zmm8, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2BD58AEBA00040000" , vfnmsub213pd(zmm7, zmm8, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2BD58AE7A80" , vfnmsub213pd(zmm7, zmm8, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2BD58AEBAF8FBFFFF" , vfnmsub213pd(zmm7, zmm8, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62423D40AEEE" , vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423D47AEEE" , k(k7).vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423DC7AEEE" , k(k7).z().vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423D10AEEE" , rn_sae().vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423D50AEEE" , ru_sae().vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423D30AEEE" , rd_sae().vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62423D70AEEE" , rz_sae().vfnmsub213ps(zmm29, zmm24, zmm14));
+ TEST_INSTRUCTION("62623D40AE29" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62223D40AEACF034120000" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62623D50AE29" , vfnmsub213ps(zmm29, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62623D40AE6A7F" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62623D40AEAA00200000" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62623D40AE6A80" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62623D40AEAAC0DFFFFF" , vfnmsub213ps(zmm29, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62623D50AE6A7F" , vfnmsub213ps(zmm29, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62623D50AEAA00020000" , vfnmsub213ps(zmm29, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62623D50AE6A80" , vfnmsub213ps(zmm29, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62623D50AEAAFCFDFFFF" , vfnmsub213ps(zmm29, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6222BD08AFCF" , vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD09AFCF" , k(k1).vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD89AFCF" , k(k1).z().vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD18AFCF" , rn_sae().vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD58AFCF" , ru_sae().vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD38AFCF" , rd_sae().vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6222BD78AFCF" , rz_sae().vfnmsub213sd(xmm25, xmm8, xmm23));
+ TEST_INSTRUCTION("6262BD08AF09" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222BD08AF8CF034120000" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262BD08AF4A7F" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262BD08AF8A00040000" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262BD08AF4A80" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262BD08AF8AF8FBFFFF" , vfnmsub213sd(xmm25, xmm8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62425D00AFC7" , vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D06AFC7" , k(k6).vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D86AFC7" , k(k6).z().vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D10AFC7" , rn_sae().vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D50AFC7" , ru_sae().vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D30AFC7" , rd_sae().vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62425D70AFC7" , rz_sae().vfnmsub213ss(xmm24, xmm20, xmm15));
+ TEST_INSTRUCTION("62625D00AF01" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62225D00AF84F034120000" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62625D00AF427F" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62625D00AF8200020000" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62625D00AF4280" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62625D00AF82FCFDFFFF" , vfnmsub213ss(xmm24, xmm20, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62D2AD48BECC" , vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2AD4DBECC" , k(k5).vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2ADCDBECC" , k(k5).z().vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2AD18BECC" , rn_sae().vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2AD58BECC" , ru_sae().vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2AD38BECC" , rd_sae().vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62D2AD78BECC" , rz_sae().vfnmsub231pd(zmm1, zmm10, zmm12));
+ TEST_INSTRUCTION("62F2AD48BE09" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2AD48BE8CF034120000" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2AD58BE09" , vfnmsub231pd(zmm1, zmm10, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2AD48BE4A7F" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2AD48BE8A00200000" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2AD48BE4A80" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2AD48BE8AC0DFFFFF" , vfnmsub231pd(zmm1, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2AD58BE4A7F" , vfnmsub231pd(zmm1, zmm10, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2AD58BE8A00040000" , vfnmsub231pd(zmm1, zmm10, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD58BE4A80" , vfnmsub231pd(zmm1, zmm10, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2AD58BE8AF8FBFFFF" , vfnmsub231pd(zmm1, zmm10, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62A22D40BECB" , vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22D44BECB" , k(k4).vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22DC4BECB" , k(k4).z().vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22D10BECB" , rn_sae().vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22D50BECB" , ru_sae().vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22D30BECB" , rd_sae().vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62A22D70BECB" , rz_sae().vfnmsub231ps(zmm17, zmm26, zmm19));
+ TEST_INSTRUCTION("62E22D40BE09" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A22D40BE8CF034120000" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E22D50BE09" , vfnmsub231ps(zmm17, zmm26, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E22D40BE4A7F" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E22D40BE8A00200000" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E22D40BE4A80" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E22D40BE8AC0DFFFFF" , vfnmsub231ps(zmm17, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E22D50BE4A7F" , vfnmsub231ps(zmm17, zmm26, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E22D50BE8A00020000" , vfnmsub231ps(zmm17, zmm26, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E22D50BE4A80" , vfnmsub231ps(zmm17, zmm26, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E22D50BE8AFCFDFFFF" , vfnmsub231ps(zmm17, zmm26, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6282CD08BFDA" , vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD0FBFDA" , k(k7).vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD8FBFDA" , k(k7).z().vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD18BFDA" , rn_sae().vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD58BFDA" , ru_sae().vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD38BFDA" , rd_sae().vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("6282CD78BFDA" , rz_sae().vfnmsub231sd(xmm19, xmm6, xmm26));
+ TEST_INSTRUCTION("62E2CD08BF19" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD08BF9CF034120000" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2CD08BF5A7F" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E2CD08BF9A00040000" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E2CD08BF5A80" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E2CD08BF9AF8FBFFFF" , vfnmsub231sd(xmm19, xmm6, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62726D00BFE9" , vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D05BFE9" , k(k5).vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D85BFE9" , k(k5).z().vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D10BFE9" , rn_sae().vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D50BFE9" , ru_sae().vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D30BFE9" , rd_sae().vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D70BFE9" , rz_sae().vfnmsub231ss(xmm13, xmm18, xmm1));
+ TEST_INSTRUCTION("62726D00BF29" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62326D00BFACF034120000" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62726D00BF6A7F" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62726D00BFAA00020000" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62726D00BF6A80" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62726D00BFAAFCFDFFFF" , vfnmsub231ss(xmm13, xmm18, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6292FD4842F1" , vgetexppd(zmm6, zmm25));
+ TEST_INSTRUCTION("6292FD4B42F1" , k(k3).vgetexppd(zmm6, zmm25));
+ TEST_INSTRUCTION("6292FDCB42F1" , k(k3).z().vgetexppd(zmm6, zmm25));
+ TEST_INSTRUCTION("6292FD1842F1" , sae().vgetexppd(zmm6, zmm25));
+ TEST_INSTRUCTION("62F2FD484231" , vgetexppd(zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2FD4842B4F034120000" , vgetexppd(zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2FD584231" , vgetexppd(zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2FD4842727F" , vgetexppd(zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2FD4842B200200000" , vgetexppd(zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2FD48427280" , vgetexppd(zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2FD4842B2C0DFFFFF" , vgetexppd(zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2FD5842727F" , vgetexppd(zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2FD5842B200040000" , vgetexppd(zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2FD58427280" , vgetexppd(zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2FD5842B2F8FBFFFF" , vgetexppd(zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B27D4842F8" , vgetexpps(zmm7, zmm16));
+ TEST_INSTRUCTION("62B27D4A42F8" , k(k2).vgetexpps(zmm7, zmm16));
+ TEST_INSTRUCTION("62B27DCA42F8" , k(k2).z().vgetexpps(zmm7, zmm16));
+ TEST_INSTRUCTION("62B27D1842F8" , sae().vgetexpps(zmm7, zmm16));
+ TEST_INSTRUCTION("62F27D484239" , vgetexpps(zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D4842BCF034120000" , vgetexpps(zmm7, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D584239" , vgetexpps(zmm7, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D48427A7F" , vgetexpps(zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D4842BA00200000" , vgetexpps(zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D48427A80" , vgetexpps(zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D4842BAC0DFFFFF" , vgetexpps(zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D58427A7F" , vgetexpps(zmm7, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D5842BA00020000" , vgetexpps(zmm7, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D58427A80" , vgetexpps(zmm7, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D5842BAFCFDFFFF" , vgetexpps(zmm7, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62728D0843D5" , vgetexpsd(xmm10, xmm14, xmm5));
+ TEST_INSTRUCTION("62728D0C43D5" , k(k4).vgetexpsd(xmm10, xmm14, xmm5));
+ TEST_INSTRUCTION("62728D8C43D5" , k(k4).z().vgetexpsd(xmm10, xmm14, xmm5));
+ TEST_INSTRUCTION("62728D1843D5" , sae().vgetexpsd(xmm10, xmm14, xmm5));
+ TEST_INSTRUCTION("62728D084311" , vgetexpsd(xmm10, xmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62328D084394F034120000" , vgetexpsd(xmm10, xmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62728D0843527F" , vgetexpsd(xmm10, xmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62728D08439200040000" , vgetexpsd(xmm10, xmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62728D08435280" , vgetexpsd(xmm10, xmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62728D084392F8FBFFFF" , vgetexpsd(xmm10, xmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A2550043C7" , vgetexpss(xmm16, xmm21, xmm23));
+ TEST_INSTRUCTION("62A2550243C7" , k(k2).vgetexpss(xmm16, xmm21, xmm23));
+ TEST_INSTRUCTION("62A2558243C7" , k(k2).z().vgetexpss(xmm16, xmm21, xmm23));
+ TEST_INSTRUCTION("62A2551043C7" , sae().vgetexpss(xmm16, xmm21, xmm23));
+ TEST_INSTRUCTION("62E255004301" , vgetexpss(xmm16, xmm21, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A255004384F034120000" , vgetexpss(xmm16, xmm21, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2550043427F" , vgetexpss(xmm16, xmm21, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E25500438200020000" , vgetexpss(xmm16, xmm21, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E25500434280" , vgetexpss(xmm16, xmm21, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E255004382FCFDFFFF" , vgetexpss(xmm16, xmm21, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6253FD4826CAAB" , vgetmantpd(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("6253FD4D26CAAB" , k(k5).vgetmantpd(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("6253FDCD26CAAB" , k(k5).z().vgetmantpd(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("6253FD1826CAAB" , sae().vgetmantpd(zmm9, zmm10, 171));
+ TEST_INSTRUCTION("6253FD4826CA7B" , vgetmantpd(zmm9, zmm10, 123));
+ TEST_INSTRUCTION("6253FD1826CA7B" , sae().vgetmantpd(zmm9, zmm10, 123));
+ TEST_INSTRUCTION("6273FD4826097B" , vgetmantpd(zmm9, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233FD48268CF0341200007B" , vgetmantpd(zmm9, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273FD5826097B" , vgetmantpd(zmm9, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD48264A7F7B" , vgetmantpd(zmm9, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273FD48268A002000007B" , vgetmantpd(zmm9, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273FD48264A807B" , vgetmantpd(zmm9, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273FD48268AC0DFFFFF7B" , vgetmantpd(zmm9, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273FD58264A7F7B" , vgetmantpd(zmm9, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD58268A000400007B" , vgetmantpd(zmm9, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD58264A807B" , vgetmantpd(zmm9, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD58268AF8FBFFFF7B" , vgetmantpd(zmm9, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62037D4826E9AB" , vgetmantps(zmm29, zmm25, 171));
+ TEST_INSTRUCTION("62037D4B26E9AB" , k(k3).vgetmantps(zmm29, zmm25, 171));
+ TEST_INSTRUCTION("62037DCB26E9AB" , k(k3).z().vgetmantps(zmm29, zmm25, 171));
+ TEST_INSTRUCTION("62037D1826E9AB" , sae().vgetmantps(zmm29, zmm25, 171));
+ TEST_INSTRUCTION("62037D4826E97B" , vgetmantps(zmm29, zmm25, 123));
+ TEST_INSTRUCTION("62037D1826E97B" , sae().vgetmantps(zmm29, zmm25, 123));
+ TEST_INSTRUCTION("62637D4826297B" , vgetmantps(zmm29, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62237D4826ACF0341200007B" , vgetmantps(zmm29, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62637D5826297B" , vgetmantps(zmm29, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62637D48266A7F7B" , vgetmantps(zmm29, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62637D4826AA002000007B" , vgetmantps(zmm29, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62637D48266A807B" , vgetmantps(zmm29, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62637D4826AAC0DFFFFF7B" , vgetmantps(zmm29, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62637D58266A7F7B" , vgetmantps(zmm29, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62637D5826AA000200007B" , vgetmantps(zmm29, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D58266A807B" , vgetmantps(zmm29, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D5826AAFCFDFFFF7B" , vgetmantps(zmm29, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62A3E50827E1AB" , vgetmantsd(xmm20, xmm3, xmm17, 171));
+ TEST_INSTRUCTION("62A3E50F27E1AB" , k(k7).vgetmantsd(xmm20, xmm3, xmm17, 171));
+ TEST_INSTRUCTION("62A3E58F27E1AB" , k(k7).z().vgetmantsd(xmm20, xmm3, xmm17, 171));
+ TEST_INSTRUCTION("62A3E51827E1AB" , sae().vgetmantsd(xmm20, xmm3, xmm17, 171));
+ TEST_INSTRUCTION("62A3E50827E17B" , vgetmantsd(xmm20, xmm3, xmm17, 123));
+ TEST_INSTRUCTION("62A3E51827E17B" , sae().vgetmantsd(xmm20, xmm3, xmm17, 123));
+ TEST_INSTRUCTION("62E3E50827217B" , vgetmantsd(xmm20, xmm3, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A3E50827A4F0341200007B" , vgetmantsd(xmm20, xmm3, qword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62E3E50827627F7B" , vgetmantsd(xmm20, xmm3, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62E3E50827A2000400007B" , vgetmantsd(xmm20, xmm3, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62E3E5082762807B" , vgetmantsd(xmm20, xmm3, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62E3E50827A2F8FBFFFF7B" , vgetmantsd(xmm20, xmm3, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62731D0827EEAB" , vgetmantss(xmm13, xmm12, xmm6, 171));
+ TEST_INSTRUCTION("62731D0A27EEAB" , k(k2).vgetmantss(xmm13, xmm12, xmm6, 171));
+ TEST_INSTRUCTION("62731D8A27EEAB" , k(k2).z().vgetmantss(xmm13, xmm12, xmm6, 171));
+ TEST_INSTRUCTION("62731D1827EEAB" , sae().vgetmantss(xmm13, xmm12, xmm6, 171));
+ TEST_INSTRUCTION("62731D0827EE7B" , vgetmantss(xmm13, xmm12, xmm6, 123));
+ TEST_INSTRUCTION("62731D1827EE7B" , sae().vgetmantss(xmm13, xmm12, xmm6, 123));
+ TEST_INSTRUCTION("62731D0827297B" , vgetmantss(xmm13, xmm12, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62331D0827ACF0341200007B" , vgetmantss(xmm13, xmm12, dword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62731D08276A7F7B" , vgetmantss(xmm13, xmm12, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62731D0827AA000200007B" , vgetmantss(xmm13, xmm12, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62731D08276A807B" , vgetmantss(xmm13, xmm12, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62731D0827AAFCFDFFFF7B" , vgetmantss(xmm13, xmm12, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62337D4018C6AB" , vinsertf32x4(zmm8, zmm16, xmm22, 171));
+ TEST_INSTRUCTION("62337D4518C6AB" , k(k5).vinsertf32x4(zmm8, zmm16, xmm22, 171));
+ TEST_INSTRUCTION("62337DC518C6AB" , k(k5).z().vinsertf32x4(zmm8, zmm16, xmm22, 171));
+ TEST_INSTRUCTION("62337D4018C67B" , vinsertf32x4(zmm8, zmm16, xmm22, 123));
+ TEST_INSTRUCTION("62737D4018017B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62337D401884F0341200007B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62737D4018427F7B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rdx, 2032), 123));
+ TEST_INSTRUCTION("62737D401882000800007B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rdx, 2048), 123));
+ TEST_INSTRUCTION("62737D401842807B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rdx, -2048), 123));
+ TEST_INSTRUCTION("62737D401882F0F7FFFF7B" , vinsertf32x4(zmm8, zmm16, xmmword_ptr(rdx, -2064), 123));
+ TEST_INSTRUCTION("62C3B5481AF4AB" , vinsertf64x4(zmm22, zmm9, ymm12, 171));
+ TEST_INSTRUCTION("62C3B54E1AF4AB" , k(k6).vinsertf64x4(zmm22, zmm9, ymm12, 171));
+ TEST_INSTRUCTION("62C3B5CE1AF4AB" , k(k6).z().vinsertf64x4(zmm22, zmm9, ymm12, 171));
+ TEST_INSTRUCTION("62C3B5481AF47B" , vinsertf64x4(zmm22, zmm9, ymm12, 123));
+ TEST_INSTRUCTION("62E3B5481A317B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A3B5481AB4F0341200007B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62E3B5481A727F7B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rdx, 4064), 123));
+ TEST_INSTRUCTION("62E3B5481AB2001000007B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rdx, 4096), 123));
+ TEST_INSTRUCTION("62E3B5481A72807B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rdx, -4096), 123));
+ TEST_INSTRUCTION("62E3B5481AB2E0EFFFFF7B" , vinsertf64x4(zmm22, zmm9, ymmword_ptr(rdx, -4128), 123));
+ TEST_INSTRUCTION("62935D4838F8AB" , vinserti32x4(zmm7, zmm4, xmm24, 171));
+ TEST_INSTRUCTION("62935D4F38F8AB" , k(k7).vinserti32x4(zmm7, zmm4, xmm24, 171));
+ TEST_INSTRUCTION("62935DCF38F8AB" , k(k7).z().vinserti32x4(zmm7, zmm4, xmm24, 171));
+ TEST_INSTRUCTION("62935D4838F87B" , vinserti32x4(zmm7, zmm4, xmm24, 123));
+ TEST_INSTRUCTION("62F35D4838397B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B35D4838BCF0341200007B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F35D48387A7F7B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rdx, 2032), 123));
+ TEST_INSTRUCTION("62F35D4838BA000800007B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rdx, 2048), 123));
+ TEST_INSTRUCTION("62F35D48387A807B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rdx, -2048), 123));
+ TEST_INSTRUCTION("62F35D4838BAF0F7FFFF7B" , vinserti32x4(zmm7, zmm4, xmmword_ptr(rdx, -2064), 123));
+ TEST_INSTRUCTION("62A3D5483AD7AB" , vinserti64x4(zmm18, zmm5, ymm23, 171));
+ TEST_INSTRUCTION("62A3D54A3AD7AB" , k(k2).vinserti64x4(zmm18, zmm5, ymm23, 171));
+ TEST_INSTRUCTION("62A3D5CA3AD7AB" , k(k2).z().vinserti64x4(zmm18, zmm5, ymm23, 171));
+ TEST_INSTRUCTION("62A3D5483AD77B" , vinserti64x4(zmm18, zmm5, ymm23, 123));
+ TEST_INSTRUCTION("62E3D5483A117B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A3D5483A94F0341200007B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62E3D5483A527F7B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rdx, 4064), 123));
+ TEST_INSTRUCTION("62E3D5483A92001000007B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rdx, 4096), 123));
+ TEST_INSTRUCTION("62E3D5483A52807B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rdx, -4096), 123));
+ TEST_INSTRUCTION("62E3D5483A92E0EFFFFF7B" , vinserti64x4(zmm18, zmm5, ymmword_ptr(rdx, -4128), 123));
+ TEST_INSTRUCTION("62034D0821C4AB" , vinsertps(xmm24, xmm6, xmm28, 171));
+ TEST_INSTRUCTION("62034D0821C47B" , vinsertps(xmm24, xmm6, xmm28, 123));
+ TEST_INSTRUCTION("62634D0821017B" , vinsertps(xmm24, xmm6, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62234D082184F0341200007B" , vinsertps(xmm24, xmm6, dword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62634D0821427F7B" , vinsertps(xmm24, xmm6, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62634D082182000200007B" , vinsertps(xmm24, xmm6, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62634D082142807B" , vinsertps(xmm24, xmm6, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62634D082182FCFDFFFF7B" , vinsertps(xmm24, xmm6, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62319D485FCD" , vmaxpd(zmm9, zmm12, zmm21));
+ TEST_INSTRUCTION("62319D4E5FCD" , k(k6).vmaxpd(zmm9, zmm12, zmm21));
+ TEST_INSTRUCTION("62319DCE5FCD" , k(k6).z().vmaxpd(zmm9, zmm12, zmm21));
+ TEST_INSTRUCTION("62319D185FCD" , sae().vmaxpd(zmm9, zmm12, zmm21));
+ TEST_INSTRUCTION("62719D485F09" , vmaxpd(zmm9, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62319D485F8CF034120000" , vmaxpd(zmm9, zmm12, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62719D585F09" , vmaxpd(zmm9, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62719D485F4A7F" , vmaxpd(zmm9, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62719D485F8A00200000" , vmaxpd(zmm9, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62719D485F4A80" , vmaxpd(zmm9, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62719D485F8AC0DFFFFF" , vmaxpd(zmm9, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62719D585F4A7F" , vmaxpd(zmm9, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62719D585F8A00040000" , vmaxpd(zmm9, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62719D585F4A80" , vmaxpd(zmm9, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62719D585F8AF8FBFFFF" , vmaxpd(zmm9, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62813C405FC8" , vmaxps(zmm17, zmm24, zmm24));
+ TEST_INSTRUCTION("62813C445FC8" , k(k4).vmaxps(zmm17, zmm24, zmm24));
+ TEST_INSTRUCTION("62813CC45FC8" , k(k4).z().vmaxps(zmm17, zmm24, zmm24));
+ TEST_INSTRUCTION("62813C105FC8" , sae().vmaxps(zmm17, zmm24, zmm24));
+ TEST_INSTRUCTION("62E13C405F09" , vmaxps(zmm17, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A13C405F8CF034120000" , vmaxps(zmm17, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E13C505F09" , vmaxps(zmm17, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E13C405F4A7F" , vmaxps(zmm17, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E13C405F8A00200000" , vmaxps(zmm17, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E13C405F4A80" , vmaxps(zmm17, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E13C405F8AC0DFFFFF" , vmaxps(zmm17, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E13C505F4A7F" , vmaxps(zmm17, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E13C505F8A00020000" , vmaxps(zmm17, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E13C505F4A80" , vmaxps(zmm17, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E13C505F8AFCFDFFFF" , vmaxps(zmm17, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1D7005FF8" , vmaxsd(xmm23, xmm21, xmm16));
+ TEST_INSTRUCTION("62A1D7035FF8" , k(k3).vmaxsd(xmm23, xmm21, xmm16));
+ TEST_INSTRUCTION("62A1D7835FF8" , k(k3).z().vmaxsd(xmm23, xmm21, xmm16));
+ TEST_INSTRUCTION("62A1D7105FF8" , sae().vmaxsd(xmm23, xmm21, xmm16));
+ TEST_INSTRUCTION("62E1D7005F39" , vmaxsd(xmm23, xmm21, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1D7005FBCF034120000" , vmaxsd(xmm23, xmm21, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1D7005F7A7F" , vmaxsd(xmm23, xmm21, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1D7005FBA00040000" , vmaxsd(xmm23, xmm21, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1D7005F7A80" , vmaxsd(xmm23, xmm21, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1D7005FBAF8FBFFFF" , vmaxsd(xmm23, xmm21, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A176005FF0" , vmaxss(xmm22, xmm17, xmm16));
+ TEST_INSTRUCTION("62A176075FF0" , k(k7).vmaxss(xmm22, xmm17, xmm16));
+ TEST_INSTRUCTION("62A176875FF0" , k(k7).z().vmaxss(xmm22, xmm17, xmm16));
+ TEST_INSTRUCTION("62A176105FF0" , sae().vmaxss(xmm22, xmm17, xmm16));
+ TEST_INSTRUCTION("62E176005F31" , vmaxss(xmm22, xmm17, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A176005FB4F034120000" , vmaxss(xmm22, xmm17, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E176005F727F" , vmaxss(xmm22, xmm17, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E176005FB200020000" , vmaxss(xmm22, xmm17, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E176005F7280" , vmaxss(xmm22, xmm17, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E176005FB2FCFDFFFF" , vmaxss(xmm22, xmm17, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6211B5405DD3" , vminpd(zmm10, zmm25, zmm27));
+ TEST_INSTRUCTION("6211B5445DD3" , k(k4).vminpd(zmm10, zmm25, zmm27));
+ TEST_INSTRUCTION("6211B5C45DD3" , k(k4).z().vminpd(zmm10, zmm25, zmm27));
+ TEST_INSTRUCTION("6211B5105DD3" , sae().vminpd(zmm10, zmm25, zmm27));
+ TEST_INSTRUCTION("6271B5405D11" , vminpd(zmm10, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231B5405D94F034120000" , vminpd(zmm10, zmm25, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271B5505D11" , vminpd(zmm10, zmm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271B5405D527F" , vminpd(zmm10, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271B5405D9200200000" , vminpd(zmm10, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271B5405D5280" , vminpd(zmm10, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271B5405D92C0DFFFFF" , vminpd(zmm10, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271B5505D527F" , vminpd(zmm10, zmm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271B5505D9200040000" , vminpd(zmm10, zmm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271B5505D5280" , vminpd(zmm10, zmm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271B5505D92F8FBFFFF" , vminpd(zmm10, zmm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B10C485DD8" , vminps(zmm3, zmm14, zmm16));
+ TEST_INSTRUCTION("62B10C4F5DD8" , k(k7).vminps(zmm3, zmm14, zmm16));
+ TEST_INSTRUCTION("62B10CCF5DD8" , k(k7).z().vminps(zmm3, zmm14, zmm16));
+ TEST_INSTRUCTION("62B10C185DD8" , sae().vminps(zmm3, zmm14, zmm16));
+ TEST_INSTRUCTION("62F10C485D19" , vminps(zmm3, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B10C485D9CF034120000" , vminps(zmm3, zmm14, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F10C585D19" , vminps(zmm3, zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F10C485D5A7F" , vminps(zmm3, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F10C485D9A00200000" , vminps(zmm3, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F10C485D5A80" , vminps(zmm3, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F10C485D9AC0DFFFFF" , vminps(zmm3, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F10C585D5A7F" , vminps(zmm3, zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F10C585D9A00020000" , vminps(zmm3, zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F10C585D5A80" , vminps(zmm3, zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F10C585D9AFCFDFFFF" , vminps(zmm3, zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6211F7085DD4" , vminsd(xmm10, xmm1, xmm28));
+ TEST_INSTRUCTION("6211F70A5DD4" , k(k2).vminsd(xmm10, xmm1, xmm28));
+ TEST_INSTRUCTION("6211F78A5DD4" , k(k2).z().vminsd(xmm10, xmm1, xmm28));
+ TEST_INSTRUCTION("6211F7185DD4" , sae().vminsd(xmm10, xmm1, xmm28));
+ TEST_INSTRUCTION("C5735D11" , vminsd(xmm10, xmm1, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C421735D94F034120000" , vminsd(xmm10, xmm1, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5735D92F8030000" , vminsd(xmm10, xmm1, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C5735D9200040000" , vminsd(xmm10, xmm1, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C5735D9200FCFFFF" , vminsd(xmm10, xmm1, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C5735D92F8FBFFFF" , vminsd(xmm10, xmm1, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("624156085DE0" , vminss(xmm28, xmm5, xmm8));
+ TEST_INSTRUCTION("6241560C5DE0" , k(k4).vminss(xmm28, xmm5, xmm8));
+ TEST_INSTRUCTION("6241568C5DE0" , k(k4).z().vminss(xmm28, xmm5, xmm8));
+ TEST_INSTRUCTION("624156185DE0" , sae().vminss(xmm28, xmm5, xmm8));
+ TEST_INSTRUCTION("626156085D21" , vminss(xmm28, xmm5, dword_ptr(rcx)));
+ TEST_INSTRUCTION("622156085DA4F034120000" , vminss(xmm28, xmm5, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626156085D627F" , vminss(xmm28, xmm5, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("626156085DA200020000" , vminss(xmm28, xmm5, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("626156085D6280" , vminss(xmm28, xmm5, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("626156085DA2FCFDFFFF" , vminss(xmm28, xmm5, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C1FD4828F9" , vmovapd(zmm23, zmm9));
+ TEST_INSTRUCTION("62C1FD4D28F9" , k(k5).vmovapd(zmm23, zmm9));
+ TEST_INSTRUCTION("62C1FDCD28F9" , k(k5).z().vmovapd(zmm23, zmm9));
+ TEST_INSTRUCTION("62E1FD482839" , vmovapd(zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD4828BCF034120000" , vmovapd(zmm23, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FD48287A7F" , vmovapd(zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD4828BA00200000" , vmovapd(zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD48287A80" , vmovapd(zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD4828BAC0DFFFFF" , vmovapd(zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62417C4828D3" , vmovaps(zmm26, zmm11));
+ TEST_INSTRUCTION("62417C4F28D3" , k(k7).vmovaps(zmm26, zmm11));
+ TEST_INSTRUCTION("62417CCF28D3" , k(k7).z().vmovaps(zmm26, zmm11));
+ TEST_INSTRUCTION("62617C482811" , vmovaps(zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62217C482894F034120000" , vmovaps(zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62617C4828527F" , vmovaps(zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62617C48289200200000" , vmovaps(zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62617C48285280" , vmovaps(zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62617C482892C0DFFFFF" , vmovaps(zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("C5796EF0" , vmovd(xmm14, eax));
+ TEST_INSTRUCTION("C5796EF5" , vmovd(xmm14, ebp));
+ TEST_INSTRUCTION("C441796EF5" , vmovd(xmm14, r13d));
+ TEST_INSTRUCTION("C5796E31" , vmovd(xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C421796EB4F034120000" , vmovd(xmm14, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5796EB2FC010000" , vmovd(xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5796EB200020000" , vmovd(xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5796EB200FEFFFF" , vmovd(xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5796EB2FCFDFFFF" , vmovd(xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C5797E31" , vmovd(dword_ptr(rcx), xmm14));
+ TEST_INSTRUCTION("C421797EB4F034120000" , vmovd(dword_ptr(rax, r14, 3, 4660), xmm14));
+ TEST_INSTRUCTION("C5797EB2FC010000" , vmovd(dword_ptr(rdx, 508), xmm14));
+ TEST_INSTRUCTION("C5797EB200020000" , vmovd(dword_ptr(rdx, 512), xmm14));
+ TEST_INSTRUCTION("C5797EB200FEFFFF" , vmovd(dword_ptr(rdx, -512), xmm14));
+ TEST_INSTRUCTION("C5797EB2FCFDFFFF" , vmovd(dword_ptr(rdx, -516), xmm14));
+ TEST_INSTRUCTION("62D1FF4812CA" , vmovddup(zmm1, zmm10));
+ TEST_INSTRUCTION("62D1FF4B12CA" , k(k3).vmovddup(zmm1, zmm10));
+ TEST_INSTRUCTION("62D1FFCB12CA" , k(k3).z().vmovddup(zmm1, zmm10));
+ TEST_INSTRUCTION("62F1FF481209" , vmovddup(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF48128CF034120000" , vmovddup(zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FF48124A7F" , vmovddup(zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1FF48128A00200000" , vmovddup(zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1FF48124A80" , vmovddup(zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1FF48128AC0DFFFFF" , vmovddup(zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62817D486FF5" , vmovdqa32(zmm22, zmm29));
+ TEST_INSTRUCTION("62817D4D6FF5" , k(k5).vmovdqa32(zmm22, zmm29));
+ TEST_INSTRUCTION("62817DCD6FF5" , k(k5).z().vmovdqa32(zmm22, zmm29));
+ TEST_INSTRUCTION("62E17D486F31" , vmovdqa32(zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17D486FB4F034120000" , vmovdqa32(zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17D486F727F" , vmovdqa32(zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17D486FB200200000" , vmovdqa32(zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17D486F7280" , vmovdqa32(zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17D486FB2C0DFFFFF" , vmovdqa32(zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271FD486FCF" , vmovdqa64(zmm9, zmm7));
+ TEST_INSTRUCTION("6271FD4A6FCF" , k(k2).vmovdqa64(zmm9, zmm7));
+ TEST_INSTRUCTION("6271FDCA6FCF" , k(k2).z().vmovdqa64(zmm9, zmm7));
+ TEST_INSTRUCTION("6271FD486F09" , vmovdqa64(zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FD486F8CF034120000" , vmovdqa64(zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FD486F4A7F" , vmovdqa64(zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271FD486F8A00200000" , vmovdqa64(zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271FD486F4A80" , vmovdqa64(zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271FD486F8AC0DFFFFF" , vmovdqa64(zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62B17E486FEE" , vmovdqu32(zmm5, zmm22));
+ TEST_INSTRUCTION("62B17E4D6FEE" , k(k5).vmovdqu32(zmm5, zmm22));
+ TEST_INSTRUCTION("62B17ECD6FEE" , k(k5).z().vmovdqu32(zmm5, zmm22));
+ TEST_INSTRUCTION("62F17E486F29" , vmovdqu32(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E486FACF034120000" , vmovdqu32(zmm5, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17E486F6A7F" , vmovdqu32(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17E486FAA00200000" , vmovdqu32(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17E486F6A80" , vmovdqu32(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17E486FAAC0DFFFFF" , vmovdqu32(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261FE486FE5" , vmovdqu64(zmm28, zmm5));
+ TEST_INSTRUCTION("6261FE4B6FE5" , k(k3).vmovdqu64(zmm28, zmm5));
+ TEST_INSTRUCTION("6261FECB6FE5" , k(k3).z().vmovdqu64(zmm28, zmm5));
+ TEST_INSTRUCTION("6261FE486F21" , vmovdqu64(zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221FE486FA4F034120000" , vmovdqu64(zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261FE486F627F" , vmovdqu64(zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261FE486FA200200000" , vmovdqu64(zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261FE486F6280" , vmovdqu64(zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261FE486FA2C0DFFFFF" , vmovdqu64(zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62817C0012F1" , vmovhlps(xmm22, xmm16, xmm25));
+ TEST_INSTRUCTION("6261F5081609" , vmovhpd(xmm25, xmm1, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221F508168CF034120000" , vmovhpd(xmm25, xmm1, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261F508164A7F" , vmovhpd(xmm25, xmm1, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261F508168A00040000" , vmovhpd(xmm25, xmm1, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261F508164A80" , vmovhpd(xmm25, xmm1, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261F508168AF8FBFFFF" , vmovhpd(xmm25, xmm1, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5791709" , vmovhpd(qword_ptr(rcx), xmm9));
+ TEST_INSTRUCTION("C42179178CF034120000" , vmovhpd(qword_ptr(rax, r14, 3, 4660), xmm9));
+ TEST_INSTRUCTION("C579178AF8030000" , vmovhpd(qword_ptr(rdx, 1016), xmm9));
+ TEST_INSTRUCTION("C579178A00040000" , vmovhpd(qword_ptr(rdx, 1024), xmm9));
+ TEST_INSTRUCTION("C579178A00FCFFFF" , vmovhpd(qword_ptr(rdx, -1024), xmm9));
+ TEST_INSTRUCTION("C579178AF8FBFFFF" , vmovhpd(qword_ptr(rdx, -1032), xmm9));
+ TEST_INSTRUCTION("626174001621" , vmovhps(xmm28, xmm17, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221740016A4F034120000" , vmovhps(xmm28, xmm17, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261740016627F" , vmovhps(xmm28, xmm17, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261740016A200040000" , vmovhps(xmm28, xmm17, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62617400166280" , vmovhps(xmm28, xmm17, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261740016A2F8FBFFFF" , vmovhps(xmm28, xmm17, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5781729" , vmovhps(qword_ptr(rcx), xmm13));
+ TEST_INSTRUCTION("C4217817ACF034120000" , vmovhps(qword_ptr(rax, r14, 3, 4660), xmm13));
+ TEST_INSTRUCTION("C57817AAF8030000" , vmovhps(qword_ptr(rdx, 1016), xmm13));
+ TEST_INSTRUCTION("C57817AA00040000" , vmovhps(qword_ptr(rdx, 1024), xmm13));
+ TEST_INSTRUCTION("C57817AA00FCFFFF" , vmovhps(qword_ptr(rdx, -1024), xmm13));
+ TEST_INSTRUCTION("C57817AAF8FBFFFF" , vmovhps(qword_ptr(rdx, -1032), xmm13));
+ TEST_INSTRUCTION("C59816F6" , vmovlhps(xmm6, xmm12, xmm6));
+ TEST_INSTRUCTION("62E1DD001209" , vmovlpd(xmm17, xmm20, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1DD00128CF034120000" , vmovlpd(xmm17, xmm20, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1DD00124A7F" , vmovlpd(xmm17, xmm20, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1DD00128A00040000" , vmovlpd(xmm17, xmm20, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1DD00124A80" , vmovlpd(xmm17, xmm20, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1DD00128AF8FBFFFF" , vmovlpd(xmm17, xmm20, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("C5F91339" , vmovlpd(qword_ptr(rcx), xmm7));
+ TEST_INSTRUCTION("C4A17913BCF034120000" , vmovlpd(qword_ptr(rax, r14, 3, 4660), xmm7));
+ TEST_INSTRUCTION("C5F913BAF8030000" , vmovlpd(qword_ptr(rdx, 1016), xmm7));
+ TEST_INSTRUCTION("C5F913BA00040000" , vmovlpd(qword_ptr(rdx, 1024), xmm7));
+ TEST_INSTRUCTION("C5F913BA00FCFFFF" , vmovlpd(qword_ptr(rdx, -1024), xmm7));
+ TEST_INSTRUCTION("C5F913BAF8FBFFFF" , vmovlpd(qword_ptr(rdx, -1032), xmm7));
+ TEST_INSTRUCTION("C5201219" , vmovlps(xmm11, xmm11, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C42120129CF034120000" , vmovlps(xmm11, xmm11, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C520129AF8030000" , vmovlps(xmm11, xmm11, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C520129A00040000" , vmovlps(xmm11, xmm11, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C520129A00FCFFFF" , vmovlps(xmm11, xmm11, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C520129AF8FBFFFF" , vmovlps(xmm11, xmm11, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E17C081329" , vmovlps(qword_ptr(rcx), xmm21));
+ TEST_INSTRUCTION("62A17C0813ACF034120000" , vmovlps(qword_ptr(rax, r14, 3, 4660), xmm21));
+ TEST_INSTRUCTION("62E17C08136A7F" , vmovlps(qword_ptr(rdx, 1016), xmm21));
+ TEST_INSTRUCTION("62E17C0813AA00040000" , vmovlps(qword_ptr(rdx, 1024), xmm21));
+ TEST_INSTRUCTION("62E17C08136A80" , vmovlps(qword_ptr(rdx, -1024), xmm21));
+ TEST_INSTRUCTION("62E17C0813AAF8FBFFFF" , vmovlps(qword_ptr(rdx, -1032), xmm21));
+ TEST_INSTRUCTION("62E17D48E721" , vmovntdq(zmmword_ptr(rcx), zmm20));
+ TEST_INSTRUCTION("62A17D48E7A4F034120000" , vmovntdq(zmmword_ptr(rax, r14, 3, 4660), zmm20));
+ TEST_INSTRUCTION("62E17D48E7627F" , vmovntdq(zmmword_ptr(rdx, 8128), zmm20));
+ TEST_INSTRUCTION("62E17D48E7A200200000" , vmovntdq(zmmword_ptr(rdx, 8192), zmm20));
+ TEST_INSTRUCTION("62E17D48E76280" , vmovntdq(zmmword_ptr(rdx, -8192), zmm20));
+ TEST_INSTRUCTION("62E17D48E7A2C0DFFFFF" , vmovntdq(zmmword_ptr(rdx, -8256), zmm20));
+ TEST_INSTRUCTION("62727D482A11" , vmovntdqa(zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D482A94F034120000" , vmovntdqa(zmm10, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D482A527F" , vmovntdqa(zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62727D482A9200200000" , vmovntdqa(zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62727D482A5280" , vmovntdqa(zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62727D482A92C0DFFFFF" , vmovntdqa(zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FD482B29" , vmovntpd(zmmword_ptr(rcx), zmm21));
+ TEST_INSTRUCTION("62A1FD482BACF034120000" , vmovntpd(zmmword_ptr(rax, r14, 3, 4660), zmm21));
+ TEST_INSTRUCTION("62E1FD482B6A7F" , vmovntpd(zmmword_ptr(rdx, 8128), zmm21));
+ TEST_INSTRUCTION("62E1FD482BAA00200000" , vmovntpd(zmmword_ptr(rdx, 8192), zmm21));
+ TEST_INSTRUCTION("62E1FD482B6A80" , vmovntpd(zmmword_ptr(rdx, -8192), zmm21));
+ TEST_INSTRUCTION("62E1FD482BAAC0DFFFFF" , vmovntpd(zmmword_ptr(rdx, -8256), zmm21));
+ TEST_INSTRUCTION("62E17C482B39" , vmovntps(zmmword_ptr(rcx), zmm23));
+ TEST_INSTRUCTION("62A17C482BBCF034120000" , vmovntps(zmmword_ptr(rax, r14, 3, 4660), zmm23));
+ TEST_INSTRUCTION("62E17C482B7A7F" , vmovntps(zmmword_ptr(rdx, 8128), zmm23));
+ TEST_INSTRUCTION("62E17C482BBA00200000" , vmovntps(zmmword_ptr(rdx, 8192), zmm23));
+ TEST_INSTRUCTION("62E17C482B7A80" , vmovntps(zmmword_ptr(rdx, -8192), zmm23));
+ TEST_INSTRUCTION("62E17C482BBAC0DFFFFF" , vmovntps(zmmword_ptr(rdx, -8256), zmm23));
+ TEST_INSTRUCTION("6261FD086EC0" , vmovq(xmm24, rax));
+ TEST_INSTRUCTION("6241FD086EC0" , vmovq(xmm24, r8));
+ TEST_INSTRUCTION("C5FB1029" , vmovsd(xmm5, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62F1FF0B1029" , k(k3).vmovsd(xmm5, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62F1FF8B1029" , k(k3).z().vmovsd(xmm5, qword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A17B10ACF034120000" , vmovsd(xmm5, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5FB10AAF8030000" , vmovsd(xmm5, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("C5FB10AA00040000" , vmovsd(xmm5, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("C5FB10AA00FCFFFF" , vmovsd(xmm5, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("C5FB10AAF8FBFFFF" , vmovsd(xmm5, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E1FF081109" , vmovsd(qword_ptr(rcx), xmm17));
+ TEST_INSTRUCTION("62E1FF0B1109" , k(k3).vmovsd(qword_ptr(rcx), xmm17));
+ TEST_INSTRUCTION("62A1FF08118CF034120000" , vmovsd(qword_ptr(rax, r14, 3, 4660), xmm17));
+ TEST_INSTRUCTION("62E1FF08114A7F" , vmovsd(qword_ptr(rdx, 1016), xmm17));
+ TEST_INSTRUCTION("62E1FF08118A00040000" , vmovsd(qword_ptr(rdx, 1024), xmm17));
+ TEST_INSTRUCTION("62E1FF08114A80" , vmovsd(qword_ptr(rdx, -1024), xmm17));
+ TEST_INSTRUCTION("62E1FF08118AF8FBFFFF" , vmovsd(qword_ptr(rdx, -1032), xmm17));
+ TEST_INSTRUCTION("62C1970010EC" , vmovsd(xmm21, xmm29, xmm12));
+ TEST_INSTRUCTION("62C1970710EC" , k(k7).vmovsd(xmm21, xmm29, xmm12));
+ TEST_INSTRUCTION("62C1978710EC" , k(k7).z().vmovsd(xmm21, xmm29, xmm12));
+ TEST_INSTRUCTION("62A17E4816D4" , vmovshdup(zmm18, zmm20));
+ TEST_INSTRUCTION("62A17E4D16D4" , k(k5).vmovshdup(zmm18, zmm20));
+ TEST_INSTRUCTION("62A17ECD16D4" , k(k5).z().vmovshdup(zmm18, zmm20));
+ TEST_INSTRUCTION("62E17E481611" , vmovshdup(zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17E481694F034120000" , vmovshdup(zmm18, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17E4816527F" , vmovshdup(zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17E48169200200000" , vmovshdup(zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17E48165280" , vmovshdup(zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17E481692C0DFFFFF" , vmovshdup(zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62717E4812CD" , vmovsldup(zmm9, zmm5));
+ TEST_INSTRUCTION("62717E4F12CD" , k(k7).vmovsldup(zmm9, zmm5));
+ TEST_INSTRUCTION("62717ECF12CD" , k(k7).z().vmovsldup(zmm9, zmm5));
+ TEST_INSTRUCTION("62717E481209" , vmovsldup(zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E48128CF034120000" , vmovsldup(zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717E48124A7F" , vmovsldup(zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62717E48128A00200000" , vmovsldup(zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62717E48124A80" , vmovsldup(zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62717E48128AC0DFFFFF" , vmovsldup(zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("C5FA1009" , vmovss(xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E0C1009" , k(k4).vmovss(xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62F17E8C1009" , k(k4).z().vmovss(xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("C4A17A108CF034120000" , vmovss(xmm1, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5FA108AFC010000" , vmovss(xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("C5FA108A00020000" , vmovss(xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("C5FA108A00FEFFFF" , vmovss(xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("C5FA108AFCFDFFFF" , vmovss(xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("C57A1129" , vmovss(dword_ptr(rcx), xmm13));
+ TEST_INSTRUCTION("62717E0A1129" , k(k2).vmovss(dword_ptr(rcx), xmm13));
+ TEST_INSTRUCTION("C4217A11ACF034120000" , vmovss(dword_ptr(rax, r14, 3, 4660), xmm13));
+ TEST_INSTRUCTION("C57A11AAFC010000" , vmovss(dword_ptr(rdx, 508), xmm13));
+ TEST_INSTRUCTION("C57A11AA00020000" , vmovss(dword_ptr(rdx, 512), xmm13));
+ TEST_INSTRUCTION("C57A11AA00FEFFFF" , vmovss(dword_ptr(rdx, -512), xmm13));
+ TEST_INSTRUCTION("C57A11AAFCFDFFFF" , vmovss(dword_ptr(rdx, -516), xmm13));
+ TEST_INSTRUCTION("62C1260010D6" , vmovss(xmm18, xmm27, xmm14));
+ TEST_INSTRUCTION("62C1260210D6" , k(k2).vmovss(xmm18, xmm27, xmm14));
+ TEST_INSTRUCTION("62C1268210D6" , k(k2).z().vmovss(xmm18, xmm27, xmm14));
+ TEST_INSTRUCTION("62E1FD4810C6" , vmovupd(zmm16, zmm6));
+ TEST_INSTRUCTION("62E1FD4A10C6" , k(k2).vmovupd(zmm16, zmm6));
+ TEST_INSTRUCTION("62E1FDCA10C6" , k(k2).z().vmovupd(zmm16, zmm6));
+ TEST_INSTRUCTION("62E1FD481001" , vmovupd(zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD481084F034120000" , vmovupd(zmm16, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FD4810427F" , vmovupd(zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD48108200200000" , vmovupd(zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD48104280" , vmovupd(zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD481082C0DFFFFF" , vmovupd(zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17C4810F4" , vmovups(zmm22, zmm4));
+ TEST_INSTRUCTION("62E17C4F10F4" , k(k7).vmovups(zmm22, zmm4));
+ TEST_INSTRUCTION("62E17CCF10F4" , k(k7).z().vmovups(zmm22, zmm4));
+ TEST_INSTRUCTION("62E17C481031" , vmovups(zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17C4810B4F034120000" , vmovups(zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17C4810727F" , vmovups(zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17C4810B200200000" , vmovups(zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17C48107280" , vmovups(zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17C4810B2C0DFFFFF" , vmovups(zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261B54059C5" , vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B54459C5" , k(k4).vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B5C459C5" , k(k4).z().vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B51059C5" , rn_sae().vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B55059C5" , ru_sae().vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B53059C5" , rd_sae().vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B57059C5" , rz_sae().vmulpd(zmm24, zmm25, zmm5));
+ TEST_INSTRUCTION("6261B5405901" , vmulpd(zmm24, zmm25, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221B5405984F034120000" , vmulpd(zmm24, zmm25, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261B5505901" , vmulpd(zmm24, zmm25, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261B54059427F" , vmulpd(zmm24, zmm25, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261B540598200200000" , vmulpd(zmm24, zmm25, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261B540594280" , vmulpd(zmm24, zmm25, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261B5405982C0DFFFFF" , vmulpd(zmm24, zmm25, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261B55059427F" , vmulpd(zmm24, zmm25, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261B550598200040000" , vmulpd(zmm24, zmm25, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261B550594280" , vmulpd(zmm24, zmm25, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261B5505982F8FBFFFF" , vmulpd(zmm24, zmm25, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F1244059F3" , vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F1244559F3" , k(k5).vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F124C559F3" , k(k5).z().vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F1241059F3" , rn_sae().vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F1245059F3" , ru_sae().vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F1243059F3" , rd_sae().vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F1247059F3" , rz_sae().vmulps(zmm6, zmm27, zmm3));
+ TEST_INSTRUCTION("62F124405931" , vmulps(zmm6, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1244059B4F034120000" , vmulps(zmm6, zmm27, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F124505931" , vmulps(zmm6, zmm27, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F1244059727F" , vmulps(zmm6, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1244059B200200000" , vmulps(zmm6, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F12440597280" , vmulps(zmm6, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1244059B2C0DFFFFF" , vmulps(zmm6, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1245059727F" , vmulps(zmm6, zmm27, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F1245059B200020000" , vmulps(zmm6, zmm27, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F12450597280" , vmulps(zmm6, zmm27, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F1245059B2FCFDFFFF" , vmulps(zmm6, zmm27, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1970059FE" , vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1970559FE" , k(k5).vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1978559FE" , k(k5).z().vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1971059FE" , rn_sae().vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1975059FE" , ru_sae().vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1973059FE" , rd_sae().vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62A1977059FE" , rz_sae().vmulsd(xmm23, xmm29, xmm22));
+ TEST_INSTRUCTION("62E197005939" , vmulsd(xmm23, xmm29, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1970059BCF034120000" , vmulsd(xmm23, xmm29, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E19700597A7F" , vmulsd(xmm23, xmm29, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1970059BA00040000" , vmulsd(xmm23, xmm29, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E19700597A80" , vmulsd(xmm23, xmm29, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1970059BAF8FBFFFF" , vmulsd(xmm23, xmm29, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62412E0059C8" , vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E0559C8" , k(k5).vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E8559C8" , k(k5).z().vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E1059C8" , rn_sae().vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E5059C8" , ru_sae().vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E3059C8" , rd_sae().vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62412E7059C8" , rz_sae().vmulss(xmm25, xmm26, xmm8));
+ TEST_INSTRUCTION("62612E005909" , vmulss(xmm25, xmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62212E00598CF034120000" , vmulss(xmm25, xmm26, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62612E00594A7F" , vmulss(xmm25, xmm26, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62612E00598A00020000" , vmulss(xmm25, xmm26, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62612E00594A80" , vmulss(xmm25, xmm26, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62612E00598AFCFDFFFF" , vmulss(xmm25, xmm26, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62927D481EE5" , vpabsd(zmm4, zmm29));
+ TEST_INSTRUCTION("62927D4C1EE5" , k(k4).vpabsd(zmm4, zmm29));
+ TEST_INSTRUCTION("62927DCC1EE5" , k(k4).z().vpabsd(zmm4, zmm29));
+ TEST_INSTRUCTION("62F27D481E21" , vpabsd(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D481EA4F034120000" , vpabsd(zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D581E21" , vpabsd(zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D481E627F" , vpabsd(zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D481EA200200000" , vpabsd(zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D481E6280" , vpabsd(zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D481EA2C0DFFFFF" , vpabsd(zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D581E627F" , vpabsd(zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D581EA200020000" , vpabsd(zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D581E6280" , vpabsd(zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D581EA2FCFDFFFF" , vpabsd(zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62E2FD481FCB" , vpabsq(zmm17, zmm3));
+ TEST_INSTRUCTION("62E2FD4A1FCB" , k(k2).vpabsq(zmm17, zmm3));
+ TEST_INSTRUCTION("62E2FDCA1FCB" , k(k2).z().vpabsq(zmm17, zmm3));
+ TEST_INSTRUCTION("62E2FD481F09" , vpabsq(zmm17, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2FD481F8CF034120000" , vpabsq(zmm17, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2FD581F09" , vpabsq(zmm17, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2FD481F4A7F" , vpabsq(zmm17, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2FD481F8A00200000" , vpabsq(zmm17, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2FD481F4A80" , vpabsq(zmm17, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2FD481F8AC0DFFFFF" , vpabsq(zmm17, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2FD581F4A7F" , vpabsq(zmm17, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2FD581F8A00040000" , vpabsq(zmm17, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD581F4A80" , vpabsq(zmm17, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2FD581F8AF8FBFFFF" , vpabsq(zmm17, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62513D48FED3" , vpaddd(zmm10, zmm8, zmm11));
+ TEST_INSTRUCTION("62513D4FFED3" , k(k7).vpaddd(zmm10, zmm8, zmm11));
+ TEST_INSTRUCTION("62513DCFFED3" , k(k7).z().vpaddd(zmm10, zmm8, zmm11));
+ TEST_INSTRUCTION("62713D48FE11" , vpaddd(zmm10, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62313D48FE94F034120000" , vpaddd(zmm10, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62713D58FE11" , vpaddd(zmm10, zmm8, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62713D48FE527F" , vpaddd(zmm10, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62713D48FE9200200000" , vpaddd(zmm10, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62713D48FE5280" , vpaddd(zmm10, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62713D48FE92C0DFFFFF" , vpaddd(zmm10, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62713D58FE527F" , vpaddd(zmm10, zmm8, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62713D58FE9200020000" , vpaddd(zmm10, zmm8, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62713D58FE5280" , vpaddd(zmm10, zmm8, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62713D58FE92FCFDFFFF" , vpaddd(zmm10, zmm8, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6291DD48D4F2" , vpaddq(zmm6, zmm4, zmm26));
+ TEST_INSTRUCTION("6291DD4BD4F2" , k(k3).vpaddq(zmm6, zmm4, zmm26));
+ TEST_INSTRUCTION("6291DDCBD4F2" , k(k3).z().vpaddq(zmm6, zmm4, zmm26));
+ TEST_INSTRUCTION("62F1DD48D431" , vpaddq(zmm6, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1DD48D4B4F034120000" , vpaddq(zmm6, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1DD58D431" , vpaddq(zmm6, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1DD48D4727F" , vpaddq(zmm6, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1DD48D4B200200000" , vpaddq(zmm6, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1DD48D47280" , vpaddq(zmm6, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1DD48D4B2C0DFFFFF" , vpaddq(zmm6, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1DD58D4727F" , vpaddq(zmm6, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1DD58D4B200040000" , vpaddq(zmm6, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1DD58D47280" , vpaddq(zmm6, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1DD58D4B2F8FBFFFF" , vpaddq(zmm6, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B11540DBC8" , vpandd(zmm1, zmm29, zmm16));
+ TEST_INSTRUCTION("62B11542DBC8" , k(k2).vpandd(zmm1, zmm29, zmm16));
+ TEST_INSTRUCTION("62B115C2DBC8" , k(k2).z().vpandd(zmm1, zmm29, zmm16));
+ TEST_INSTRUCTION("62F11540DB09" , vpandd(zmm1, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B11540DB8CF034120000" , vpandd(zmm1, zmm29, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F11550DB09" , vpandd(zmm1, zmm29, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F11540DB4A7F" , vpandd(zmm1, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F11540DB8A00200000" , vpandd(zmm1, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F11540DB4A80" , vpandd(zmm1, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F11540DB8AC0DFFFFF" , vpandd(zmm1, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F11550DB4A7F" , vpandd(zmm1, zmm29, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F11550DB8A00020000" , vpandd(zmm1, zmm29, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F11550DB4A80" , vpandd(zmm1, zmm29, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F11550DB8AFCFDFFFF" , vpandd(zmm1, zmm29, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A17540DFF0" , vpandnd(zmm22, zmm17, zmm16));
+ TEST_INSTRUCTION("62A17545DFF0" , k(k5).vpandnd(zmm22, zmm17, zmm16));
+ TEST_INSTRUCTION("62A175C5DFF0" , k(k5).z().vpandnd(zmm22, zmm17, zmm16));
+ TEST_INSTRUCTION("62E17540DF31" , vpandnd(zmm22, zmm17, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A17540DFB4F034120000" , vpandnd(zmm22, zmm17, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E17550DF31" , vpandnd(zmm22, zmm17, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E17540DF727F" , vpandnd(zmm22, zmm17, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E17540DFB200200000" , vpandnd(zmm22, zmm17, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E17540DF7280" , vpandnd(zmm22, zmm17, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E17540DFB2C0DFFFFF" , vpandnd(zmm22, zmm17, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E17550DF727F" , vpandnd(zmm22, zmm17, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E17550DFB200020000" , vpandnd(zmm22, zmm17, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E17550DF7280" , vpandnd(zmm22, zmm17, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E17550DFB2FCFDFFFF" , vpandnd(zmm22, zmm17, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6261DD48DFCA" , vpandnq(zmm25, zmm4, zmm2));
+ TEST_INSTRUCTION("6261DD4BDFCA" , k(k3).vpandnq(zmm25, zmm4, zmm2));
+ TEST_INSTRUCTION("6261DDCBDFCA" , k(k3).z().vpandnq(zmm25, zmm4, zmm2));
+ TEST_INSTRUCTION("6261DD48DF09" , vpandnq(zmm25, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221DD48DF8CF034120000" , vpandnq(zmm25, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261DD58DF09" , vpandnq(zmm25, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6261DD48DF4A7F" , vpandnq(zmm25, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6261DD48DF8A00200000" , vpandnq(zmm25, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6261DD48DF4A80" , vpandnq(zmm25, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6261DD48DF8AC0DFFFFF" , vpandnq(zmm25, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6261DD58DF4A7F" , vpandnq(zmm25, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6261DD58DF8A00040000" , vpandnq(zmm25, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6261DD58DF4A80" , vpandnq(zmm25, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6261DD58DF8AF8FBFFFF" , vpandnq(zmm25, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62419D48DBD9" , vpandq(zmm27, zmm12, zmm9));
+ TEST_INSTRUCTION("62419D4ADBD9" , k(k2).vpandq(zmm27, zmm12, zmm9));
+ TEST_INSTRUCTION("62419DCADBD9" , k(k2).z().vpandq(zmm27, zmm12, zmm9));
+ TEST_INSTRUCTION("62619D48DB19" , vpandq(zmm27, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62219D48DB9CF034120000" , vpandq(zmm27, zmm12, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62619D58DB19" , vpandq(zmm27, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62619D48DB5A7F" , vpandq(zmm27, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62619D48DB9A00200000" , vpandq(zmm27, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62619D48DB5A80" , vpandq(zmm27, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62619D48DB9AC0DFFFFF" , vpandq(zmm27, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62619D58DB5A7F" , vpandq(zmm27, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62619D58DB9A00040000" , vpandq(zmm27, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62619D58DB5A80" , vpandq(zmm27, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62619D58DB9AF8FBFFFF" , vpandq(zmm27, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C23D4064FC" , vpblendmd(zmm23, zmm24, zmm12));
+ TEST_INSTRUCTION("62C23D4164FC" , k(k1).vpblendmd(zmm23, zmm24, zmm12));
+ TEST_INSTRUCTION("62C23DC164FC" , k(k1).z().vpblendmd(zmm23, zmm24, zmm12));
+ TEST_INSTRUCTION("62E23D406439" , vpblendmd(zmm23, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A23D4064BCF034120000" , vpblendmd(zmm23, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E23D506439" , vpblendmd(zmm23, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E23D40647A7F" , vpblendmd(zmm23, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E23D4064BA00200000" , vpblendmd(zmm23, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E23D40647A80" , vpblendmd(zmm23, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E23D4064BAC0DFFFFF" , vpblendmd(zmm23, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E23D50647A7F" , vpblendmd(zmm23, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E23D5064BA00020000" , vpblendmd(zmm23, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E23D50647A80" , vpblendmd(zmm23, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E23D5064BAFCFDFFFF" , vpblendmd(zmm23, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62E27D485819" , vpbroadcastd(zmm19, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62E27D4D5819" , k(k5).vpbroadcastd(zmm19, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62E27DCD5819" , k(k5).z().vpbroadcastd(zmm19, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D48589CF034120000" , vpbroadcastd(zmm19, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E27D48585A7F" , vpbroadcastd(zmm19, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E27D48589A00020000" , vpbroadcastd(zmm19, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E27D48585A80" , vpbroadcastd(zmm19, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E27D48589AFCFDFFFF" , vpbroadcastd(zmm19, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F27D4858D9" , vpbroadcastd(zmm3, xmm1));
+ TEST_INSTRUCTION("62F27D4E58D9" , k(k6).vpbroadcastd(zmm3, xmm1));
+ TEST_INSTRUCTION("62F27DCE58D9" , k(k6).z().vpbroadcastd(zmm3, xmm1));
+ TEST_INSTRUCTION("62727D487CC0" , vpbroadcastd(zmm8, eax));
+ TEST_INSTRUCTION("62727D4B7CC0" , k(k3).vpbroadcastd(zmm8, eax));
+ TEST_INSTRUCTION("62727DCB7CC0" , k(k3).z().vpbroadcastd(zmm8, eax));
+ TEST_INSTRUCTION("62727D487CC5" , vpbroadcastd(zmm8, ebp));
+ TEST_INSTRUCTION("62527D487CC5" , vpbroadcastd(zmm8, r13d));
+ TEST_INSTRUCTION("6272FD485931" , vpbroadcastq(zmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6272FD4D5931" , k(k5).vpbroadcastq(zmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6272FDCD5931" , k(k5).z().vpbroadcastq(zmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6232FD4859B4F034120000" , vpbroadcastq(zmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272FD4859727F" , vpbroadcastq(zmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6272FD4859B200040000" , vpbroadcastq(zmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6272FD48597280" , vpbroadcastq(zmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6272FD4859B2F8FBFFFF" , vpbroadcastq(zmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6272FD4859C4" , vpbroadcastq(zmm8, xmm4));
+ TEST_INSTRUCTION("6272FD4B59C4" , k(k3).vpbroadcastq(zmm8, xmm4));
+ TEST_INSTRUCTION("6272FDCB59C4" , k(k3).z().vpbroadcastq(zmm8, xmm4));
+ TEST_INSTRUCTION("62F2FD487CE8" , vpbroadcastq(zmm5, rax));
+ TEST_INSTRUCTION("62F2FD4E7CE8" , k(k6).vpbroadcastq(zmm5, rax));
+ TEST_INSTRUCTION("62F2FDCE7CE8" , k(k6).z().vpbroadcastq(zmm5, rax));
+ TEST_INSTRUCTION("62D2FD487CE8" , vpbroadcastq(zmm5, r8));
+ TEST_INSTRUCTION("62B335401FD6AB" , vpcmpd(k2, zmm25, zmm22, 171));
+ TEST_INSTRUCTION("62B335431FD6AB" , k(k3).vpcmpd(k2, zmm25, zmm22, 171));
+ TEST_INSTRUCTION("62B335401FD67B" , vpcmpd(k2, zmm25, zmm22, 123));
+ TEST_INSTRUCTION("62F335401F117B" , vpcmpd(k2, zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B335401F94F0341200007B" , vpcmpd(k2, zmm25, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F335501F117B" , vpcmpd(k2, zmm25, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F335401F527F7B" , vpcmpd(k2, zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F335401F92002000007B" , vpcmpd(k2, zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F335401F52807B" , vpcmpd(k2, zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F335401F92C0DFFFFF7B" , vpcmpd(k2, zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F335501F527F7B" , vpcmpd(k2, zmm25, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501F92000200007B" , vpcmpd(k2, zmm25, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501F52807B" , vpcmpd(k2, zmm25, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F335501F92FCFDFFFF7B" , vpcmpd(k2, zmm25, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62B13D4876ED" , vpcmpeqd(k5, zmm8, zmm21));
+ TEST_INSTRUCTION("62B13D4C76ED" , k(k4).vpcmpeqd(k5, zmm8, zmm21));
+ TEST_INSTRUCTION("62F13D487629" , vpcmpeqd(k5, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B13D4876ACF034120000" , vpcmpeqd(k5, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F13D587629" , vpcmpeqd(k5, zmm8, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F13D48766A7F" , vpcmpeqd(k5, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F13D4876AA00200000" , vpcmpeqd(k5, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F13D48766A80" , vpcmpeqd(k5, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F13D4876AAC0DFFFFF" , vpcmpeqd(k5, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F13D58766A7F" , vpcmpeqd(k5, zmm8, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F13D5876AA00020000" , vpcmpeqd(k5, zmm8, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F13D58766A80" , vpcmpeqd(k5, zmm8, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F13D5876AAFCFDFFFF" , vpcmpeqd(k5, zmm8, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D28D4829E1" , vpcmpeqq(k4, zmm14, zmm9));
+ TEST_INSTRUCTION("62D28D4E29E1" , k(k6).vpcmpeqq(k4, zmm14, zmm9));
+ TEST_INSTRUCTION("62F28D482921" , vpcmpeqq(k4, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B28D4829A4F034120000" , vpcmpeqq(k4, zmm14, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F28D582921" , vpcmpeqq(k4, zmm14, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F28D4829627F" , vpcmpeqq(k4, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F28D4829A200200000" , vpcmpeqq(k4, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F28D48296280" , vpcmpeqq(k4, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F28D4829A2C0DFFFFF" , vpcmpeqq(k4, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F28D5829627F" , vpcmpeqq(k4, zmm14, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F28D5829A200040000" , vpcmpeqq(k4, zmm14, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F28D58296280" , vpcmpeqq(k4, zmm14, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F28D5829A2F8FBFFFF" , vpcmpeqq(k4, zmm14, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D13D4866E0" , vpcmpgtd(k4, zmm8, zmm8));
+ TEST_INSTRUCTION("62D13D4F66E0" , k(k7).vpcmpgtd(k4, zmm8, zmm8));
+ TEST_INSTRUCTION("62F13D486621" , vpcmpgtd(k4, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B13D4866A4F034120000" , vpcmpgtd(k4, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F13D586621" , vpcmpgtd(k4, zmm8, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F13D4866627F" , vpcmpgtd(k4, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F13D4866A200200000" , vpcmpgtd(k4, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F13D48666280" , vpcmpgtd(k4, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F13D4866A2C0DFFFFF" , vpcmpgtd(k4, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F13D5866627F" , vpcmpgtd(k4, zmm8, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F13D5866A200020000" , vpcmpgtd(k4, zmm8, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F13D58666280" , vpcmpgtd(k4, zmm8, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F13D5866A2FCFDFFFF" , vpcmpgtd(k4, zmm8, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62929D4837DA" , vpcmpgtq(k3, zmm12, zmm26));
+ TEST_INSTRUCTION("62929D4C37DA" , k(k4).vpcmpgtq(k3, zmm12, zmm26));
+ TEST_INSTRUCTION("62F29D483719" , vpcmpgtq(k3, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B29D48379CF034120000" , vpcmpgtq(k3, zmm12, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F29D583719" , vpcmpgtq(k3, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F29D48375A7F" , vpcmpgtq(k3, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F29D48379A00200000" , vpcmpgtq(k3, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F29D48375A80" , vpcmpgtq(k3, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F29D48379AC0DFFFFF" , vpcmpgtq(k3, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F29D58375A7F" , vpcmpgtq(k3, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F29D58379A00040000" , vpcmpgtq(k3, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F29D58375A80" , vpcmpgtq(k3, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F29D58379AF8FBFFFF" , vpcmpgtq(k3, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D3B5401FDFAB" , vpcmpq(k3, zmm25, zmm15, 171));
+ TEST_INSTRUCTION("62D3B5441FDFAB" , k(k4).vpcmpq(k3, zmm25, zmm15, 171));
+ TEST_INSTRUCTION("62D3B5401FDF7B" , vpcmpq(k3, zmm25, zmm15, 123));
+ TEST_INSTRUCTION("62F3B5401F197B" , vpcmpq(k3, zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B3B5401F9CF0341200007B" , vpcmpq(k3, zmm25, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F3B5501F197B" , vpcmpq(k3, zmm25, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F3B5401F5A7F7B" , vpcmpq(k3, zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F3B5401F9A002000007B" , vpcmpq(k3, zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F3B5401F5A807B" , vpcmpq(k3, zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F3B5401F9AC0DFFFFF7B" , vpcmpq(k3, zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F3B5501F5A7F7B" , vpcmpq(k3, zmm25, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F3B5501F9A000400007B" , vpcmpq(k3, zmm25, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3B5501F5A807B" , vpcmpq(k3, zmm25, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F3B5501F9AF8FBFFFF7B" , vpcmpq(k3, zmm25, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F315401EDDAB" , vpcmpud(k3, zmm29, zmm5, 171));
+ TEST_INSTRUCTION("62F315471EDDAB" , k(k7).vpcmpud(k3, zmm29, zmm5, 171));
+ TEST_INSTRUCTION("62F315401EDD7B" , vpcmpud(k3, zmm29, zmm5, 123));
+ TEST_INSTRUCTION("62F315401E197B" , vpcmpud(k3, zmm29, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B315401E9CF0341200007B" , vpcmpud(k3, zmm29, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F315501E197B" , vpcmpud(k3, zmm29, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F315401E5A7F7B" , vpcmpud(k3, zmm29, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F315401E9A002000007B" , vpcmpud(k3, zmm29, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F315401E5A807B" , vpcmpud(k3, zmm29, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F315401E9AC0DFFFFF7B" , vpcmpud(k3, zmm29, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F315501E5A7F7B" , vpcmpud(k3, zmm29, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F315501E9A000200007B" , vpcmpud(k3, zmm29, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F315501E5A807B" , vpcmpud(k3, zmm29, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F315501E9AFCFDFFFF7B" , vpcmpud(k3, zmm29, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D38D481ED4AB" , vpcmpuq(k2, zmm14, zmm12, 171));
+ TEST_INSTRUCTION("62D38D4B1ED4AB" , k(k3).vpcmpuq(k2, zmm14, zmm12, 171));
+ TEST_INSTRUCTION("62D38D481ED47B" , vpcmpuq(k2, zmm14, zmm12, 123));
+ TEST_INSTRUCTION("62F38D481E117B" , vpcmpuq(k2, zmm14, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B38D481E94F0341200007B" , vpcmpuq(k2, zmm14, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F38D581E117B" , vpcmpuq(k2, zmm14, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D481E527F7B" , vpcmpuq(k2, zmm14, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F38D481E92002000007B" , vpcmpuq(k2, zmm14, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F38D481E52807B" , vpcmpuq(k2, zmm14, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F38D481E92C0DFFFFF7B" , vpcmpuq(k2, zmm14, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F38D581E527F7B" , vpcmpuq(k2, zmm14, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E92000400007B" , vpcmpuq(k2, zmm14, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E52807B" , vpcmpuq(k2, zmm14, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F38D581E92F8FBFFFF7B" , vpcmpuq(k2, zmm14, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("6262ED4064C5" , vpblendmq(zmm24, zmm18, zmm5));
+ TEST_INSTRUCTION("6262ED4364C5" , k(k3).vpblendmq(zmm24, zmm18, zmm5));
+ TEST_INSTRUCTION("6262EDC364C5" , k(k3).z().vpblendmq(zmm24, zmm18, zmm5));
+ TEST_INSTRUCTION("6262ED406401" , vpblendmq(zmm24, zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222ED406484F034120000" , vpblendmq(zmm24, zmm18, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262ED506401" , vpblendmq(zmm24, zmm18, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262ED4064427F" , vpblendmq(zmm24, zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262ED40648200200000" , vpblendmq(zmm24, zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262ED40644280" , vpblendmq(zmm24, zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262ED406482C0DFFFFF" , vpblendmq(zmm24, zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262ED5064427F" , vpblendmq(zmm24, zmm18, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262ED50648200040000" , vpblendmq(zmm24, zmm18, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262ED50644280" , vpblendmq(zmm24, zmm18, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262ED506482F8FBFFFF" , vpblendmq(zmm24, zmm18, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E27D488B21" , vpcompressd(zmmword_ptr(rcx), zmm20));
+ TEST_INSTRUCTION("62E27D4E8B21" , k(k6).vpcompressd(zmmword_ptr(rcx), zmm20));
+ TEST_INSTRUCTION("62A27D488BA4F034120000" , vpcompressd(zmmword_ptr(rax, r14, 3, 4660), zmm20));
+ TEST_INSTRUCTION("62E27D488B627F" , vpcompressd(zmmword_ptr(rdx, 508), zmm20));
+ TEST_INSTRUCTION("62E27D488BA200020000" , vpcompressd(zmmword_ptr(rdx, 512), zmm20));
+ TEST_INSTRUCTION("62E27D488B6280" , vpcompressd(zmmword_ptr(rdx, -512), zmm20));
+ TEST_INSTRUCTION("62E27D488BA2FCFDFFFF" , vpcompressd(zmmword_ptr(rdx, -516), zmm20));
+ TEST_INSTRUCTION("62127D488BE0" , vpcompressd(zmm24, zmm12));
+ TEST_INSTRUCTION("62127D4D8BE0" , k(k5).vpcompressd(zmm24, zmm12));
+ TEST_INSTRUCTION("62127DCD8BE0" , k(k5).z().vpcompressd(zmm24, zmm12));
+ TEST_INSTRUCTION("62422D4836C8" , vpermd(zmm25, zmm10, zmm8));
+ TEST_INSTRUCTION("62422D4E36C8" , k(k6).vpermd(zmm25, zmm10, zmm8));
+ TEST_INSTRUCTION("62422DCE36C8" , k(k6).z().vpermd(zmm25, zmm10, zmm8));
+ TEST_INSTRUCTION("62622D483609" , vpermd(zmm25, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62222D48368CF034120000" , vpermd(zmm25, zmm10, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62622D583609" , vpermd(zmm25, zmm10, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62622D48364A7F" , vpermd(zmm25, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62622D48368A00200000" , vpermd(zmm25, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62622D48364A80" , vpermd(zmm25, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62622D48368AC0DFFFFF" , vpermd(zmm25, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62622D58364A7F" , vpermd(zmm25, zmm10, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62622D58368A00020000" , vpermd(zmm25, zmm10, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62622D58364A80" , vpermd(zmm25, zmm10, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62622D58368AFCFDFFFF" , vpermd(zmm25, zmm10, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6253FD4805F8AB" , vpermilpd(zmm15, zmm8, 171));
+ TEST_INSTRUCTION("6253FD4E05F8AB" , k(k6).vpermilpd(zmm15, zmm8, 171));
+ TEST_INSTRUCTION("6253FDCE05F8AB" , k(k6).z().vpermilpd(zmm15, zmm8, 171));
+ TEST_INSTRUCTION("6253FD4805F87B" , vpermilpd(zmm15, zmm8, 123));
+ TEST_INSTRUCTION("6273FD4805397B" , vpermilpd(zmm15, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233FD4805BCF0341200007B" , vpermilpd(zmm15, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273FD5805397B" , vpermilpd(zmm15, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD48057A7F7B" , vpermilpd(zmm15, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273FD4805BA002000007B" , vpermilpd(zmm15, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273FD48057A807B" , vpermilpd(zmm15, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273FD4805BAC0DFFFFF7B" , vpermilpd(zmm15, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273FD58057A7F7B" , vpermilpd(zmm15, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD5805BA000400007B" , vpermilpd(zmm15, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD58057A807B" , vpermilpd(zmm15, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD5805BAF8FBFFFF7B" , vpermilpd(zmm15, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62C2AD400DF8" , vpermilpd(zmm23, zmm26, zmm8));
+ TEST_INSTRUCTION("62C2AD410DF8" , k(k1).vpermilpd(zmm23, zmm26, zmm8));
+ TEST_INSTRUCTION("62C2ADC10DF8" , k(k1).z().vpermilpd(zmm23, zmm26, zmm8));
+ TEST_INSTRUCTION("62E2AD400D39" , vpermilpd(zmm23, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2AD400DBCF034120000" , vpermilpd(zmm23, zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2AD500D39" , vpermilpd(zmm23, zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2AD400D7A7F" , vpermilpd(zmm23, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2AD400DBA00200000" , vpermilpd(zmm23, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2AD400D7A80" , vpermilpd(zmm23, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2AD400DBAC0DFFFFF" , vpermilpd(zmm23, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2AD500D7A7F" , vpermilpd(zmm23, zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2AD500DBA00040000" , vpermilpd(zmm23, zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2AD500D7A80" , vpermilpd(zmm23, zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2AD500DBAF8FBFFFF" , vpermilpd(zmm23, zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62637D4804CFAB" , vpermilps(zmm25, zmm7, 171));
+ TEST_INSTRUCTION("62637D4A04CFAB" , k(k2).vpermilps(zmm25, zmm7, 171));
+ TEST_INSTRUCTION("62637DCA04CFAB" , k(k2).z().vpermilps(zmm25, zmm7, 171));
+ TEST_INSTRUCTION("62637D4804CF7B" , vpermilps(zmm25, zmm7, 123));
+ TEST_INSTRUCTION("62637D4804097B" , vpermilps(zmm25, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62237D48048CF0341200007B" , vpermilps(zmm25, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62637D5804097B" , vpermilps(zmm25, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62637D48044A7F7B" , vpermilps(zmm25, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62637D48048A002000007B" , vpermilps(zmm25, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62637D48044A807B" , vpermilps(zmm25, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62637D48048AC0DFFFFF7B" , vpermilps(zmm25, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62637D58044A7F7B" , vpermilps(zmm25, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62637D58048A000200007B" , vpermilps(zmm25, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D58044A807B" , vpermilps(zmm25, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D58048AFCFDFFFF7B" , vpermilps(zmm25, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62B22D400CD9" , vpermilps(zmm3, zmm26, zmm17));
+ TEST_INSTRUCTION("62B22D430CD9" , k(k3).vpermilps(zmm3, zmm26, zmm17));
+ TEST_INSTRUCTION("62B22DC30CD9" , k(k3).z().vpermilps(zmm3, zmm26, zmm17));
+ TEST_INSTRUCTION("62F22D400C19" , vpermilps(zmm3, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B22D400C9CF034120000" , vpermilps(zmm3, zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F22D500C19" , vpermilps(zmm3, zmm26, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F22D400C5A7F" , vpermilps(zmm3, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F22D400C9A00200000" , vpermilps(zmm3, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F22D400C5A80" , vpermilps(zmm3, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F22D400C9AC0DFFFFF" , vpermilps(zmm3, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F22D500C5A7F" , vpermilps(zmm3, zmm26, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F22D500C9A00020000" , vpermilps(zmm3, zmm26, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F22D500C5A80" , vpermilps(zmm3, zmm26, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F22D500C9AFCFDFFFF" , vpermilps(zmm3, zmm26, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6243FD4801E7AB" , vpermpd(zmm28, zmm15, 171));
+ TEST_INSTRUCTION("6243FD4C01E7AB" , k(k4).vpermpd(zmm28, zmm15, 171));
+ TEST_INSTRUCTION("6243FDCC01E7AB" , k(k4).z().vpermpd(zmm28, zmm15, 171));
+ TEST_INSTRUCTION("6243FD4801E77B" , vpermpd(zmm28, zmm15, 123));
+ TEST_INSTRUCTION("6263FD4801217B" , vpermpd(zmm28, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223FD4801A4F0341200007B" , vpermpd(zmm28, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6263FD5801217B" , vpermpd(zmm28, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD4801627F7B" , vpermpd(zmm28, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6263FD4801A2002000007B" , vpermpd(zmm28, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6263FD480162807B" , vpermpd(zmm28, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6263FD4801A2C0DFFFFF7B" , vpermpd(zmm28, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6263FD5801627F7B" , vpermpd(zmm28, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD5801A2000400007B" , vpermpd(zmm28, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD580162807B" , vpermpd(zmm28, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD5801A2F8FBFFFF7B" , vpermpd(zmm28, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62A24D4816F5" , vpermps(zmm22, zmm6, zmm21));
+ TEST_INSTRUCTION("62A24D4D16F5" , k(k5).vpermps(zmm22, zmm6, zmm21));
+ TEST_INSTRUCTION("62A24DCD16F5" , k(k5).z().vpermps(zmm22, zmm6, zmm21));
+ TEST_INSTRUCTION("62E24D481631" , vpermps(zmm22, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A24D4816B4F034120000" , vpermps(zmm22, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E24D581631" , vpermps(zmm22, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E24D4816727F" , vpermps(zmm22, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E24D4816B200200000" , vpermps(zmm22, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E24D48167280" , vpermps(zmm22, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E24D4816B2C0DFFFFF" , vpermps(zmm22, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E24D5816727F" , vpermps(zmm22, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E24D5816B200020000" , vpermps(zmm22, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E24D58167280" , vpermps(zmm22, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E24D5816B2FCFDFFFF" , vpermps(zmm22, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6223FD4800C7AB" , vpermq(zmm24, zmm23, 171));
+ TEST_INSTRUCTION("6223FD4B00C7AB" , k(k3).vpermq(zmm24, zmm23, 171));
+ TEST_INSTRUCTION("6223FDCB00C7AB" , k(k3).z().vpermq(zmm24, zmm23, 171));
+ TEST_INSTRUCTION("6223FD4800C77B" , vpermq(zmm24, zmm23, 123));
+ TEST_INSTRUCTION("6263FD4800017B" , vpermq(zmm24, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223FD480084F0341200007B" , vpermq(zmm24, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6263FD5800017B" , vpermq(zmm24, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD4800427F7B" , vpermq(zmm24, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6263FD480082002000007B" , vpermq(zmm24, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6263FD480042807B" , vpermq(zmm24, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6263FD480082C0DFFFFF7B" , vpermq(zmm24, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6263FD5800427F7B" , vpermq(zmm24, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD580082000400007B" , vpermq(zmm24, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD580042807B" , vpermq(zmm24, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263FD580082F8FBFFFF7B" , vpermq(zmm24, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62E27D488911" , vpexpandd(zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62E27D4A8911" , k(k2).vpexpandd(zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62E27DCA8911" , k(k2).z().vpexpandd(zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D488994F034120000" , vpexpandd(zmm18, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E27D4889527F" , vpexpandd(zmm18, zmmword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E27D48899200020000" , vpexpandd(zmm18, zmmword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E27D48895280" , vpexpandd(zmm18, zmmword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E27D488992FCFDFFFF" , vpexpandd(zmm18, zmmword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62127D4889E4" , vpexpandd(zmm12, zmm28));
+ TEST_INSTRUCTION("62127D4E89E4" , k(k6).vpexpandd(zmm12, zmm28));
+ TEST_INSTRUCTION("62127DCE89E4" , k(k6).z().vpexpandd(zmm12, zmm28));
+ TEST_INSTRUCTION("62F2FD488909" , vpexpandq(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F2FD4F8909" , k(k7).vpexpandq(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62F2FDCF8909" , k(k7).z().vpexpandq(zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2FD48898CF034120000" , vpexpandq(zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2FD48894A7F" , vpexpandq(zmm1, zmmword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2FD48898A00040000" , vpexpandq(zmm1, zmmword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2FD48894A80" , vpexpandq(zmm1, zmmword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2FD48898AF8FBFFFF" , vpexpandq(zmm1, zmmword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6282FD4889CA" , vpexpandq(zmm17, zmm26));
+ TEST_INSTRUCTION("6282FD4F89CA" , k(k7).vpexpandq(zmm17, zmm26));
+ TEST_INSTRUCTION("6282FDCF89CA" , k(k7).z().vpexpandq(zmm17, zmm26));
+ TEST_INSTRUCTION("624215483DF1" , vpmaxsd(zmm30, zmm13, zmm9));
+ TEST_INSTRUCTION("6242154F3DF1" , k(k7).vpmaxsd(zmm30, zmm13, zmm9));
+ TEST_INSTRUCTION("624215CF3DF1" , k(k7).z().vpmaxsd(zmm30, zmm13, zmm9));
+ TEST_INSTRUCTION("626215483D31" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("622215483DB4F034120000" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626215583D31" , vpmaxsd(zmm30, zmm13, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("626215483D727F" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("626215483DB200200000" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("626215483D7280" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("626215483DB2C0DFFFFF" , vpmaxsd(zmm30, zmm13, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("626215583D727F" , vpmaxsd(zmm30, zmm13, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("626215583DB200020000" , vpmaxsd(zmm30, zmm13, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("626215583D7280" , vpmaxsd(zmm30, zmm13, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("626215583DB2FCFDFFFF" , vpmaxsd(zmm30, zmm13, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2C5483DDD" , vpmaxsq(zmm3, zmm7, zmm5));
+ TEST_INSTRUCTION("62F2C54B3DDD" , k(k3).vpmaxsq(zmm3, zmm7, zmm5));
+ TEST_INSTRUCTION("62F2C5CB3DDD" , k(k3).z().vpmaxsq(zmm3, zmm7, zmm5));
+ TEST_INSTRUCTION("62F2C5483D19" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2C5483D9CF034120000" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2C5583D19" , vpmaxsq(zmm3, zmm7, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2C5483D5A7F" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2C5483D9A00200000" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2C5483D5A80" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2C5483D9AC0DFFFFF" , vpmaxsq(zmm3, zmm7, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2C5583D5A7F" , vpmaxsq(zmm3, zmm7, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2C5583D9A00040000" , vpmaxsq(zmm3, zmm7, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2C5583D5A80" , vpmaxsq(zmm3, zmm7, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2C5583D9AF8FBFFFF" , vpmaxsq(zmm3, zmm7, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C225403FF4" , vpmaxud(zmm22, zmm27, zmm12));
+ TEST_INSTRUCTION("62C225473FF4" , k(k7).vpmaxud(zmm22, zmm27, zmm12));
+ TEST_INSTRUCTION("62C225C73FF4" , k(k7).z().vpmaxud(zmm22, zmm27, zmm12));
+ TEST_INSTRUCTION("62E225403F31" , vpmaxud(zmm22, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A225403FB4F034120000" , vpmaxud(zmm22, zmm27, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E225503F31" , vpmaxud(zmm22, zmm27, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E225403F727F" , vpmaxud(zmm22, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E225403FB200200000" , vpmaxud(zmm22, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E225403F7280" , vpmaxud(zmm22, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E225403FB2C0DFFFFF" , vpmaxud(zmm22, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E225503F727F" , vpmaxud(zmm22, zmm27, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E225503FB200020000" , vpmaxud(zmm22, zmm27, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E225503F7280" , vpmaxud(zmm22, zmm27, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E225503FB2FCFDFFFF" , vpmaxud(zmm22, zmm27, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D2B5483FCC" , vpmaxuq(zmm1, zmm9, zmm12));
+ TEST_INSTRUCTION("62D2B54A3FCC" , k(k2).vpmaxuq(zmm1, zmm9, zmm12));
+ TEST_INSTRUCTION("62D2B5CA3FCC" , k(k2).z().vpmaxuq(zmm1, zmm9, zmm12));
+ TEST_INSTRUCTION("62F2B5483F09" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2B5483F8CF034120000" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2B5583F09" , vpmaxuq(zmm1, zmm9, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2B5483F4A7F" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2B5483F8A00200000" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2B5483F4A80" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2B5483F8AC0DFFFFF" , vpmaxuq(zmm1, zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2B5583F4A7F" , vpmaxuq(zmm1, zmm9, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2B5583F8A00040000" , vpmaxuq(zmm1, zmm9, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2B5583F4A80" , vpmaxuq(zmm1, zmm9, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2B5583F8AF8FBFFFF" , vpmaxuq(zmm1, zmm9, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E2754039DA" , vpminsd(zmm19, zmm17, zmm2));
+ TEST_INSTRUCTION("62E2754739DA" , k(k7).vpminsd(zmm19, zmm17, zmm2));
+ TEST_INSTRUCTION("62E275C739DA" , k(k7).z().vpminsd(zmm19, zmm17, zmm2));
+ TEST_INSTRUCTION("62E275403919" , vpminsd(zmm19, zmm17, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27540399CF034120000" , vpminsd(zmm19, zmm17, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E275503919" , vpminsd(zmm19, zmm17, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E27540395A7F" , vpminsd(zmm19, zmm17, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E27540399A00200000" , vpminsd(zmm19, zmm17, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E27540395A80" , vpminsd(zmm19, zmm17, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E27540399AC0DFFFFF" , vpminsd(zmm19, zmm17, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E27550395A7F" , vpminsd(zmm19, zmm17, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E27550399A00020000" , vpminsd(zmm19, zmm17, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E27550395A80" , vpminsd(zmm19, zmm17, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E27550399AFCFDFFFF" , vpminsd(zmm19, zmm17, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2F54839EE" , vpminsq(zmm21, zmm1, zmm22));
+ TEST_INSTRUCTION("62A2F54E39EE" , k(k6).vpminsq(zmm21, zmm1, zmm22));
+ TEST_INSTRUCTION("62A2F5CE39EE" , k(k6).z().vpminsq(zmm21, zmm1, zmm22));
+ TEST_INSTRUCTION("62E2F5483929" , vpminsq(zmm21, zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2F54839ACF034120000" , vpminsq(zmm21, zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2F5583929" , vpminsq(zmm21, zmm1, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2F548396A7F" , vpminsq(zmm21, zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2F54839AA00200000" , vpminsq(zmm21, zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2F548396A80" , vpminsq(zmm21, zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2F54839AAC0DFFFFF" , vpminsq(zmm21, zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2F558396A7F" , vpminsq(zmm21, zmm1, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2F55839AA00040000" , vpminsq(zmm21, zmm1, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2F558396A80" , vpminsq(zmm21, zmm1, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2F55839AAF8FBFFFF" , vpminsq(zmm21, zmm1, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F24D403BE3" , vpminud(zmm4, zmm22, zmm3));
+ TEST_INSTRUCTION("62F24D443BE3" , k(k4).vpminud(zmm4, zmm22, zmm3));
+ TEST_INSTRUCTION("62F24DC43BE3" , k(k4).z().vpminud(zmm4, zmm22, zmm3));
+ TEST_INSTRUCTION("62F24D403B21" , vpminud(zmm4, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B24D403BA4F034120000" , vpminud(zmm4, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F24D503B21" , vpminud(zmm4, zmm22, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F24D403B627F" , vpminud(zmm4, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F24D403BA200200000" , vpminud(zmm4, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F24D403B6280" , vpminud(zmm4, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F24D403BA2C0DFFFFF" , vpminud(zmm4, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F24D503B627F" , vpminud(zmm4, zmm22, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F24D503BA200020000" , vpminud(zmm4, zmm22, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F24D503B6280" , vpminud(zmm4, zmm22, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F24D503BA2FCFDFFFF" , vpminud(zmm4, zmm22, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6202AD403BCB" , vpminuq(zmm25, zmm26, zmm27));
+ TEST_INSTRUCTION("6202AD463BCB" , k(k6).vpminuq(zmm25, zmm26, zmm27));
+ TEST_INSTRUCTION("6202ADC63BCB" , k(k6).z().vpminuq(zmm25, zmm26, zmm27));
+ TEST_INSTRUCTION("6262AD403B09" , vpminuq(zmm25, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222AD403B8CF034120000" , vpminuq(zmm25, zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262AD503B09" , vpminuq(zmm25, zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262AD403B4A7F" , vpminuq(zmm25, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262AD403B8A00200000" , vpminuq(zmm25, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262AD403B4A80" , vpminuq(zmm25, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262AD403B8AC0DFFFFF" , vpminuq(zmm25, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262AD503B4A7F" , vpminuq(zmm25, zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262AD503B8A00040000" , vpminuq(zmm25, zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262AD503B4A80" , vpminuq(zmm25, zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262AD503B8AF8FBFFFF" , vpminuq(zmm25, zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62427D4821CA" , vpmovsxbd(zmm25, xmm10));
+ TEST_INSTRUCTION("62427D4921CA" , k(k1).vpmovsxbd(zmm25, xmm10));
+ TEST_INSTRUCTION("62427DC921CA" , k(k1).z().vpmovsxbd(zmm25, xmm10));
+ TEST_INSTRUCTION("62627D482109" , vpmovsxbd(zmm25, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D48218CF034120000" , vpmovsxbd(zmm25, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62627D48214A7F" , vpmovsxbd(zmm25, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62627D48218A00080000" , vpmovsxbd(zmm25, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62627D48214A80" , vpmovsxbd(zmm25, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62627D48218AF0F7FFFF" , vpmovsxbd(zmm25, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62527D4822F6" , vpmovsxbq(zmm14, xmm14));
+ TEST_INSTRUCTION("62527D4D22F6" , k(k5).vpmovsxbq(zmm14, xmm14));
+ TEST_INSTRUCTION("62527DCD22F6" , k(k5).z().vpmovsxbq(zmm14, xmm14));
+ TEST_INSTRUCTION("62727D482231" , vpmovsxbq(zmm14, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D4822B4F034120000" , vpmovsxbq(zmm14, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D4822727F" , vpmovsxbq(zmm14, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62727D4822B200040000" , vpmovsxbq(zmm14, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62727D48227280" , vpmovsxbq(zmm14, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62727D4822B2F8FBFFFF" , vpmovsxbq(zmm14, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62527D4825D9" , vpmovsxdq(zmm11, ymm9));
+ TEST_INSTRUCTION("62527D4E25D9" , k(k6).vpmovsxdq(zmm11, ymm9));
+ TEST_INSTRUCTION("62527DCE25D9" , k(k6).z().vpmovsxdq(zmm11, ymm9));
+ TEST_INSTRUCTION("62727D482519" , vpmovsxdq(zmm11, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D48259CF034120000" , vpmovsxdq(zmm11, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D48255A7F" , vpmovsxdq(zmm11, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D48259A00100000" , vpmovsxdq(zmm11, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48255A80" , vpmovsxdq(zmm11, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D48259AE0EFFFFF" , vpmovsxdq(zmm11, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62527D4823E3" , vpmovsxwd(zmm12, ymm11));
+ TEST_INSTRUCTION("62527D4A23E3" , k(k2).vpmovsxwd(zmm12, ymm11));
+ TEST_INSTRUCTION("62527DCA23E3" , k(k2).z().vpmovsxwd(zmm12, ymm11));
+ TEST_INSTRUCTION("62727D482321" , vpmovsxwd(zmm12, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D4823A4F034120000" , vpmovsxwd(zmm12, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D4823627F" , vpmovsxwd(zmm12, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D4823A200100000" , vpmovsxwd(zmm12, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48236280" , vpmovsxwd(zmm12, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D4823A2E0EFFFFF" , vpmovsxwd(zmm12, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62527D4824DE" , vpmovsxwq(zmm11, xmm14));
+ TEST_INSTRUCTION("62527D4D24DE" , k(k5).vpmovsxwq(zmm11, xmm14));
+ TEST_INSTRUCTION("62527DCD24DE" , k(k5).z().vpmovsxwq(zmm11, xmm14));
+ TEST_INSTRUCTION("62727D482419" , vpmovsxwq(zmm11, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D48249CF034120000" , vpmovsxwq(zmm11, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D48245A7F" , vpmovsxwq(zmm11, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62727D48249A00080000" , vpmovsxwq(zmm11, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62727D48245A80" , vpmovsxwq(zmm11, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62727D48249AF0F7FFFF" , vpmovsxwq(zmm11, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62027D4831C9" , vpmovzxbd(zmm25, xmm25));
+ TEST_INSTRUCTION("62027D4C31C9" , k(k4).vpmovzxbd(zmm25, xmm25));
+ TEST_INSTRUCTION("62027DCC31C9" , k(k4).z().vpmovzxbd(zmm25, xmm25));
+ TEST_INSTRUCTION("62627D483109" , vpmovzxbd(zmm25, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62227D48318CF034120000" , vpmovzxbd(zmm25, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62627D48314A7F" , vpmovzxbd(zmm25, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62627D48318A00080000" , vpmovzxbd(zmm25, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62627D48314A80" , vpmovzxbd(zmm25, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62627D48318AF0F7FFFF" , vpmovzxbd(zmm25, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62A27D4832FC" , vpmovzxbq(zmm23, xmm20));
+ TEST_INSTRUCTION("62A27D4B32FC" , k(k3).vpmovzxbq(zmm23, xmm20));
+ TEST_INSTRUCTION("62A27DCB32FC" , k(k3).z().vpmovzxbq(zmm23, xmm20));
+ TEST_INSTRUCTION("62E27D483239" , vpmovzxbq(zmm23, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A27D4832BCF034120000" , vpmovzxbq(zmm23, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E27D48327A7F" , vpmovzxbq(zmm23, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E27D4832BA00040000" , vpmovzxbq(zmm23, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E27D48327A80" , vpmovzxbq(zmm23, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E27D4832BAF8FBFFFF" , vpmovzxbq(zmm23, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62327D4835CE" , vpmovzxdq(zmm9, ymm22));
+ TEST_INSTRUCTION("62327D4B35CE" , k(k3).vpmovzxdq(zmm9, ymm22));
+ TEST_INSTRUCTION("62327DCB35CE" , k(k3).z().vpmovzxdq(zmm9, ymm22));
+ TEST_INSTRUCTION("62727D483509" , vpmovzxdq(zmm9, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D48358CF034120000" , vpmovzxdq(zmm9, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D48354A7F" , vpmovzxdq(zmm9, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62727D48358A00100000" , vpmovzxdq(zmm9, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62727D48354A80" , vpmovzxdq(zmm9, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62727D48358AE0EFFFFF" , vpmovzxdq(zmm9, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62927D4833F5" , vpmovzxwd(zmm6, ymm29));
+ TEST_INSTRUCTION("62927D4C33F5" , k(k4).vpmovzxwd(zmm6, ymm29));
+ TEST_INSTRUCTION("62927DCC33F5" , k(k4).z().vpmovzxwd(zmm6, ymm29));
+ TEST_INSTRUCTION("62F27D483331" , vpmovzxwd(zmm6, ymmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D4833B4F034120000" , vpmovzxwd(zmm6, ymmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D4833727F" , vpmovzxwd(zmm6, ymmword_ptr(rdx, 4064)));
+ TEST_INSTRUCTION("62F27D4833B200100000" , vpmovzxwd(zmm6, ymmword_ptr(rdx, 4096)));
+ TEST_INSTRUCTION("62F27D48337280" , vpmovzxwd(zmm6, ymmword_ptr(rdx, -4096)));
+ TEST_INSTRUCTION("62F27D4833B2E0EFFFFF" , vpmovzxwd(zmm6, ymmword_ptr(rdx, -4128)));
+ TEST_INSTRUCTION("62327D4834E2" , vpmovzxwq(zmm12, xmm18));
+ TEST_INSTRUCTION("62327D4E34E2" , k(k6).vpmovzxwq(zmm12, xmm18));
+ TEST_INSTRUCTION("62327DCE34E2" , k(k6).z().vpmovzxwq(zmm12, xmm18));
+ TEST_INSTRUCTION("62727D483421" , vpmovzxwq(zmm12, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62327D4834A4F034120000" , vpmovzxwq(zmm12, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62727D4834627F" , vpmovzxwq(zmm12, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62727D4834A200080000" , vpmovzxwq(zmm12, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62727D48346280" , vpmovzxwq(zmm12, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62727D4834A2F0F7FFFF" , vpmovzxwq(zmm12, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62D2CD4028EC" , vpmuldq(zmm5, zmm22, zmm12));
+ TEST_INSTRUCTION("62D2CD4428EC" , k(k4).vpmuldq(zmm5, zmm22, zmm12));
+ TEST_INSTRUCTION("62D2CDC428EC" , k(k4).z().vpmuldq(zmm5, zmm22, zmm12));
+ TEST_INSTRUCTION("62F2CD402829" , vpmuldq(zmm5, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2CD4028ACF034120000" , vpmuldq(zmm5, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2CD502829" , vpmuldq(zmm5, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2CD40286A7F" , vpmuldq(zmm5, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2CD4028AA00200000" , vpmuldq(zmm5, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2CD40286A80" , vpmuldq(zmm5, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2CD4028AAC0DFFFFF" , vpmuldq(zmm5, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2CD50286A7F" , vpmuldq(zmm5, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2CD5028AA00040000" , vpmuldq(zmm5, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD50286A80" , vpmuldq(zmm5, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2CD5028AAF8FBFFFF" , vpmuldq(zmm5, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62723D4040E2" , vpmulld(zmm12, zmm24, zmm2));
+ TEST_INSTRUCTION("62723D4640E2" , k(k6).vpmulld(zmm12, zmm24, zmm2));
+ TEST_INSTRUCTION("62723DC640E2" , k(k6).z().vpmulld(zmm12, zmm24, zmm2));
+ TEST_INSTRUCTION("62723D404021" , vpmulld(zmm12, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62323D4040A4F034120000" , vpmulld(zmm12, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62723D504021" , vpmulld(zmm12, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62723D4040627F" , vpmulld(zmm12, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62723D4040A200200000" , vpmulld(zmm12, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62723D40406280" , vpmulld(zmm12, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62723D4040A2C0DFFFFF" , vpmulld(zmm12, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62723D5040627F" , vpmulld(zmm12, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62723D5040A200020000" , vpmulld(zmm12, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62723D50406280" , vpmulld(zmm12, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62723D5040A2FCFDFFFF" , vpmulld(zmm12, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6251ED48F4C2" , vpmuludq(zmm8, zmm2, zmm10));
+ TEST_INSTRUCTION("6251ED4FF4C2" , k(k7).vpmuludq(zmm8, zmm2, zmm10));
+ TEST_INSTRUCTION("6251EDCFF4C2" , k(k7).z().vpmuludq(zmm8, zmm2, zmm10));
+ TEST_INSTRUCTION("6271ED48F401" , vpmuludq(zmm8, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231ED48F484F034120000" , vpmuludq(zmm8, zmm2, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271ED58F401" , vpmuludq(zmm8, zmm2, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271ED48F4427F" , vpmuludq(zmm8, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271ED48F48200200000" , vpmuludq(zmm8, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271ED48F44280" , vpmuludq(zmm8, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271ED48F482C0DFFFFF" , vpmuludq(zmm8, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271ED58F4427F" , vpmuludq(zmm8, zmm2, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271ED58F48200040000" , vpmuludq(zmm8, zmm2, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271ED58F44280" , vpmuludq(zmm8, zmm2, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271ED58F482F8FBFFFF" , vpmuludq(zmm8, zmm2, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62412D48EBEF" , vpord(zmm29, zmm10, zmm15));
+ TEST_INSTRUCTION("62412D4CEBEF" , k(k4).vpord(zmm29, zmm10, zmm15));
+ TEST_INSTRUCTION("62412DCCEBEF" , k(k4).z().vpord(zmm29, zmm10, zmm15));
+ TEST_INSTRUCTION("62612D48EB29" , vpord(zmm29, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62212D48EBACF034120000" , vpord(zmm29, zmm10, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62612D58EB29" , vpord(zmm29, zmm10, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62612D48EB6A7F" , vpord(zmm29, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62612D48EBAA00200000" , vpord(zmm29, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62612D48EB6A80" , vpord(zmm29, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62612D48EBAAC0DFFFFF" , vpord(zmm29, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62612D58EB6A7F" , vpord(zmm29, zmm10, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62612D58EBAA00020000" , vpord(zmm29, zmm10, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62612D58EB6A80" , vpord(zmm29, zmm10, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62612D58EBAAFCFDFFFF" , vpord(zmm29, zmm10, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6291C540EBDA" , vporq(zmm3, zmm23, zmm26));
+ TEST_INSTRUCTION("6291C544EBDA" , k(k4).vporq(zmm3, zmm23, zmm26));
+ TEST_INSTRUCTION("6291C5C4EBDA" , k(k4).z().vporq(zmm3, zmm23, zmm26));
+ TEST_INSTRUCTION("62F1C540EB19" , vporq(zmm3, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1C540EB9CF034120000" , vporq(zmm3, zmm23, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1C550EB19" , vporq(zmm3, zmm23, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1C540EB5A7F" , vporq(zmm3, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1C540EB9A00200000" , vporq(zmm3, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1C540EB5A80" , vporq(zmm3, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1C540EB9AC0DFFFFF" , vporq(zmm3, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1C550EB5A7F" , vporq(zmm3, zmm23, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1C550EB9A00040000" , vporq(zmm3, zmm23, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1C550EB5A80" , vporq(zmm3, zmm23, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1C550EB9AF8FBFFFF" , vporq(zmm3, zmm23, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D17D4870FCAB" , vpshufd(zmm7, zmm12, 171));
+ TEST_INSTRUCTION("62D17D4970FCAB" , k(k1).vpshufd(zmm7, zmm12, 171));
+ TEST_INSTRUCTION("62D17DC970FCAB" , k(k1).z().vpshufd(zmm7, zmm12, 171));
+ TEST_INSTRUCTION("62D17D4870FC7B" , vpshufd(zmm7, zmm12, 123));
+ TEST_INSTRUCTION("62F17D4870397B" , vpshufd(zmm7, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B17D4870BCF0341200007B" , vpshufd(zmm7, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F17D5870397B" , vpshufd(zmm7, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F17D48707A7F7B" , vpshufd(zmm7, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F17D4870BA002000007B" , vpshufd(zmm7, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F17D48707A807B" , vpshufd(zmm7, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F17D4870BAC0DFFFFF7B" , vpshufd(zmm7, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F17D58707A7F7B" , vpshufd(zmm7, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F17D5870BA000200007B" , vpshufd(zmm7, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17D58707A807B" , vpshufd(zmm7, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17D5870BAFCFDFFFF7B" , vpshufd(zmm7, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D14D40F2FE" , vpslld(zmm7, zmm22, xmm14));
+ TEST_INSTRUCTION("62D14D44F2FE" , k(k4).vpslld(zmm7, zmm22, xmm14));
+ TEST_INSTRUCTION("62D14DC4F2FE" , k(k4).z().vpslld(zmm7, zmm22, xmm14));
+ TEST_INSTRUCTION("62F14D40F239" , vpslld(zmm7, zmm22, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B14D40F2BCF034120000" , vpslld(zmm7, zmm22, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F14D40F27A7F" , vpslld(zmm7, zmm22, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62F14D40F2BA00080000" , vpslld(zmm7, zmm22, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62F14D40F27A80" , vpslld(zmm7, zmm22, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62F14D40F2BAF0F7FFFF" , vpslld(zmm7, zmm22, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6201ED48F3EB" , vpsllq(zmm29, zmm2, xmm27));
+ TEST_INSTRUCTION("6201ED4DF3EB" , k(k5).vpsllq(zmm29, zmm2, xmm27));
+ TEST_INSTRUCTION("6201EDCDF3EB" , k(k5).z().vpsllq(zmm29, zmm2, xmm27));
+ TEST_INSTRUCTION("6261ED48F329" , vpsllq(zmm29, zmm2, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6221ED48F3ACF034120000" , vpsllq(zmm29, zmm2, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261ED48F36A7F" , vpsllq(zmm29, zmm2, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("6261ED48F3AA00080000" , vpsllq(zmm29, zmm2, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("6261ED48F36A80" , vpsllq(zmm29, zmm2, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("6261ED48F3AAF0F7FFFF" , vpsllq(zmm29, zmm2, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("6242654847EF" , vpsllvd(zmm29, zmm3, zmm15));
+ TEST_INSTRUCTION("6242654F47EF" , k(k7).vpsllvd(zmm29, zmm3, zmm15));
+ TEST_INSTRUCTION("624265CF47EF" , k(k7).z().vpsllvd(zmm29, zmm3, zmm15));
+ TEST_INSTRUCTION("626265484729" , vpsllvd(zmm29, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222654847ACF034120000" , vpsllvd(zmm29, zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626265584729" , vpsllvd(zmm29, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62626548476A7F" , vpsllvd(zmm29, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262654847AA00200000" , vpsllvd(zmm29, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62626548476A80" , vpsllvd(zmm29, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262654847AAC0DFFFFF" , vpsllvd(zmm29, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62626558476A7F" , vpsllvd(zmm29, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("6262655847AA00020000" , vpsllvd(zmm29, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62626558476A80" , vpsllvd(zmm29, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("6262655847AAFCFDFFFF" , vpsllvd(zmm29, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D2954047E5" , vpsllvq(zmm4, zmm29, zmm13));
+ TEST_INSTRUCTION("62D2954547E5" , k(k5).vpsllvq(zmm4, zmm29, zmm13));
+ TEST_INSTRUCTION("62D295C547E5" , k(k5).z().vpsllvq(zmm4, zmm29, zmm13));
+ TEST_INSTRUCTION("62F295404721" , vpsllvq(zmm4, zmm29, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2954047A4F034120000" , vpsllvq(zmm4, zmm29, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F295504721" , vpsllvq(zmm4, zmm29, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2954047627F" , vpsllvq(zmm4, zmm29, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2954047A200200000" , vpsllvq(zmm4, zmm29, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F29540476280" , vpsllvq(zmm4, zmm29, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2954047A2C0DFFFFF" , vpsllvq(zmm4, zmm29, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2955047627F" , vpsllvq(zmm4, zmm29, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2955047A200040000" , vpsllvq(zmm4, zmm29, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F29550476280" , vpsllvq(zmm4, zmm29, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2955047A2F8FBFFFF" , vpsllvq(zmm4, zmm29, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62812D48E2D9" , vpsrad(zmm19, zmm10, xmm25));
+ TEST_INSTRUCTION("62812D4AE2D9" , k(k2).vpsrad(zmm19, zmm10, xmm25));
+ TEST_INSTRUCTION("62812DCAE2D9" , k(k2).z().vpsrad(zmm19, zmm10, xmm25));
+ TEST_INSTRUCTION("62E12D48E219" , vpsrad(zmm19, zmm10, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A12D48E29CF034120000" , vpsrad(zmm19, zmm10, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E12D48E25A7F" , vpsrad(zmm19, zmm10, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E12D48E29A00080000" , vpsrad(zmm19, zmm10, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E12D48E25A80" , vpsrad(zmm19, zmm10, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E12D48E29AF0F7FFFF" , vpsrad(zmm19, zmm10, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62A1C540E2FA" , vpsraq(zmm23, zmm23, xmm18));
+ TEST_INSTRUCTION("62A1C544E2FA" , k(k4).vpsraq(zmm23, zmm23, xmm18));
+ TEST_INSTRUCTION("62A1C5C4E2FA" , k(k4).z().vpsraq(zmm23, zmm23, xmm18));
+ TEST_INSTRUCTION("62E1C540E239" , vpsraq(zmm23, zmm23, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1C540E2BCF034120000" , vpsraq(zmm23, zmm23, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1C540E27A7F" , vpsraq(zmm23, zmm23, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E1C540E2BA00080000" , vpsraq(zmm23, zmm23, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E1C540E27A80" , vpsraq(zmm23, zmm23, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E1C540E2BAF0F7FFFF" , vpsraq(zmm23, zmm23, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62E2554846CE" , vpsravd(zmm17, zmm5, zmm6));
+ TEST_INSTRUCTION("62E2554E46CE" , k(k6).vpsravd(zmm17, zmm5, zmm6));
+ TEST_INSTRUCTION("62E255CE46CE" , k(k6).z().vpsravd(zmm17, zmm5, zmm6));
+ TEST_INSTRUCTION("62E255484609" , vpsravd(zmm17, zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A25548468CF034120000" , vpsravd(zmm17, zmm5, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E255584609" , vpsravd(zmm17, zmm5, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E25548464A7F" , vpsravd(zmm17, zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E25548468A00200000" , vpsravd(zmm17, zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E25548464A80" , vpsravd(zmm17, zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E25548468AC0DFFFFF" , vpsravd(zmm17, zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E25558464A7F" , vpsravd(zmm17, zmm5, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E25558468A00020000" , vpsravd(zmm17, zmm5, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E25558464A80" , vpsravd(zmm17, zmm5, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E25558468AFCFDFFFF" , vpsravd(zmm17, zmm5, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6292BD4846DA" , vpsravq(zmm3, zmm8, zmm26));
+ TEST_INSTRUCTION("6292BD4946DA" , k(k1).vpsravq(zmm3, zmm8, zmm26));
+ TEST_INSTRUCTION("6292BDC946DA" , k(k1).z().vpsravq(zmm3, zmm8, zmm26));
+ TEST_INSTRUCTION("62F2BD484619" , vpsravq(zmm3, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2BD48469CF034120000" , vpsravq(zmm3, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2BD584619" , vpsravq(zmm3, zmm8, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2BD48465A7F" , vpsravq(zmm3, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2BD48469A00200000" , vpsravq(zmm3, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2BD48465A80" , vpsravq(zmm3, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2BD48469AC0DFFFFF" , vpsravq(zmm3, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2BD58465A7F" , vpsravq(zmm3, zmm8, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2BD58469A00040000" , vpsravq(zmm3, zmm8, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2BD58465A80" , vpsravq(zmm3, zmm8, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2BD58469AF8FBFFFF" , vpsravq(zmm3, zmm8, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62216540D2CF" , vpsrld(zmm25, zmm19, xmm23));
+ TEST_INSTRUCTION("62216546D2CF" , k(k6).vpsrld(zmm25, zmm19, xmm23));
+ TEST_INSTRUCTION("622165C6D2CF" , k(k6).z().vpsrld(zmm25, zmm19, xmm23));
+ TEST_INSTRUCTION("62616540D209" , vpsrld(zmm25, zmm19, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62216540D28CF034120000" , vpsrld(zmm25, zmm19, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62616540D24A7F" , vpsrld(zmm25, zmm19, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62616540D28A00080000" , vpsrld(zmm25, zmm19, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62616540D24A80" , vpsrld(zmm25, zmm19, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62616540D28AF0F7FFFF" , vpsrld(zmm25, zmm19, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62A1AD48D3DD" , vpsrlq(zmm19, zmm10, xmm21));
+ TEST_INSTRUCTION("62A1AD4CD3DD" , k(k4).vpsrlq(zmm19, zmm10, xmm21));
+ TEST_INSTRUCTION("62A1ADCCD3DD" , k(k4).z().vpsrlq(zmm19, zmm10, xmm21));
+ TEST_INSTRUCTION("62E1AD48D319" , vpsrlq(zmm19, zmm10, xmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1AD48D39CF034120000" , vpsrlq(zmm19, zmm10, xmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1AD48D35A7F" , vpsrlq(zmm19, zmm10, xmmword_ptr(rdx, 2032)));
+ TEST_INSTRUCTION("62E1AD48D39A00080000" , vpsrlq(zmm19, zmm10, xmmword_ptr(rdx, 2048)));
+ TEST_INSTRUCTION("62E1AD48D35A80" , vpsrlq(zmm19, zmm10, xmmword_ptr(rdx, -2048)));
+ TEST_INSTRUCTION("62E1AD48D39AF0F7FFFF" , vpsrlq(zmm19, zmm10, xmmword_ptr(rdx, -2064)));
+ TEST_INSTRUCTION("62D25D4845D3" , vpsrlvd(zmm2, zmm4, zmm11));
+ TEST_INSTRUCTION("62D25D4F45D3" , k(k7).vpsrlvd(zmm2, zmm4, zmm11));
+ TEST_INSTRUCTION("62D25DCF45D3" , k(k7).z().vpsrlvd(zmm2, zmm4, zmm11));
+ TEST_INSTRUCTION("62F25D484511" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B25D484594F034120000" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F25D584511" , vpsrlvd(zmm2, zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F25D4845527F" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F25D48459200200000" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F25D48455280" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F25D484592C0DFFFFF" , vpsrlvd(zmm2, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F25D5845527F" , vpsrlvd(zmm2, zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F25D58459200020000" , vpsrlvd(zmm2, zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F25D58455280" , vpsrlvd(zmm2, zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F25D584592FCFDFFFF" , vpsrlvd(zmm2, zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62529D4045C7" , vpsrlvq(zmm8, zmm28, zmm15));
+ TEST_INSTRUCTION("62529D4545C7" , k(k5).vpsrlvq(zmm8, zmm28, zmm15));
+ TEST_INSTRUCTION("62529DC545C7" , k(k5).z().vpsrlvq(zmm8, zmm28, zmm15));
+ TEST_INSTRUCTION("62729D404501" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62329D404584F034120000" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62729D504501" , vpsrlvq(zmm8, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62729D4045427F" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62729D40458200200000" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62729D40454280" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62729D404582C0DFFFFF" , vpsrlvq(zmm8, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62729D5045427F" , vpsrlvq(zmm8, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62729D50458200040000" , vpsrlvq(zmm8, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62729D50454280" , vpsrlvq(zmm8, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62729D504582F8FBFFFF" , vpsrlvq(zmm8, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D1254872D1AB" , vpsrld(zmm11, zmm9, 171));
+ TEST_INSTRUCTION("62D1254E72D1AB" , k(k6).vpsrld(zmm11, zmm9, 171));
+ TEST_INSTRUCTION("62D125CE72D1AB" , k(k6).z().vpsrld(zmm11, zmm9, 171));
+ TEST_INSTRUCTION("62D1254872D17B" , vpsrld(zmm11, zmm9, 123));
+ TEST_INSTRUCTION("62F1254872117B" , vpsrld(zmm11, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B125487294F0341200007B" , vpsrld(zmm11, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1255872117B" , vpsrld(zmm11, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1254872527F7B" , vpsrld(zmm11, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F125487292002000007B" , vpsrld(zmm11, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F125487252807B" , vpsrld(zmm11, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F125487292C0DFFFFF7B" , vpsrld(zmm11, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1255872527F7B" , vpsrld(zmm11, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F125587292000200007B" , vpsrld(zmm11, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F125587252807B" , vpsrld(zmm11, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F125587292FCFDFFFF7B" , vpsrld(zmm11, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62D1CD4873D6AB" , vpsrlq(zmm6, zmm14, 171));
+ TEST_INSTRUCTION("62D1CD4D73D6AB" , k(k5).vpsrlq(zmm6, zmm14, 171));
+ TEST_INSTRUCTION("62D1CDCD73D6AB" , k(k5).z().vpsrlq(zmm6, zmm14, 171));
+ TEST_INSTRUCTION("62D1CD4873D67B" , vpsrlq(zmm6, zmm14, 123));
+ TEST_INSTRUCTION("62F1CD4873117B" , vpsrlq(zmm6, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1CD487394F0341200007B" , vpsrlq(zmm6, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1CD5873117B" , vpsrlq(zmm6, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD4873527F7B" , vpsrlq(zmm6, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1CD487392002000007B" , vpsrlq(zmm6, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1CD487352807B" , vpsrlq(zmm6, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1CD487392C0DFFFFF7B" , vpsrlq(zmm6, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1CD5873527F7B" , vpsrlq(zmm6, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD587392000400007B" , vpsrlq(zmm6, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD587352807B" , vpsrlq(zmm6, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1CD587392F8FBFFFF7B" , vpsrlq(zmm6, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62210D48FAD7" , vpsubd(zmm26, zmm14, zmm23));
+ TEST_INSTRUCTION("62210D4FFAD7" , k(k7).vpsubd(zmm26, zmm14, zmm23));
+ TEST_INSTRUCTION("62210DCFFAD7" , k(k7).z().vpsubd(zmm26, zmm14, zmm23));
+ TEST_INSTRUCTION("62610D48FA11" , vpsubd(zmm26, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62210D48FA94F034120000" , vpsubd(zmm26, zmm14, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62610D58FA11" , vpsubd(zmm26, zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62610D48FA527F" , vpsubd(zmm26, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62610D48FA9200200000" , vpsubd(zmm26, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62610D48FA5280" , vpsubd(zmm26, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62610D48FA92C0DFFFFF" , vpsubd(zmm26, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62610D58FA527F" , vpsubd(zmm26, zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62610D58FA9200020000" , vpsubd(zmm26, zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62610D58FA5280" , vpsubd(zmm26, zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62610D58FA92FCFDFFFF" , vpsubd(zmm26, zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A1BD48FBC7" , vpsubq(zmm16, zmm8, zmm23));
+ TEST_INSTRUCTION("62A1BD4FFBC7" , k(k7).vpsubq(zmm16, zmm8, zmm23));
+ TEST_INSTRUCTION("62A1BDCFFBC7" , k(k7).z().vpsubq(zmm16, zmm8, zmm23));
+ TEST_INSTRUCTION("62E1BD48FB01" , vpsubq(zmm16, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1BD48FB84F034120000" , vpsubq(zmm16, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1BD58FB01" , vpsubq(zmm16, zmm8, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1BD48FB427F" , vpsubq(zmm16, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1BD48FB8200200000" , vpsubq(zmm16, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1BD48FB4280" , vpsubq(zmm16, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1BD48FB82C0DFFFFF" , vpsubq(zmm16, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1BD58FB427F" , vpsubq(zmm16, zmm8, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1BD58FB8200040000" , vpsubq(zmm16, zmm8, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1BD58FB4280" , vpsubq(zmm16, zmm8, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1BD58FB82F8FBFFFF" , vpsubq(zmm16, zmm8, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62923D4027D0" , vptestmd(k2, zmm24, zmm24));
+ TEST_INSTRUCTION("62923D4227D0" , k(k2).vptestmd(k2, zmm24, zmm24));
+ TEST_INSTRUCTION("62F23D402711" , vptestmd(k2, zmm24, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B23D402794F034120000" , vptestmd(k2, zmm24, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F23D502711" , vptestmd(k2, zmm24, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23D4027527F" , vptestmd(k2, zmm24, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F23D40279200200000" , vptestmd(k2, zmm24, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23D40275280" , vptestmd(k2, zmm24, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F23D402792C0DFFFFF" , vptestmd(k2, zmm24, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23D5027527F" , vptestmd(k2, zmm24, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F23D50279200020000" , vptestmd(k2, zmm24, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23D50275280" , vptestmd(k2, zmm24, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F23D502792FCFDFFFF" , vptestmd(k2, zmm24, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B2854827E4" , vptestmq(k4, zmm15, zmm20));
+ TEST_INSTRUCTION("62B2854A27E4" , k(k2).vptestmq(k4, zmm15, zmm20));
+ TEST_INSTRUCTION("62F285482721" , vptestmq(k4, zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2854827A4F034120000" , vptestmq(k4, zmm15, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F285582721" , vptestmq(k4, zmm15, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2854827627F" , vptestmq(k4, zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2854827A200200000" , vptestmq(k4, zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F28548276280" , vptestmq(k4, zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2854827A2C0DFFFFF" , vptestmq(k4, zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2855827627F" , vptestmq(k4, zmm15, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2855827A200040000" , vptestmq(k4, zmm15, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F28558276280" , vptestmq(k4, zmm15, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2855827A2F8FBFFFF" , vptestmq(k4, zmm15, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62714D486ADF" , vpunpckhdq(zmm11, zmm6, zmm7));
+ TEST_INSTRUCTION("62714D4B6ADF" , k(k3).vpunpckhdq(zmm11, zmm6, zmm7));
+ TEST_INSTRUCTION("62714DCB6ADF" , k(k3).z().vpunpckhdq(zmm11, zmm6, zmm7));
+ TEST_INSTRUCTION("62714D486A19" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62314D486A9CF034120000" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62714D586A19" , vpunpckhdq(zmm11, zmm6, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62714D486A5A7F" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62714D486A9A00200000" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62714D486A5A80" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62714D486A9AC0DFFFFF" , vpunpckhdq(zmm11, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62714D586A5A7F" , vpunpckhdq(zmm11, zmm6, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62714D586A9A00020000" , vpunpckhdq(zmm11, zmm6, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62714D586A5A80" , vpunpckhdq(zmm11, zmm6, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62714D586A9AFCFDFFFF" , vpunpckhdq(zmm11, zmm6, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6211CD486DC2" , vpunpckhqdq(zmm8, zmm6, zmm26));
+ TEST_INSTRUCTION("6211CD4E6DC2" , k(k6).vpunpckhqdq(zmm8, zmm6, zmm26));
+ TEST_INSTRUCTION("6211CDCE6DC2" , k(k6).z().vpunpckhqdq(zmm8, zmm6, zmm26));
+ TEST_INSTRUCTION("6271CD486D01" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231CD486D84F034120000" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271CD586D01" , vpunpckhqdq(zmm8, zmm6, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271CD486D427F" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271CD486D8200200000" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271CD486D4280" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271CD486D82C0DFFFFF" , vpunpckhqdq(zmm8, zmm6, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271CD586D427F" , vpunpckhqdq(zmm8, zmm6, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271CD586D8200040000" , vpunpckhqdq(zmm8, zmm6, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271CD586D4280" , vpunpckhqdq(zmm8, zmm6, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271CD586D82F8FBFFFF" , vpunpckhqdq(zmm8, zmm6, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62C16D4062C5" , vpunpckldq(zmm16, zmm18, zmm13));
+ TEST_INSTRUCTION("62C16D4762C5" , k(k7).vpunpckldq(zmm16, zmm18, zmm13));
+ TEST_INSTRUCTION("62C16DC762C5" , k(k7).z().vpunpckldq(zmm16, zmm18, zmm13));
+ TEST_INSTRUCTION("62E16D406201" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A16D406284F034120000" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E16D506201" , vpunpckldq(zmm16, zmm18, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E16D4062427F" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E16D40628200200000" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E16D40624280" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E16D406282C0DFFFFF" , vpunpckldq(zmm16, zmm18, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E16D5062427F" , vpunpckldq(zmm16, zmm18, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E16D50628200020000" , vpunpckldq(zmm16, zmm18, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E16D50624280" , vpunpckldq(zmm16, zmm18, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E16D506282FCFDFFFF" , vpunpckldq(zmm16, zmm18, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C1FD406CC9" , vpunpcklqdq(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C1FD456CC9" , k(k5).vpunpcklqdq(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62C1FDC56CC9" , k(k5).z().vpunpcklqdq(zmm17, zmm16, zmm9));
+ TEST_INSTRUCTION("62E1FD406C09" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD406C8CF034120000" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FD506C09" , vpunpcklqdq(zmm17, zmm16, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1FD406C4A7F" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FD406C8A00200000" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FD406C4A80" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FD406C8AC0DFFFFF" , vpunpcklqdq(zmm17, zmm16, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FD506C4A7F" , vpunpcklqdq(zmm17, zmm16, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1FD506C8A00040000" , vpunpcklqdq(zmm17, zmm16, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD506C4A80" , vpunpcklqdq(zmm17, zmm16, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1FD506C8AF8FBFFFF" , vpunpcklqdq(zmm17, zmm16, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62916548EFE9" , vpxord(zmm5, zmm3, zmm25));
+ TEST_INSTRUCTION("6291654BEFE9" , k(k3).vpxord(zmm5, zmm3, zmm25));
+ TEST_INSTRUCTION("629165CBEFE9" , k(k3).z().vpxord(zmm5, zmm3, zmm25));
+ TEST_INSTRUCTION("62F16548EF29" , vpxord(zmm5, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B16548EFACF034120000" , vpxord(zmm5, zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F16558EF29" , vpxord(zmm5, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F16548EF6A7F" , vpxord(zmm5, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F16548EFAA00200000" , vpxord(zmm5, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F16548EF6A80" , vpxord(zmm5, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F16548EFAAC0DFFFFF" , vpxord(zmm5, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F16558EF6A7F" , vpxord(zmm5, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F16558EFAA00020000" , vpxord(zmm5, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F16558EF6A80" , vpxord(zmm5, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F16558EFAAFCFDFFFF" , vpxord(zmm5, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6231DD48EFD2" , vpxorq(zmm10, zmm4, zmm18));
+ TEST_INSTRUCTION("6231DD4CEFD2" , k(k4).vpxorq(zmm10, zmm4, zmm18));
+ TEST_INSTRUCTION("6231DDCCEFD2" , k(k4).z().vpxorq(zmm10, zmm4, zmm18));
+ TEST_INSTRUCTION("6271DD48EF11" , vpxorq(zmm10, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231DD48EF94F034120000" , vpxorq(zmm10, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271DD58EF11" , vpxorq(zmm10, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271DD48EF527F" , vpxorq(zmm10, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271DD48EF9200200000" , vpxorq(zmm10, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271DD48EF5280" , vpxorq(zmm10, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271DD48EF92C0DFFFFF" , vpxorq(zmm10, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271DD58EF527F" , vpxorq(zmm10, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271DD58EF9200040000" , vpxorq(zmm10, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271DD58EF5280" , vpxorq(zmm10, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271DD58EF92F8FBFFFF" , vpxorq(zmm10, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6242FD484CD2" , vrcp14pd(zmm26, zmm10));
+ TEST_INSTRUCTION("6242FD4E4CD2" , k(k6).vrcp14pd(zmm26, zmm10));
+ TEST_INSTRUCTION("6242FDCE4CD2" , k(k6).z().vrcp14pd(zmm26, zmm10));
+ TEST_INSTRUCTION("6262FD484C11" , vrcp14pd(zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222FD484C94F034120000" , vrcp14pd(zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262FD584C11" , vrcp14pd(zmm26, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262FD484C527F" , vrcp14pd(zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262FD484C9200200000" , vrcp14pd(zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262FD484C5280" , vrcp14pd(zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262FD484C92C0DFFFFF" , vrcp14pd(zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262FD584C527F" , vrcp14pd(zmm26, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262FD584C9200040000" , vrcp14pd(zmm26, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262FD584C5280" , vrcp14pd(zmm26, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262FD584C92F8FBFFFF" , vrcp14pd(zmm26, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62927D484CDB" , vrcp14ps(zmm3, zmm27));
+ TEST_INSTRUCTION("62927D4D4CDB" , k(k5).vrcp14ps(zmm3, zmm27));
+ TEST_INSTRUCTION("62927DCD4CDB" , k(k5).z().vrcp14ps(zmm3, zmm27));
+ TEST_INSTRUCTION("62F27D484C19" , vrcp14ps(zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D484C9CF034120000" , vrcp14ps(zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D584C19" , vrcp14ps(zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D484C5A7F" , vrcp14ps(zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D484C9A00200000" , vrcp14ps(zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D484C5A80" , vrcp14ps(zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D484C9AC0DFFFFF" , vrcp14ps(zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D584C5A7F" , vrcp14ps(zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D584C9A00020000" , vrcp14ps(zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D584C5A80" , vrcp14ps(zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D584C9AFCFDFFFF" , vrcp14ps(zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6272CD084DF7" , vrcp14sd(xmm14, xmm6, xmm7));
+ TEST_INSTRUCTION("6272CD094DF7" , k(k1).vrcp14sd(xmm14, xmm6, xmm7));
+ TEST_INSTRUCTION("6272CD894DF7" , k(k1).z().vrcp14sd(xmm14, xmm6, xmm7));
+ TEST_INSTRUCTION("6272CD084D31" , vrcp14sd(xmm14, xmm6, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6232CD084DB4F034120000" , vrcp14sd(xmm14, xmm6, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272CD084D727F" , vrcp14sd(xmm14, xmm6, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6272CD084DB200040000" , vrcp14sd(xmm14, xmm6, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6272CD084D7280" , vrcp14sd(xmm14, xmm6, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6272CD084DB2F8FBFFFF" , vrcp14sd(xmm14, xmm6, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("622275084DCD" , vrcp14ss(xmm25, xmm1, xmm21));
+ TEST_INSTRUCTION("6222750A4DCD" , k(k2).vrcp14ss(xmm25, xmm1, xmm21));
+ TEST_INSTRUCTION("6222758A4DCD" , k(k2).z().vrcp14ss(xmm25, xmm1, xmm21));
+ TEST_INSTRUCTION("626275084D09" , vrcp14ss(xmm25, xmm1, dword_ptr(rcx)));
+ TEST_INSTRUCTION("622275084D8CF034120000" , vrcp14ss(xmm25, xmm1, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626275084D4A7F" , vrcp14ss(xmm25, xmm1, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("626275084D8A00020000" , vrcp14ss(xmm25, xmm1, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("626275084D4A80" , vrcp14ss(xmm25, xmm1, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("626275084D8AFCFDFFFF" , vrcp14ss(xmm25, xmm1, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6272FD484EF4" , vrsqrt14pd(zmm14, zmm4));
+ TEST_INSTRUCTION("6272FD4F4EF4" , k(k7).vrsqrt14pd(zmm14, zmm4));
+ TEST_INSTRUCTION("6272FDCF4EF4" , k(k7).z().vrsqrt14pd(zmm14, zmm4));
+ TEST_INSTRUCTION("6272FD484E31" , vrsqrt14pd(zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232FD484EB4F034120000" , vrsqrt14pd(zmm14, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272FD584E31" , vrsqrt14pd(zmm14, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272FD484E727F" , vrsqrt14pd(zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272FD484EB200200000" , vrsqrt14pd(zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272FD484E7280" , vrsqrt14pd(zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272FD484EB2C0DFFFFF" , vrsqrt14pd(zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272FD584E727F" , vrsqrt14pd(zmm14, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272FD584EB200040000" , vrsqrt14pd(zmm14, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272FD584E7280" , vrsqrt14pd(zmm14, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272FD584EB2F8FBFFFF" , vrsqrt14pd(zmm14, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62927D484ED9" , vrsqrt14ps(zmm3, zmm25));
+ TEST_INSTRUCTION("62927D4B4ED9" , k(k3).vrsqrt14ps(zmm3, zmm25));
+ TEST_INSTRUCTION("62927DCB4ED9" , k(k3).z().vrsqrt14ps(zmm3, zmm25));
+ TEST_INSTRUCTION("62F27D484E19" , vrsqrt14ps(zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B27D484E9CF034120000" , vrsqrt14ps(zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F27D584E19" , vrsqrt14ps(zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F27D484E5A7F" , vrsqrt14ps(zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F27D484E9A00200000" , vrsqrt14ps(zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F27D484E5A80" , vrsqrt14ps(zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F27D484E9AC0DFFFFF" , vrsqrt14ps(zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F27D584E5A7F" , vrsqrt14ps(zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F27D584E9A00020000" , vrsqrt14ps(zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F27D584E5A80" , vrsqrt14ps(zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F27D584E9AFCFDFFFF" , vrsqrt14ps(zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2D5004FCB" , vrsqrt14sd(xmm1, xmm21, xmm3));
+ TEST_INSTRUCTION("62F2D5024FCB" , k(k2).vrsqrt14sd(xmm1, xmm21, xmm3));
+ TEST_INSTRUCTION("62F2D5824FCB" , k(k2).z().vrsqrt14sd(xmm1, xmm21, xmm3));
+ TEST_INSTRUCTION("62F2D5004F09" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2D5004F8CF034120000" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2D5004F4A7F" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F2D5004F8A00040000" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F2D5004F4A80" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F2D5004F8AF8FBFFFF" , vrsqrt14sd(xmm1, xmm21, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62A22D004FDA" , vrsqrt14ss(xmm19, xmm26, xmm18));
+ TEST_INSTRUCTION("62A22D034FDA" , k(k3).vrsqrt14ss(xmm19, xmm26, xmm18));
+ TEST_INSTRUCTION("62A22D834FDA" , k(k3).z().vrsqrt14ss(xmm19, xmm26, xmm18));
+ TEST_INSTRUCTION("62E22D004F19" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A22D004F9CF034120000" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E22D004F5A7F" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E22D004F9A00020000" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E22D004F5A80" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E22D004F9AFCFDFFFF" , vrsqrt14ss(xmm19, xmm26, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6291AD48C6C9AB" , vshufpd(zmm1, zmm10, zmm25, 171));
+ TEST_INSTRUCTION("6291AD4BC6C9AB" , k(k3).vshufpd(zmm1, zmm10, zmm25, 171));
+ TEST_INSTRUCTION("6291ADCBC6C9AB" , k(k3).z().vshufpd(zmm1, zmm10, zmm25, 171));
+ TEST_INSTRUCTION("6291AD48C6C97B" , vshufpd(zmm1, zmm10, zmm25, 123));
+ TEST_INSTRUCTION("62F1AD48C6097B" , vshufpd(zmm1, zmm10, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1AD48C68CF0341200007B" , vshufpd(zmm1, zmm10, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1AD58C6097B" , vshufpd(zmm1, zmm10, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1AD48C64A7F7B" , vshufpd(zmm1, zmm10, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1AD48C68A002000007B" , vshufpd(zmm1, zmm10, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1AD48C64A807B" , vshufpd(zmm1, zmm10, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1AD48C68AC0DFFFFF7B" , vshufpd(zmm1, zmm10, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1AD58C64A7F7B" , vshufpd(zmm1, zmm10, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1AD58C68A000400007B" , vshufpd(zmm1, zmm10, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1AD58C64A807B" , vshufpd(zmm1, zmm10, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1AD58C68AF8FBFFFF7B" , vshufpd(zmm1, zmm10, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62917448C6C9AB" , vshufps(zmm1, zmm1, zmm25, 171));
+ TEST_INSTRUCTION("62917449C6C9AB" , k(k1).vshufps(zmm1, zmm1, zmm25, 171));
+ TEST_INSTRUCTION("629174C9C6C9AB" , k(k1).z().vshufps(zmm1, zmm1, zmm25, 171));
+ TEST_INSTRUCTION("62917448C6C97B" , vshufps(zmm1, zmm1, zmm25, 123));
+ TEST_INSTRUCTION("62F17448C6097B" , vshufps(zmm1, zmm1, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B17448C68CF0341200007B" , vshufps(zmm1, zmm1, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F17458C6097B" , vshufps(zmm1, zmm1, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F17448C64A7F7B" , vshufps(zmm1, zmm1, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F17448C68A002000007B" , vshufps(zmm1, zmm1, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F17448C64A807B" , vshufps(zmm1, zmm1, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F17448C68AC0DFFFFF7B" , vshufps(zmm1, zmm1, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F17458C64A7F7B" , vshufps(zmm1, zmm1, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F17458C68A000200007B" , vshufps(zmm1, zmm1, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17458C64A807B" , vshufps(zmm1, zmm1, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F17458C68AFCFDFFFF7B" , vshufps(zmm1, zmm1, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6271FD4851CD" , vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD4A51CD" , k(k2).vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FDCA51CD" , k(k2).z().vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD1851CD" , rn_sae().vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD5851CD" , ru_sae().vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD3851CD" , rd_sae().vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD7851CD" , rz_sae().vsqrtpd(zmm9, zmm5));
+ TEST_INSTRUCTION("6271FD485109" , vsqrtpd(zmm9, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FD48518CF034120000" , vsqrtpd(zmm9, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FD585109" , vsqrtpd(zmm9, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6271FD48514A7F" , vsqrtpd(zmm9, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6271FD48518A00200000" , vsqrtpd(zmm9, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6271FD48514A80" , vsqrtpd(zmm9, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6271FD48518AC0DFFFFF" , vsqrtpd(zmm9, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6271FD58514A7F" , vsqrtpd(zmm9, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6271FD58518A00040000" , vsqrtpd(zmm9, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6271FD58514A80" , vsqrtpd(zmm9, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6271FD58518AF8FBFFFF" , vsqrtpd(zmm9, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B17C4851E7" , vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17C4E51E7" , k(k6).vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17CCE51E7" , k(k6).z().vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17C1851E7" , rn_sae().vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17C5851E7" , ru_sae().vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17C3851E7" , rd_sae().vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62B17C7851E7" , rz_sae().vsqrtps(zmm4, zmm23));
+ TEST_INSTRUCTION("62F17C485121" , vsqrtps(zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17C4851A4F034120000" , vsqrtps(zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17C585121" , vsqrtps(zmm4, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F17C4851627F" , vsqrtps(zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17C4851A200200000" , vsqrtps(zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17C48516280" , vsqrtps(zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17C4851A2C0DFFFFF" , vsqrtps(zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F17C5851627F" , vsqrtps(zmm4, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F17C5851A200020000" , vsqrtps(zmm4, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F17C58516280" , vsqrtps(zmm4, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F17C5851A2FCFDFFFF" , vsqrtps(zmm4, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6271BF0051C5" , vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF0351C5" , k(k3).vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF8351C5" , k(k3).z().vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF1051C5" , rn_sae().vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF5051C5" , ru_sae().vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF3051C5" , rd_sae().vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF7051C5" , rz_sae().vsqrtsd(xmm8, xmm24, xmm5));
+ TEST_INSTRUCTION("6271BF005101" , vsqrtsd(xmm8, xmm24, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231BF005184F034120000" , vsqrtsd(xmm8, xmm24, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271BF0051427F" , vsqrtsd(xmm8, xmm24, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271BF00518200040000" , vsqrtsd(xmm8, xmm24, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271BF00514280" , vsqrtsd(xmm8, xmm24, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271BF005182F8FBFFFF" , vsqrtsd(xmm8, xmm24, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62410E0851CB" , vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E0F51CB" , k(k7).vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E8F51CB" , k(k7).z().vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E1851CB" , rn_sae().vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E5851CB" , ru_sae().vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E3851CB" , rd_sae().vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62410E7851CB" , rz_sae().vsqrtss(xmm25, xmm14, xmm11));
+ TEST_INSTRUCTION("62610E085109" , vsqrtss(xmm25, xmm14, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62210E08518CF034120000" , vsqrtss(xmm25, xmm14, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62610E08514A7F" , vsqrtss(xmm25, xmm14, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62610E08518A00020000" , vsqrtss(xmm25, xmm14, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62610E08514A80" , vsqrtss(xmm25, xmm14, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62610E08518AFCFDFFFF" , vsqrtss(xmm25, xmm14, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62C19D405CE8" , vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D415CE8" , k(k1).vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19DC15CE8" , k(k1).z().vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D105CE8" , rn_sae().vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D505CE8" , ru_sae().vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D305CE8" , rd_sae().vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D705CE8" , rz_sae().vsubpd(zmm21, zmm28, zmm8));
+ TEST_INSTRUCTION("62E19D405C29" , vsubpd(zmm21, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A19D405CACF034120000" , vsubpd(zmm21, zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E19D505C29" , vsubpd(zmm21, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E19D405C6A7F" , vsubpd(zmm21, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E19D405CAA00200000" , vsubpd(zmm21, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E19D405C6A80" , vsubpd(zmm21, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E19D405CAAC0DFFFFF" , vsubpd(zmm21, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E19D505C6A7F" , vsubpd(zmm21, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E19D505CAA00040000" , vsubpd(zmm21, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E19D505C6A80" , vsubpd(zmm21, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E19D505CAAF8FBFFFF" , vsubpd(zmm21, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62E12C485CDD" , vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C4F5CDD" , k(k7).vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12CCF5CDD" , k(k7).z().vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C185CDD" , rn_sae().vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C585CDD" , ru_sae().vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C385CDD" , rd_sae().vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C785CDD" , rz_sae().vsubps(zmm19, zmm10, zmm5));
+ TEST_INSTRUCTION("62E12C485C19" , vsubps(zmm19, zmm10, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A12C485C9CF034120000" , vsubps(zmm19, zmm10, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E12C585C19" , vsubps(zmm19, zmm10, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E12C485C5A7F" , vsubps(zmm19, zmm10, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E12C485C9A00200000" , vsubps(zmm19, zmm10, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E12C485C5A80" , vsubps(zmm19, zmm10, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E12C485C9AC0DFFFFF" , vsubps(zmm19, zmm10, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E12C585C5A7F" , vsubps(zmm19, zmm10, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E12C585C9A00020000" , vsubps(zmm19, zmm10, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E12C585C5A80" , vsubps(zmm19, zmm10, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E12C585C9AFCFDFFFF" , vsubps(zmm19, zmm10, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6241C7005CC5" , vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7075CC5" , k(k7).vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7875CC5" , k(k7).z().vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7105CC5" , rn_sae().vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7505CC5" , ru_sae().vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7305CC5" , rd_sae().vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6241C7705CC5" , rz_sae().vsubsd(xmm24, xmm23, xmm13));
+ TEST_INSTRUCTION("6261C7005C01" , vsubsd(xmm24, xmm23, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6221C7005C84F034120000" , vsubsd(xmm24, xmm23, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6261C7005C427F" , vsubsd(xmm24, xmm23, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6261C7005C8200040000" , vsubsd(xmm24, xmm23, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6261C7005C4280" , vsubsd(xmm24, xmm23, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6261C7005C82F8FBFFFF" , vsubsd(xmm24, xmm23, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62215E005CD8" , vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E065CD8" , k(k6).vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E865CD8" , k(k6).z().vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E105CD8" , rn_sae().vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E505CD8" , ru_sae().vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E305CD8" , rd_sae().vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62215E705CD8" , rz_sae().vsubss(xmm27, xmm20, xmm16));
+ TEST_INSTRUCTION("62615E005C19" , vsubss(xmm27, xmm20, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62215E005C9CF034120000" , vsubss(xmm27, xmm20, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62615E005C5A7F" , vsubss(xmm27, xmm20, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62615E005C9A00020000" , vsubss(xmm27, xmm20, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62615E005C5A80" , vsubss(xmm27, xmm20, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62615E005C9AFCFDFFFF" , vsubss(xmm27, xmm20, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62A1FD082EEB" , vucomisd(xmm21, xmm19));
+ TEST_INSTRUCTION("62A1FD182EEB" , sae().vucomisd(xmm21, xmm19));
+ TEST_INSTRUCTION("62E1FD082E29" , vucomisd(xmm21, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FD082EACF034120000" , vucomisd(xmm21, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FD082E6A7F" , vucomisd(xmm21, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1FD082EAA00040000" , vucomisd(xmm21, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1FD082E6A80" , vucomisd(xmm21, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1FD082EAAF8FBFFFF" , vucomisd(xmm21, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62017C082EDD" , vucomiss(xmm27, xmm29));
+ TEST_INSTRUCTION("62017C182EDD" , sae().vucomiss(xmm27, xmm29));
+ TEST_INSTRUCTION("62617C082E19" , vucomiss(xmm27, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62217C082E9CF034120000" , vucomiss(xmm27, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62617C082E5A7F" , vucomiss(xmm27, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62617C082E9A00020000" , vucomiss(xmm27, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62617C082E5A80" , vucomiss(xmm27, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62617C082E9AFCFDFFFF" , vucomiss(xmm27, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62D1C54015F4" , vunpckhpd(zmm6, zmm23, zmm12));
+ TEST_INSTRUCTION("62D1C54715F4" , k(k7).vunpckhpd(zmm6, zmm23, zmm12));
+ TEST_INSTRUCTION("62D1C5C715F4" , k(k7).z().vunpckhpd(zmm6, zmm23, zmm12));
+ TEST_INSTRUCTION("62F1C5401531" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1C54015B4F034120000" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1C5501531" , vunpckhpd(zmm6, zmm23, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F1C54015727F" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F1C54015B200200000" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F1C540157280" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F1C54015B2C0DFFFFF" , vunpckhpd(zmm6, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F1C55015727F" , vunpckhpd(zmm6, zmm23, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F1C55015B200040000" , vunpckhpd(zmm6, zmm23, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F1C550157280" , vunpckhpd(zmm6, zmm23, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F1C55015B2F8FBFFFF" , vunpckhpd(zmm6, zmm23, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62616C4815EC" , vunpckhps(zmm29, zmm2, zmm4));
+ TEST_INSTRUCTION("62616C4C15EC" , k(k4).vunpckhps(zmm29, zmm2, zmm4));
+ TEST_INSTRUCTION("62616CCC15EC" , k(k4).z().vunpckhps(zmm29, zmm2, zmm4));
+ TEST_INSTRUCTION("62616C481529" , vunpckhps(zmm29, zmm2, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62216C4815ACF034120000" , vunpckhps(zmm29, zmm2, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62616C581529" , vunpckhps(zmm29, zmm2, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62616C48156A7F" , vunpckhps(zmm29, zmm2, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62616C4815AA00200000" , vunpckhps(zmm29, zmm2, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62616C48156A80" , vunpckhps(zmm29, zmm2, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62616C4815AAC0DFFFFF" , vunpckhps(zmm29, zmm2, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62616C58156A7F" , vunpckhps(zmm29, zmm2, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62616C5815AA00020000" , vunpckhps(zmm29, zmm2, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62616C58156A80" , vunpckhps(zmm29, zmm2, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62616C5815AAFCFDFFFF" , vunpckhps(zmm29, zmm2, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62C19D4014D0" , vunpcklpd(zmm18, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19D4114D0" , k(k1).vunpcklpd(zmm18, zmm28, zmm8));
+ TEST_INSTRUCTION("62C19DC114D0" , k(k1).z().vunpcklpd(zmm18, zmm28, zmm8));
+ TEST_INSTRUCTION("62E19D401411" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A19D401494F034120000" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E19D501411" , vunpcklpd(zmm18, zmm28, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E19D4014527F" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E19D40149200200000" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E19D40145280" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E19D401492C0DFFFFF" , vunpcklpd(zmm18, zmm28, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E19D5014527F" , vunpcklpd(zmm18, zmm28, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E19D50149200040000" , vunpcklpd(zmm18, zmm28, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E19D50145280" , vunpcklpd(zmm18, zmm28, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E19D501492F8FBFFFF" , vunpcklpd(zmm18, zmm28, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62610C4814CE" , vunpcklps(zmm25, zmm14, zmm6));
+ TEST_INSTRUCTION("62610C4E14CE" , k(k6).vunpcklps(zmm25, zmm14, zmm6));
+ TEST_INSTRUCTION("62610CCE14CE" , k(k6).z().vunpcklps(zmm25, zmm14, zmm6));
+ TEST_INSTRUCTION("62610C481409" , vunpcklps(zmm25, zmm14, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62210C48148CF034120000" , vunpcklps(zmm25, zmm14, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62610C581409" , vunpcklps(zmm25, zmm14, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62610C48144A7F" , vunpcklps(zmm25, zmm14, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62610C48148A00200000" , vunpcklps(zmm25, zmm14, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62610C48144A80" , vunpcklps(zmm25, zmm14, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62610C48148AC0DFFFFF" , vunpcklps(zmm25, zmm14, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62610C58144A7F" , vunpcklps(zmm25, zmm14, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62610C58148A00020000" , vunpcklps(zmm25, zmm14, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62610C58144A80" , vunpcklps(zmm25, zmm14, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62610C58148AFCFDFFFF" , vunpcklps(zmm25, zmm14, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6253154825D2AB" , vpternlogd(zmm10, zmm13, zmm10, 171));
+ TEST_INSTRUCTION("6253154F25D2AB" , k(k7).vpternlogd(zmm10, zmm13, zmm10, 171));
+ TEST_INSTRUCTION("625315CF25D2AB" , k(k7).z().vpternlogd(zmm10, zmm13, zmm10, 171));
+ TEST_INSTRUCTION("6253154825D27B" , vpternlogd(zmm10, zmm13, zmm10, 123));
+ TEST_INSTRUCTION("6273154825117B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("623315482594F0341200007B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273155825117B" , vpternlogd(zmm10, zmm13, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("6273154825527F7B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("627315482592002000007B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("627315482552807B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("627315482592C0DFFFFF7B" , vpternlogd(zmm10, zmm13, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273155825527F7B" , vpternlogd(zmm10, zmm13, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("627315582592000200007B" , vpternlogd(zmm10, zmm13, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("627315582552807B" , vpternlogd(zmm10, zmm13, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("627315582592FCFDFFFF7B" , vpternlogd(zmm10, zmm13, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62C39D4825C5AB" , vpternlogq(zmm16, zmm12, zmm13, 171));
+ TEST_INSTRUCTION("62C39D4A25C5AB" , k(k2).vpternlogq(zmm16, zmm12, zmm13, 171));
+ TEST_INSTRUCTION("62C39DCA25C5AB" , k(k2).z().vpternlogq(zmm16, zmm12, zmm13, 171));
+ TEST_INSTRUCTION("62C39D4825C57B" , vpternlogq(zmm16, zmm12, zmm13, 123));
+ TEST_INSTRUCTION("62E39D4825017B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A39D482584F0341200007B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62E39D5825017B" , vpternlogq(zmm16, zmm12, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62E39D4825427F7B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E39D482582002000007B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E39D482542807B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E39D482582C0DFFFFF7B" , vpternlogq(zmm16, zmm12, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E39D5825427F7B" , vpternlogq(zmm16, zmm12, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62E39D582582000400007B" , vpternlogq(zmm16, zmm12, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E39D582542807B" , vpternlogq(zmm16, zmm12, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62E39D582582F8FBFFFF7B" , vpternlogq(zmm16, zmm12, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62327E4832F7" , vpmovqb(xmm23, zmm14));
+ TEST_INSTRUCTION("62327E4A32F7" , k(k2).vpmovqb(xmm23, zmm14));
+ TEST_INSTRUCTION("62327ECA32F7" , k(k2).z().vpmovqb(xmm23, zmm14));
+ TEST_INSTRUCTION("62227E4822CC" , vpmovsqb(xmm20, zmm25));
+ TEST_INSTRUCTION("62227E4922CC" , k(k1).vpmovsqb(xmm20, zmm25));
+ TEST_INSTRUCTION("62227EC922CC" , k(k1).z().vpmovsqb(xmm20, zmm25));
+ TEST_INSTRUCTION("62D27E4812D0" , vpmovusqb(xmm8, zmm2));
+ TEST_INSTRUCTION("62D27E4C12D0" , k(k4).vpmovusqb(xmm8, zmm2));
+ TEST_INSTRUCTION("62D27ECC12D0" , k(k4).z().vpmovusqb(xmm8, zmm2));
+ TEST_INSTRUCTION("62A27E4834DD" , vpmovqw(xmm21, zmm19));
+ TEST_INSTRUCTION("62A27E4A34DD" , k(k2).vpmovqw(xmm21, zmm19));
+ TEST_INSTRUCTION("62A27ECA34DD" , k(k2).z().vpmovqw(xmm21, zmm19));
+ TEST_INSTRUCTION("62B27E4824E0" , vpmovsqw(xmm16, zmm4));
+ TEST_INSTRUCTION("62B27E4E24E0" , k(k6).vpmovsqw(xmm16, zmm4));
+ TEST_INSTRUCTION("62B27ECE24E0" , k(k6).z().vpmovsqw(xmm16, zmm4));
+ TEST_INSTRUCTION("62927E4814CD" , vpmovusqw(xmm29, zmm1));
+ TEST_INSTRUCTION("62927E4A14CD" , k(k2).vpmovusqw(xmm29, zmm1));
+ TEST_INSTRUCTION("62927ECA14CD" , k(k2).z().vpmovusqw(xmm29, zmm1));
+ TEST_INSTRUCTION("62027E4835EC" , vpmovqd(ymm28, zmm29));
+ TEST_INSTRUCTION("62027E4A35EC" , k(k2).vpmovqd(ymm28, zmm29));
+ TEST_INSTRUCTION("62027ECA35EC" , k(k2).z().vpmovqd(ymm28, zmm29));
+ TEST_INSTRUCTION("62327E4825CE" , vpmovsqd(ymm22, zmm9));
+ TEST_INSTRUCTION("62327E4C25CE" , k(k4).vpmovsqd(ymm22, zmm9));
+ TEST_INSTRUCTION("62327ECC25CE" , k(k4).z().vpmovsqd(ymm22, zmm9));
+ TEST_INSTRUCTION("62627E4815D2" , vpmovusqd(ymm2, zmm26));
+ TEST_INSTRUCTION("62627E4F15D2" , k(k7).vpmovusqd(ymm2, zmm26));
+ TEST_INSTRUCTION("62627ECF15D2" , k(k7).z().vpmovusqd(ymm2, zmm26));
+ TEST_INSTRUCTION("62727E4831D9" , vpmovdb(xmm1, zmm11));
+ TEST_INSTRUCTION("62727E4F31D9" , k(k7).vpmovdb(xmm1, zmm11));
+ TEST_INSTRUCTION("62727ECF31D9" , k(k7).z().vpmovdb(xmm1, zmm11));
+ TEST_INSTRUCTION("62927E4821CB" , vpmovsdb(xmm27, zmm1));
+ TEST_INSTRUCTION("62927E4F21CB" , k(k7).vpmovsdb(xmm27, zmm1));
+ TEST_INSTRUCTION("62927ECF21CB" , k(k7).z().vpmovsdb(xmm27, zmm1));
+ TEST_INSTRUCTION("62E27E4811DB" , vpmovusdb(xmm3, zmm19));
+ TEST_INSTRUCTION("62E27E4A11DB" , k(k2).vpmovusdb(xmm3, zmm19));
+ TEST_INSTRUCTION("62E27ECA11DB" , k(k2).z().vpmovusdb(xmm3, zmm19));
+ TEST_INSTRUCTION("62527E4833D1" , vpmovdw(ymm9, zmm10));
+ TEST_INSTRUCTION("62527E4C33D1" , k(k4).vpmovdw(ymm9, zmm10));
+ TEST_INSTRUCTION("62527ECC33D1" , k(k4).z().vpmovdw(ymm9, zmm10));
+ TEST_INSTRUCTION("62027E4823C0" , vpmovsdw(ymm24, zmm24));
+ TEST_INSTRUCTION("62027E4E23C0" , k(k6).vpmovsdw(ymm24, zmm24));
+ TEST_INSTRUCTION("62027ECE23C0" , k(k6).z().vpmovsdw(ymm24, zmm24));
+ TEST_INSTRUCTION("62C27E4813CF" , vpmovusdw(ymm15, zmm17));
+ TEST_INSTRUCTION("62C27E4F13CF" , k(k7).vpmovusdw(ymm15, zmm17));
+ TEST_INSTRUCTION("62C27ECF13CF" , k(k7).z().vpmovusdw(ymm15, zmm17));
+ TEST_INSTRUCTION("62E3254823CCAB" , vshuff32x4(zmm17, zmm11, zmm4, 171));
+ TEST_INSTRUCTION("62E3254E23CCAB" , k(k6).vshuff32x4(zmm17, zmm11, zmm4, 171));
+ TEST_INSTRUCTION("62E325CE23CCAB" , k(k6).z().vshuff32x4(zmm17, zmm11, zmm4, 171));
+ TEST_INSTRUCTION("62E3254823CC7B" , vshuff32x4(zmm17, zmm11, zmm4, 123));
+ TEST_INSTRUCTION("62E3254823097B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62A32548238CF0341200007B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62E3255823097B" , vshuff32x4(zmm17, zmm11, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62E32548234A7F7B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62E32548238A002000007B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62E32548234A807B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62E32548238AC0DFFFFF7B" , vshuff32x4(zmm17, zmm11, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62E32558234A7F7B" , vshuff32x4(zmm17, zmm11, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62E32558238A000200007B" , vshuff32x4(zmm17, zmm11, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62E32558234A807B" , vshuff32x4(zmm17, zmm11, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62E32558238AFCFDFFFF7B" , vshuff32x4(zmm17, zmm11, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62939D4823F0AB" , vshuff64x2(zmm6, zmm12, zmm24, 171));
+ TEST_INSTRUCTION("62939D4B23F0AB" , k(k3).vshuff64x2(zmm6, zmm12, zmm24, 171));
+ TEST_INSTRUCTION("62939DCB23F0AB" , k(k3).z().vshuff64x2(zmm6, zmm12, zmm24, 171));
+ TEST_INSTRUCTION("62939D4823F07B" , vshuff64x2(zmm6, zmm12, zmm24, 123));
+ TEST_INSTRUCTION("62F39D4823317B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B39D4823B4F0341200007B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F39D5823317B" , vshuff64x2(zmm6, zmm12, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D4823727F7B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F39D4823B2002000007B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F39D482372807B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F39D4823B2C0DFFFFF7B" , vshuff64x2(zmm6, zmm12, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F39D5823727F7B" , vshuff64x2(zmm6, zmm12, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D5823B2000400007B" , vshuff64x2(zmm6, zmm12, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D582372807B" , vshuff64x2(zmm6, zmm12, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F39D5823B2F8FBFFFF7B" , vshuff64x2(zmm6, zmm12, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62F33D4043DDAB" , vshufi32x4(zmm3, zmm24, zmm5, 171));
+ TEST_INSTRUCTION("62F33D4443DDAB" , k(k4).vshufi32x4(zmm3, zmm24, zmm5, 171));
+ TEST_INSTRUCTION("62F33DC443DDAB" , k(k4).z().vshufi32x4(zmm3, zmm24, zmm5, 171));
+ TEST_INSTRUCTION("62F33D4043DD7B" , vshufi32x4(zmm3, zmm24, zmm5, 123));
+ TEST_INSTRUCTION("62F33D4043197B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B33D40439CF0341200007B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F33D5043197B" , vshufi32x4(zmm3, zmm24, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D40435A7F7B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F33D40439A002000007B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F33D40435A807B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F33D40439AC0DFFFFF7B" , vshufi32x4(zmm3, zmm24, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F33D50435A7F7B" , vshufi32x4(zmm3, zmm24, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D50439A000200007B" , vshufi32x4(zmm3, zmm24, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D50435A807B" , vshufi32x4(zmm3, zmm24, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D50439AFCFDFFFF7B" , vshufi32x4(zmm3, zmm24, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62438D4843F1AB" , vshufi64x2(zmm30, zmm14, zmm9, 171));
+ TEST_INSTRUCTION("62438D4943F1AB" , k(k1).vshufi64x2(zmm30, zmm14, zmm9, 171));
+ TEST_INSTRUCTION("62438DC943F1AB" , k(k1).z().vshufi64x2(zmm30, zmm14, zmm9, 171));
+ TEST_INSTRUCTION("62438D4843F17B" , vshufi64x2(zmm30, zmm14, zmm9, 123));
+ TEST_INSTRUCTION("62638D4843317B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62238D4843B4F0341200007B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62638D5843317B" , vshufi64x2(zmm30, zmm14, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62638D4843727F7B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62638D4843B2002000007B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62638D484372807B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62638D4843B2C0DFFFFF7B" , vshufi64x2(zmm30, zmm14, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62638D5843727F7B" , vshufi64x2(zmm30, zmm14, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62638D5843B2000400007B" , vshufi64x2(zmm30, zmm14, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62638D584372807B" , vshufi64x2(zmm30, zmm14, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62638D5843B2F8FBFFFF7B" , vshufi64x2(zmm30, zmm14, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62A2CD4036D3" , vpermq(zmm18, zmm22, zmm19));
+ TEST_INSTRUCTION("62A2CD4736D3" , k(k7).vpermq(zmm18, zmm22, zmm19));
+ TEST_INSTRUCTION("62A2CDC736D3" , k(k7).z().vpermq(zmm18, zmm22, zmm19));
+ TEST_INSTRUCTION("62E2CD403611" , vpermq(zmm18, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD403694F034120000" , vpermq(zmm18, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2CD503611" , vpermq(zmm18, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2CD4036527F" , vpermq(zmm18, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2CD40369200200000" , vpermq(zmm18, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2CD40365280" , vpermq(zmm18, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2CD403692C0DFFFFF" , vpermq(zmm18, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2CD5036527F" , vpermq(zmm18, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2CD50369200040000" , vpermq(zmm18, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD50365280" , vpermq(zmm18, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD503692F8FBFFFF" , vpermq(zmm18, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62629D4816DA" , vpermpd(zmm27, zmm12, zmm2));
+ TEST_INSTRUCTION("62629D4B16DA" , k(k3).vpermpd(zmm27, zmm12, zmm2));
+ TEST_INSTRUCTION("62629DCB16DA" , k(k3).z().vpermpd(zmm27, zmm12, zmm2));
+ TEST_INSTRUCTION("62629D481619" , vpermpd(zmm27, zmm12, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62229D48169CF034120000" , vpermpd(zmm27, zmm12, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62629D581619" , vpermpd(zmm27, zmm12, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62629D48165A7F" , vpermpd(zmm27, zmm12, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62629D48169A00200000" , vpermpd(zmm27, zmm12, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62629D48165A80" , vpermpd(zmm27, zmm12, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62629D48169AC0DFFFFF" , vpermpd(zmm27, zmm12, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62629D58165A7F" , vpermpd(zmm27, zmm12, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62629D58169A00040000" , vpermpd(zmm27, zmm12, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62629D58165A80" , vpermpd(zmm27, zmm12, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62629D58169AF8FBFFFF" , vpermpd(zmm27, zmm12, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("628205487ED9" , vpermt2d(zmm19, zmm15, zmm25));
+ TEST_INSTRUCTION("6282054A7ED9" , k(k2).vpermt2d(zmm19, zmm15, zmm25));
+ TEST_INSTRUCTION("628205CA7ED9" , k(k2).z().vpermt2d(zmm19, zmm15, zmm25));
+ TEST_INSTRUCTION("62E205487E19" , vpermt2d(zmm19, zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A205487E9CF034120000" , vpermt2d(zmm19, zmm15, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E205587E19" , vpermt2d(zmm19, zmm15, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62E205487E5A7F" , vpermt2d(zmm19, zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E205487E9A00200000" , vpermt2d(zmm19, zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E205487E5A80" , vpermt2d(zmm19, zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E205487E9AC0DFFFFF" , vpermt2d(zmm19, zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E205587E5A7F" , vpermt2d(zmm19, zmm15, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62E205587E9A00020000" , vpermt2d(zmm19, zmm15, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62E205587E5A80" , vpermt2d(zmm19, zmm15, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62E205587E9AFCFDFFFF" , vpermt2d(zmm19, zmm15, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62F2D5407ED4" , vpermt2q(zmm2, zmm21, zmm4));
+ TEST_INSTRUCTION("62F2D5477ED4" , k(k7).vpermt2q(zmm2, zmm21, zmm4));
+ TEST_INSTRUCTION("62F2D5C77ED4" , k(k7).z().vpermt2q(zmm2, zmm21, zmm4));
+ TEST_INSTRUCTION("62F2D5407E11" , vpermt2q(zmm2, zmm21, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2D5407E94F034120000" , vpermt2q(zmm2, zmm21, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2D5507E11" , vpermt2q(zmm2, zmm21, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2D5407E527F" , vpermt2q(zmm2, zmm21, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2D5407E9200200000" , vpermt2q(zmm2, zmm21, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2D5407E5280" , vpermt2q(zmm2, zmm21, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2D5407E92C0DFFFFF" , vpermt2q(zmm2, zmm21, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2D5507E527F" , vpermt2q(zmm2, zmm21, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2D5507E9200040000" , vpermt2q(zmm2, zmm21, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2D5507E5280" , vpermt2q(zmm2, zmm21, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2D5507E92F8FBFFFF" , vpermt2q(zmm2, zmm21, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62F205487FFF" , vpermt2ps(zmm7, zmm15, zmm7));
+ TEST_INSTRUCTION("62F2054F7FFF" , k(k7).vpermt2ps(zmm7, zmm15, zmm7));
+ TEST_INSTRUCTION("62F205CF7FFF" , k(k7).z().vpermt2ps(zmm7, zmm15, zmm7));
+ TEST_INSTRUCTION("62F205487F39" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B205487FBCF034120000" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F205587F39" , vpermt2ps(zmm7, zmm15, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F205487F7A7F" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F205487FBA00200000" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F205487F7A80" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F205487FBAC0DFFFFF" , vpermt2ps(zmm7, zmm15, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F205587F7A7F" , vpermt2ps(zmm7, zmm15, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F205587FBA00020000" , vpermt2ps(zmm7, zmm15, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F205587F7A80" , vpermt2ps(zmm7, zmm15, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F205587FBAFCFDFFFF" , vpermt2ps(zmm7, zmm15, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6212CD407FE1" , vpermt2pd(zmm12, zmm22, zmm25));
+ TEST_INSTRUCTION("6212CD417FE1" , k(k1).vpermt2pd(zmm12, zmm22, zmm25));
+ TEST_INSTRUCTION("6212CDC17FE1" , k(k1).z().vpermt2pd(zmm12, zmm22, zmm25));
+ TEST_INSTRUCTION("6272CD407F21" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6232CD407FA4F034120000" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6272CD507F21" , vpermt2pd(zmm12, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6272CD407F627F" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6272CD407FA200200000" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6272CD407F6280" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6272CD407FA2C0DFFFFF" , vpermt2pd(zmm12, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6272CD507F627F" , vpermt2pd(zmm12, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6272CD507FA200040000" , vpermt2pd(zmm12, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6272CD507F6280" , vpermt2pd(zmm12, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6272CD507FA2F8FBFFFF" , vpermt2pd(zmm12, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6223F54003C8AB" , valignq(zmm25, zmm17, zmm16, 171));
+ TEST_INSTRUCTION("6223F54703C8AB" , k(k7).valignq(zmm25, zmm17, zmm16, 171));
+ TEST_INSTRUCTION("6223F5C703C8AB" , k(k7).z().valignq(zmm25, zmm17, zmm16, 171));
+ TEST_INSTRUCTION("6223F54003C87B" , valignq(zmm25, zmm17, zmm16, 123));
+ TEST_INSTRUCTION("6263F54003097B" , valignq(zmm25, zmm17, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223F540038CF0341200007B" , valignq(zmm25, zmm17, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6263F55003097B" , valignq(zmm25, zmm17, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6263F540034A7F7B" , valignq(zmm25, zmm17, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6263F540038A002000007B" , valignq(zmm25, zmm17, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6263F540034A807B" , valignq(zmm25, zmm17, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6263F540038AC0DFFFFF7B" , valignq(zmm25, zmm17, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6263F550034A7F7B" , valignq(zmm25, zmm17, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6263F550038A000400007B" , valignq(zmm25, zmm17, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263F550034A807B" , valignq(zmm25, zmm17, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6263F550038AF8FBFFFF7B" , valignq(zmm25, zmm17, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62D17F0879C3" , vcvtsd2usi(eax, xmm11));
+ TEST_INSTRUCTION("62D17F1879C3" , rn_sae().vcvtsd2usi(eax, xmm11));
+ TEST_INSTRUCTION("62D17F5879C3" , ru_sae().vcvtsd2usi(eax, xmm11));
+ TEST_INSTRUCTION("62D17F3879C3" , rd_sae().vcvtsd2usi(eax, xmm11));
+ TEST_INSTRUCTION("62D17F7879C3" , rz_sae().vcvtsd2usi(eax, xmm11));
+ TEST_INSTRUCTION("62F17F087901" , vcvtsd2usi(eax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F087984F034120000" , vcvtsd2usi(eax, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17F0879427F" , vcvtsd2usi(eax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F08798200040000" , vcvtsd2usi(eax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08794280" , vcvtsd2usi(eax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F087982F8FBFFFF" , vcvtsd2usi(eax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62D17F0879EB" , vcvtsd2usi(ebp, xmm11));
+ TEST_INSTRUCTION("62D17F1879EB" , rn_sae().vcvtsd2usi(ebp, xmm11));
+ TEST_INSTRUCTION("62D17F5879EB" , ru_sae().vcvtsd2usi(ebp, xmm11));
+ TEST_INSTRUCTION("62D17F3879EB" , rd_sae().vcvtsd2usi(ebp, xmm11));
+ TEST_INSTRUCTION("62D17F7879EB" , rz_sae().vcvtsd2usi(ebp, xmm11));
+ TEST_INSTRUCTION("62F17F087929" , vcvtsd2usi(ebp, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F0879ACF034120000" , vcvtsd2usi(ebp, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17F08796A7F" , vcvtsd2usi(ebp, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F0879AA00040000" , vcvtsd2usi(ebp, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08796A80" , vcvtsd2usi(ebp, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F0879AAF8FBFFFF" , vcvtsd2usi(ebp, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62517F0879EB" , vcvtsd2usi(r13d, xmm11));
+ TEST_INSTRUCTION("62517F1879EB" , rn_sae().vcvtsd2usi(r13d, xmm11));
+ TEST_INSTRUCTION("62517F5879EB" , ru_sae().vcvtsd2usi(r13d, xmm11));
+ TEST_INSTRUCTION("62517F3879EB" , rd_sae().vcvtsd2usi(r13d, xmm11));
+ TEST_INSTRUCTION("62517F7879EB" , rz_sae().vcvtsd2usi(r13d, xmm11));
+ TEST_INSTRUCTION("62717F087929" , vcvtsd2usi(r13d, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62317F0879ACF034120000" , vcvtsd2usi(r13d, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717F08796A7F" , vcvtsd2usi(r13d, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62717F0879AA00040000" , vcvtsd2usi(r13d, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62717F08796A80" , vcvtsd2usi(r13d, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62717F0879AAF8FBFFFF" , vcvtsd2usi(r13d, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62D1FF0879C5" , vcvtsd2usi(rax, xmm13));
+ TEST_INSTRUCTION("62D1FF1879C5" , rn_sae().vcvtsd2usi(rax, xmm13));
+ TEST_INSTRUCTION("62D1FF5879C5" , ru_sae().vcvtsd2usi(rax, xmm13));
+ TEST_INSTRUCTION("62D1FF3879C5" , rd_sae().vcvtsd2usi(rax, xmm13));
+ TEST_INSTRUCTION("62D1FF7879C5" , rz_sae().vcvtsd2usi(rax, xmm13));
+ TEST_INSTRUCTION("62F1FF087901" , vcvtsd2usi(rax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF087984F034120000" , vcvtsd2usi(rax, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FF0879427F" , vcvtsd2usi(rax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1FF08798200040000" , vcvtsd2usi(rax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1FF08794280" , vcvtsd2usi(rax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1FF087982F8FBFFFF" , vcvtsd2usi(rax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6251FF0879C5" , vcvtsd2usi(r8, xmm13));
+ TEST_INSTRUCTION("6251FF1879C5" , rn_sae().vcvtsd2usi(r8, xmm13));
+ TEST_INSTRUCTION("6251FF5879C5" , ru_sae().vcvtsd2usi(r8, xmm13));
+ TEST_INSTRUCTION("6251FF3879C5" , rd_sae().vcvtsd2usi(r8, xmm13));
+ TEST_INSTRUCTION("6251FF7879C5" , rz_sae().vcvtsd2usi(r8, xmm13));
+ TEST_INSTRUCTION("6271FF087901" , vcvtsd2usi(r8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FF087984F034120000" , vcvtsd2usi(r8, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FF0879427F" , vcvtsd2usi(r8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271FF08798200040000" , vcvtsd2usi(r8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271FF08794280" , vcvtsd2usi(r8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271FF087982F8FBFFFF" , vcvtsd2usi(r8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62F17E0879C1" , vcvtss2usi(eax, xmm1));
+ TEST_INSTRUCTION("62F17E1879C1" , rn_sae().vcvtss2usi(eax, xmm1));
+ TEST_INSTRUCTION("62F17E5879C1" , ru_sae().vcvtss2usi(eax, xmm1));
+ TEST_INSTRUCTION("62F17E3879C1" , rd_sae().vcvtss2usi(eax, xmm1));
+ TEST_INSTRUCTION("62F17E7879C1" , rz_sae().vcvtss2usi(eax, xmm1));
+ TEST_INSTRUCTION("62F17E087901" , vcvtss2usi(eax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E087984F034120000" , vcvtss2usi(eax, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17E0879427F" , vcvtss2usi(eax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E08798200020000" , vcvtss2usi(eax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08794280" , vcvtss2usi(eax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E087982FCFDFFFF" , vcvtss2usi(eax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F17E0879E9" , vcvtss2usi(ebp, xmm1));
+ TEST_INSTRUCTION("62F17E1879E9" , rn_sae().vcvtss2usi(ebp, xmm1));
+ TEST_INSTRUCTION("62F17E5879E9" , ru_sae().vcvtss2usi(ebp, xmm1));
+ TEST_INSTRUCTION("62F17E3879E9" , rd_sae().vcvtss2usi(ebp, xmm1));
+ TEST_INSTRUCTION("62F17E7879E9" , rz_sae().vcvtss2usi(ebp, xmm1));
+ TEST_INSTRUCTION("62F17E087929" , vcvtss2usi(ebp, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E0879ACF034120000" , vcvtss2usi(ebp, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17E08796A7F" , vcvtss2usi(ebp, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E0879AA00020000" , vcvtss2usi(ebp, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08796A80" , vcvtss2usi(ebp, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E0879AAFCFDFFFF" , vcvtss2usi(ebp, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62717E0879E9" , vcvtss2usi(r13d, xmm1));
+ TEST_INSTRUCTION("62717E1879E9" , rn_sae().vcvtss2usi(r13d, xmm1));
+ TEST_INSTRUCTION("62717E5879E9" , ru_sae().vcvtss2usi(r13d, xmm1));
+ TEST_INSTRUCTION("62717E3879E9" , rd_sae().vcvtss2usi(r13d, xmm1));
+ TEST_INSTRUCTION("62717E7879E9" , rz_sae().vcvtss2usi(r13d, xmm1));
+ TEST_INSTRUCTION("62717E087929" , vcvtss2usi(r13d, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E0879ACF034120000" , vcvtss2usi(r13d, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717E08796A7F" , vcvtss2usi(r13d, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62717E0879AA00020000" , vcvtss2usi(r13d, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62717E08796A80" , vcvtss2usi(r13d, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62717E0879AAFCFDFFFF" , vcvtss2usi(r13d, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F1FE0879C3" , vcvtss2usi(rax, xmm3));
+ TEST_INSTRUCTION("62F1FE1879C3" , rn_sae().vcvtss2usi(rax, xmm3));
+ TEST_INSTRUCTION("62F1FE5879C3" , ru_sae().vcvtss2usi(rax, xmm3));
+ TEST_INSTRUCTION("62F1FE3879C3" , rd_sae().vcvtss2usi(rax, xmm3));
+ TEST_INSTRUCTION("62F1FE7879C3" , rz_sae().vcvtss2usi(rax, xmm3));
+ TEST_INSTRUCTION("62F1FE087901" , vcvtss2usi(rax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FE087984F034120000" , vcvtss2usi(rax, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FE0879427F" , vcvtss2usi(rax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F1FE08798200020000" , vcvtss2usi(rax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F1FE08794280" , vcvtss2usi(rax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F1FE087982FCFDFFFF" , vcvtss2usi(rax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6271FE0879C3" , vcvtss2usi(r8, xmm3));
+ TEST_INSTRUCTION("6271FE1879C3" , rn_sae().vcvtss2usi(r8, xmm3));
+ TEST_INSTRUCTION("6271FE5879C3" , ru_sae().vcvtss2usi(r8, xmm3));
+ TEST_INSTRUCTION("6271FE3879C3" , rd_sae().vcvtss2usi(r8, xmm3));
+ TEST_INSTRUCTION("6271FE7879C3" , rz_sae().vcvtss2usi(r8, xmm3));
+ TEST_INSTRUCTION("6271FE087901" , vcvtss2usi(r8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FE087984F034120000" , vcvtss2usi(r8, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FE0879427F" , vcvtss2usi(r8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("6271FE08798200020000" , vcvtss2usi(r8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("6271FE08794280" , vcvtss2usi(r8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("6271FE087982FCFDFFFF" , vcvtss2usi(r8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("626177007BD0" , vcvtusi2sd(xmm26, xmm17, eax));
+ TEST_INSTRUCTION("626177007BD5" , vcvtusi2sd(xmm26, xmm17, ebp));
+ TEST_INSTRUCTION("624177007BD5" , vcvtusi2sd(xmm26, xmm17, r13d));
+ TEST_INSTRUCTION("626177007B11" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rcx)));
+ TEST_INSTRUCTION("622177007B94F034120000" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626177007B527F" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("626177007B9200020000" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("626177007B5280" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("626177007B92FCFDFFFF" , vcvtusi2sd(xmm26, xmm17, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6271CF087BD8" , vcvtusi2sd(xmm11, xmm6, rax));
+ TEST_INSTRUCTION("6271CF187BD8" , rn_sae().vcvtusi2sd(xmm11, xmm6, rax));
+ TEST_INSTRUCTION("6271CF587BD8" , ru_sae().vcvtusi2sd(xmm11, xmm6, rax));
+ TEST_INSTRUCTION("6271CF387BD8" , rd_sae().vcvtusi2sd(xmm11, xmm6, rax));
+ TEST_INSTRUCTION("6271CF787BD8" , rz_sae().vcvtusi2sd(xmm11, xmm6, rax));
+ TEST_INSTRUCTION("6251CF087BD8" , vcvtusi2sd(xmm11, xmm6, r8));
+ TEST_INSTRUCTION("6251CF187BD8" , rn_sae().vcvtusi2sd(xmm11, xmm6, r8));
+ TEST_INSTRUCTION("6251CF587BD8" , ru_sae().vcvtusi2sd(xmm11, xmm6, r8));
+ TEST_INSTRUCTION("6251CF387BD8" , rd_sae().vcvtusi2sd(xmm11, xmm6, r8));
+ TEST_INSTRUCTION("6251CF787BD8" , rz_sae().vcvtusi2sd(xmm11, xmm6, r8));
+ TEST_INSTRUCTION("6271CF087B19" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231CF087B9CF034120000" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271CF087B5A7F" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271CF087B9A00040000" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271CF087B5A80" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271CF087B9AF8FBFFFF" , vcvtusi2sd(xmm11, xmm6, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("627146087BC8" , vcvtusi2ss(xmm9, xmm7, eax));
+ TEST_INSTRUCTION("627146187BC8" , rn_sae().vcvtusi2ss(xmm9, xmm7, eax));
+ TEST_INSTRUCTION("627146587BC8" , ru_sae().vcvtusi2ss(xmm9, xmm7, eax));
+ TEST_INSTRUCTION("627146387BC8" , rd_sae().vcvtusi2ss(xmm9, xmm7, eax));
+ TEST_INSTRUCTION("627146787BC8" , rz_sae().vcvtusi2ss(xmm9, xmm7, eax));
+ TEST_INSTRUCTION("627146087BCD" , vcvtusi2ss(xmm9, xmm7, ebp));
+ TEST_INSTRUCTION("627146187BCD" , rn_sae().vcvtusi2ss(xmm9, xmm7, ebp));
+ TEST_INSTRUCTION("627146587BCD" , ru_sae().vcvtusi2ss(xmm9, xmm7, ebp));
+ TEST_INSTRUCTION("627146387BCD" , rd_sae().vcvtusi2ss(xmm9, xmm7, ebp));
+ TEST_INSTRUCTION("627146787BCD" , rz_sae().vcvtusi2ss(xmm9, xmm7, ebp));
+ TEST_INSTRUCTION("625146087BCD" , vcvtusi2ss(xmm9, xmm7, r13d));
+ TEST_INSTRUCTION("625146187BCD" , rn_sae().vcvtusi2ss(xmm9, xmm7, r13d));
+ TEST_INSTRUCTION("625146587BCD" , ru_sae().vcvtusi2ss(xmm9, xmm7, r13d));
+ TEST_INSTRUCTION("625146387BCD" , rd_sae().vcvtusi2ss(xmm9, xmm7, r13d));
+ TEST_INSTRUCTION("625146787BCD" , rz_sae().vcvtusi2ss(xmm9, xmm7, r13d));
+ TEST_INSTRUCTION("627146087B09" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rcx)));
+ TEST_INSTRUCTION("623146087B8CF034120000" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("627146087B4A7F" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("627146087B8A00020000" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("627146087B4A80" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("627146087B8AFCFDFFFF" , vcvtusi2ss(xmm9, xmm7, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62E1AE087BE8" , vcvtusi2ss(xmm21, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE187BE8" , rn_sae().vcvtusi2ss(xmm21, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE587BE8" , ru_sae().vcvtusi2ss(xmm21, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE387BE8" , rd_sae().vcvtusi2ss(xmm21, xmm10, rax));
+ TEST_INSTRUCTION("62E1AE787BE8" , rz_sae().vcvtusi2ss(xmm21, xmm10, rax));
+ TEST_INSTRUCTION("62C1AE087BE8" , vcvtusi2ss(xmm21, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE187BE8" , rn_sae().vcvtusi2ss(xmm21, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE587BE8" , ru_sae().vcvtusi2ss(xmm21, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE387BE8" , rd_sae().vcvtusi2ss(xmm21, xmm10, r8));
+ TEST_INSTRUCTION("62C1AE787BE8" , rz_sae().vcvtusi2ss(xmm21, xmm10, r8));
+ TEST_INSTRUCTION("62E1AE087B29" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1AE087BACF034120000" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1AE087B6A7F" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62E1AE087BAA00040000" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62E1AE087B6A80" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62E1AE087BAAF8FBFFFF" , vcvtusi2ss(xmm21, xmm10, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B2DD482CF8" , vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DD4D2CF8" , k(k5).vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DDCD2CF8" , k(k5).z().vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DD182CF8" , rn_sae().vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DD582CF8" , ru_sae().vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DD382CF8" , rd_sae().vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62B2DD782CF8" , rz_sae().vscalefpd(zmm7, zmm4, zmm16));
+ TEST_INSTRUCTION("62F2DD482C39" , vscalefpd(zmm7, zmm4, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B2DD482CBCF034120000" , vscalefpd(zmm7, zmm4, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F2DD582C39" , vscalefpd(zmm7, zmm4, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62F2DD482C7A7F" , vscalefpd(zmm7, zmm4, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F2DD482CBA00200000" , vscalefpd(zmm7, zmm4, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F2DD482C7A80" , vscalefpd(zmm7, zmm4, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F2DD482CBAC0DFFFFF" , vscalefpd(zmm7, zmm4, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F2DD582C7A7F" , vscalefpd(zmm7, zmm4, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62F2DD582CBA00040000" , vscalefpd(zmm7, zmm4, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62F2DD582C7A80" , vscalefpd(zmm7, zmm4, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F2DD582CBAF8FBFFFF" , vscalefpd(zmm7, zmm4, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B225482CE3" , vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B2254A2CE3" , k(k2).vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B225CA2CE3" , k(k2).z().vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B225182CE3" , rn_sae().vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B225582CE3" , ru_sae().vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B225382CE3" , rd_sae().vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62B225782CE3" , rz_sae().vscalefps(zmm4, zmm11, zmm19));
+ TEST_INSTRUCTION("62F225482C21" , vscalefps(zmm4, zmm11, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B225482CA4F034120000" , vscalefps(zmm4, zmm11, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F225582C21" , vscalefps(zmm4, zmm11, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F225482C627F" , vscalefps(zmm4, zmm11, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F225482CA200200000" , vscalefps(zmm4, zmm11, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F225482C6280" , vscalefps(zmm4, zmm11, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F225482CA2C0DFFFFF" , vscalefps(zmm4, zmm11, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F225582C627F" , vscalefps(zmm4, zmm11, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F225582CA200020000" , vscalefps(zmm4, zmm11, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F225582C6280" , vscalefps(zmm4, zmm11, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F225582CA2FCFDFFFF" , vscalefps(zmm4, zmm11, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6222E5002DEE" , vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5042DEE" , k(k4).vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5842DEE" , k(k4).z().vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5102DEE" , rn_sae().vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5502DEE" , ru_sae().vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5302DEE" , rd_sae().vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6222E5702DEE" , rz_sae().vscalefsd(xmm29, xmm19, xmm22));
+ TEST_INSTRUCTION("6262E5002D29" , vscalefsd(xmm29, xmm19, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6222E5002DACF034120000" , vscalefsd(xmm29, xmm19, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262E5002D6A7F" , vscalefsd(xmm29, xmm19, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6262E5002DAA00040000" , vscalefsd(xmm29, xmm19, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6262E5002D6A80" , vscalefsd(xmm29, xmm19, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6262E5002DAAF8FBFFFF" , vscalefsd(xmm29, xmm19, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62E21D082DE6" , vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D0A2DE6" , k(k2).vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D8A2DE6" , k(k2).z().vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D182DE6" , rn_sae().vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D582DE6" , ru_sae().vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D382DE6" , rd_sae().vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D782DE6" , rz_sae().vscalefss(xmm20, xmm12, xmm6));
+ TEST_INSTRUCTION("62E21D082D21" , vscalefss(xmm20, xmm12, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62A21D082DA4F034120000" , vscalefss(xmm20, xmm12, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E21D082D627F" , vscalefss(xmm20, xmm12, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62E21D082DA200020000" , vscalefss(xmm20, xmm12, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62E21D082D6280" , vscalefss(xmm20, xmm12, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62E21D082DA2FCFDFFFF" , vscalefss(xmm20, xmm12, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F33D4854E7AB" , vfixupimmps(zmm4, zmm8, zmm7, 171));
+ TEST_INSTRUCTION("62F33D4F54E7AB" , k(k7).vfixupimmps(zmm4, zmm8, zmm7, 171));
+ TEST_INSTRUCTION("62F33DCF54E7AB" , k(k7).z().vfixupimmps(zmm4, zmm8, zmm7, 171));
+ TEST_INSTRUCTION("62F33D1854E7AB" , sae().vfixupimmps(zmm4, zmm8, zmm7, 171));
+ TEST_INSTRUCTION("62F33D4854E77B" , vfixupimmps(zmm4, zmm8, zmm7, 123));
+ TEST_INSTRUCTION("62F33D1854E77B" , sae().vfixupimmps(zmm4, zmm8, zmm7, 123));
+ TEST_INSTRUCTION("62F33D4854217B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B33D4854A4F0341200007B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F33D5854217B" , vfixupimmps(zmm4, zmm8, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D4854627F7B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F33D4854A2002000007B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F33D485462807B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F33D4854A2C0DFFFFF7B" , vfixupimmps(zmm4, zmm8, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F33D5854627F7B" , vfixupimmps(zmm4, zmm8, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D5854A2000200007B" , vfixupimmps(zmm4, zmm8, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D585462807B" , vfixupimmps(zmm4, zmm8, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F33D5854A2FCFDFFFF7B" , vfixupimmps(zmm4, zmm8, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6273D54854FDAB" , vfixupimmpd(zmm15, zmm5, zmm5, 171));
+ TEST_INSTRUCTION("6273D54D54FDAB" , k(k5).vfixupimmpd(zmm15, zmm5, zmm5, 171));
+ TEST_INSTRUCTION("6273D5CD54FDAB" , k(k5).z().vfixupimmpd(zmm15, zmm5, zmm5, 171));
+ TEST_INSTRUCTION("6273D51854FDAB" , sae().vfixupimmpd(zmm15, zmm5, zmm5, 171));
+ TEST_INSTRUCTION("6273D54854FD7B" , vfixupimmpd(zmm15, zmm5, zmm5, 123));
+ TEST_INSTRUCTION("6273D51854FD7B" , sae().vfixupimmpd(zmm15, zmm5, zmm5, 123));
+ TEST_INSTRUCTION("6273D54854397B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233D54854BCF0341200007B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273D55854397B" , vfixupimmpd(zmm15, zmm5, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273D548547A7F7B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273D54854BA002000007B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273D548547A807B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273D54854BAC0DFFFFF7B" , vfixupimmpd(zmm15, zmm5, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273D558547A7F7B" , vfixupimmpd(zmm15, zmm5, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273D55854BA000400007B" , vfixupimmpd(zmm15, zmm5, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273D558547A807B" , vfixupimmpd(zmm15, zmm5, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273D55854BAF8FBFFFF7B" , vfixupimmpd(zmm15, zmm5, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62633D0055CFAB" , vfixupimmss(xmm25, xmm24, xmm7, 171));
+ TEST_INSTRUCTION("62633D0455CFAB" , k(k4).vfixupimmss(xmm25, xmm24, xmm7, 171));
+ TEST_INSTRUCTION("62633D8455CFAB" , k(k4).z().vfixupimmss(xmm25, xmm24, xmm7, 171));
+ TEST_INSTRUCTION("62633D1055CFAB" , sae().vfixupimmss(xmm25, xmm24, xmm7, 171));
+ TEST_INSTRUCTION("62633D0055CF7B" , vfixupimmss(xmm25, xmm24, xmm7, 123));
+ TEST_INSTRUCTION("62633D1055CF7B" , sae().vfixupimmss(xmm25, xmm24, xmm7, 123));
+ TEST_INSTRUCTION("62633D0055097B" , vfixupimmss(xmm25, xmm24, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62233D00558CF0341200007B" , vfixupimmss(xmm25, xmm24, dword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62633D00554A7F7B" , vfixupimmss(xmm25, xmm24, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62633D00558A000200007B" , vfixupimmss(xmm25, xmm24, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62633D00554A807B" , vfixupimmss(xmm25, xmm24, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62633D00558AFCFDFFFF7B" , vfixupimmss(xmm25, xmm24, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62239D0855C0AB" , vfixupimmsd(xmm24, xmm12, xmm16, 171));
+ TEST_INSTRUCTION("62239D0A55C0AB" , k(k2).vfixupimmsd(xmm24, xmm12, xmm16, 171));
+ TEST_INSTRUCTION("62239D8A55C0AB" , k(k2).z().vfixupimmsd(xmm24, xmm12, xmm16, 171));
+ TEST_INSTRUCTION("62239D1855C0AB" , sae().vfixupimmsd(xmm24, xmm12, xmm16, 171));
+ TEST_INSTRUCTION("62239D0855C07B" , vfixupimmsd(xmm24, xmm12, xmm16, 123));
+ TEST_INSTRUCTION("62239D1855C07B" , sae().vfixupimmsd(xmm24, xmm12, xmm16, 123));
+ TEST_INSTRUCTION("62639D0855017B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62239D085584F0341200007B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62639D0855427F7B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("62639D085582000400007B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("62639D085542807B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("62639D085582F8FBFFFF7B" , vfixupimmsd(xmm24, xmm12, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62F1254072F5AB" , vpslld(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F1254172F5AB" , k(k1).vpslld(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F125C172F5AB" , k(k1).z().vpslld(zmm27, zmm5, 171));
+ TEST_INSTRUCTION("62F1254072F57B" , vpslld(zmm27, zmm5, 123));
+ TEST_INSTRUCTION("62F1254072317B" , vpslld(zmm27, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1254072B4F0341200007B" , vpslld(zmm27, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1255072317B" , vpslld(zmm27, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1254072727F7B" , vpslld(zmm27, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1254072B2002000007B" , vpslld(zmm27, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F125407272807B" , vpslld(zmm27, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1254072B2C0DFFFFF7B" , vpslld(zmm27, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1255072727F7B" , vpslld(zmm27, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F1255072B2000200007B" , vpslld(zmm27, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F125507272807B" , vpslld(zmm27, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F1255072B2FCFDFFFF7B" , vpslld(zmm27, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62F1DD4873F6AB" , vpsllq(zmm4, zmm6, 171));
+ TEST_INSTRUCTION("62F1DD4C73F6AB" , k(k4).vpsllq(zmm4, zmm6, 171));
+ TEST_INSTRUCTION("62F1DDCC73F6AB" , k(k4).z().vpsllq(zmm4, zmm6, 171));
+ TEST_INSTRUCTION("62F1DD4873F67B" , vpsllq(zmm4, zmm6, 123));
+ TEST_INSTRUCTION("62F1DD4873317B" , vpsllq(zmm4, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1DD4873B4F0341200007B" , vpsllq(zmm4, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1DD5873317B" , vpsllq(zmm4, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1DD4873727F7B" , vpsllq(zmm4, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1DD4873B2002000007B" , vpsllq(zmm4, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1DD487372807B" , vpsllq(zmm4, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1DD4873B2C0DFFFFF7B" , vpsllq(zmm4, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1DD5873727F7B" , vpsllq(zmm4, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1DD5873B2000400007B" , vpsllq(zmm4, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1DD587372807B" , vpsllq(zmm4, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1DD5873B2F8FBFFFF7B" , vpsllq(zmm4, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62B13D4872E4AB" , vpsrad(zmm8, zmm20, 171));
+ TEST_INSTRUCTION("62B13D4A72E4AB" , k(k2).vpsrad(zmm8, zmm20, 171));
+ TEST_INSTRUCTION("62B13DCA72E4AB" , k(k2).z().vpsrad(zmm8, zmm20, 171));
+ TEST_INSTRUCTION("62B13D4872E47B" , vpsrad(zmm8, zmm20, 123));
+ TEST_INSTRUCTION("62F13D4872217B" , vpsrad(zmm8, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B13D4872A4F0341200007B" , vpsrad(zmm8, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F13D5872217B" , vpsrad(zmm8, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F13D4872627F7B" , vpsrad(zmm8, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F13D4872A2002000007B" , vpsrad(zmm8, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F13D487262807B" , vpsrad(zmm8, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F13D4872A2C0DFFFFF7B" , vpsrad(zmm8, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F13D5872627F7B" , vpsrad(zmm8, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F13D5872A2000200007B" , vpsrad(zmm8, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F13D587262807B" , vpsrad(zmm8, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F13D5872A2FCFDFFFF7B" , vpsrad(zmm8, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("62B1E54872E2AB" , vpsraq(zmm3, zmm18, 171));
+ TEST_INSTRUCTION("62B1E54E72E2AB" , k(k6).vpsraq(zmm3, zmm18, 171));
+ TEST_INSTRUCTION("62B1E5CE72E2AB" , k(k6).z().vpsraq(zmm3, zmm18, 171));
+ TEST_INSTRUCTION("62B1E54872E27B" , vpsraq(zmm3, zmm18, 123));
+ TEST_INSTRUCTION("62F1E54872217B" , vpsraq(zmm3, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1E54872A4F0341200007B" , vpsraq(zmm3, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1E55872217B" , vpsraq(zmm3, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E54872627F7B" , vpsraq(zmm3, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1E54872A2002000007B" , vpsraq(zmm3, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1E5487262807B" , vpsraq(zmm3, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1E54872A2C0DFFFFF7B" , vpsraq(zmm3, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1E55872627F7B" , vpsraq(zmm3, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E55872A2000400007B" , vpsraq(zmm3, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E5587262807B" , vpsraq(zmm3, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1E55872A2F8FBFFFF7B" , vpsraq(zmm3, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("6242754815E2" , vprolvd(zmm28, zmm1, zmm10));
+ TEST_INSTRUCTION("6242754E15E2" , k(k6).vprolvd(zmm28, zmm1, zmm10));
+ TEST_INSTRUCTION("624275CE15E2" , k(k6).z().vprolvd(zmm28, zmm1, zmm10));
+ TEST_INSTRUCTION("626275481521" , vprolvd(zmm28, zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222754815A4F034120000" , vprolvd(zmm28, zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("626275581521" , vprolvd(zmm28, zmm1, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("6262754815627F" , vprolvd(zmm28, zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262754815A200200000" , vprolvd(zmm28, zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62627548156280" , vprolvd(zmm28, zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262754815A2C0DFFFFF" , vprolvd(zmm28, zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262755815627F" , vprolvd(zmm28, zmm1, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("6262755815A200020000" , vprolvd(zmm28, zmm1, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62627558156280" , vprolvd(zmm28, zmm1, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("6262755815A2FCFDFFFF" , vprolvd(zmm28, zmm1, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6291654072CBAB" , vprold(zmm19, zmm27, 171));
+ TEST_INSTRUCTION("6291654472CBAB" , k(k4).vprold(zmm19, zmm27, 171));
+ TEST_INSTRUCTION("629165C472CBAB" , k(k4).z().vprold(zmm19, zmm27, 171));
+ TEST_INSTRUCTION("6291654072CB7B" , vprold(zmm19, zmm27, 123));
+ TEST_INSTRUCTION("62F1654072097B" , vprold(zmm19, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B16540728CF0341200007B" , vprold(zmm19, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1655072097B" , vprold(zmm19, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F16540724A7F7B" , vprold(zmm19, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F16540728A002000007B" , vprold(zmm19, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F16540724A807B" , vprold(zmm19, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F16540728AC0DFFFFF7B" , vprold(zmm19, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F16550724A7F7B" , vprold(zmm19, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F16550728A000200007B" , vprold(zmm19, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F16550724A807B" , vprold(zmm19, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F16550728AFCFDFFFF7B" , vprold(zmm19, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6222F54815CE" , vprolvq(zmm25, zmm1, zmm22));
+ TEST_INSTRUCTION("6222F54F15CE" , k(k7).vprolvq(zmm25, zmm1, zmm22));
+ TEST_INSTRUCTION("6222F5CF15CE" , k(k7).z().vprolvq(zmm25, zmm1, zmm22));
+ TEST_INSTRUCTION("6262F5481509" , vprolvq(zmm25, zmm1, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("6222F548158CF034120000" , vprolvq(zmm25, zmm1, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6262F5581509" , vprolvq(zmm25, zmm1, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("6262F548154A7F" , vprolvq(zmm25, zmm1, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("6262F548158A00200000" , vprolvq(zmm25, zmm1, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("6262F548154A80" , vprolvq(zmm25, zmm1, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("6262F548158AC0DFFFFF" , vprolvq(zmm25, zmm1, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("6262F558154A7F" , vprolvq(zmm25, zmm1, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("6262F558158A00040000" , vprolvq(zmm25, zmm1, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("6262F558154A80" , vprolvq(zmm25, zmm1, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("6262F558158AF8FBFFFF" , vprolvq(zmm25, zmm1, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D1F54072CAAB" , vprolq(zmm17, zmm10, 171));
+ TEST_INSTRUCTION("62D1F54472CAAB" , k(k4).vprolq(zmm17, zmm10, 171));
+ TEST_INSTRUCTION("62D1F5C472CAAB" , k(k4).z().vprolq(zmm17, zmm10, 171));
+ TEST_INSTRUCTION("62D1F54072CA7B" , vprolq(zmm17, zmm10, 123));
+ TEST_INSTRUCTION("62F1F54072097B" , vprolq(zmm17, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1F540728CF0341200007B" , vprolq(zmm17, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1F55072097B" , vprolq(zmm17, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1F540724A7F7B" , vprolq(zmm17, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1F540728A002000007B" , vprolq(zmm17, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1F540724A807B" , vprolq(zmm17, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1F540728AC0DFFFFF7B" , vprolq(zmm17, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1F550724A7F7B" , vprolq(zmm17, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1F550728A000400007B" , vprolq(zmm17, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1F550724A807B" , vprolq(zmm17, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1F550728AF8FBFFFF7B" , vprolq(zmm17, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62D23D4814CD" , vprorvd(zmm1, zmm8, zmm13));
+ TEST_INSTRUCTION("62D23D4A14CD" , k(k2).vprorvd(zmm1, zmm8, zmm13));
+ TEST_INSTRUCTION("62D23DCA14CD" , k(k2).z().vprorvd(zmm1, zmm8, zmm13));
+ TEST_INSTRUCTION("62F23D481409" , vprorvd(zmm1, zmm8, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B23D48148CF034120000" , vprorvd(zmm1, zmm8, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F23D581409" , vprorvd(zmm1, zmm8, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F23D48144A7F" , vprorvd(zmm1, zmm8, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F23D48148A00200000" , vprorvd(zmm1, zmm8, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F23D48144A80" , vprorvd(zmm1, zmm8, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F23D48148AC0DFFFFF" , vprorvd(zmm1, zmm8, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F23D58144A7F" , vprorvd(zmm1, zmm8, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F23D58148A00020000" , vprorvd(zmm1, zmm8, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F23D58144A80" , vprorvd(zmm1, zmm8, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F23D58148AFCFDFFFF" , vprorvd(zmm1, zmm8, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62D1454872C7AB" , vprord(zmm7, zmm15, 171));
+ TEST_INSTRUCTION("62D1454972C7AB" , k(k1).vprord(zmm7, zmm15, 171));
+ TEST_INSTRUCTION("62D145C972C7AB" , k(k1).z().vprord(zmm7, zmm15, 171));
+ TEST_INSTRUCTION("62D1454872C77B" , vprord(zmm7, zmm15, 123));
+ TEST_INSTRUCTION("62F1454872017B" , vprord(zmm7, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B145487284F0341200007B" , vprord(zmm7, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1455872017B" , vprord(zmm7, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62F1454872427F7B" , vprord(zmm7, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F145487282002000007B" , vprord(zmm7, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F145487242807B" , vprord(zmm7, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F145487282C0DFFFFF7B" , vprord(zmm7, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1455872427F7B" , vprord(zmm7, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62F145587282000200007B" , vprord(zmm7, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62F145587242807B" , vprord(zmm7, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62F145587282FCFDFFFF7B" , vprord(zmm7, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6282C54014E8" , vprorvq(zmm21, zmm23, zmm24));
+ TEST_INSTRUCTION("6282C54714E8" , k(k7).vprorvq(zmm21, zmm23, zmm24));
+ TEST_INSTRUCTION("6282C5C714E8" , k(k7).z().vprorvq(zmm21, zmm23, zmm24));
+ TEST_INSTRUCTION("62E2C5401429" , vprorvq(zmm21, zmm23, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2C54014ACF034120000" , vprorvq(zmm21, zmm23, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2C5501429" , vprorvq(zmm21, zmm23, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2C540146A7F" , vprorvq(zmm21, zmm23, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2C54014AA00200000" , vprorvq(zmm21, zmm23, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2C540146A80" , vprorvq(zmm21, zmm23, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2C54014AAC0DFFFFF" , vprorvq(zmm21, zmm23, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2C550146A7F" , vprorvq(zmm21, zmm23, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2C55014AA00040000" , vprorvq(zmm21, zmm23, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2C550146A80" , vprorvq(zmm21, zmm23, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2C55014AAF8FBFFFF" , vprorvq(zmm21, zmm23, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("6291FD4072C3AB" , vprorq(zmm16, zmm27, 171));
+ TEST_INSTRUCTION("6291FD4372C3AB" , k(k3).vprorq(zmm16, zmm27, 171));
+ TEST_INSTRUCTION("6291FDC372C3AB" , k(k3).z().vprorq(zmm16, zmm27, 171));
+ TEST_INSTRUCTION("6291FD4072C37B" , vprorq(zmm16, zmm27, 123));
+ TEST_INSTRUCTION("62F1FD4072017B" , vprorq(zmm16, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B1FD407284F0341200007B" , vprorq(zmm16, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F1FD5072017B" , vprorq(zmm16, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("62F1FD4072427F7B" , vprorq(zmm16, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62F1FD407282002000007B" , vprorq(zmm16, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62F1FD407242807B" , vprorq(zmm16, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62F1FD407282C0DFFFFF7B" , vprorq(zmm16, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62F1FD5072427F7B" , vprorq(zmm16, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("62F1FD507282000400007B" , vprorq(zmm16, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1FD507242807B" , vprorq(zmm16, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("62F1FD507282F8FBFFFF7B" , vprorq(zmm16, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("6213FD4809EAAB" , vrndscalepd(zmm13, zmm26, 171));
+ TEST_INSTRUCTION("6213FD4A09EAAB" , k(k2).vrndscalepd(zmm13, zmm26, 171));
+ TEST_INSTRUCTION("6213FDCA09EAAB" , k(k2).z().vrndscalepd(zmm13, zmm26, 171));
+ TEST_INSTRUCTION("6213FD1809EAAB" , sae().vrndscalepd(zmm13, zmm26, 171));
+ TEST_INSTRUCTION("6213FD4809EA7B" , vrndscalepd(zmm13, zmm26, 123));
+ TEST_INSTRUCTION("6213FD1809EA7B" , sae().vrndscalepd(zmm13, zmm26, 123));
+ TEST_INSTRUCTION("6273FD4809297B" , vrndscalepd(zmm13, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6233FD4809ACF0341200007B" , vrndscalepd(zmm13, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6273FD5809297B" , vrndscalepd(zmm13, qword_ptr(rcx)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD48096A7F7B" , vrndscalepd(zmm13, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("6273FD4809AA002000007B" , vrndscalepd(zmm13, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("6273FD48096A807B" , vrndscalepd(zmm13, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("6273FD4809AAC0DFFFFF7B" , vrndscalepd(zmm13, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("6273FD58096A7F7B" , vrndscalepd(zmm13, qword_ptr(rdx, 1016)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD5809AA000400007B" , vrndscalepd(zmm13, qword_ptr(rdx, 1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD58096A807B" , vrndscalepd(zmm13, qword_ptr(rdx, -1024)._1to8(), 123));
+ TEST_INSTRUCTION("6273FD5809AAF8FBFFFF7B" , vrndscalepd(zmm13, qword_ptr(rdx, -1032)._1to8(), 123));
+ TEST_INSTRUCTION("62637D4808C7AB" , vrndscaleps(zmm24, zmm7, 171));
+ TEST_INSTRUCTION("62637D4908C7AB" , k(k1).vrndscaleps(zmm24, zmm7, 171));
+ TEST_INSTRUCTION("62637DC908C7AB" , k(k1).z().vrndscaleps(zmm24, zmm7, 171));
+ TEST_INSTRUCTION("62637D1808C7AB" , sae().vrndscaleps(zmm24, zmm7, 171));
+ TEST_INSTRUCTION("62637D4808C77B" , vrndscaleps(zmm24, zmm7, 123));
+ TEST_INSTRUCTION("62637D1808C77B" , sae().vrndscaleps(zmm24, zmm7, 123));
+ TEST_INSTRUCTION("62637D4808017B" , vrndscaleps(zmm24, zmmword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62237D480884F0341200007B" , vrndscaleps(zmm24, zmmword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62637D5808017B" , vrndscaleps(zmm24, dword_ptr(rcx)._1to16(), 123));
+ TEST_INSTRUCTION("62637D4808427F7B" , vrndscaleps(zmm24, zmmword_ptr(rdx, 8128), 123));
+ TEST_INSTRUCTION("62637D480882002000007B" , vrndscaleps(zmm24, zmmword_ptr(rdx, 8192), 123));
+ TEST_INSTRUCTION("62637D480842807B" , vrndscaleps(zmm24, zmmword_ptr(rdx, -8192), 123));
+ TEST_INSTRUCTION("62637D480882C0DFFFFF7B" , vrndscaleps(zmm24, zmmword_ptr(rdx, -8256), 123));
+ TEST_INSTRUCTION("62637D5808427F7B" , vrndscaleps(zmm24, dword_ptr(rdx, 508)._1to16(), 123));
+ TEST_INSTRUCTION("62637D580882000200007B" , vrndscaleps(zmm24, dword_ptr(rdx, 512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D580842807B" , vrndscaleps(zmm24, dword_ptr(rdx, -512)._1to16(), 123));
+ TEST_INSTRUCTION("62637D580882FCFDFFFF7B" , vrndscaleps(zmm24, dword_ptr(rdx, -516)._1to16(), 123));
+ TEST_INSTRUCTION("6223C5080BD2AB" , vrndscalesd(xmm26, xmm7, xmm18, 171));
+ TEST_INSTRUCTION("6223C5090BD2AB" , k(k1).vrndscalesd(xmm26, xmm7, xmm18, 171));
+ TEST_INSTRUCTION("6223C5890BD2AB" , k(k1).z().vrndscalesd(xmm26, xmm7, xmm18, 171));
+ TEST_INSTRUCTION("6223C5180BD2AB" , sae().vrndscalesd(xmm26, xmm7, xmm18, 171));
+ TEST_INSTRUCTION("6223C5080BD27B" , vrndscalesd(xmm26, xmm7, xmm18, 123));
+ TEST_INSTRUCTION("6223C5180BD27B" , sae().vrndscalesd(xmm26, xmm7, xmm18, 123));
+ TEST_INSTRUCTION("6263C5080B117B" , vrndscalesd(xmm26, xmm7, qword_ptr(rcx), 123));
+ TEST_INSTRUCTION("6223C5080B94F0341200007B" , vrndscalesd(xmm26, xmm7, qword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("6263C5080B527F7B" , vrndscalesd(xmm26, xmm7, qword_ptr(rdx, 1016), 123));
+ TEST_INSTRUCTION("6263C5080B92000400007B" , vrndscalesd(xmm26, xmm7, qword_ptr(rdx, 1024), 123));
+ TEST_INSTRUCTION("6263C5080B52807B" , vrndscalesd(xmm26, xmm7, qword_ptr(rdx, -1024), 123));
+ TEST_INSTRUCTION("6263C5080B92F8FBFFFF7B" , vrndscalesd(xmm26, xmm7, qword_ptr(rdx, -1032), 123));
+ TEST_INSTRUCTION("62F345000AFEAB" , vrndscaless(xmm7, xmm23, xmm6, 171));
+ TEST_INSTRUCTION("62F345040AFEAB" , k(k4).vrndscaless(xmm7, xmm23, xmm6, 171));
+ TEST_INSTRUCTION("62F345840AFEAB" , k(k4).z().vrndscaless(xmm7, xmm23, xmm6, 171));
+ TEST_INSTRUCTION("62F345100AFEAB" , sae().vrndscaless(xmm7, xmm23, xmm6, 171));
+ TEST_INSTRUCTION("62F345000AFE7B" , vrndscaless(xmm7, xmm23, xmm6, 123));
+ TEST_INSTRUCTION("62F345100AFE7B" , sae().vrndscaless(xmm7, xmm23, xmm6, 123));
+ TEST_INSTRUCTION("62F345000A397B" , vrndscaless(xmm7, xmm23, dword_ptr(rcx), 123));
+ TEST_INSTRUCTION("62B345000ABCF0341200007B" , vrndscaless(xmm7, xmm23, dword_ptr(rax, r14, 3, 4660), 123));
+ TEST_INSTRUCTION("62F345000A7A7F7B" , vrndscaless(xmm7, xmm23, dword_ptr(rdx, 508), 123));
+ TEST_INSTRUCTION("62F345000ABA000200007B" , vrndscaless(xmm7, xmm23, dword_ptr(rdx, 512), 123));
+ TEST_INSTRUCTION("62F345000A7A807B" , vrndscaless(xmm7, xmm23, dword_ptr(rdx, -512), 123));
+ TEST_INSTRUCTION("62F345000ABAFCFDFFFF7B" , vrndscaless(xmm7, xmm23, dword_ptr(rdx, -516), 123));
+ TEST_INSTRUCTION("62E2FD488B19" , vpcompressq(zmmword_ptr(rcx), zmm19));
+ TEST_INSTRUCTION("62E2FD4B8B19" , k(k3).vpcompressq(zmmword_ptr(rcx), zmm19));
+ TEST_INSTRUCTION("62A2FD488B9CF034120000" , vpcompressq(zmmword_ptr(rax, r14, 3, 4660), zmm19));
+ TEST_INSTRUCTION("62E2FD488B5A7F" , vpcompressq(zmmword_ptr(rdx, 1016), zmm19));
+ TEST_INSTRUCTION("62E2FD488B9A00040000" , vpcompressq(zmmword_ptr(rdx, 1024), zmm19));
+ TEST_INSTRUCTION("62E2FD488B5A80" , vpcompressq(zmmword_ptr(rdx, -1024), zmm19));
+ TEST_INSTRUCTION("62E2FD488B9AF8FBFFFF" , vpcompressq(zmmword_ptr(rdx, -1032), zmm19));
+ TEST_INSTRUCTION("6252FD488BC4" , vpcompressq(zmm12, zmm8));
+ TEST_INSTRUCTION("6252FD4E8BC4" , k(k6).vpcompressq(zmm12, zmm8));
+ TEST_INSTRUCTION("6252FDCE8BC4" , k(k6).z().vpcompressq(zmm12, zmm8));
+ TEST_INSTRUCTION("C5DC41EE" , kandw(k5, k4, k6));
+ TEST_INSTRUCTION("C5DC42EE" , kandnw(k5, k4, k6));
+ TEST_INSTRUCTION("C5E445D5" , korw(k2, k3, k5));
+ TEST_INSTRUCTION("C5CC46D7" , kxnorw(k2, k6, k7));
+ TEST_INSTRUCTION("C5DC47DE" , kxorw(k3, k4, k6));
+ TEST_INSTRUCTION("C5F844E3" , knotw(k4, k3));
+ TEST_INSTRUCTION("C5F898DE" , kortestw(k3, k6));
+ TEST_INSTRUCTION("C4E3F930DDAB" , kshiftrw(k3, k5, 171));
+ TEST_INSTRUCTION("C4E3F930DD7B" , kshiftrw(k3, k5, 123));
+ TEST_INSTRUCTION("C4E3F932DBAB" , kshiftlw(k3, k3, 171));
+ TEST_INSTRUCTION("C4E3F932DB7B" , kshiftlw(k3, k3, 123));
+ TEST_INSTRUCTION("C5F890D5" , kmovw(k2, k5));
+ TEST_INSTRUCTION("C5F89011" , kmovw(k2, word_ptr(rcx)));
+ TEST_INSTRUCTION("C4A1789094F034120000" , kmovw(k2, word_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("C5F89129" , kmovw(word_ptr(rcx), k5));
+ TEST_INSTRUCTION("C4A17891ACF034120000" , kmovw(word_ptr(rax, r14, 3, 4660), k5));
+ TEST_INSTRUCTION("C5F892D8" , kmovw(k3, eax));
+ TEST_INSTRUCTION("C5F892DD" , kmovw(k3, ebp));
+ TEST_INSTRUCTION("C4C17892DD" , kmovw(k3, r13d));
+ TEST_INSTRUCTION("C5F893C3" , kmovw(eax, k3));
+ TEST_INSTRUCTION("C5F893EB" , kmovw(ebp, k3));
+ TEST_INSTRUCTION("C57893EB" , kmovw(r13d, k3));
+ TEST_INSTRUCTION("C5E54BD7" , kunpckbw(k2, k3, k7));
+ TEST_INSTRUCTION("62F37D481D31AB" , vcvtps2ph(ymmword_ptr(rcx), zmm6, 171));
+ TEST_INSTRUCTION("62F37D491D31AB" , k(k1).vcvtps2ph(ymmword_ptr(rcx), zmm6, 171));
+ TEST_INSTRUCTION("62F37D481D317B" , vcvtps2ph(ymmword_ptr(rcx), zmm6, 123));
+ TEST_INSTRUCTION("62B37D481DB4F0341200007B" , vcvtps2ph(ymmword_ptr(rax, r14, 3, 4660), zmm6, 123));
+ TEST_INSTRUCTION("62F37D481D727F7B" , vcvtps2ph(ymmword_ptr(rdx, 4064), zmm6, 123));
+ TEST_INSTRUCTION("62F37D481DB2001000007B" , vcvtps2ph(ymmword_ptr(rdx, 4096), zmm6, 123));
+ TEST_INSTRUCTION("62F37D481D72807B" , vcvtps2ph(ymmword_ptr(rdx, -4096), zmm6, 123));
+ TEST_INSTRUCTION("62F37D481DB2E0EFFFFF7B" , vcvtps2ph(ymmword_ptr(rdx, -4128), zmm6, 123));
+ TEST_INSTRUCTION("62E37D481931AB" , vextractf32x4(xmmword_ptr(rcx), zmm22, 171));
+ TEST_INSTRUCTION("62E37D4B1931AB" , k(k3).vextractf32x4(xmmword_ptr(rcx), zmm22, 171));
+ TEST_INSTRUCTION("62E37D4819317B" , vextractf32x4(xmmword_ptr(rcx), zmm22, 123));
+ TEST_INSTRUCTION("62A37D4819B4F0341200007B" , vextractf32x4(xmmword_ptr(rax, r14, 3, 4660), zmm22, 123));
+ TEST_INSTRUCTION("62E37D4819727F7B" , vextractf32x4(xmmword_ptr(rdx, 2032), zmm22, 123));
+ TEST_INSTRUCTION("62E37D4819B2000800007B" , vextractf32x4(xmmword_ptr(rdx, 2048), zmm22, 123));
+ TEST_INSTRUCTION("62E37D481972807B" , vextractf32x4(xmmword_ptr(rdx, -2048), zmm22, 123));
+ TEST_INSTRUCTION("62E37D4819B2F0F7FFFF7B" , vextractf32x4(xmmword_ptr(rdx, -2064), zmm22, 123));
+ TEST_INSTRUCTION("6273FD481B21AB" , vextractf64x4(ymmword_ptr(rcx), zmm12, 171));
+ TEST_INSTRUCTION("6273FD4F1B21AB" , k(k7).vextractf64x4(ymmword_ptr(rcx), zmm12, 171));
+ TEST_INSTRUCTION("6273FD481B217B" , vextractf64x4(ymmword_ptr(rcx), zmm12, 123));
+ TEST_INSTRUCTION("6233FD481BA4F0341200007B" , vextractf64x4(ymmword_ptr(rax, r14, 3, 4660), zmm12, 123));
+ TEST_INSTRUCTION("6273FD481B627F7B" , vextractf64x4(ymmword_ptr(rdx, 4064), zmm12, 123));
+ TEST_INSTRUCTION("6273FD481BA2001000007B" , vextractf64x4(ymmword_ptr(rdx, 4096), zmm12, 123));
+ TEST_INSTRUCTION("6273FD481B62807B" , vextractf64x4(ymmword_ptr(rdx, -4096), zmm12, 123));
+ TEST_INSTRUCTION("6273FD481BA2E0EFFFFF7B" , vextractf64x4(ymmword_ptr(rdx, -4128), zmm12, 123));
+ TEST_INSTRUCTION("62F37D483909AB" , vextracti32x4(xmmword_ptr(rcx), zmm1, 171));
+ TEST_INSTRUCTION("62F37D4B3909AB" , k(k3).vextracti32x4(xmmword_ptr(rcx), zmm1, 171));
+ TEST_INSTRUCTION("62F37D4839097B" , vextracti32x4(xmmword_ptr(rcx), zmm1, 123));
+ TEST_INSTRUCTION("62B37D48398CF0341200007B" , vextracti32x4(xmmword_ptr(rax, r14, 3, 4660), zmm1, 123));
+ TEST_INSTRUCTION("62F37D48394A7F7B" , vextracti32x4(xmmword_ptr(rdx, 2032), zmm1, 123));
+ TEST_INSTRUCTION("62F37D48398A000800007B" , vextracti32x4(xmmword_ptr(rdx, 2048), zmm1, 123));
+ TEST_INSTRUCTION("62F37D48394A807B" , vextracti32x4(xmmword_ptr(rdx, -2048), zmm1, 123));
+ TEST_INSTRUCTION("62F37D48398AF0F7FFFF7B" , vextracti32x4(xmmword_ptr(rdx, -2064), zmm1, 123));
+ TEST_INSTRUCTION("62F3FD483B11AB" , vextracti64x4(ymmword_ptr(rcx), zmm2, 171));
+ TEST_INSTRUCTION("62F3FD4A3B11AB" , k(k2).vextracti64x4(ymmword_ptr(rcx), zmm2, 171));
+ TEST_INSTRUCTION("62F3FD483B117B" , vextracti64x4(ymmword_ptr(rcx), zmm2, 123));
+ TEST_INSTRUCTION("62B3FD483B94F0341200007B" , vextracti64x4(ymmword_ptr(rax, r14, 3, 4660), zmm2, 123));
+ TEST_INSTRUCTION("62F3FD483B527F7B" , vextracti64x4(ymmword_ptr(rdx, 4064), zmm2, 123));
+ TEST_INSTRUCTION("62F3FD483B92001000007B" , vextracti64x4(ymmword_ptr(rdx, 4096), zmm2, 123));
+ TEST_INSTRUCTION("62F3FD483B52807B" , vextracti64x4(ymmword_ptr(rdx, -4096), zmm2, 123));
+ TEST_INSTRUCTION("62F3FD483B92E0EFFFFF7B" , vextracti64x4(ymmword_ptr(rdx, -4128), zmm2, 123));
+ TEST_INSTRUCTION("6261FD482919" , vmovapd(zmmword_ptr(rcx), zmm27));
+ TEST_INSTRUCTION("6261FD492919" , k(k1).vmovapd(zmmword_ptr(rcx), zmm27));
+ TEST_INSTRUCTION("6221FD48299CF034120000" , vmovapd(zmmword_ptr(rax, r14, 3, 4660), zmm27));
+ TEST_INSTRUCTION("6261FD48295A7F" , vmovapd(zmmword_ptr(rdx, 8128), zmm27));
+ TEST_INSTRUCTION("6261FD48299A00200000" , vmovapd(zmmword_ptr(rdx, 8192), zmm27));
+ TEST_INSTRUCTION("6261FD48295A80" , vmovapd(zmmword_ptr(rdx, -8192), zmm27));
+ TEST_INSTRUCTION("6261FD48299AC0DFFFFF" , vmovapd(zmmword_ptr(rdx, -8256), zmm27));
+ TEST_INSTRUCTION("62E17C482909" , vmovaps(zmmword_ptr(rcx), zmm17));
+ TEST_INSTRUCTION("62E17C4D2909" , k(k5).vmovaps(zmmword_ptr(rcx), zmm17));
+ TEST_INSTRUCTION("62A17C48298CF034120000" , vmovaps(zmmword_ptr(rax, r14, 3, 4660), zmm17));
+ TEST_INSTRUCTION("62E17C48294A7F" , vmovaps(zmmword_ptr(rdx, 8128), zmm17));
+ TEST_INSTRUCTION("62E17C48298A00200000" , vmovaps(zmmword_ptr(rdx, 8192), zmm17));
+ TEST_INSTRUCTION("62E17C48294A80" , vmovaps(zmmword_ptr(rdx, -8192), zmm17));
+ TEST_INSTRUCTION("62E17C48298AC0DFFFFF" , vmovaps(zmmword_ptr(rdx, -8256), zmm17));
+ TEST_INSTRUCTION("62F17D487F19" , vmovdqa32(zmmword_ptr(rcx), zmm3));
+ TEST_INSTRUCTION("62F17D497F19" , k(k1).vmovdqa32(zmmword_ptr(rcx), zmm3));
+ TEST_INSTRUCTION("62B17D487F9CF034120000" , vmovdqa32(zmmword_ptr(rax, r14, 3, 4660), zmm3));
+ TEST_INSTRUCTION("62F17D487F5A7F" , vmovdqa32(zmmword_ptr(rdx, 8128), zmm3));
+ TEST_INSTRUCTION("62F17D487F9A00200000" , vmovdqa32(zmmword_ptr(rdx, 8192), zmm3));
+ TEST_INSTRUCTION("62F17D487F5A80" , vmovdqa32(zmmword_ptr(rdx, -8192), zmm3));
+ TEST_INSTRUCTION("62F17D487F9AC0DFFFFF" , vmovdqa32(zmmword_ptr(rdx, -8256), zmm3));
+ TEST_INSTRUCTION("62E1FD487F11" , vmovdqa64(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E1FD497F11" , k(k1).vmovdqa64(zmmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A1FD487F94F034120000" , vmovdqa64(zmmword_ptr(rax, r14, 3, 4660), zmm18));
+ TEST_INSTRUCTION("62E1FD487F527F" , vmovdqa64(zmmword_ptr(rdx, 8128), zmm18));
+ TEST_INSTRUCTION("62E1FD487F9200200000" , vmovdqa64(zmmword_ptr(rdx, 8192), zmm18));
+ TEST_INSTRUCTION("62E1FD487F5280" , vmovdqa64(zmmword_ptr(rdx, -8192), zmm18));
+ TEST_INSTRUCTION("62E1FD487F92C0DFFFFF" , vmovdqa64(zmmword_ptr(rdx, -8256), zmm18));
+ TEST_INSTRUCTION("62F17E487F11" , vmovdqu32(zmmword_ptr(rcx), zmm2));
+ TEST_INSTRUCTION("62F17E4F7F11" , k(k7).vmovdqu32(zmmword_ptr(rcx), zmm2));
+ TEST_INSTRUCTION("62B17E487F94F034120000" , vmovdqu32(zmmword_ptr(rax, r14, 3, 4660), zmm2));
+ TEST_INSTRUCTION("62F17E487F527F" , vmovdqu32(zmmword_ptr(rdx, 8128), zmm2));
+ TEST_INSTRUCTION("62F17E487F9200200000" , vmovdqu32(zmmword_ptr(rdx, 8192), zmm2));
+ TEST_INSTRUCTION("62F17E487F5280" , vmovdqu32(zmmword_ptr(rdx, -8192), zmm2));
+ TEST_INSTRUCTION("62F17E487F92C0DFFFFF" , vmovdqu32(zmmword_ptr(rdx, -8256), zmm2));
+ TEST_INSTRUCTION("62F1FE487F39" , vmovdqu64(zmmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62F1FE497F39" , k(k1).vmovdqu64(zmmword_ptr(rcx), zmm7));
+ TEST_INSTRUCTION("62B1FE487FBCF034120000" , vmovdqu64(zmmword_ptr(rax, r14, 3, 4660), zmm7));
+ TEST_INSTRUCTION("62F1FE487F7A7F" , vmovdqu64(zmmword_ptr(rdx, 8128), zmm7));
+ TEST_INSTRUCTION("62F1FE487FBA00200000" , vmovdqu64(zmmword_ptr(rdx, 8192), zmm7));
+ TEST_INSTRUCTION("62F1FE487F7A80" , vmovdqu64(zmmword_ptr(rdx, -8192), zmm7));
+ TEST_INSTRUCTION("62F1FE487FBAC0DFFFFF" , vmovdqu64(zmmword_ptr(rdx, -8256), zmm7));
+ TEST_INSTRUCTION("6271FD481101" , vmovupd(zmmword_ptr(rcx), zmm8));
+ TEST_INSTRUCTION("6271FD4C1101" , k(k4).vmovupd(zmmword_ptr(rcx), zmm8));
+ TEST_INSTRUCTION("6231FD481184F034120000" , vmovupd(zmmword_ptr(rax, r14, 3, 4660), zmm8));
+ TEST_INSTRUCTION("6271FD4811427F" , vmovupd(zmmword_ptr(rdx, 8128), zmm8));
+ TEST_INSTRUCTION("6271FD48118200200000" , vmovupd(zmmword_ptr(rdx, 8192), zmm8));
+ TEST_INSTRUCTION("6271FD48114280" , vmovupd(zmmword_ptr(rdx, -8192), zmm8));
+ TEST_INSTRUCTION("6271FD481182C0DFFFFF" , vmovupd(zmmword_ptr(rdx, -8256), zmm8));
+ TEST_INSTRUCTION("62F17C481121" , vmovups(zmmword_ptr(rcx), zmm4));
+ TEST_INSTRUCTION("62F17C491121" , k(k1).vmovups(zmmword_ptr(rcx), zmm4));
+ TEST_INSTRUCTION("62B17C4811A4F034120000" , vmovups(zmmword_ptr(rax, r14, 3, 4660), zmm4));
+ TEST_INSTRUCTION("62F17C4811627F" , vmovups(zmmword_ptr(rdx, 8128), zmm4));
+ TEST_INSTRUCTION("62F17C4811A200200000" , vmovups(zmmword_ptr(rdx, 8192), zmm4));
+ TEST_INSTRUCTION("62F17C48116280" , vmovups(zmmword_ptr(rdx, -8192), zmm4));
+ TEST_INSTRUCTION("62F17C4811A2C0DFFFFF" , vmovups(zmmword_ptr(rdx, -8256), zmm4));
+ TEST_INSTRUCTION("62727E483231" , vpmovqb(qword_ptr(rcx), zmm14));
+ TEST_INSTRUCTION("62727E4A3231" , k(k2).vpmovqb(qword_ptr(rcx), zmm14));
+ TEST_INSTRUCTION("62327E4832B4F034120000" , vpmovqb(qword_ptr(rax, r14, 3, 4660), zmm14));
+ TEST_INSTRUCTION("62727E4832727F" , vpmovqb(qword_ptr(rdx, 1016), zmm14));
+ TEST_INSTRUCTION("62727E4832B200040000" , vpmovqb(qword_ptr(rdx, 1024), zmm14));
+ TEST_INSTRUCTION("62727E48327280" , vpmovqb(qword_ptr(rdx, -1024), zmm14));
+ TEST_INSTRUCTION("62727E4832B2F8FBFFFF" , vpmovqb(qword_ptr(rdx, -1032), zmm14));
+ TEST_INSTRUCTION("62E27E482211" , vpmovsqb(qword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E27E4E2211" , k(k6).vpmovsqb(qword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A27E482294F034120000" , vpmovsqb(qword_ptr(rax, r14, 3, 4660), zmm18));
+ TEST_INSTRUCTION("62E27E4822527F" , vpmovsqb(qword_ptr(rdx, 1016), zmm18));
+ TEST_INSTRUCTION("62E27E48229200040000" , vpmovsqb(qword_ptr(rdx, 1024), zmm18));
+ TEST_INSTRUCTION("62E27E48225280" , vpmovsqb(qword_ptr(rdx, -1024), zmm18));
+ TEST_INSTRUCTION("62E27E482292F8FBFFFF" , vpmovsqb(qword_ptr(rdx, -1032), zmm18));
+ TEST_INSTRUCTION("62727E481229" , vpmovusqb(qword_ptr(rcx), zmm13));
+ TEST_INSTRUCTION("62727E4A1229" , k(k2).vpmovusqb(qword_ptr(rcx), zmm13));
+ TEST_INSTRUCTION("62327E4812ACF034120000" , vpmovusqb(qword_ptr(rax, r14, 3, 4660), zmm13));
+ TEST_INSTRUCTION("62727E48126A7F" , vpmovusqb(qword_ptr(rdx, 1016), zmm13));
+ TEST_INSTRUCTION("62727E4812AA00040000" , vpmovusqb(qword_ptr(rdx, 1024), zmm13));
+ TEST_INSTRUCTION("62727E48126A80" , vpmovusqb(qword_ptr(rdx, -1024), zmm13));
+ TEST_INSTRUCTION("62727E4812AAF8FBFFFF" , vpmovusqb(qword_ptr(rdx, -1032), zmm13));
+ TEST_INSTRUCTION("62E27E483431" , vpmovqw(xmmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62E27E4E3431" , k(k6).vpmovqw(xmmword_ptr(rcx), zmm22));
+ TEST_INSTRUCTION("62A27E4834B4F034120000" , vpmovqw(xmmword_ptr(rax, r14, 3, 4660), zmm22));
+ TEST_INSTRUCTION("62E27E4834727F" , vpmovqw(xmmword_ptr(rdx, 2032), zmm22));
+ TEST_INSTRUCTION("62E27E4834B200080000" , vpmovqw(xmmword_ptr(rdx, 2048), zmm22));
+ TEST_INSTRUCTION("62E27E48347280" , vpmovqw(xmmword_ptr(rdx, -2048), zmm22));
+ TEST_INSTRUCTION("62E27E4834B2F0F7FFFF" , vpmovqw(xmmword_ptr(rdx, -2064), zmm22));
+ TEST_INSTRUCTION("62627E482411" , vpmovsqw(xmmword_ptr(rcx), zmm26));
+ TEST_INSTRUCTION("62627E4A2411" , k(k2).vpmovsqw(xmmword_ptr(rcx), zmm26));
+ TEST_INSTRUCTION("62227E482494F034120000" , vpmovsqw(xmmword_ptr(rax, r14, 3, 4660), zmm26));
+ TEST_INSTRUCTION("62627E4824527F" , vpmovsqw(xmmword_ptr(rdx, 2032), zmm26));
+ TEST_INSTRUCTION("62627E48249200080000" , vpmovsqw(xmmword_ptr(rdx, 2048), zmm26));
+ TEST_INSTRUCTION("62627E48245280" , vpmovsqw(xmmword_ptr(rdx, -2048), zmm26));
+ TEST_INSTRUCTION("62627E482492F0F7FFFF" , vpmovsqw(xmmword_ptr(rdx, -2064), zmm26));
+ TEST_INSTRUCTION("62F27E481431" , vpmovusqw(xmmword_ptr(rcx), zmm6));
+ TEST_INSTRUCTION("62F27E4F1431" , k(k7).vpmovusqw(xmmword_ptr(rcx), zmm6));
+ TEST_INSTRUCTION("62B27E4814B4F034120000" , vpmovusqw(xmmword_ptr(rax, r14, 3, 4660), zmm6));
+ TEST_INSTRUCTION("62F27E4814727F" , vpmovusqw(xmmword_ptr(rdx, 2032), zmm6));
+ TEST_INSTRUCTION("62F27E4814B200080000" , vpmovusqw(xmmword_ptr(rdx, 2048), zmm6));
+ TEST_INSTRUCTION("62F27E48147280" , vpmovusqw(xmmword_ptr(rdx, -2048), zmm6));
+ TEST_INSTRUCTION("62F27E4814B2F0F7FFFF" , vpmovusqw(xmmword_ptr(rdx, -2064), zmm6));
+ TEST_INSTRUCTION("62727E483511" , vpmovqd(ymmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62727E4D3511" , k(k5).vpmovqd(ymmword_ptr(rcx), zmm10));
+ TEST_INSTRUCTION("62327E483594F034120000" , vpmovqd(ymmword_ptr(rax, r14, 3, 4660), zmm10));
+ TEST_INSTRUCTION("62727E4835527F" , vpmovqd(ymmword_ptr(rdx, 4064), zmm10));
+ TEST_INSTRUCTION("62727E48359200100000" , vpmovqd(ymmword_ptr(rdx, 4096), zmm10));
+ TEST_INSTRUCTION("62727E48355280" , vpmovqd(ymmword_ptr(rdx, -4096), zmm10));
+ TEST_INSTRUCTION("62727E483592E0EFFFFF" , vpmovqd(ymmword_ptr(rdx, -4128), zmm10));
+ TEST_INSTRUCTION("62E27E482511" , vpmovsqd(ymmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E27E4D2511" , k(k5).vpmovsqd(ymmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A27E482594F034120000" , vpmovsqd(ymmword_ptr(rax, r14, 3, 4660), zmm18));
+ TEST_INSTRUCTION("62E27E4825527F" , vpmovsqd(ymmword_ptr(rdx, 4064), zmm18));
+ TEST_INSTRUCTION("62E27E48259200100000" , vpmovsqd(ymmword_ptr(rdx, 4096), zmm18));
+ TEST_INSTRUCTION("62E27E48255280" , vpmovsqd(ymmword_ptr(rdx, -4096), zmm18));
+ TEST_INSTRUCTION("62E27E482592E0EFFFFF" , vpmovsqd(ymmword_ptr(rdx, -4128), zmm18));
+ TEST_INSTRUCTION("62E27E481509" , vpmovusqd(ymmword_ptr(rcx), zmm17));
+ TEST_INSTRUCTION("62E27E4C1509" , k(k4).vpmovusqd(ymmword_ptr(rcx), zmm17));
+ TEST_INSTRUCTION("62A27E48158CF034120000" , vpmovusqd(ymmword_ptr(rax, r14, 3, 4660), zmm17));
+ TEST_INSTRUCTION("62E27E48154A7F" , vpmovusqd(ymmword_ptr(rdx, 4064), zmm17));
+ TEST_INSTRUCTION("62E27E48158A00100000" , vpmovusqd(ymmword_ptr(rdx, 4096), zmm17));
+ TEST_INSTRUCTION("62E27E48154A80" , vpmovusqd(ymmword_ptr(rdx, -4096), zmm17));
+ TEST_INSTRUCTION("62E27E48158AE0EFFFFF" , vpmovusqd(ymmword_ptr(rdx, -4128), zmm17));
+ TEST_INSTRUCTION("62627E483129" , vpmovdb(xmmword_ptr(rcx), zmm29));
+ TEST_INSTRUCTION("62627E4C3129" , k(k4).vpmovdb(xmmword_ptr(rcx), zmm29));
+ TEST_INSTRUCTION("62227E4831ACF034120000" , vpmovdb(xmmword_ptr(rax, r14, 3, 4660), zmm29));
+ TEST_INSTRUCTION("62627E48316A7F" , vpmovdb(xmmword_ptr(rdx, 2032), zmm29));
+ TEST_INSTRUCTION("62627E4831AA00080000" , vpmovdb(xmmword_ptr(rdx, 2048), zmm29));
+ TEST_INSTRUCTION("62627E48316A80" , vpmovdb(xmmword_ptr(rdx, -2048), zmm29));
+ TEST_INSTRUCTION("62627E4831AAF0F7FFFF" , vpmovdb(xmmword_ptr(rdx, -2064), zmm29));
+ TEST_INSTRUCTION("62627E482121" , vpmovsdb(xmmword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62627E4D2121" , k(k5).vpmovsdb(xmmword_ptr(rcx), zmm28));
+ TEST_INSTRUCTION("62227E4821A4F034120000" , vpmovsdb(xmmword_ptr(rax, r14, 3, 4660), zmm28));
+ TEST_INSTRUCTION("62627E4821627F" , vpmovsdb(xmmword_ptr(rdx, 2032), zmm28));
+ TEST_INSTRUCTION("62627E4821A200080000" , vpmovsdb(xmmword_ptr(rdx, 2048), zmm28));
+ TEST_INSTRUCTION("62627E48216280" , vpmovsdb(xmmword_ptr(rdx, -2048), zmm28));
+ TEST_INSTRUCTION("62627E4821A2F0F7FFFF" , vpmovsdb(xmmword_ptr(rdx, -2064), zmm28));
+ TEST_INSTRUCTION("62627E481131" , vpmovusdb(xmmword_ptr(rcx), zmm30));
+ TEST_INSTRUCTION("62627E491131" , k(k1).vpmovusdb(xmmword_ptr(rcx), zmm30));
+ TEST_INSTRUCTION("62227E4811B4F034120000" , vpmovusdb(xmmword_ptr(rax, r14, 3, 4660), zmm30));
+ TEST_INSTRUCTION("62627E4811727F" , vpmovusdb(xmmword_ptr(rdx, 2032), zmm30));
+ TEST_INSTRUCTION("62627E4811B200080000" , vpmovusdb(xmmword_ptr(rdx, 2048), zmm30));
+ TEST_INSTRUCTION("62627E48117280" , vpmovusdb(xmmword_ptr(rdx, -2048), zmm30));
+ TEST_INSTRUCTION("62627E4811B2F0F7FFFF" , vpmovusdb(xmmword_ptr(rdx, -2064), zmm30));
+ TEST_INSTRUCTION("62F27E483329" , vpmovdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62F27E4F3329" , k(k7).vpmovdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62B27E4833ACF034120000" , vpmovdw(ymmword_ptr(rax, r14, 3, 4660), zmm5));
+ TEST_INSTRUCTION("62F27E48336A7F" , vpmovdw(ymmword_ptr(rdx, 4064), zmm5));
+ TEST_INSTRUCTION("62F27E4833AA00100000" , vpmovdw(ymmword_ptr(rdx, 4096), zmm5));
+ TEST_INSTRUCTION("62F27E48336A80" , vpmovdw(ymmword_ptr(rdx, -4096), zmm5));
+ TEST_INSTRUCTION("62F27E4833AAE0EFFFFF" , vpmovdw(ymmword_ptr(rdx, -4128), zmm5));
+ TEST_INSTRUCTION("62E27E482311" , vpmovsdw(ymmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62E27E4F2311" , k(k7).vpmovsdw(ymmword_ptr(rcx), zmm18));
+ TEST_INSTRUCTION("62A27E482394F034120000" , vpmovsdw(ymmword_ptr(rax, r14, 3, 4660), zmm18));
+ TEST_INSTRUCTION("62E27E4823527F" , vpmovsdw(ymmword_ptr(rdx, 4064), zmm18));
+ TEST_INSTRUCTION("62E27E48239200100000" , vpmovsdw(ymmword_ptr(rdx, 4096), zmm18));
+ TEST_INSTRUCTION("62E27E48235280" , vpmovsdw(ymmword_ptr(rdx, -4096), zmm18));
+ TEST_INSTRUCTION("62E27E482392E0EFFFFF" , vpmovsdw(ymmword_ptr(rdx, -4128), zmm18));
+ TEST_INSTRUCTION("62F27E481329" , vpmovusdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62F27E4C1329" , k(k4).vpmovusdw(ymmword_ptr(rcx), zmm5));
+ TEST_INSTRUCTION("62B27E4813ACF034120000" , vpmovusdw(ymmword_ptr(rax, r14, 3, 4660), zmm5));
+ TEST_INSTRUCTION("62F27E48136A7F" , vpmovusdw(ymmword_ptr(rdx, 4064), zmm5));
+ TEST_INSTRUCTION("62F27E4813AA00100000" , vpmovusdw(ymmword_ptr(rdx, 4096), zmm5));
+ TEST_INSTRUCTION("62F27E48136A80" , vpmovusdw(ymmword_ptr(rdx, -4096), zmm5));
+ TEST_INSTRUCTION("62F27E4813AAE0EFFFFF" , vpmovusdw(ymmword_ptr(rdx, -4128), zmm5));
+ TEST_INSTRUCTION("62C1FC4878E6" , vcvttpd2udq(ymm20, zmm14));
+ TEST_INSTRUCTION("62C1FC4B78E6" , k(k3).vcvttpd2udq(ymm20, zmm14));
+ TEST_INSTRUCTION("62C1FCCB78E6" , k(k3).z().vcvttpd2udq(ymm20, zmm14));
+ TEST_INSTRUCTION("62C1FC1878E6" , sae().vcvttpd2udq(ymm20, zmm14));
+ TEST_INSTRUCTION("62E1FC487821" , vcvttpd2udq(ymm20, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A1FC4878A4F034120000" , vcvttpd2udq(ymm20, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E1FC587821" , vcvttpd2udq(ymm20, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E1FC4878627F" , vcvttpd2udq(ymm20, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E1FC4878A200200000" , vcvttpd2udq(ymm20, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E1FC48786280" , vcvttpd2udq(ymm20, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E1FC4878A2C0DFFFFF" , vcvttpd2udq(ymm20, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E1FC5878627F" , vcvttpd2udq(ymm20, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E1FC5878A200040000" , vcvttpd2udq(ymm20, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E1FC58786280" , vcvttpd2udq(ymm20, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E1FC5878A2F8FBFFFF" , vcvttpd2udq(ymm20, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62B17C4878EC" , vcvttps2udq(zmm5, zmm20));
+ TEST_INSTRUCTION("62B17C4A78EC" , k(k2).vcvttps2udq(zmm5, zmm20));
+ TEST_INSTRUCTION("62B17CCA78EC" , k(k2).z().vcvttps2udq(zmm5, zmm20));
+ TEST_INSTRUCTION("62B17C1878EC" , sae().vcvttps2udq(zmm5, zmm20));
+ TEST_INSTRUCTION("62F17C487829" , vcvttps2udq(zmm5, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17C4878ACF034120000" , vcvttps2udq(zmm5, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17C587829" , vcvttps2udq(zmm5, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62F17C48786A7F" , vcvttps2udq(zmm5, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62F17C4878AA00200000" , vcvttps2udq(zmm5, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62F17C48786A80" , vcvttps2udq(zmm5, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62F17C4878AAC0DFFFFF" , vcvttps2udq(zmm5, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62F17C58786A7F" , vcvttps2udq(zmm5, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62F17C5878AA00020000" , vcvttps2udq(zmm5, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62F17C58786A80" , vcvttps2udq(zmm5, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62F17C5878AAFCFDFFFF" , vcvttps2udq(zmm5, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62B17F0878C7" , vcvttsd2usi(eax, xmm23));
+ TEST_INSTRUCTION("62B17F1878C7" , sae().vcvttsd2usi(eax, xmm23));
+ TEST_INSTRUCTION("62F17F087801" , vcvttsd2usi(eax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F087884F034120000" , vcvttsd2usi(eax, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17F0878427F" , vcvttsd2usi(eax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F08788200040000" , vcvttsd2usi(eax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08784280" , vcvttsd2usi(eax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F087882F8FBFFFF" , vcvttsd2usi(eax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B17F0878EF" , vcvttsd2usi(ebp, xmm23));
+ TEST_INSTRUCTION("62B17F1878EF" , sae().vcvttsd2usi(ebp, xmm23));
+ TEST_INSTRUCTION("62F17F087829" , vcvttsd2usi(ebp, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17F0878ACF034120000" , vcvttsd2usi(ebp, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17F08786A7F" , vcvttsd2usi(ebp, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F17F0878AA00040000" , vcvttsd2usi(ebp, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F17F08786A80" , vcvttsd2usi(ebp, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F17F0878AAF8FBFFFF" , vcvttsd2usi(ebp, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62317F0878EF" , vcvttsd2usi(r13d, xmm23));
+ TEST_INSTRUCTION("62317F1878EF" , sae().vcvttsd2usi(r13d, xmm23));
+ TEST_INSTRUCTION("62717F087829" , vcvttsd2usi(r13d, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62317F0878ACF034120000" , vcvttsd2usi(r13d, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717F08786A7F" , vcvttsd2usi(r13d, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62717F0878AA00040000" , vcvttsd2usi(r13d, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62717F08786A80" , vcvttsd2usi(r13d, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62717F0878AAF8FBFFFF" , vcvttsd2usi(r13d, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B1FF0878C3" , vcvttsd2usi(rax, xmm19));
+ TEST_INSTRUCTION("62B1FF1878C3" , sae().vcvttsd2usi(rax, xmm19));
+ TEST_INSTRUCTION("62F1FF087801" , vcvttsd2usi(rax, qword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FF087884F034120000" , vcvttsd2usi(rax, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FF0878427F" , vcvttsd2usi(rax, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("62F1FF08788200040000" , vcvttsd2usi(rax, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("62F1FF08784280" , vcvttsd2usi(rax, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("62F1FF087882F8FBFFFF" , vcvttsd2usi(rax, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("6231FF0878C3" , vcvttsd2usi(r8, xmm19));
+ TEST_INSTRUCTION("6231FF1878C3" , sae().vcvttsd2usi(r8, xmm19));
+ TEST_INSTRUCTION("6271FF087801" , vcvttsd2usi(r8, qword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FF087884F034120000" , vcvttsd2usi(r8, qword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FF0878427F" , vcvttsd2usi(r8, qword_ptr(rdx, 1016)));
+ TEST_INSTRUCTION("6271FF08788200040000" , vcvttsd2usi(r8, qword_ptr(rdx, 1024)));
+ TEST_INSTRUCTION("6271FF08784280" , vcvttsd2usi(r8, qword_ptr(rdx, -1024)));
+ TEST_INSTRUCTION("6271FF087882F8FBFFFF" , vcvttsd2usi(r8, qword_ptr(rdx, -1032)));
+ TEST_INSTRUCTION("62B17E0878C5" , vcvttss2usi(eax, xmm21));
+ TEST_INSTRUCTION("62B17E1878C5" , sae().vcvttss2usi(eax, xmm21));
+ TEST_INSTRUCTION("62F17E087801" , vcvttss2usi(eax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E087884F034120000" , vcvttss2usi(eax, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17E0878427F" , vcvttss2usi(eax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E08788200020000" , vcvttss2usi(eax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08784280" , vcvttss2usi(eax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E087882FCFDFFFF" , vcvttss2usi(eax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62B17E0878ED" , vcvttss2usi(ebp, xmm21));
+ TEST_INSTRUCTION("62B17E1878ED" , sae().vcvttss2usi(ebp, xmm21));
+ TEST_INSTRUCTION("62F17E087829" , vcvttss2usi(ebp, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B17E0878ACF034120000" , vcvttss2usi(ebp, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F17E08786A7F" , vcvttss2usi(ebp, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F17E0878AA00020000" , vcvttss2usi(ebp, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F17E08786A80" , vcvttss2usi(ebp, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F17E0878AAFCFDFFFF" , vcvttss2usi(ebp, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62317E0878ED" , vcvttss2usi(r13d, xmm21));
+ TEST_INSTRUCTION("62317E1878ED" , sae().vcvttss2usi(r13d, xmm21));
+ TEST_INSTRUCTION("62717E087829" , vcvttss2usi(r13d, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62317E0878ACF034120000" , vcvttss2usi(r13d, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62717E08786A7F" , vcvttss2usi(r13d, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62717E0878AA00020000" , vcvttss2usi(r13d, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62717E08786A80" , vcvttss2usi(r13d, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62717E0878AAFCFDFFFF" , vcvttss2usi(r13d, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("62F1FE0878C7" , vcvttss2usi(rax, xmm7));
+ TEST_INSTRUCTION("62F1FE1878C7" , sae().vcvttss2usi(rax, xmm7));
+ TEST_INSTRUCTION("62F1FE087801" , vcvttss2usi(rax, dword_ptr(rcx)));
+ TEST_INSTRUCTION("62B1FE087884F034120000" , vcvttss2usi(rax, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62F1FE0878427F" , vcvttss2usi(rax, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("62F1FE08788200020000" , vcvttss2usi(rax, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("62F1FE08784280" , vcvttss2usi(rax, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("62F1FE087882FCFDFFFF" , vcvttss2usi(rax, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6271FE0878C7" , vcvttss2usi(r8, xmm7));
+ TEST_INSTRUCTION("6271FE1878C7" , sae().vcvttss2usi(r8, xmm7));
+ TEST_INSTRUCTION("6271FE087801" , vcvttss2usi(r8, dword_ptr(rcx)));
+ TEST_INSTRUCTION("6231FE087884F034120000" , vcvttss2usi(r8, dword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("6271FE0878427F" , vcvttss2usi(r8, dword_ptr(rdx, 508)));
+ TEST_INSTRUCTION("6271FE08788200020000" , vcvttss2usi(r8, dword_ptr(rdx, 512)));
+ TEST_INSTRUCTION("6271FE08784280" , vcvttss2usi(r8, dword_ptr(rdx, -512)));
+ TEST_INSTRUCTION("6271FE087882FCFDFFFF" , vcvttss2usi(r8, dword_ptr(rdx, -516)));
+ TEST_INSTRUCTION("6252654876C9" , vpermi2d(zmm9, zmm3, zmm9));
+ TEST_INSTRUCTION("6252654976C9" , k(k1).vpermi2d(zmm9, zmm3, zmm9));
+ TEST_INSTRUCTION("625265C976C9" , k(k1).z().vpermi2d(zmm9, zmm3, zmm9));
+ TEST_INSTRUCTION("627265487609" , vpermi2d(zmm9, zmm3, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62326548768CF034120000" , vpermi2d(zmm9, zmm3, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("627265587609" , vpermi2d(zmm9, zmm3, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62726548764A7F" , vpermi2d(zmm9, zmm3, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62726548768A00200000" , vpermi2d(zmm9, zmm3, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62726548764A80" , vpermi2d(zmm9, zmm3, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62726548768AC0DFFFFF" , vpermi2d(zmm9, zmm3, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62726558764A7F" , vpermi2d(zmm9, zmm3, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62726558768A00020000" , vpermi2d(zmm9, zmm3, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62726558764A80" , vpermi2d(zmm9, zmm3, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62726558768AFCFDFFFF" , vpermi2d(zmm9, zmm3, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("6282CD4076E9" , vpermi2q(zmm21, zmm22, zmm25));
+ TEST_INSTRUCTION("6282CD4276E9" , k(k2).vpermi2q(zmm21, zmm22, zmm25));
+ TEST_INSTRUCTION("6282CDC276E9" , k(k2).z().vpermi2q(zmm21, zmm22, zmm25));
+ TEST_INSTRUCTION("62E2CD407629" , vpermi2q(zmm21, zmm22, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2CD4076ACF034120000" , vpermi2q(zmm21, zmm22, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2CD507629" , vpermi2q(zmm21, zmm22, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2CD40766A7F" , vpermi2q(zmm21, zmm22, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2CD4076AA00200000" , vpermi2q(zmm21, zmm22, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2CD40766A80" , vpermi2q(zmm21, zmm22, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2CD4076AAC0DFFFFF" , vpermi2q(zmm21, zmm22, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2CD50766A7F" , vpermi2q(zmm21, zmm22, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2CD5076AA00040000" , vpermi2q(zmm21, zmm22, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD50766A80" , vpermi2q(zmm21, zmm22, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2CD5076AAF8FBFFFF" , vpermi2q(zmm21, zmm22, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62622D4077D1" , vpermi2ps(zmm26, zmm26, zmm1));
+ TEST_INSTRUCTION("62622D4577D1" , k(k5).vpermi2ps(zmm26, zmm26, zmm1));
+ TEST_INSTRUCTION("62622DC577D1" , k(k5).z().vpermi2ps(zmm26, zmm26, zmm1));
+ TEST_INSTRUCTION("62622D407711" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62222D407794F034120000" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62622D507711" , vpermi2ps(zmm26, zmm26, dword_ptr(rcx)._1to16()));
+ TEST_INSTRUCTION("62622D4077527F" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62622D40779200200000" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62622D40775280" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62622D407792C0DFFFFF" , vpermi2ps(zmm26, zmm26, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62622D5077527F" , vpermi2ps(zmm26, zmm26, dword_ptr(rdx, 508)._1to16()));
+ TEST_INSTRUCTION("62622D50779200020000" , vpermi2ps(zmm26, zmm26, dword_ptr(rdx, 512)._1to16()));
+ TEST_INSTRUCTION("62622D50775280" , vpermi2ps(zmm26, zmm26, dword_ptr(rdx, -512)._1to16()));
+ TEST_INSTRUCTION("62622D507792FCFDFFFF" , vpermi2ps(zmm26, zmm26, dword_ptr(rdx, -516)._1to16()));
+ TEST_INSTRUCTION("62A2A54077ED" , vpermi2pd(zmm21, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A54477ED" , k(k4).vpermi2pd(zmm21, zmm27, zmm21));
+ TEST_INSTRUCTION("62A2A5C477ED" , k(k4).z().vpermi2pd(zmm21, zmm27, zmm21));
+ TEST_INSTRUCTION("62E2A5407729" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rcx)));
+ TEST_INSTRUCTION("62A2A54077ACF034120000" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rax, r14, 3, 4660)));
+ TEST_INSTRUCTION("62E2A5507729" , vpermi2pd(zmm21, zmm27, qword_ptr(rcx)._1to8()));
+ TEST_INSTRUCTION("62E2A540776A7F" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rdx, 8128)));
+ TEST_INSTRUCTION("62E2A54077AA00200000" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rdx, 8192)));
+ TEST_INSTRUCTION("62E2A540776A80" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rdx, -8192)));
+ TEST_INSTRUCTION("62E2A54077AAC0DFFFFF" , vpermi2pd(zmm21, zmm27, zmmword_ptr(rdx, -8256)));
+ TEST_INSTRUCTION("62E2A550776A7F" , vpermi2pd(zmm21, zmm27, qword_ptr(rdx, 1016)._1to8()));
+ TEST_INSTRUCTION("62E2A55077AA00040000" , vpermi2pd(zmm21, zmm27, qword_ptr(rdx, 1024)._1to8()));
+ TEST_INSTRUCTION("62E2A550776A80" , vpermi2pd(zmm21, zmm27, qword_ptr(rdx, -1024)._1to8()));
+ TEST_INSTRUCTION("62E2A55077AAF8FBFFFF" , vpermi2pd(zmm21, zmm27, qword_ptr(rdx, -1032)._1to8()));
+ TEST_INSTRUCTION("62D2FD4192B4C67B000000" , k(k1).vgatherdpd(zmm6, zmmword_ptr(r14, ymm16, 3, 123)));
+ TEST_INSTRUCTION("62D2FD4192740120" , k(k1).vgatherdpd(zmm6, zmmword_ptr(r9, ymm16, 0, 256)));
+ TEST_INSTRUCTION("62F2FD4192B48100040000" , k(k1).vgatherdpd(zmm6, zmmword_ptr(rcx, ymm16, 2, 1024)));
+ TEST_INSTRUCTION("62527D41928CDE7B000000" , k(k1).vgatherdps(zmm9, zmmword_ptr(r14, zmm19, 3, 123)));
+ TEST_INSTRUCTION("62527D41924C1940" , k(k1).vgatherdps(zmm9, zmmword_ptr(r9, zmm19, 0, 256)));
+ TEST_INSTRUCTION("62727D41928C9900040000" , k(k1).vgatherdps(zmm9, zmmword_ptr(rcx, zmm19, 2, 1024)));
+ TEST_INSTRUCTION("6242FD4993ACD67B000000" , k(k1).vgatherqpd(zmm29, zmmword_ptr(r14, zmm2, 3, 123)));
+ TEST_INSTRUCTION("6242FD49936C1120" , k(k1).vgatherqpd(zmm29, zmmword_ptr(r9, zmm2, 0, 256)));
+ TEST_INSTRUCTION("6262FD4993AC9100040000" , k(k1).vgatherqpd(zmm29, zmmword_ptr(rcx, zmm2, 2, 1024)));
+ TEST_INSTRUCTION("62C27D499394E67B000000" , k(k1).vgatherqps(ymm18, ymmword_ptr(r14, zmm4, 3, 123)));
+ TEST_INSTRUCTION("62C27D4993542140" , k(k1).vgatherqps(ymm18, ymmword_ptr(r9, zmm4, 0, 256)));
+ TEST_INSTRUCTION("62E27D499394A100040000" , k(k1).vgatherqps(ymm18, ymmword_ptr(rcx, zmm4, 2, 1024)));
+ TEST_INSTRUCTION("62827D49908CDE7B000000" , k(k1).vpgatherdd(zmm17, zmmword_ptr(r14, zmm11, 3, 123)));
+ TEST_INSTRUCTION("62827D49904C1940" , k(k1).vpgatherdd(zmm17, zmmword_ptr(r9, zmm11, 0, 256)));
+ TEST_INSTRUCTION("62A27D49908C9900040000" , k(k1).vpgatherdd(zmm17, zmmword_ptr(rcx, zmm11, 2, 1024)));
+ TEST_INSTRUCTION("6212FD499084F67B000000" , k(k1).vpgatherdq(zmm8, zmmword_ptr(r14, ymm14, 3, 123)));
+ TEST_INSTRUCTION("6212FD4990443120" , k(k1).vpgatherdq(zmm8, zmmword_ptr(r9, ymm14, 0, 256)));
+ TEST_INSTRUCTION("6232FD499084B100040000" , k(k1).vpgatherdq(zmm8, zmmword_ptr(rcx, ymm14, 2, 1024)));
+ TEST_INSTRUCTION("62D27D41919CCE7B000000" , k(k1).vpgatherqd(ymm3, ymmword_ptr(r14, zmm17, 3, 123)));
+ TEST_INSTRUCTION("62D27D41915C0940" , k(k1).vpgatherqd(ymm3, ymmword_ptr(r9, zmm17, 0, 256)));
+ TEST_INSTRUCTION("62F27D41919C8900040000" , k(k1).vpgatherqd(ymm3, ymmword_ptr(rcx, zmm17, 2, 1024)));
+ TEST_INSTRUCTION("62C2FD41918CEE7B000000" , k(k1).vpgatherqq(zmm17, zmmword_ptr(r14, zmm21, 3, 123)));
+ TEST_INSTRUCTION("62C2FD41914C2920" , k(k1).vpgatherqq(zmm17, zmmword_ptr(r9, zmm21, 0, 256)));
+ TEST_INSTRUCTION("62E2FD41918CA900040000" , k(k1).vpgatherqq(zmm17, zmmword_ptr(rcx, zmm21, 2, 1024)));
+ TEST_INSTRUCTION("62C27D41A09CC67B000000" , k(k1).vpscatterdd(zmmword_ptr(r14, zmm16, 3, 123), zmm19));
+ TEST_INSTRUCTION("62C27D41A09CC67B000000" , k(k1).vpscatterdd(zmmword_ptr(r14, zmm16, 3, 123), zmm19));
+ TEST_INSTRUCTION("62C27D41A05C0140" , k(k1).vpscatterdd(zmmword_ptr(r9, zmm16, 0, 256), zmm19));
+ TEST_INSTRUCTION("62E27D41A09C8100040000" , k(k1).vpscatterdd(zmmword_ptr(rcx, zmm16, 2, 1024), zmm19));
+ TEST_INSTRUCTION("62D2FD49A0ACF67B000000" , k(k1).vpscatterdq(zmmword_ptr(r14, ymm6, 3, 123), zmm5));
+ TEST_INSTRUCTION("62D2FD49A0ACF67B000000" , k(k1).vpscatterdq(zmmword_ptr(r14, ymm6, 3, 123), zmm5));
+ TEST_INSTRUCTION("62D2FD49A06C3120" , k(k1).vpscatterdq(zmmword_ptr(r9, ymm6, 0, 256), zmm5));
+ TEST_INSTRUCTION("62F2FD49A0ACB100040000" , k(k1).vpscatterdq(zmmword_ptr(rcx, ymm6, 2, 1024), zmm5));
+ TEST_INSTRUCTION("62C27D49A1A4D67B000000" , k(k1).vpscatterqd(ymmword_ptr(r14, zmm2, 3, 123), ymm20));
+ TEST_INSTRUCTION("62C27D49A1A4D67B000000" , k(k1).vpscatterqd(ymmword_ptr(r14, zmm2, 3, 123), ymm20));
+ TEST_INSTRUCTION("62C27D49A1641140" , k(k1).vpscatterqd(ymmword_ptr(r9, zmm2, 0, 256), ymm20));
+ TEST_INSTRUCTION("62E27D49A1A49100040000" , k(k1).vpscatterqd(ymmword_ptr(rcx, zmm2, 2, 1024), ymm20));
+ TEST_INSTRUCTION("6252FD41A1B4E67B000000" , k(k1).vpscatterqq(zmmword_ptr(r14, zmm20, 3, 123), zmm14));
+ TEST_INSTRUCTION("6252FD41A1B4E67B000000" , k(k1).vpscatterqq(zmmword_ptr(r14, zmm20, 3, 123), zmm14));
+ TEST_INSTRUCTION("6252FD41A1742120" , k(k1).vpscatterqq(zmmword_ptr(r9, zmm20, 0, 256), zmm14));
+ TEST_INSTRUCTION("6272FD41A1B4A100040000" , k(k1).vpscatterqq(zmmword_ptr(rcx, zmm20, 2, 1024), zmm14));
+ TEST_INSTRUCTION("6282FD41A294C67B000000" , k(k1).vscatterdpd(zmmword_ptr(r14, ymm24, 3, 123), zmm18));
+ TEST_INSTRUCTION("6282FD41A294C67B000000" , k(k1).vscatterdpd(zmmword_ptr(r14, ymm24, 3, 123), zmm18));
+ TEST_INSTRUCTION("6282FD41A2540120" , k(k1).vscatterdpd(zmmword_ptr(r9, ymm24, 0, 256), zmm18));
+ TEST_INSTRUCTION("62A2FD41A2948100040000" , k(k1).vscatterdpd(zmmword_ptr(rcx, ymm24, 2, 1024), zmm18));
+ TEST_INSTRUCTION("62C27D41A28CDE7B000000" , k(k1).vscatterdps(zmmword_ptr(r14, zmm19, 3, 123), zmm17));
+ TEST_INSTRUCTION("62C27D41A28CDE7B000000" , k(k1).vscatterdps(zmmword_ptr(r14, zmm19, 3, 123), zmm17));
+ TEST_INSTRUCTION("62C27D41A24C1940" , k(k1).vscatterdps(zmmword_ptr(r9, zmm19, 0, 256), zmm17));
+ TEST_INSTRUCTION("62E27D41A28C9900040000" , k(k1).vscatterdps(zmmword_ptr(rcx, zmm19, 2, 1024), zmm17));
+ TEST_INSTRUCTION("6282FD41A3B4E67B000000" , k(k1).vscatterqpd(zmmword_ptr(r14, zmm28, 3, 123), zmm22));
+ TEST_INSTRUCTION("6282FD41A3B4E67B000000" , k(k1).vscatterqpd(zmmword_ptr(r14, zmm28, 3, 123), zmm22));
+ TEST_INSTRUCTION("6282FD41A3742120" , k(k1).vscatterqpd(zmmword_ptr(r9, zmm28, 0, 256), zmm22));
+ TEST_INSTRUCTION("62A2FD41A3B4A100040000" , k(k1).vscatterqpd(zmmword_ptr(rcx, zmm28, 2, 1024), zmm22));
+ TEST_INSTRUCTION("62927D41A3B4DE7B000000" , k(k1).vscatterqps(ymmword_ptr(r14, zmm27, 3, 123), ymm6));
+ TEST_INSTRUCTION("62927D41A3B4DE7B000000" , k(k1).vscatterqps(ymmword_ptr(r14, zmm27, 3, 123), ymm6));
+ TEST_INSTRUCTION("62927D41A3741940" , k(k1).vscatterqps(ymmword_ptr(r9, zmm27, 0, 256), ymm6));
+ TEST_INSTRUCTION("62B27D41A3B49900040000" , k(k1).vscatterqps(ymmword_ptr(rcx, zmm27, 2, 1024), ymm6));
+ TEST_INSTRUCTION("6282FD41A294DE85FFFFFF" , k(k1).vscatterdpd(zmmword_ptr(r14, ymm27, 3, -123), zmm18));
+ TEST_INSTRUCTION("6282FD41A294DE85FFFFFF" , k(k1).vscatterdpd(zmmword_ptr(r14, ymm27, 3, -123), zmm18));
+ TEST_INSTRUCTION("6282FD41A2541920" , k(k1).vscatterdpd(zmmword_ptr(r9, ymm27, 0, 256), zmm18));
+ TEST_INSTRUCTION("62A2FD41A2949900040000" , k(k1).vscatterdpd(zmmword_ptr(rcx, ymm27, 2, 1024), zmm18));
+ TEST_INSTRUCTION("62D27D41A28CCE85FFFFFF" , k(k1).vscatterdps(zmmword_ptr(r14, zmm17, 3, -123), zmm1));
+ TEST_INSTRUCTION("62D27D41A28CCE85FFFFFF" , k(k1).vscatterdps(zmmword_ptr(r14, zmm17, 3, -123), zmm1));
+ TEST_INSTRUCTION("62D27D41A24C0940" , k(k1).vscatterdps(zmmword_ptr(r9, zmm17, 0, 256), zmm1));
+ TEST_INSTRUCTION("62F27D41A28C8900040000" , k(k1).vscatterdps(zmmword_ptr(rcx, zmm17, 2, 1024), zmm1));
+ TEST_INSTRUCTION("6212FD41A384CE85FFFFFF" , k(k1).vscatterqpd(zmmword_ptr(r14, zmm25, 3, -123), zmm8));
+ TEST_INSTRUCTION("6212FD41A384CE85FFFFFF" , k(k1).vscatterqpd(zmmword_ptr(r14, zmm25, 3, -123), zmm8));
+ TEST_INSTRUCTION("6212FD41A3440920" , k(k1).vscatterqpd(zmmword_ptr(r9, zmm25, 0, 256), zmm8));
+ TEST_INSTRUCTION("6232FD41A3848900040000" , k(k1).vscatterqpd(zmmword_ptr(rcx, zmm25, 2, 1024), zmm8));
+ TEST_INSTRUCTION("62127D49A3ACD685FFFFFF" , k(k1).vscatterqps(ymmword_ptr(r14, zmm10, 3, -123), ymm13));
+ TEST_INSTRUCTION("62127D49A3ACD685FFFFFF" , k(k1).vscatterqps(ymmword_ptr(r14, zmm10, 3, -123), ymm13));
+ TEST_INSTRUCTION("62127D49A36C1140" , k(k1).vscatterqps(ymmword_ptr(r9, zmm10, 0, 256), ymm13));
+ TEST_INSTRUCTION("62327D49A3AC9100040000" , k(k1).vscatterqps(ymmword_ptr(rcx, zmm10, 2, 1024), ymm13));
+ TEST_INSTRUCTION("6242FD4992B4EE85FFFFFF" , k(k1).vgatherdpd(zmm30, zmmword_ptr(r14, ymm5, 3, -123)));
+ TEST_INSTRUCTION("6242FD4992742920" , k(k1).vgatherdpd(zmm30, zmmword_ptr(r9, ymm5, 0, 256)));
+ TEST_INSTRUCTION("6262FD4992B4A900040000" , k(k1).vgatherdpd(zmm30, zmmword_ptr(rcx, ymm5, 2, 1024)));
+ TEST_INSTRUCTION("62127D419284D685FFFFFF" , k(k1).vgatherdps(zmm8, zmmword_ptr(r14, zmm26, 3, -123)));
+ TEST_INSTRUCTION("62127D4192441140" , k(k1).vgatherdps(zmm8, zmmword_ptr(r9, zmm26, 0, 256)));
+ TEST_INSTRUCTION("62327D4192849100040000" , k(k1).vgatherdps(zmm8, zmmword_ptr(rcx, zmm26, 2, 1024)));
+ TEST_INSTRUCTION("6202FD49939CEE85FFFFFF" , k(k1).vgatherqpd(zmm27, zmmword_ptr(r14, zmm13, 3, -123)));
+ TEST_INSTRUCTION("6202FD49935C2920" , k(k1).vgatherqpd(zmm27, zmmword_ptr(r9, zmm13, 0, 256)));
+ TEST_INSTRUCTION("6222FD49939CA900040000" , k(k1).vgatherqpd(zmm27, zmmword_ptr(rcx, zmm13, 2, 1024)));
+ TEST_INSTRUCTION("62027D49939CF685FFFFFF" , k(k1).vgatherqps(ymm27, ymmword_ptr(r14, zmm14, 3, -123)));
+ TEST_INSTRUCTION("62027D49935C3140" , k(k1).vgatherqps(ymm27, ymmword_ptr(r9, zmm14, 0, 256)));
+ TEST_INSTRUCTION("62227D49939CB100040000" , k(k1).vgatherqps(ymm27, ymmword_ptr(rcx, zmm14, 2, 1024)));
+ TEST_INSTRUCTION("62D27D4190BCC685FFFFFF" , k(k1).vpgatherdd(zmm7, zmmword_ptr(r14, zmm16, 3, -123)));
+ TEST_INSTRUCTION("62D27D41907C0140" , k(k1).vpgatherdd(zmm7, zmmword_ptr(r9, zmm16, 0, 256)));
+ TEST_INSTRUCTION("62F27D4190BC8100040000" , k(k1).vpgatherdd(zmm7, zmmword_ptr(rcx, zmm16, 2, 1024)));
+ TEST_INSTRUCTION("6242FD49908CFE85FFFFFF" , k(k1).vpgatherdq(zmm25, zmmword_ptr(r14, ymm7, 3, -123)));
+ TEST_INSTRUCTION("6242FD49904C3920" , k(k1).vpgatherdq(zmm25, zmmword_ptr(r9, ymm7, 0, 256)));
+ TEST_INSTRUCTION("6262FD49908CB900040000" , k(k1).vpgatherdq(zmm25, zmmword_ptr(rcx, ymm7, 2, 1024)));
+ TEST_INSTRUCTION("62C27D41919CCE85FFFFFF" , k(k1).vpgatherqd(ymm19, ymmword_ptr(r14, zmm17, 3, -123)));
+ TEST_INSTRUCTION("62C27D41915C0940" , k(k1).vpgatherqd(ymm19, ymmword_ptr(r9, zmm17, 0, 256)));
+ TEST_INSTRUCTION("62E27D41919C8900040000" , k(k1).vpgatherqd(ymm19, ymmword_ptr(rcx, zmm17, 2, 1024)));
+ TEST_INSTRUCTION("6212FD499194EE85FFFFFF" , k(k1).vpgatherqq(zmm10, zmmword_ptr(r14, zmm13, 3, -123)));
+ TEST_INSTRUCTION("6212FD4991542920" , k(k1).vpgatherqq(zmm10, zmmword_ptr(r9, zmm13, 0, 256)));
+ TEST_INSTRUCTION("6232FD499194A900040000" , k(k1).vpgatherqq(zmm10, zmmword_ptr(rcx, zmm13, 2, 1024)));
+ TEST_INSTRUCTION("62C27D49A0BCE685FFFFFF" , k(k1).vpscatterdd(zmmword_ptr(r14, zmm4, 3, -123), zmm23));
+ TEST_INSTRUCTION("62C27D49A0BCE685FFFFFF" , k(k1).vpscatterdd(zmmword_ptr(r14, zmm4, 3, -123), zmm23));
+ TEST_INSTRUCTION("62C27D49A07C2140" , k(k1).vpscatterdd(zmmword_ptr(r9, zmm4, 0, 256), zmm23));
+ TEST_INSTRUCTION("62E27D49A0BCA100040000" , k(k1).vpscatterdd(zmmword_ptr(rcx, zmm4, 2, 1024), zmm23));
+ TEST_INSTRUCTION("6292FD41A08CCE85FFFFFF" , k(k1).vpscatterdq(zmmword_ptr(r14, ymm25, 3, -123), zmm1));
+ TEST_INSTRUCTION("6292FD41A08CCE85FFFFFF" , k(k1).vpscatterdq(zmmword_ptr(r14, ymm25, 3, -123), zmm1));
+ TEST_INSTRUCTION("6292FD41A04C0920" , k(k1).vpscatterdq(zmmword_ptr(r9, ymm25, 0, 256), zmm1));
+ TEST_INSTRUCTION("62B2FD41A08C8900040000" , k(k1).vpscatterdq(zmmword_ptr(rcx, ymm25, 2, 1024), zmm1));
+ TEST_INSTRUCTION("62C27D41A1BCF685FFFFFF" , k(k1).vpscatterqd(ymmword_ptr(r14, zmm22, 3, -123), ymm23));
+ TEST_INSTRUCTION("62C27D41A1BCF685FFFFFF" , k(k1).vpscatterqd(ymmword_ptr(r14, zmm22, 3, -123), ymm23));
+ TEST_INSTRUCTION("62C27D41A17C3140" , k(k1).vpscatterqd(ymmword_ptr(r9, zmm22, 0, 256), ymm23));
+ TEST_INSTRUCTION("62E27D41A1BCB100040000" , k(k1).vpscatterqd(ymmword_ptr(rcx, zmm22, 2, 1024), ymm23));
+ TEST_INSTRUCTION("6292FD49A194C685FFFFFF" , k(k1).vpscatterqq(zmmword_ptr(r14, zmm8, 3, -123), zmm2));
+ TEST_INSTRUCTION("6292FD49A194C685FFFFFF" , k(k1).vpscatterqq(zmmword_ptr(r14, zmm8, 3, -123), zmm2));
+ TEST_INSTRUCTION("6292FD49A1540120" , k(k1).vpscatterqq(zmmword_ptr(r9, zmm8, 0, 256), zmm2));
+ TEST_INSTRUCTION("62B2FD49A1948100040000" , k(k1).vpscatterqq(zmmword_ptr(rcx, zmm8, 2, 1024), zmm2));
+
+}
+
static void ASMJIT_NOINLINE testX64AssemblerAMX(AssemblerTester<x86::Assembler>& tester) noexcept {
using namespace x86;
@@ -8181,7 +17782,7 @@ static void ASMJIT_NOINLINE testX64AssemblerExtras(AssemblerTester<x86::Assemble
TEST_INSTRUCTION("62F16C1FC25498400F" , k(k7).vcmpps(k2, xmm2, dword_ptr(rax, rbx, 2, 256)._1to4(), 15));
TEST_INSTRUCTION("62F16C3FC25498400F" , k(k7).vcmpps(k2, ymm2, dword_ptr(rax, rbx, 2, 256)._1to8(), 15));
TEST_INSTRUCTION("62F16C5FC25498400F" , k(k7).vcmpps(k2, zmm2, dword_ptr(rax, rbx, 2, 256)._1to16(), 15));
- TEST_INSTRUCTION("62F1FD58C2C100" , sae().vcmppd(k0, zmm0, zmm1, 0x00));
+ TEST_INSTRUCTION("62F1FD18C2C100" , sae().vcmppd(k0, zmm0, zmm1, 0x00));
TEST_INSTRUCTION("6201FD182EF5" , sae().vucomisd(xmm30, xmm29));
TEST_INSTRUCTION("62017C182EF5" , sae().vucomiss(xmm30, xmm29));
TEST_INSTRUCTION("C4E2FD91040500000000" , vpgatherqq(ymm0, ptr(0, ymm0), ymm0));
@@ -8210,12 +17811,16 @@ static void ASMJIT_NOINLINE testX64AssemblerExtras(AssemblerTester<x86::Assemble
bool testX64Assembler(const TestSettings& settings) noexcept {
using namespace x86;
- AssemblerTester<Assembler> tester(Environment::kArchX64, settings);
+ AssemblerTester<Assembler> tester(Arch::kX64, settings);
tester.printHeader("X64");
+ TEST_INSTRUCTION("62919D18C2D2AB" , sae().vcmppd(k2, zmm12, zmm26, 171));
+
testX64AssemblerBase(tester);
testX64AssemblerMMX_SSE(tester);
testX64AssemblerAVX(tester);
+ testX64AssemblerAVX512_FP16(tester);
+ testX64AssemblerAVX512_LLVM(tester);
testX64AssemblerAMX(tester);
testX64AssemblerExtras(tester);
diff --git a/test/asmjit_test_assembler_x86.cpp b/test/asmjit_test_assembler_x86.cpp
index 4a23fa9..a5ea03a 100644
--- a/test/asmjit_test_assembler_x86.cpp
+++ b/test/asmjit_test_assembler_x86.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
#if !defined(ASMJIT_NO_X86)
@@ -7532,6 +7514,650 @@ static void ASMJIT_NOINLINE testX86AssemblerAVX(AssemblerTester<x86::Assembler>&
TEST_INSTRUCTION("C5F877" , vzeroupper());
}
+static void ASMJIT_NOINLINE testX86AssemblerAVX512_FP16(AssemblerTester<x86::Assembler>& tester) noexcept {
+ using namespace x86;
+
+ TEST_INSTRUCTION("62F5560810F4" , vmovsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F57E0F10B4F400000010" , k(k7).vmovsh(xmm6, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E081031" , vmovsh(xmm6, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57E0810717F" , vmovsh(xmm6, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57E8F107280" , k(k7).z().vmovsh(xmm6, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57E0F11B4F400000010" , k(k7).vmovsh(word_ptr(esp, esi, 3, 268435456), xmm6));
+ TEST_INSTRUCTION("62F57E081131" , vmovsh(word_ptr(ecx), xmm6));
+ TEST_INSTRUCTION("62F57E0811717F" , vmovsh(word_ptr(ecx, 254), xmm6));
+ TEST_INSTRUCTION("62F57E0F117280" , k(k7).vmovsh(word_ptr(edx, -256), xmm6));
+ TEST_INSTRUCTION("62F57D086EF2" , vmovw(xmm6, edx));
+ TEST_INSTRUCTION("62F57D087EF2" , vmovw(edx, xmm6));
+ TEST_INSTRUCTION("62F57D086EB4F400000010" , vmovw(xmm6, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D086E31" , vmovw(xmm6, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57D086E717F" , vmovw(xmm6, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57D086E717F" , vmovw(xmm6, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57D086E7280" , vmovw(xmm6, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57D087EB4F400000010" , vmovw(word_ptr(esp, esi, 3, 268435456), xmm6));
+ TEST_INSTRUCTION("62F57D087E31" , vmovw(word_ptr(ecx), xmm6));
+ TEST_INSTRUCTION("62F57D087E717F" , vmovw(word_ptr(ecx, 254), xmm6));
+ TEST_INSTRUCTION("62F57D087E7280" , vmovw(word_ptr(edx, -256), xmm6));
+
+ TEST_INSTRUCTION("62F5544858F4" , vaddph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5541858F4" , rn_sae().vaddph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F58B4F400000010" , k(k7).vaddph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585831" , vaddph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F5544858717F" , vaddph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF587280" , k(k7).z().vaddph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F5560858F4" , vaddsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5561858F4" , rn_sae().vaddsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F58B4F400000010" , k(k7).vaddsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085831" , vaddsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F5560858717F" , vaddsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F587280" , k(k7).z().vaddsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F35448C2EC7B" , vcmpph(k5, zmm5, zmm4, 123));
+ TEST_INSTRUCTION("62F35418C2EC7B" , sae().vcmpph(k5, zmm5, zmm4, 123));
+ TEST_INSTRUCTION("62F3544FC2ACF4000000107B" , k(k7).vcmpph(k5, zmm5, zmmword_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F35458C2297B" , vcmpph(k5, zmm5, word_ptr(ecx)._1to32(), 123));
+ TEST_INSTRUCTION("62F35448C2697F7B" , vcmpph(k5, zmm5, zmmword_ptr(ecx, 8128), 123));
+ TEST_INSTRUCTION("62F3545FC26A807B" , k(k7).vcmpph(k5, zmm5, word_ptr(edx, -256)._1to32(), 123));
+ TEST_INSTRUCTION("62F35608C2EC7B" , vcmpsh(k5, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F35618C2EC7B" , sae().vcmpsh(k5, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3560FC2ACF4000000107B" , k(k7).vcmpsh(k5, xmm5, word_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F35608C2297B" , vcmpsh(k5, xmm5, word_ptr(ecx), 123));
+ TEST_INSTRUCTION("62F35608C2697F7B" , vcmpsh(k5, xmm5, word_ptr(ecx, 254), 123));
+ TEST_INSTRUCTION("62F3560FC26A807B" , k(k7).vcmpsh(k5, xmm5, word_ptr(edx, -256), 123));
+ TEST_INSTRUCTION("62F57C082FF5" , vcomish(xmm6, xmm5));
+ TEST_INSTRUCTION("62F57C182FF5" , sae().vcomish(xmm6, xmm5));
+ TEST_INSTRUCTION("62F57C082FB4F400000010" , vcomish(xmm6, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C082F31" , vcomish(xmm6, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57C082F717F" , vcomish(xmm6, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57C082F7280" , vcomish(xmm6, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57C485BF5" , vcvtdq2ph(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57C185BF5" , rn_sae().vcvtdq2ph(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57C4F5BB4F400000010" , k(k7).vcvtdq2ph(ymm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C585B31" , vcvtdq2ph(ymm6, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57C485B717F" , vcvtdq2ph(ymm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57CDF5B7280" , k(k7).z().vcvtdq2ph(ymm6, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F5FD485AF5" , vcvtpd2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FD185AF5" , rn_sae().vcvtpd2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FD4F5AB4F400000010" , k(k7).vcvtpd2ph(xmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F5FD585A31" , vcvtpd2ph(xmm6, qword_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F5FD485A717F" , vcvtpd2ph(xmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F5FDDF5A7280" , k(k7).z().vcvtpd2ph(xmm6, qword_ptr(edx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F57D485BF5" , vcvtph2dq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57D185BF5" , rn_sae().vcvtph2dq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57D4F5BB4F400000010" , k(k7).vcvtph2dq(zmm6, ymmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D585B31" , vcvtph2dq(zmm6, word_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57D485B717F" , vcvtph2dq(zmm6, ymmword_ptr(ecx, 4064)));
+ TEST_INSTRUCTION("62F57DDF5B7280" , k(k7).z().vcvtph2dq(zmm6, word_ptr(edx, -256)._1to16()));
+ TEST_INSTRUCTION("62F57C485AF5" , vcvtph2pd(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57C185AF5" , sae().vcvtph2pd(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57C4F5AB4F400000010" , k(k7).vcvtph2pd(zmm6, xmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C585A31" , vcvtph2pd(zmm6, word_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F57C485A717F" , vcvtph2pd(zmm6, xmmword_ptr(ecx, 2032)));
+ TEST_INSTRUCTION("62F57CDF5A7280" , k(k7).z().vcvtph2pd(zmm6, word_ptr(edx, -256)._1to8()));
+ TEST_INSTRUCTION("62F67D4813F5" , vcvtph2psx(zmm6, ymm5));
+ TEST_INSTRUCTION("62F67D1813F5" , sae().vcvtph2psx(zmm6, ymm5));
+ TEST_INSTRUCTION("62F67D4F13B4F400000010" , k(k7).vcvtph2psx(zmm6, ymmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F67D581331" , vcvtph2psx(zmm6, word_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F67D4813717F" , vcvtph2psx(zmm6, ymmword_ptr(ecx, 4064)));
+ TEST_INSTRUCTION("62F67DDF137280" , k(k7).z().vcvtph2psx(zmm6, word_ptr(edx, -256)._1to16()));
+ TEST_INSTRUCTION("62F57D487BF5" , vcvtph2qq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D187BF5" , rn_sae().vcvtph2qq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D4F7BB4F400000010" , k(k7).vcvtph2qq(zmm6, xmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587B31" , vcvtph2qq(zmm6, word_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F57D487B717F" , vcvtph2qq(zmm6, xmmword_ptr(ecx, 2032)));
+ TEST_INSTRUCTION("62F57DDF7B7280" , k(k7).z().vcvtph2qq(zmm6, word_ptr(edx, -256)._1to8()));
+ TEST_INSTRUCTION("62F57C4879F5" , vcvtph2udq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57C1879F5" , rn_sae().vcvtph2udq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57C4F79B4F400000010" , k(k7).vcvtph2udq(zmm6, ymmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C587931" , vcvtph2udq(zmm6, word_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57C4879717F" , vcvtph2udq(zmm6, ymmword_ptr(ecx, 4064)));
+ TEST_INSTRUCTION("62F57CDF797280" , k(k7).z().vcvtph2udq(zmm6, word_ptr(edx, -256)._1to16()));
+ TEST_INSTRUCTION("62F57D4879F5" , vcvtph2uqq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D1879F5" , rn_sae().vcvtph2uqq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D4F79B4F400000010" , k(k7).vcvtph2uqq(zmm6, xmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587931" , vcvtph2uqq(zmm6, word_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F57D4879717F" , vcvtph2uqq(zmm6, xmmword_ptr(ecx, 2032)));
+ TEST_INSTRUCTION("62F57DDF797280" , k(k7).z().vcvtph2uqq(zmm6, word_ptr(edx, -256)._1to8()));
+ TEST_INSTRUCTION("62F57C487DF5" , vcvtph2uw(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C187DF5" , rn_sae().vcvtph2uw(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C4F7DB4F400000010" , k(k7).vcvtph2uw(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C587D31" , vcvtph2uw(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57C487D717F" , vcvtph2uw(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57CDF7D7280" , k(k7).z().vcvtph2uw(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F57D487DF5" , vcvtph2w(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57D187DF5" , rn_sae().vcvtph2w(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57D4F7DB4F400000010" , k(k7).vcvtph2w(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587D31" , vcvtph2w(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57D487D717F" , vcvtph2w(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57DDF7D7280" , k(k7).z().vcvtph2w(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F57D481DF5" , vcvtps2phx(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57D181DF5" , rn_sae().vcvtps2phx(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57D4F1DB4F400000010" , k(k7).vcvtps2phx(ymm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D581D31" , vcvtps2phx(ymm6, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57D481D717F" , vcvtps2phx(ymm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57DDF1D7280" , k(k7).z().vcvtps2phx(ymm6, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F5FC485BF5" , vcvtqq2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FC185BF5" , rn_sae().vcvtqq2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FC4F5BB4F400000010" , k(k7).vcvtqq2ph(xmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F5FC585B31" , vcvtqq2ph(xmm6, qword_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F5FC485B717F" , vcvtqq2ph(xmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F5FCDF5B7280" , k(k7).z().vcvtqq2ph(xmm6, qword_ptr(edx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F5D7085AF4" , vcvtsd2sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5D7185AF4" , rn_sae().vcvtsd2sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5D70F5AB4F400000010" , k(k7).vcvtsd2sh(xmm6, xmm5, qword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F5D7085A31" , vcvtsd2sh(xmm6, xmm5, qword_ptr(ecx)));
+ TEST_INSTRUCTION("62F5D7085A717F" , vcvtsd2sh(xmm6, xmm5, qword_ptr(ecx, 1016)));
+ TEST_INSTRUCTION("62F5D78F5A7280" , k(k7).z().vcvtsd2sh(xmm6, xmm5, qword_ptr(edx, -1024)));
+ TEST_INSTRUCTION("62F556085AF4" , vcvtsh2sd(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F556185AF4" , sae().vcvtsh2sd(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F5AB4F400000010" , k(k7).vcvtsh2sd(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085A31" , vcvtsh2sd(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F556085A717F" , vcvtsh2sd(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F5A7280" , k(k7).z().vcvtsh2sd(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57E082DD6" , vcvtsh2si(edx, xmm6));
+ TEST_INSTRUCTION("62F57E182DD6" , rn_sae().vcvtsh2si(edx, xmm6));
+ TEST_INSTRUCTION("62F57E082D94F400000010" , vcvtsh2si(edx, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E082D11" , vcvtsh2si(edx, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57E082D517F" , vcvtsh2si(edx, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57E082D5280" , vcvtsh2si(edx, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F6540813F4" , vcvtsh2ss(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6541813F4" , sae().vcvtsh2ss(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6540F13B4F400000010" , k(k7).vcvtsh2ss(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F654081331" , vcvtsh2ss(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F6540813717F" , vcvtsh2ss(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6548F137280" , k(k7).z().vcvtsh2ss(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57E0879D6" , vcvtsh2usi(edx, xmm6));
+ TEST_INSTRUCTION("62F57E1879D6" , rn_sae().vcvtsh2usi(edx, xmm6));
+ TEST_INSTRUCTION("62F57E087994F400000010" , vcvtsh2usi(edx, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E087911" , vcvtsh2usi(edx, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57E0879517F" , vcvtsh2usi(edx, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57E08795280" , vcvtsh2usi(edx, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F556082AF2" , vcvtsi2sh(xmm6, xmm5, edx));
+ TEST_INSTRUCTION("62F556182AF2" , rn_sae().vcvtsi2sh(xmm6, xmm5, edx));
+ TEST_INSTRUCTION("62F556082AB4F400000010" , vcvtsi2sh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556082A31" , vcvtsi2sh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F556082A717F" , vcvtsi2sh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F556082A7280" , vcvtsi2sh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F554081DF4" , vcvtss2sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F554181DF4" , rn_sae().vcvtss2sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5540F1DB4F400000010" , k(k7).vcvtss2sh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554081D31" , vcvtss2sh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F554081D717F" , vcvtss2sh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F5548F1D7280" , k(k7).z().vcvtss2sh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F57E485BF5" , vcvttph2dq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57E185BF5" , sae().vcvttph2dq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57E4F5BB4F400000010" , k(k7).vcvttph2dq(zmm6, ymmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E585B31" , vcvttph2dq(zmm6, word_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57E485B717F" , vcvttph2dq(zmm6, ymmword_ptr(ecx, 4064)));
+ TEST_INSTRUCTION("62F57EDF5B7280" , k(k7).z().vcvttph2dq(zmm6, word_ptr(edx, -256)._1to16()));
+ TEST_INSTRUCTION("62F57D487AF5" , vcvttph2qq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D187AF5" , sae().vcvttph2qq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D4F7AB4F400000010" , k(k7).vcvttph2qq(zmm6, xmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587A31" , vcvttph2qq(zmm6, word_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F57D487A717F" , vcvttph2qq(zmm6, xmmword_ptr(ecx, 2032)));
+ TEST_INSTRUCTION("62F57DDF7A7280" , k(k7).z().vcvttph2qq(zmm6, word_ptr(edx, -256)._1to8()));
+ TEST_INSTRUCTION("62F57C4878F5" , vcvttph2udq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57C1878F5" , sae().vcvttph2udq(zmm6, ymm5));
+ TEST_INSTRUCTION("62F57C4F78B4F400000010" , k(k7).vcvttph2udq(zmm6, ymmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C587831" , vcvttph2udq(zmm6, word_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57C4878717F" , vcvttph2udq(zmm6, ymmword_ptr(ecx, 4064)));
+ TEST_INSTRUCTION("62F57CDF787280" , k(k7).z().vcvttph2udq(zmm6, word_ptr(edx, -256)._1to16()));
+ TEST_INSTRUCTION("62F57D4878F5" , vcvttph2uqq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D1878F5" , sae().vcvttph2uqq(zmm6, xmm5));
+ TEST_INSTRUCTION("62F57D4F78B4F400000010" , k(k7).vcvttph2uqq(zmm6, xmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587831" , vcvttph2uqq(zmm6, word_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F57D4878717F" , vcvttph2uqq(zmm6, xmmword_ptr(ecx, 2032)));
+ TEST_INSTRUCTION("62F57DDF787280" , k(k7).z().vcvttph2uqq(zmm6, word_ptr(edx, -256)._1to8()));
+ TEST_INSTRUCTION("62F57C487CF5" , vcvttph2uw(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C187CF5" , sae().vcvttph2uw(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C4F7CB4F400000010" , k(k7).vcvttph2uw(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C587C31" , vcvttph2uw(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57C487C717F" , vcvttph2uw(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57CDF7C7280" , k(k7).z().vcvttph2uw(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F57D487CF5" , vcvttph2w(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57D187CF5" , sae().vcvttph2w(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57D4F7CB4F400000010" , k(k7).vcvttph2w(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57D587C31" , vcvttph2w(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57D487C717F" , vcvttph2w(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57DDF7C7280" , k(k7).z().vcvttph2w(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F57E082CD6" , vcvttsh2si(edx, xmm6));
+ TEST_INSTRUCTION("62F57E182CD6" , sae().vcvttsh2si(edx, xmm6));
+ TEST_INSTRUCTION("62F57E082C94F400000010" , vcvttsh2si(edx, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E082C11" , vcvttsh2si(edx, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57E082C517F" , vcvttsh2si(edx, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57E082C5280" , vcvttsh2si(edx, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57E0878D6" , vcvttsh2usi(edx, xmm6));
+ TEST_INSTRUCTION("62F57E1878D6" , sae().vcvttsh2usi(edx, xmm6));
+ TEST_INSTRUCTION("62F57E087894F400000010" , vcvttsh2usi(edx, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E087811" , vcvttsh2usi(edx, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57E0878517F" , vcvttsh2usi(edx, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57E08785280" , vcvttsh2usi(edx, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57F487AF5" , vcvtudq2ph(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57F187AF5" , rn_sae().vcvtudq2ph(ymm6, zmm5));
+ TEST_INSTRUCTION("62F57F4F7AB4F400000010" , k(k7).vcvtudq2ph(ymm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57F587A31" , vcvtudq2ph(ymm6, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F57F487A717F" , vcvtudq2ph(ymm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57FDF7A7280" , k(k7).z().vcvtudq2ph(ymm6, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F5FF487AF5" , vcvtuqq2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FF187AF5" , rn_sae().vcvtuqq2ph(xmm6, zmm5));
+ TEST_INSTRUCTION("62F5FF4F7AB4F400000010" , k(k7).vcvtuqq2ph(xmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F5FF587A31" , vcvtuqq2ph(xmm6, qword_ptr(ecx)._1to8()));
+ TEST_INSTRUCTION("62F5FF487A717F" , vcvtuqq2ph(xmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F5FFDF7A7280" , k(k7).z().vcvtuqq2ph(xmm6, qword_ptr(edx, -1024)._1to8()));
+ TEST_INSTRUCTION("62F556087BF2" , vcvtusi2sh(xmm6, xmm5, edx));
+ TEST_INSTRUCTION("62F556187BF2" , rn_sae().vcvtusi2sh(xmm6, xmm5, edx));
+ TEST_INSTRUCTION("62F556087BB4F400000010" , vcvtusi2sh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556087B31" , vcvtusi2sh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F556087B717F" , vcvtusi2sh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F556087B7280" , vcvtusi2sh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F57F487DF5" , vcvtuw2ph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57F187DF5" , rn_sae().vcvtuw2ph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57F4F7DB4F400000010" , k(k7).vcvtuw2ph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57F587D31" , vcvtuw2ph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57F487D717F" , vcvtuw2ph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57FDF7D7280" , k(k7).z().vcvtuw2ph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F57E487DF5" , vcvtw2ph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57E187DF5" , rn_sae().vcvtw2ph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57E4F7DB4F400000010" , k(k7).vcvtw2ph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57E587D31" , vcvtw2ph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57E487D717F" , vcvtw2ph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57EDF7D7280" , k(k7).z().vcvtw2ph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F554485EF4" , vdivph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F554185EF4" , rn_sae().vdivph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F5EB4F400000010" , k(k7).vdivph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585E31" , vdivph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F554485E717F" , vdivph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF5E7280" , k(k7).z().vdivph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F556085EF4" , vdivsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F556185EF4" , rn_sae().vdivsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F5EB4F400000010" , k(k7).vdivsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085E31" , vdivsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F556085E717F" , vdivsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F5E7280" , k(k7).z().vdivsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F554485FF4" , vmaxph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F554185FF4" , sae().vmaxph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F5FB4F400000010" , k(k7).vmaxph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585F31" , vmaxph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F554485F717F" , vmaxph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF5F7280" , k(k7).z().vmaxph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F556085FF4" , vmaxsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F556185FF4" , sae().vmaxsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F5FB4F400000010" , k(k7).vmaxsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085F31" , vmaxsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F556085F717F" , vmaxsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F5F7280" , k(k7).z().vmaxsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F554485DF4" , vminph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F554185DF4" , sae().vminph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F5DB4F400000010" , k(k7).vminph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585D31" , vminph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F554485D717F" , vminph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF5D7280" , k(k7).z().vminph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F556085DF4" , vminsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F556185DF4" , sae().vminsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F5DB4F400000010" , k(k7).vminsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085D31" , vminsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F556085D717F" , vminsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F5D7280" , k(k7).z().vminsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F5544859F4" , vmulph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5541859F4" , rn_sae().vmulph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F59B4F400000010" , k(k7).vmulph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585931" , vmulph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F5544859717F" , vmulph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF597280" , k(k7).z().vmulph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F5560859F4" , vmulsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5561859F4" , rn_sae().vmulsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F59B4F400000010" , k(k7).vmulsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085931" , vmulsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F5560859717F" , vmulsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F597280" , k(k7).z().vmulsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F554485CF4" , vsubph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F554185CF4" , rn_sae().vsubph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F5544F5CB4F400000010" , k(k7).vsubph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F554585C31" , vsubph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F554485C717F" , vsubph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F554DF5C7280" , k(k7).z().vsubph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F556085CF4" , vsubsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F556185CF4" , rn_sae().vsubsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F5CB4F400000010" , k(k7).vsubsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085C31" , vsubsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F556085C717F" , vsubsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F5C7280" , k(k7).z().vsubsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57C082EF5" , vucomish(xmm6, xmm5));
+ TEST_INSTRUCTION("62F57C182EF5" , sae().vucomish(xmm6, xmm5));
+ TEST_INSTRUCTION("62F57C082EB4F400000010" , vucomish(xmm6, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C082E31" , vucomish(xmm6, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F57C082E717F" , vucomish(xmm6, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F57C082E7280" , vucomish(xmm6, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F37C4866EE7B" , vfpclassph(k5, zmm6, 123));
+ TEST_INSTRUCTION("62F37C4F66ACF4000000107B" , k(k7).vfpclassph(k5, zmmword_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F37C5866297B" , vfpclassph(k5, word_ptr(ecx)._1to32(), 123));
+ TEST_INSTRUCTION("62F37C4866697F7B" , vfpclassph(k5, zmmword_ptr(ecx, 8128), 123));
+ TEST_INSTRUCTION("62F37C5F666A807B" , k(k7).vfpclassph(k5, word_ptr(edx, -256)._1to32(), 123));
+ TEST_INSTRUCTION("62F37C0867EE7B" , vfpclasssh(k5, xmm6, 123));
+ TEST_INSTRUCTION("62F37C0F67ACF4000000107B" , k(k7).vfpclasssh(k5, word_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F37C0867297B" , vfpclasssh(k5, word_ptr(ecx), 123));
+ TEST_INSTRUCTION("62F37C0867697F7B" , vfpclasssh(k5, word_ptr(ecx, 254), 123));
+ TEST_INSTRUCTION("62F37C0F676A807B" , k(k7).vfpclasssh(k5, word_ptr(edx, -256), 123));
+ TEST_INSTRUCTION("62F67D4842F5" , vgetexpph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F67D1842F5" , sae().vgetexpph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F67D4F42B4F400000010" , k(k7).vgetexpph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F67D584231" , vgetexpph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F67D4842717F" , vgetexpph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F67DDF427280" , k(k7).z().vgetexpph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F6550843F4" , vgetexpsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6551843F4" , sae().vgetexpsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F43B4F400000010" , k(k7).vgetexpsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655084331" , vgetexpsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F6550843717F" , vgetexpsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F437280" , k(k7).z().vgetexpsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F37C4826F57B" , vgetmantph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C1826F57B" , sae().vgetmantph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C4F26B4F4000000107B" , k(k7).vgetmantph(zmm6, zmmword_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F37C5826317B" , vgetmantph(zmm6, word_ptr(ecx)._1to32(), 123));
+ TEST_INSTRUCTION("62F37C4826717F7B" , vgetmantph(zmm6, zmmword_ptr(ecx, 8128), 123));
+ TEST_INSTRUCTION("62F37CDF2672807B" , k(k7).z().vgetmantph(zmm6, word_ptr(edx, -256)._1to32(), 123));
+ TEST_INSTRUCTION("62F3540827F47B" , vgetmantsh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3541827F47B" , sae().vgetmantsh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3540F27B4F4000000107B" , k(k7).vgetmantsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F3540827317B" , vgetmantsh(xmm6, xmm5, word_ptr(ecx), 123));
+ TEST_INSTRUCTION("62F3540827717F7B" , vgetmantsh(xmm6, xmm5, word_ptr(ecx, 254), 123));
+ TEST_INSTRUCTION("62F3548F2772807B" , k(k7).z().vgetmantsh(xmm6, xmm5, word_ptr(edx, -256), 123));
+ TEST_INSTRUCTION("62F67D484CF5" , vrcpph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F67D4F4CB4F400000010" , k(k7).vrcpph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F67D584C31" , vrcpph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F67D484C717F" , vrcpph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F67DDF4C7280" , k(k7).z().vrcpph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655084DF4" , vrcpsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F4DB4F400000010" , k(k7).vrcpsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655084D31" , vrcpsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655084D717F" , vrcpsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F4D7280" , k(k7).z().vrcpsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F37C4856F57B" , vreduceph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C1856F57B" , sae().vreduceph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C4F56B4F4000000107B" , k(k7).vreduceph(zmm6, zmmword_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F37C5856317B" , vreduceph(zmm6, word_ptr(ecx)._1to32(), 123));
+ TEST_INSTRUCTION("62F37C4856717F7B" , vreduceph(zmm6, zmmword_ptr(ecx, 8128), 123));
+ TEST_INSTRUCTION("62F37CDF5672807B" , k(k7).z().vreduceph(zmm6, word_ptr(edx, -256)._1to32(), 123));
+ TEST_INSTRUCTION("62F3540857F47B" , vreducesh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3541857F47B" , sae().vreducesh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3540F57B4F4000000107B" , k(k7).vreducesh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F3540857317B" , vreducesh(xmm6, xmm5, word_ptr(ecx), 123));
+ TEST_INSTRUCTION("62F3540857717F7B" , vreducesh(xmm6, xmm5, word_ptr(ecx, 254), 123));
+ TEST_INSTRUCTION("62F3548F5772807B" , k(k7).z().vreducesh(xmm6, xmm5, word_ptr(edx, -256), 123));
+ TEST_INSTRUCTION("62F37C4808F57B" , vrndscaleph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C1808F57B" , sae().vrndscaleph(zmm6, zmm5, 123));
+ TEST_INSTRUCTION("62F37C4F08B4F4000000107B" , k(k7).vrndscaleph(zmm6, zmmword_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F37C5808317B" , vrndscaleph(zmm6, word_ptr(ecx)._1to32(), 123));
+ TEST_INSTRUCTION("62F37C4808717F7B" , vrndscaleph(zmm6, zmmword_ptr(ecx, 8128), 123));
+ TEST_INSTRUCTION("62F37CDF0872807B" , k(k7).z().vrndscaleph(zmm6, word_ptr(edx, -256)._1to32(), 123));
+ TEST_INSTRUCTION("62F354080AF47B" , vrndscalesh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F354180AF47B" , sae().vrndscalesh(xmm6, xmm5, xmm4, 123));
+ TEST_INSTRUCTION("62F3540F0AB4F4000000107B" , k(k7).vrndscalesh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456), 123));
+ TEST_INSTRUCTION("62F354080A317B" , vrndscalesh(xmm6, xmm5, word_ptr(ecx), 123));
+ TEST_INSTRUCTION("62F354080A717F7B" , vrndscalesh(xmm6, xmm5, word_ptr(ecx, 254), 123));
+ TEST_INSTRUCTION("62F3548F0A72807B" , k(k7).z().vrndscalesh(xmm6, xmm5, word_ptr(edx, -256), 123));
+ TEST_INSTRUCTION("62F67D484EF5" , vrsqrtph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F67D4F4EB4F400000010" , k(k7).vrsqrtph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F67D584E31" , vrsqrtph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F67D484E717F" , vrsqrtph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F67DDF4E7280" , k(k7).z().vrsqrtph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655084FF4" , vrsqrtsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F4FB4F400000010" , k(k7).vrsqrtsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655084F31" , vrsqrtsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655084F717F" , vrsqrtsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F4F7280" , k(k7).z().vrsqrtsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F655482CF4" , vscalefph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F655182CF4" , rn_sae().vscalefph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F2CB4F400000010" , k(k7).vscalefph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655582C31" , vscalefph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F655482C717F" , vscalefph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF2C7280" , k(k7).z().vscalefph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655082DF4" , vscalefsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F655182DF4" , rn_sae().vscalefsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F2DB4F400000010" , k(k7).vscalefsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655082D31" , vscalefsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655082D717F" , vscalefsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F2D7280" , k(k7).z().vscalefsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F57C4851F5" , vsqrtph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C1851F5" , rn_sae().vsqrtph(zmm6, zmm5));
+ TEST_INSTRUCTION("62F57C4F51B4F400000010" , k(k7).vsqrtph(zmm6, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F57C585131" , vsqrtph(zmm6, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F57C4851717F" , vsqrtph(zmm6, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F57CDF517280" , k(k7).z().vsqrtph(zmm6, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F5560851F4" , vsqrtsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5561851F4" , rn_sae().vsqrtsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F5560F51B4F400000010" , k(k7).vsqrtsh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F556085131" , vsqrtsh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F5560851717F" , vsqrtsh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F5568F517280" , k(k7).z().vsqrtsh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F6554898F4" , vfmadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6551898F4" , rn_sae().vfmadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F98B4F400000010" , k(k7).vfmadd132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589831" , vfmadd132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F6554898717F" , vfmadd132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF987280" , k(k7).z().vfmadd132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F6550899F4" , vfmadd132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6551899F4" , rn_sae().vfmadd132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F99B4F400000010" , k(k7).vfmadd132sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655089931" , vfmadd132sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F6550899717F" , vfmadd132sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F997280" , k(k7).z().vfmadd132sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548A8F4" , vfmadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518A8F4" , rn_sae().vfmadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FA8B4F400000010" , k(k7).vfmadd213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558A831" , vfmadd213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548A8717F" , vfmadd213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFA87280" , k(k7).z().vfmadd213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508A9F4" , vfmadd213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518A9F4" , rn_sae().vfmadd213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FA9B4F400000010" , k(k7).vfmadd213sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508A931" , vfmadd213sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508A9717F" , vfmadd213sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FA97280" , k(k7).z().vfmadd213sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548B8F4" , vfmadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518B8F4" , rn_sae().vfmadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FB8B4F400000010" , k(k7).vfmadd231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558B831" , vfmadd231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548B8717F" , vfmadd231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFB87280" , k(k7).z().vfmadd231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508B9F4" , vfmadd231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518B9F4" , rn_sae().vfmadd231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FB9B4F400000010" , k(k7).vfmadd231sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508B931" , vfmadd231sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508B9717F" , vfmadd231sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FB97280" , k(k7).z().vfmadd231sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F6554896F4" , vfmaddsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6551896F4" , rn_sae().vfmaddsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F96B4F400000010" , k(k7).vfmaddsub132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589631" , vfmaddsub132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F6554896717F" , vfmaddsub132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF967280" , k(k7).z().vfmaddsub132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65548A6F4" , vfmaddsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518A6F4" , rn_sae().vfmaddsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FA6B4F400000010" , k(k7).vfmaddsub213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558A631" , vfmaddsub213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548A6717F" , vfmaddsub213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFA67280" , k(k7).z().vfmaddsub213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65548B6F4" , vfmaddsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518B6F4" , rn_sae().vfmaddsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FB6B4F400000010" , k(k7).vfmaddsub231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558B631" , vfmaddsub231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548B6717F" , vfmaddsub231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFB67280" , k(k7).z().vfmaddsub231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655489AF4" , vfmsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F655189AF4" , rn_sae().vfmsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F9AB4F400000010" , k(k7).vfmsub132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589A31" , vfmsub132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F655489A717F" , vfmsub132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF9A7280" , k(k7).z().vfmsub132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655089BF4" , vfmsub132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F655189BF4" , rn_sae().vfmsub132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F9BB4F400000010" , k(k7).vfmsub132sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655089B31" , vfmsub132sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655089B717F" , vfmsub132sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F9B7280" , k(k7).z().vfmsub132sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548AAF4" , vfmsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518AAF4" , rn_sae().vfmsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FAAB4F400000010" , k(k7).vfmsub213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558AA31" , vfmsub213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548AA717F" , vfmsub213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFAA7280" , k(k7).z().vfmsub213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508ABF4" , vfmsub213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518ABF4" , rn_sae().vfmsub213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FABB4F400000010" , k(k7).vfmsub213sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508AB31" , vfmsub213sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508AB717F" , vfmsub213sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FAB7280" , k(k7).z().vfmsub213sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548BAF4" , vfmsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518BAF4" , rn_sae().vfmsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FBAB4F400000010" , k(k7).vfmsub231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558BA31" , vfmsub231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548BA717F" , vfmsub231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFBA7280" , k(k7).z().vfmsub231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508BBF4" , vfmsub231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518BBF4" , rn_sae().vfmsub231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FBBB4F400000010" , k(k7).vfmsub231sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508BB31" , vfmsub231sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508BB717F" , vfmsub231sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FBB7280" , k(k7).z().vfmsub231sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F6554897F4" , vfmsubadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6551897F4" , rn_sae().vfmsubadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F97B4F400000010" , k(k7).vfmsubadd132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589731" , vfmsubadd132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F6554897717F" , vfmsubadd132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF977280" , k(k7).z().vfmsubadd132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65548A7F4" , vfmsubadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518A7F4" , rn_sae().vfmsubadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FA7B4F400000010" , k(k7).vfmsubadd213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558A731" , vfmsubadd213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548A7717F" , vfmsubadd213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFA77280" , k(k7).z().vfmsubadd213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65548B7F4" , vfmsubadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518B7F4" , rn_sae().vfmsubadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FB7B4F400000010" , k(k7).vfmsubadd231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558B731" , vfmsubadd231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548B7717F" , vfmsubadd231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFB77280" , k(k7).z().vfmsubadd231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655489CF4" , vfnmadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F655189CF4" , rn_sae().vfnmadd132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F9CB4F400000010" , k(k7).vfnmadd132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589C31" , vfnmadd132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F655489C717F" , vfnmadd132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF9C7280" , k(k7).z().vfnmadd132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655089DF4" , vfnmadd132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F655189DF4" , rn_sae().vfnmadd132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F9DB4F400000010" , k(k7).vfnmadd132sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655089D31" , vfnmadd132sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655089D717F" , vfnmadd132sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F9D7280" , k(k7).z().vfnmadd132sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548ACF4" , vfnmadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518ACF4" , rn_sae().vfnmadd213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FACB4F400000010" , k(k7).vfnmadd213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558AC31" , vfnmadd213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548AC717F" , vfnmadd213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFAC7280" , k(k7).z().vfnmadd213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508ADF4" , vfnmadd213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518ADF4" , rn_sae().vfnmadd213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FADB4F400000010" , k(k7).vfnmadd213sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508AD31" , vfnmadd213sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508AD717F" , vfnmadd213sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FAD7280" , k(k7).z().vfnmadd213sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548BCF4" , vfnmadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518BCF4" , rn_sae().vfnmadd231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FBCB4F400000010" , k(k7).vfnmadd231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558BC31" , vfnmadd231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548BC717F" , vfnmadd231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFBC7280" , k(k7).z().vfnmadd231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508BDF4" , vfnmadd231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518BDF4" , rn_sae().vfnmadd231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FBDB4F400000010" , k(k7).vfnmadd231sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508BD31" , vfnmadd231sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508BD717F" , vfnmadd231sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FBD7280" , k(k7).z().vfnmadd231sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F655489EF4" , vfnmsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F655189EF4" , rn_sae().vfnmsub132ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554F9EB4F400000010" , k(k7).vfnmsub132ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655589E31" , vfnmsub132ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F655489E717F" , vfnmsub132ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DF9E7280" , k(k7).z().vfnmsub132ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F655089FF4" , vfnmsub132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F655189FF4" , rn_sae().vfnmsub132sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550F9FB4F400000010" , k(k7).vfnmsub132sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F655089F31" , vfnmsub132sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F655089F717F" , vfnmsub132sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558F9F7280" , k(k7).z().vfnmsub132sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548AEF4" , vfnmsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518AEF4" , rn_sae().vfnmsub213ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FAEB4F400000010" , k(k7).vfnmsub213ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558AE31" , vfnmsub213ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548AE717F" , vfnmsub213ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFAE7280" , k(k7).z().vfnmsub213ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508AFF4" , vfnmsub213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518AFF4" , rn_sae().vfnmsub213sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FAFB4F400000010" , k(k7).vfnmsub213sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508AF31" , vfnmsub213sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508AF717F" , vfnmsub213sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FAF7280" , k(k7).z().vfnmsub213sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F65548BEF4" , vfnmsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65518BEF4" , rn_sae().vfnmsub231ph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6554FBEB4F400000010" , k(k7).vfnmsub231ph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65558BE31" , vfnmsub231ph(zmm6, zmm5, word_ptr(ecx)._1to32()));
+ TEST_INSTRUCTION("62F65548BE717F" , vfnmsub231ph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F655DFBE7280" , k(k7).z().vfnmsub231ph(zmm6, zmm5, word_ptr(edx, -256)._1to32()));
+ TEST_INSTRUCTION("62F65508BFF4" , vfnmsub231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65518BFF4" , rn_sae().vfnmsub231sh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6550FBFB4F400000010" , k(k7).vfnmsub231sh(xmm6, xmm5, word_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65508BF31" , vfnmsub231sh(xmm6, xmm5, word_ptr(ecx)));
+ TEST_INSTRUCTION("62F65508BF717F" , vfnmsub231sh(xmm6, xmm5, word_ptr(ecx, 254)));
+ TEST_INSTRUCTION("62F6558FBF7280" , k(k7).z().vfnmsub231sh(xmm6, xmm5, word_ptr(edx, -256)));
+ TEST_INSTRUCTION("62F6574856F4" , vfcmaddcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6571856F4" , rn_sae().vfcmaddcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6574F56B4F400000010" , k(k7).vfcmaddcph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F657585631" , vfcmaddcph(zmm6, zmm5, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F6574856717F" , vfcmaddcph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F657DF567280" , k(k7).z().vfcmaddcph(zmm6, zmm5, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F6570857F4" , vfcmaddcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6571857F4" , rn_sae().vfcmaddcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6570F57B4F400000010" , k(k7).vfcmaddcsh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F657085731" , vfcmaddcsh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F6570857717F" , vfcmaddcsh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F6578F577280" , k(k7).z().vfcmaddcsh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F65748D6F4" , vfcmulcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65718D6F4" , rn_sae().vfcmulcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6574FD6B4F400000010" , k(k7).vfcmulcph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65758D631" , vfcmulcph(zmm6, zmm5, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F65748D6717F" , vfcmulcph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F657DFD67280" , k(k7).z().vfcmulcph(zmm6, zmm5, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F65708D7F4" , vfcmulcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65718D7F4" , rn_sae().vfcmulcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6570FD7B4F400000010" , k(k7).vfcmulcsh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65708D731" , vfcmulcsh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F65708D7717F" , vfcmulcsh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F6578FD77280" , k(k7).z().vfcmulcsh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F6564856F4" , vfmaddcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6561856F4" , rn_sae().vfmaddcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6564F56B4F400000010" , k(k7).vfmaddcph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F656585631" , vfmaddcph(zmm6, zmm5, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F6564856717F" , vfmaddcph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F656DF567280" , k(k7).z().vfmaddcph(zmm6, zmm5, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F6560857F4" , vfmaddcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6561857F4" , rn_sae().vfmaddcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6560F57B4F400000010" , k(k7).vfmaddcsh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F656085731" , vfmaddcsh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F6560857717F" , vfmaddcsh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F6568F577280" , k(k7).z().vfmaddcsh(xmm6, xmm5, dword_ptr(edx, -512)));
+ TEST_INSTRUCTION("62F65648D6F4" , vfmulcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F65618D6F4" , rn_sae().vfmulcph(zmm6, zmm5, zmm4));
+ TEST_INSTRUCTION("62F6564FD6B4F400000010" , k(k7).vfmulcph(zmm6, zmm5, zmmword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65658D631" , vfmulcph(zmm6, zmm5, dword_ptr(ecx)._1to16()));
+ TEST_INSTRUCTION("62F65648D6717F" , vfmulcph(zmm6, zmm5, zmmword_ptr(ecx, 8128)));
+ TEST_INSTRUCTION("62F656DFD67280" , k(k7).z().vfmulcph(zmm6, zmm5, dword_ptr(edx, -512)._1to16()));
+ TEST_INSTRUCTION("62F65608D7F4" , vfmulcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F65618D7F4" , rn_sae().vfmulcsh(xmm6, xmm5, xmm4));
+ TEST_INSTRUCTION("62F6560FD7B4F400000010" , k(k7).vfmulcsh(xmm6, xmm5, dword_ptr(esp, esi, 3, 268435456)));
+ TEST_INSTRUCTION("62F65608D731" , vfmulcsh(xmm6, xmm5, dword_ptr(ecx)));
+ TEST_INSTRUCTION("62F65608D7717F" , vfmulcsh(xmm6, xmm5, dword_ptr(ecx, 508)));
+ TEST_INSTRUCTION("62F6568FD77280" , k(k7).z().vfmulcsh(xmm6, xmm5, dword_ptr(edx, -512)));
+}
+
static void ASMJIT_NOINLINE testX86AssemblerExtras(AssemblerTester<x86::Assembler>& tester) noexcept {
using namespace x86;
@@ -7656,12 +8282,13 @@ static void ASMJIT_NOINLINE testX86AssemblerExtras(AssemblerTester<x86::Assemble
bool testX86Assembler(const TestSettings& settings) noexcept {
using namespace x86;
- AssemblerTester<Assembler> tester(Environment::kArchX86, settings);
+ AssemblerTester<Assembler> tester(Arch::kX86, settings);
tester.printHeader("X86");
testX86AssemblerBase(tester);
testX86AssemblerMMX_SSE(tester);
testX86AssemblerAVX(tester);
+ testX86AssemblerAVX512_FP16(tester);
testX86AssemblerExtras(tester);
tester.printSummary();
diff --git a/test/asmjit_test_compiler.cpp b/test/asmjit_test_compiler.cpp
index 96b5eeb..70a24a9 100644
--- a/test/asmjit_test_compiler.cpp
+++ b/test/asmjit_test_compiler.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
@@ -32,6 +14,7 @@
#include <chrono>
#include "cmdline.h"
+#include "asmjitutils.h"
#include "performancetimer.h"
#include "asmjit_test_compiler.h"
@@ -56,21 +39,6 @@ void compiler_add_a64_tests(TestApp& app);
using namespace asmjit;
-// ============================================================================
-// [TestApp]
-// ============================================================================
-
-static const char* archAsString(uint32_t arch) {
- switch (arch) {
- case Environment::kArchX86: return "X86";
- case Environment::kArchX64: return "X64";
- case Environment::kArchARM: return "A32";
- case Environment::kArchThumb: return "T32";
- case Environment::kArchAArch64: return "A64";
- default: return "Unknown";
- }
-}
-
int TestApp::handleArgs(int argc, const char* const* argv) {
CmdLine cmd(argc, argv);
@@ -86,7 +54,7 @@ void TestApp::showInfo() {
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
- archAsString(Environment::kArchHost));
+ asmjitArchAsString(Arch::kHost));
printf(" [%s] Verbose (use --verbose to turn verbose output ON)\n", _verbose ? "x" : " ");
printf(" [%s] DumpAsm (use --dump-asm to turn assembler dumps ON)\n", _dumpAsm ? "x" : " ");
printf(" [%s] DumpHex (use --dump-hex to dump binary in hexadecimal)\n", _dumpHex ? "x" : " ");
@@ -98,133 +66,156 @@ int TestApp::run() {
return 0;
#else
#ifndef ASMJIT_NO_LOGGING
- uint32_t kFormatFlags = FormatOptions::kFlagMachineCode |
- FormatOptions::kFlagExplainImms |
- FormatOptions::kFlagRegCasts |
- FormatOptions::kFlagAnnotations |
- FormatOptions::kFlagDebugPasses |
- FormatOptions::kFlagDebugRA ;
+ FormatOptions formatOptions;
+ formatOptions.addFlags(
+ FormatFlags::kMachineCode |
+ FormatFlags::kExplainImms |
+ FormatFlags::kRegCasts );
FileLogger fileLogger(stdout);
- fileLogger.addFlags(kFormatFlags);
+ fileLogger.setOptions(formatOptions);
StringLogger stringLogger;
- stringLogger.addFlags(kFormatFlags);
+ stringLogger.setOptions(formatOptions);
#endif
+ JitRuntime runtime;
+
+ PerformanceTimer compileTimer;
+ PerformanceTimer finalizeTimer;
double compileTime = 0;
double finalizeTime = 0;
for (std::unique_ptr<TestCase>& test : _tests) {
- JitRuntime runtime;
- CodeHolder code;
- SimpleErrorHandler errorHandler;
-
- PerformanceTimer perfTimer;
+ for (uint32_t pass = 0; pass < 2; pass++) {
+ CodeHolder code;
+ SimpleErrorHandler errorHandler;
- code.init(runtime.environment());
- code.setErrorHandler(&errorHandler);
+ code.init(runtime.environment());
+ code.setErrorHandler(&errorHandler);
+ if (pass != 0) {
#ifndef ASMJIT_NO_LOGGING
- if (_verbose) {
- code.setLogger(&fileLogger);
- }
- else {
- stringLogger.clear();
- code.setLogger(&stringLogger);
- }
+ if (_verbose) {
+ code.setLogger(&fileLogger);
+ }
+ else {
+ stringLogger.clear();
+ code.setLogger(&stringLogger);
+ }
#endif
- printf("[Test] %s", test->name());
+ printf("[Test] %s", test->name());
#ifndef ASMJIT_NO_LOGGING
- if (_verbose) printf("\n");
+ if (_verbose)
+ printf("\n");
#endif
+ }
+
#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
- x86::Compiler cc(&code);
+ x86::Compiler cc(&code);
#endif
#if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM == 64
- arm::Compiler cc(&code);
+ arm::Compiler cc(&code);
#endif
- perfTimer.start();
- test->compile(cc);
- perfTimer.stop();
- compileTime += perfTimer.duration();
+#ifndef ASMJIT_NO_LOGGING
+ cc.addDiagnosticOptions(DiagnosticOptions::kRAAnnotate | DiagnosticOptions::kRADebugAll);
+#endif
- void* func = nullptr;
- Error err = errorHandler._err;
+ compileTimer.start();
+ test->compile(cc);
+ compileTimer.stop();
- if (!err) {
- perfTimer.start();
- err = cc.finalize();
- perfTimer.stop();
- finalizeTime += perfTimer.duration();
- }
+ void* func = nullptr;
+ Error err = errorHandler._err;
+
+ if (!err) {
+ finalizeTimer.start();
+ err = cc.finalize();
+ finalizeTimer.stop();
+ }
+
+ // The first pass is only for timing serialization and compilation, because otherwise it would be biased by
+ // logging, which takes much more time than finalize() does. We want to benchmark Compiler the way it would
+ // be used in production.
+ if (pass == 0) {
+ compileTime += compileTimer.duration();
+ finalizeTime += finalizeTimer.duration();
+ continue;
+ }
#ifndef ASMJIT_NO_LOGGING
- if (_dumpAsm) {
- if (!_verbose) printf("\n");
+ if (_dumpAsm) {
+ if (!_verbose)
+ printf("\n");
- String sb;
- Formatter::formatNodeList(sb, kFormatFlags, &cc);
- printf("%s", sb.data());
- }
+ String sb;
+ Formatter::formatNodeList(sb, formatOptions, &cc);
+ printf("%s", sb.data());
+ }
#endif
- if (err == kErrorOk)
- err = runtime.add(&func, &code);
+ if (err == kErrorOk)
+ err = runtime.add(&func, &code);
- if (err == kErrorOk && _dumpHex) {
- String sb;
- sb.appendHex((void*)func, code.codeSize());
- printf("\n (HEX: %s)\n", sb.data());
- }
+ if (err == kErrorOk && _dumpHex) {
+ String sb;
+ sb.appendHex((void*)func, code.codeSize());
+ printf("\n (HEX: %s)\n", sb.data());
+ }
- if (_verbose)
- fflush(stdout);
+ if (_verbose)
+ fflush(stdout);
- if (err == kErrorOk) {
- _outputSize += code.codeSize();
+ if (err == kErrorOk) {
+ _outputSize += code.codeSize();
- StringTmp<128> result;
- StringTmp<128> expect;
+ StringTmp<128> result;
+ StringTmp<128> expect;
- if (test->run(func, result, expect)) {
- if (!_verbose) printf(" [OK]\n");
- }
- else {
- if (!_verbose) printf(" [FAILED]\n");
+ if (test->run(func, result, expect)) {
+ if (!_verbose)
+ printf(" [OK]\n");
+ }
+ else {
+ if (!_verbose)
+ printf(" [FAILED]\n");
#ifndef ASMJIT_NO_LOGGING
- if (!_verbose) printf("%s", stringLogger.data());
+ if (!_verbose)
+ printf("%s", stringLogger.data());
#endif
- printf("[Status]\n");
- printf(" Returned: %s\n", result.data());
- printf(" Expected: %s\n", expect.data());
+ printf("[Status]\n");
+ printf(" Returned: %s\n", result.data());
+ printf(" Expected: %s\n", expect.data());
- _nFailed++;
- }
+ _nFailed++;
+ }
- if (_dumpAsm)
- printf("\n");
+ if (_dumpAsm)
+ printf("\n");
- runtime.release(func);
- }
- else {
- if (!_verbose) printf(" [FAILED]\n");
+ runtime.release(func);
+ }
+ else {
+ if (!_verbose)
+ printf(" [FAILED]\n");
#ifndef ASMJIT_NO_LOGGING
- if (!_verbose) printf("%s", stringLogger.data());
+ if (!_verbose)
+ printf("%s", stringLogger.data());
#endif
- printf("[Status]\n");
- printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data());
+ printf("[Status]\n");
+ printf(" ERROR 0x%08X: %s\n", unsigned(err), errorHandler._message.data());
- _nFailed++;
+ _nFailed++;
+ }
}
}
@@ -244,10 +235,6 @@ int TestApp::run() {
#endif
}
-// ============================================================================
-// [Main]
-// ============================================================================
-
int main(int argc, char* argv[]) {
TestApp app;
diff --git a/test/asmjit_test_compiler.h b/test/asmjit_test_compiler.h
index 5933e4a..e694b37 100644
--- a/test/asmjit_test_compiler.h
+++ b/test/asmjit_test_compiler.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_TEST_COMPILER_H_INCLUDED
#define ASMJIT_TEST_COMPILER_H_INCLUDED
@@ -29,10 +11,6 @@
#include <memory>
#include <vector>
-// ============================================================================
-// [SimpleErrorHandler]
-// ============================================================================
-
class SimpleErrorHandler : public asmjit::ErrorHandler {
public:
SimpleErrorHandler()
@@ -48,10 +26,6 @@ public:
asmjit::String _message;
};
-// ============================================================================
-// [TestCase]
-// ============================================================================
-
//! A test case interface for testing AsmJit's Compiler.
class TestCase {
public:
@@ -70,10 +44,6 @@ public:
asmjit::String _name;
};
-// ============================================================================
-// [TestApp]
-// ============================================================================
-
class TestApp {
public:
std::vector<std::unique_ptr<TestCase>> _tests;
diff --git a/test/asmjit_test_compiler_x86.cpp b/test/asmjit_test_compiler_x86.cpp
index 0bd2130..7dbe955 100644
--- a/test/asmjit_test_compiler_x86.cpp
+++ b/test/asmjit_test_compiler_x86.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
@@ -43,9 +25,8 @@
using namespace asmjit;
-// ============================================================================
-// [X86TestCase]
-// ============================================================================
+// x86::Compiler - X86TestCase
+// ===========================
class X86TestCase : public TestCase {
public:
@@ -59,9 +40,8 @@ public:
virtual void compile(x86::Compiler& cc) = 0;
};
-// ============================================================================
-// [X86Test_AlignBase]
-// ============================================================================
+// x86::Compiler - X86Test_AlignBase
+// =================================
class X86Test_AlignBase : public X86TestCase {
public:
@@ -85,14 +65,14 @@ public:
uint32_t i;
uint32_t argCount = _argCount;
- FuncSignatureBuilder signature(CallConv::kIdHost);
+ FuncSignatureBuilder signature(CallConvId::kHost);
signature.setRetT<int>();
for (i = 0; i < argCount; i++)
signature.addArgT<int>();
- cc.addFunc(signature);
+ FuncNode* funcNode = cc.addFunc(signature);
if (_preserveFP)
- cc.func()->frame().setPreservedFP();
+ funcNode->frame().setPreservedFP();
x86::Gp gpVar = cc.newIntPtr("gpVar");
x86::Gp gpSum;
@@ -102,7 +82,7 @@ public:
if (argCount) {
for (i = 0; i < argCount; i++) {
x86::Gp gpArg = cc.newInt32("gpArg%u", i);
- cc.setArg(i, gpArg);
+ funcNode->setArg(i, gpArg);
if (i == 0)
gpSum = gpArg;
@@ -229,9 +209,8 @@ public:
bool _preserveFP;
};
-// ============================================================================
-// [X86Test_NoCode]
-// ============================================================================
+// x86::Compiler - X86Test_NoCode
+// ==============================
class X86Test_NoCode : public X86TestCase {
public:
@@ -242,7 +221,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
cc.endFunc();
}
@@ -257,9 +236,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AlignNone]
-// ============================================================================
+// x86::Compiler - X86Test_AlignNone
+// =================================
class X86Test_NoAlign : public X86TestCase {
public:
@@ -270,9 +248,9 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
- cc.align(kAlignCode, 0);
- cc.align(kAlignCode, 1);
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
+ cc.align(AlignMode::kCode, 0);
+ cc.align(AlignMode::kCode, 1);
cc.endFunc();
}
@@ -287,9 +265,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpMerge]
-// ============================================================================
+// x86::Compiler - X86Test_JumpMerge
+// =================================
class X86Test_JumpMerge : public X86TestCase {
public:
@@ -300,9 +277,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int>(CallConv::kIdHost));
-
- Label L0 = cc.newLabel();
+ Label L0 = cc.newLabel();
Label L1 = cc.newLabel();
Label L2 = cc.newLabel();
Label LEnd = cc.newLabel();
@@ -310,8 +285,9 @@ public:
x86::Gp dst = cc.newIntPtr("dst");
x86::Gp val = cc.newInt32("val");
- cc.setArg(0, dst);
- cc.setArg(1, val);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int*, int>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, val);
cc.cmp(val, 0);
cc.je(L2);
@@ -353,9 +329,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpCross]
-// ============================================================================
+// x86::Compiler - X86Test_JumpCross
+// =================================
class X86Test_JumpCross : public X86TestCase {
public:
@@ -366,7 +341,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
Label L1 = cc.newLabel();
Label L2 = cc.newLabel();
@@ -395,9 +370,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpMany]
-// ============================================================================
+// x86::Compiler - X86Test_JumpMany
+// ================================
class X86Test_JumpMany : public X86TestCase {
public:
@@ -408,7 +382,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
for (uint32_t i = 0; i < 1000; i++) {
Label L = cc.newLabel();
cc.jmp(L);
@@ -436,9 +410,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpUnreachable1]
-// ============================================================================
+// x86::Compiler - X86Test_JumpUnreachable1
+// ========================================
class X86Test_JumpUnreachable1 : public X86TestCase {
public:
@@ -449,7 +422,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel();
@@ -480,7 +453,7 @@ public:
cc.bind(L_7);
cc.add(v0, v1);
- cc.align(kAlignCode, 16);
+ cc.align(AlignMode::kCode, 16);
cc.bind(L_1);
cc.ret();
cc.endFunc();
@@ -499,9 +472,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpUnreachable2]
-// ============================================================================
+// x86::Compiler - X86Test_JumpUnreachable2
+// ========================================
class X86Test_JumpUnreachable2 : public X86TestCase {
public:
@@ -512,7 +484,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel();
@@ -546,9 +518,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpTable1]
-// ============================================================================
+// x86::Compiler - X86Test_JumpTable1
+// ==================================
class X86Test_JumpTable1 : public X86TestCase {
public:
@@ -573,25 +544,23 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConv::kIdHost));
-
x86::Xmm a = cc.newXmmSs("a");
x86::Xmm b = cc.newXmmSs("b");
x86::Gp op = cc.newUInt32("op");
x86::Gp target = cc.newIntPtr("target");
x86::Gp offset = cc.newIntPtr("offset");
- Label L_End = cc.newLabel();
-
Label L_Table = cc.newLabel();
Label L_Add = cc.newLabel();
Label L_Sub = cc.newLabel();
Label L_Mul = cc.newLabel();
Label L_Div = cc.newLabel();
+ Label L_End = cc.newLabel();
- cc.setArg(0, a);
- cc.setArg(1, b);
- cc.setArg(2, op);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float, uint32_t>(CallConvId::kHost));
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
+ funcNode->setArg(2, op);
cc.lea(offset, x86::ptr(L_Table));
if (cc.is64Bit())
@@ -665,9 +634,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_JumpTable2]
-// ============================================================================
+// x86::Compiler - X86Test_JumpTable2
+// ==================================
class X86Test_JumpTable2 : public X86TestCase {
public:
@@ -679,8 +647,6 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
-
x86::Gp result = cc.newUInt32("result");
x86::Gp value = cc.newUInt32("value");
x86::Gp target = cc.newIntPtr("target");
@@ -692,7 +658,8 @@ public:
Label L_Case1 = cc.newLabel();
Label L_End = cc.newLabel();
- cc.setArg(0, value);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int>(CallConvId::kHost));
+ funcNode->setArg(0, value);
cc.bind(L_Begin);
cc.lea(offset, x86::ptr(L_Table));
@@ -748,9 +715,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocBase]
-// ============================================================================
+// x86::Compiler - X86Test_AllocBase
+// =================================
class X86Test_AllocBase : public X86TestCase {
public:
@@ -761,7 +727,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1");
@@ -799,9 +765,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocMany1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocMany1
+// ==================================
class X86Test_AllocMany1 : public X86TestCase {
public:
@@ -814,13 +779,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int*>(CallConv::kIdHost));
-
x86::Gp a0 = cc.newIntPtr("a0");
x86::Gp a1 = cc.newIntPtr("a1");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int*, int*>(CallConvId::kHost));
+ funcNode->setArg(0, a0);
+ funcNode->setArg(1, a1);
// Create some variables.
x86::Gp t = cc.newInt32("t");
@@ -871,9 +835,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocMany2]
-// ============================================================================
+// x86::Compiler - X86Test_AllocMany2
+// ==================================
class X86Test_AllocMany2 : public X86TestCase {
public:
@@ -884,27 +847,25 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, uint32_t*>(CallConv::kIdHost));
-
x86::Gp a = cc.newIntPtr("a");
x86::Gp v[32];
- uint32_t i;
- cc.setArg(0, a);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, uint32_t*>(CallConvId::kHost));
+ funcNode->setArg(0, a);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.xor_(v[i], v[i]);
+ for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) v[i] = cc.newInt32("v%d", i);
+ for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.xor_(v[i], v[i]);
x86::Gp x = cc.newInt32("x");
Label L = cc.newLabel();
cc.mov(x, 32);
cc.bind(L);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.add(v[i], i);
+ for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.add(v[i], i);
cc.dec(x);
cc.jnz(L);
- for (i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.mov(x86::dword_ptr(a, int(i * 4)), v[i]);
+ for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(v); i++) cc.mov(x86::dword_ptr(a, int(i * 4)), v[i]);
cc.endFunc();
}
@@ -935,9 +896,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocImul1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocImul1
+// ==================================
class X86Test_AllocImul1 : public X86TestCase {
public:
@@ -948,8 +908,6 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int*, int, int>(CallConv::kIdHost));
-
x86::Gp dstHi = cc.newIntPtr("dstHi");
x86::Gp dstLo = cc.newIntPtr("dstLo");
@@ -957,13 +915,13 @@ public:
x86::Gp vLo = cc.newInt32("vLo");
x86::Gp src = cc.newInt32("src");
- cc.setArg(0, dstHi);
- cc.setArg(1, dstLo);
- cc.setArg(2, vLo);
- cc.setArg(3, src);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int*, int*, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, dstHi);
+ funcNode->setArg(1, dstLo);
+ funcNode->setArg(2, vLo);
+ funcNode->setArg(3, src);
cc.imul(vHi, vLo, src);
-
cc.mov(x86::dword_ptr(dstHi), vHi);
cc.mov(x86::dword_ptr(dstLo), vLo);
cc.endFunc();
@@ -991,9 +949,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocImul2]
-// ============================================================================
+// x86::Compiler - X86Test_AllocImul2
+// ==================================
class X86Test_AllocImul2 : public X86TestCase {
public:
@@ -1004,13 +961,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, const int*>(CallConv::kIdHost));
-
x86::Gp dst = cc.newIntPtr("dst");
x86::Gp src = cc.newIntPtr("src");
- cc.setArg(0, dst);
- cc.setArg(1, src);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int*, const int*>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src);
for (unsigned int i = 0; i < 4; i++) {
x86::Gp x = cc.newInt32("x");
@@ -1045,9 +1001,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocIdiv1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocIdiv1
+// ==================================
class X86Test_AllocIdiv1 : public X86TestCase {
public:
@@ -1058,14 +1013,13 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
-
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b");
x86::Gp dummy = cc.newInt32("dummy");
- cc.setArg(0, a);
- cc.setArg(1, b);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
cc.xor_(dummy, dummy);
cc.idiv(dummy, a, b);
@@ -1091,9 +1045,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocSetz]
-// ============================================================================
+// x86::Compiler - X86Test_AllocSetz
+// =================================
class X86Test_AllocSetz : public X86TestCase {
public:
@@ -1104,15 +1057,14 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int, int, char*>(CallConv::kIdHost));
-
x86::Gp src0 = cc.newInt32("src0");
x86::Gp src1 = cc.newInt32("src1");
x86::Gp dst0 = cc.newIntPtr("dst0");
- cc.setArg(0, src0);
- cc.setArg(1, src1);
- cc.setArg(2, dst0);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int, int, char*>(CallConvId::kHost));
+ funcNode->setArg(0, src0);
+ funcNode->setArg(1, src1);
+ funcNode->setArg(2, dst0);
cc.cmp(src0, src1);
cc.setz(x86::byte_ptr(dst0));
@@ -1142,9 +1094,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocShlRor]
-// ============================================================================
+// x86::Compiler - X86Test_AllocShlRor
+// ===================================
class X86Test_AllocShlRor : public X86TestCase {
public:
@@ -1155,21 +1106,19 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, int*, int, int, int>(CallConv::kIdHost));
-
x86::Gp dst = cc.newIntPtr("dst");
x86::Gp var = cc.newInt32("var");
x86::Gp vShlParam = cc.newInt32("vShlParam");
x86::Gp vRorParam = cc.newInt32("vRorParam");
- cc.setArg(0, dst);
- cc.setArg(1, var);
- cc.setArg(2, vShlParam);
- cc.setArg(3, vRorParam);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, int*, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, var);
+ funcNode->setArg(2, vShlParam);
+ funcNode->setArg(3, vRorParam);
cc.shl(var, vShlParam);
cc.ror(var, vRorParam);
-
cc.mov(x86::dword_ptr(dst), var);
cc.endFunc();
}
@@ -1192,41 +1141,37 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocGpbLo]
-// ============================================================================
+// x86::Compiler - X86Test_AllocGpbLo
+// ==================================
class X86Test_AllocGpbLo1 : public X86TestCase {
public:
X86Test_AllocGpbLo1() : X86TestCase("AllocGpbLo1") {}
- enum { kCount = 32 };
+ enum : uint32_t { kCount = 32 };
static void add(TestApp& app) {
app.add(new X86Test_AllocGpbLo1());
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint32_t, uint32_t*>(CallConv::kIdHost));
-
x86::Gp rPtr = cc.newUIntPtr("rPtr");
x86::Gp rSum = cc.newUInt32("rSum");
-
- cc.setArg(0, rPtr);
-
x86::Gp x[kCount];
- uint32_t i;
- for (i = 0; i < kCount; i++) {
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<uint32_t, uint32_t*>(CallConvId::kHost));
+ funcNode->setArg(0, rPtr);
+
+ for (uint32_t i = 0; i < kCount; i++) {
x[i] = cc.newUInt32("x%u", i);
}
// Init pseudo-regs with values from our array.
- for (i = 0; i < kCount; i++) {
+ for (uint32_t i = 0; i < kCount; i++) {
cc.mov(x[i], x86::dword_ptr(rPtr, int(i * 4)));
}
- for (i = 2; i < kCount; i++) {
+ for (uint32_t i = 2; i < kCount; i++) {
// Add and truncate to 8 bit; no purpose, just mess with jit.
cc.add (x[i ], x[i-1]);
cc.movzx(x[i ], x[i ].r8());
@@ -1236,7 +1181,7 @@ public:
// Sum up all computed values.
cc.mov(rSum, 0);
- for (i = 0; i < kCount; i++) {
+ for (uint32_t i = 0; i < kCount; i++) {
cc.add(rSum, x[i]);
}
@@ -1282,9 +1227,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocGpbLo2]
-// ============================================================================
+// x86::Compiler - X86Test_AllocGpbLo2
+// ===================================
class X86Test_AllocGpbLo2 : public X86TestCase {
public:
@@ -1295,10 +1239,11 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConv::kIdHost));
-
x86::Gp v = cc.newUInt32("v");
- cc.setArg(0, v);
+
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConvId::kHost));
+ funcNode->setArg(0, v);
+
cc.mov(v.r8(), 0xFF);
cc.ret(v);
cc.endFunc();
@@ -1318,9 +1263,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocRepMovsb]
-// ============================================================================
+// x86::Compiler - X86Test_AllocRepMovsb
+// =====================================
class X86Test_AllocRepMovsb : public X86TestCase {
public:
@@ -1331,15 +1275,14 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, void*, void*, size_t>(CallConv::kIdHost));
-
x86::Gp dst = cc.newIntPtr("dst");
x86::Gp src = cc.newIntPtr("src");
x86::Gp cnt = cc.newIntPtr("cnt");
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, cnt);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, void*, size_t>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src);
+ funcNode->setArg(2, cnt);
cc.rep(cnt).movs(x86::byte_ptr(dst), x86::byte_ptr(src));
cc.endFunc();
@@ -1360,9 +1303,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocIfElse1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocIfElse1
+// ====================================
class X86Test_AllocIfElse1 : public X86TestCase {
public:
@@ -1373,16 +1315,15 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
-
x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2");
Label L_1 = cc.newLabel();
Label L_2 = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, v1);
+ funcNode->setArg(1, v2);
cc.cmp(v1, v2);
cc.jg(L_1);
@@ -1412,9 +1353,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocIfElse2]
-// ============================================================================
+// x86::Compiler - X86Test_AllocIfElse2
+// ====================================
class X86Test_AllocIfElse2 : public X86TestCase {
public:
@@ -1425,8 +1365,6 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
-
x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2");
@@ -1435,8 +1373,9 @@ public:
Label L_3 = cc.newLabel();
Label L_4 = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, v1);
+ funcNode->setArg(1, v2);
cc.jmp(L_1);
cc.bind(L_2);
@@ -1473,9 +1412,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocIfElse3]
-// ============================================================================
+// x86::Compiler - X86Test_AllocIfElse3
+// ====================================
class X86Test_AllocIfElse3 : public X86TestCase {
public:
@@ -1486,8 +1424,6 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
-
x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2");
x86::Gp counter = cc.newInt32("counter");
@@ -1496,8 +1432,9 @@ public:
Label L_Loop = cc.newLabel();
Label L_Exit = cc.newLabel();
- cc.setArg(0, v1);
- cc.setArg(1, v2);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, v1);
+ funcNode->setArg(1, v2);
cc.cmp(v1, v2);
cc.jg(L_1);
@@ -1534,9 +1471,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocIfElse4]
-// ============================================================================
+// x86::Compiler - X86Test_AllocIfElse4
+// ====================================
class X86Test_AllocIfElse4 : public X86TestCase {
public:
@@ -1547,8 +1483,6 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
-
x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2");
x86::Gp counter = cc.newInt32("counter");
@@ -1558,11 +1492,11 @@ public:
Label L_Loop2 = cc.newLabel();
Label L_Exit = cc.newLabel();
- cc.mov(counter, 0);
-
- cc.setArg(0, v1);
- cc.setArg(1, v2);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, v1);
+ funcNode->setArg(1, v2);
+ cc.mov(counter, 0);
cc.cmp(v1, v2);
cc.jg(L_1);
@@ -1600,9 +1534,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocInt8]
-// ============================================================================
+// x86::Compiler - X86Test_AllocInt8
+// =================================
class X86Test_AllocInt8 : public X86TestCase {
public:
@@ -1616,8 +1549,8 @@ public:
x86::Gp x = cc.newInt8("x");
x86::Gp y = cc.newInt32("y");
- cc.addFunc(FuncSignatureT<int, char>(CallConv::kIdHost));
- cc.setArg(0, x);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, char>(CallConvId::kHost));
+ funcNode->setArg(0, x);
cc.movsx(y, x);
@@ -1639,9 +1572,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocUnhandledArg]
-// ============================================================================
+// x86::Compiler - X86Test_AllocUnhandledArg
+// =========================================
class X86Test_AllocUnhandledArg : public X86TestCase {
public:
@@ -1652,12 +1584,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
-
x86::Gp x = cc.newInt32("x");
- cc.setArg(2, x);
- cc.ret(x);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(2, x);
+
+ cc.ret(x);
cc.endFunc();
}
@@ -1675,9 +1607,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocArgsIntPtr]
-// ============================================================================
+// x86::Compiler - X86Test_AllocArgsIntPtr
+// =======================================
class X86Test_AllocArgsIntPtr : public X86TestCase {
public:
@@ -1688,23 +1619,21 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
-
- uint32_t i;
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, void*, void*, void*, void*, void*, void*, void*>(CallConvId::kHost));
x86::Gp var[8];
- for (i = 0; i < 8; i++) {
+ for (uint32_t i = 0; i < 8; i++) {
var[i] = cc.newIntPtr("var%u", i);
- cc.setArg(i, var[i]);
+ funcNode->setArg(i, var[i]);
}
- for (i = 0; i < 8; i++) {
+ for (uint32_t i = 0; i < 8; i++) {
cc.add(var[i], int(i + 1));
}
// 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++) {
+ for (uint32_t i = 0; i < 8; i++) {
cc.add(x86::byte_ptr(var[i]), int(i + 1));
}
@@ -1734,9 +1663,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocArgsFloat]
-// ============================================================================
+// x86::Compiler - X86Test_AllocArgsFloat
+// ======================================
class X86Test_AllocArgsFloat : public X86TestCase {
public:
@@ -1747,19 +1675,17 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, float, float, float, float, float, float, float, void*>(CallConv::kIdHost));
-
- uint32_t i;
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, float, float, float, float, float, float, float, void*>(CallConvId::kHost));
x86::Gp p = cc.newIntPtr("p");
x86::Xmm xv[7];
- for (i = 0; i < 7; i++) {
+ for (uint32_t i = 0; i < 7; i++) {
xv[i] = cc.newXmmSs("xv%u", i);
- cc.setArg(i, xv[i]);
+ funcNode->setArg(i, xv[i]);
}
- cc.setArg(7, p);
+ funcNode->setArg(7, p);
cc.addss(xv[0], xv[1]);
cc.addss(xv[0], xv[2]);
@@ -1788,9 +1714,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocArgsDouble]
-// ============================================================================
+// x86::Compiler - X86Test_AllocArgsDouble
+// =======================================
class X86Test_AllocArgsDouble : public X86TestCase {
public:
@@ -1801,19 +1726,17 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, double, double, double, double, double, double, double, void*>(CallConv::kIdHost));
-
- uint32_t i;
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, double, double, double, double, double, double, double, void*>(CallConvId::kHost));
x86::Gp p = cc.newIntPtr("p");
x86::Xmm xv[7];
- for (i = 0; i < 7; i++) {
+ for (uint32_t i = 0; i < 7; i++) {
xv[i] = cc.newXmmSd("xv%u", i);
- cc.setArg(i, xv[i]);
+ funcNode->setArg(i, xv[i]);
}
- cc.setArg(7, p);
+ funcNode->setArg(7, p);
cc.addsd(xv[0], xv[1]);
cc.addsd(xv[0], xv[2]);
@@ -1842,9 +1765,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocArgsVec]
-// ============================================================================
+// x86::Compiler - X86Test_AllocArgsVec
+// ====================================
class X86Test_AllocArgsVec : public X86TestCase {
public:
@@ -1854,17 +1776,18 @@ public:
// Not supported on Windows.
#ifndef _WIN32
app.add(new X86Test_AllocArgsVec());
+#else
+ DebugUtils::unused(app);
#endif
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(CallConv::kIdHost));
-
x86::Xmm a = cc.newXmm("aXmm");
x86::Xmm b = cc.newXmm("bXmm");
- cc.setArg(0, a);
- cc.setArg(1, b);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(CallConvId::kHost));
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
cc.paddb(a, b);
cc.ret(a);
@@ -1895,9 +1818,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocRetFloat1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocRetFloat1
+// ======================================
class X86Test_AllocRetFloat1 : public X86TestCase {
public:
@@ -1908,12 +1830,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float>(CallConv::kIdHost));
-
x86::Xmm x = cc.newXmmSs("x");
- cc.setArg(0, x);
- cc.ret(x);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+
+ cc.ret(x);
cc.endFunc();
}
@@ -1931,9 +1853,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocRetFloat2]
-// ============================================================================
+// x86::Compiler - X86Test_AllocRetFloat2
+// ======================================
class X86Test_AllocRetFloat2 : public X86TestCase {
public:
@@ -1944,13 +1865,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
-
x86::Xmm x = cc.newXmmSs("x");
x86::Xmm y = cc.newXmmSs("y");
- cc.setArg(0, x);
- cc.setArg(1, y);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
cc.addss(x, y);
cc.ret(x);
@@ -1972,9 +1892,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocRetDouble1]
-// ============================================================================
+// x86::Compiler - X86Test_AllocRetDouble1
+// =======================================
class X86Test_AllocRetDouble1 : public X86TestCase {
public:
@@ -1985,12 +1904,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double>(CallConv::kIdHost));
-
x86::Xmm x = cc.newXmmSd("x");
- cc.setArg(0, x);
- cc.ret(x);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+
+ cc.ret(x);
cc.endFunc();
}
@@ -2007,9 +1926,9 @@ public:
return resultRet == expectRet;
}
};
-// ============================================================================
-// [X86Test_AllocRetDouble2]
-// ============================================================================
+
+// x86::Compiler - X86Test_AllocRetDouble2
+// =======================================
class X86Test_AllocRetDouble2 : public X86TestCase {
public:
@@ -2020,13 +1939,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
-
x86::Xmm x = cc.newXmmSd("x");
x86::Xmm y = cc.newXmmSd("y");
- cc.setArg(0, x);
- cc.setArg(1, y);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
cc.addsd(x, y);
cc.ret(x);
@@ -2048,9 +1966,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocStack]
-// ============================================================================
+// x86::Compiler - X86Test_AllocStack
+// ==================================
class X86Test_AllocStack : public X86TestCase {
public:
@@ -2063,7 +1980,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
x86::Mem stack = cc.newStack(kSize, 1);
stack.setSize(1);
@@ -2116,9 +2033,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocMemcpy]
-// ============================================================================
+// x86::Compiler - X86Test_AllocMemcpy
+// ===================================
class X86Test_AllocMemcpy : public X86TestCase {
public:
@@ -2138,10 +2054,10 @@ public:
Label L_Loop = cc.newLabel(); // Create base labels we use
Label L_Exit = cc.newLabel(); // in our function.
- cc.addFunc(FuncSignatureT<void, uint32_t*, const uint32_t*, size_t>(CallConv::kIdHost));
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, cnt);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, uint32_t*, const uint32_t*, size_t>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src);
+ funcNode->setArg(2, cnt);
cc.test(cnt, cnt); // Exit if the size is zero.
cc.jz(L_Exit);
@@ -2198,9 +2114,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocExtraBlock]
-// ============================================================================
+// x86::Compiler - X86Test_AllocExtraBlock
+// =======================================
class X86Test_AllocExtraBlock : public X86TestCase {
public:
@@ -2216,10 +2131,10 @@ public:
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, cond);
- cc.setArg(1, a);
- cc.setArg(2, b);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, cond);
+ funcNode->setArg(1, a);
+ funcNode->setArg(2, b);
Label L_Ret = cc.newLabel();
Label L_Extra = cc.newLabel();
@@ -2234,7 +2149,7 @@ public:
cc.ret(ret);
// Emit code sequence at the end of the function.
- BaseNode* prevCursor = cc.setCursor(cc.func()->endNode()->prev());
+ BaseNode* prevCursor = cc.setCursor(funcNode->endNode()->prev());
cc.bind(L_Extra);
cc.mov(ret, a);
cc.sub(ret, b);
@@ -2261,9 +2176,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_AllocAlphaBlend]
-// ============================================================================
+// x86::Compiler - X86Test_AllocAlphaBlend
+// =======================================
class X86Test_AllocAlphaBlend : public X86TestCase {
public:
@@ -2340,9 +2254,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallBase1]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallBase1
+// =====================================
class X86Test_FuncCallBase1 : public X86TestCase {
public:
@@ -2357,10 +2270,10 @@ public:
x86::Gp v1 = cc.newInt32("v1");
x86::Gp v2 = cc.newInt32("v2");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, v0);
- cc.setArg(1, v1);
- cc.setArg(2, v2);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, v0);
+ funcNode->setArg(1, v1);
+ funcNode->setArg(2, v2);
// Just do something.
cc.shl(v0, 1);
@@ -2369,7 +2282,7 @@ public:
// Call a function.
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, v2);
invokeNode->setArg(1, v1);
invokeNode->setArg(2, v0);
@@ -2395,9 +2308,8 @@ public:
static int calledFunc(int a, int b, int c) { return (a + b) * c; }
};
-// ============================================================================
-// [X86Test_FuncCallBase2]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallBase2
+// =====================================
class X86Test_FuncCallBase2 : public X86TestCase {
public:
@@ -2410,7 +2322,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
const int kTokenSize = 32;
@@ -2430,19 +2342,19 @@ public:
cc.lea(p2, s2);
// Try to corrupt the stack if wrongly allocated.
- cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl));
+ cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConvId::kCDecl));
invokeNode->setArg(0, p1);
invokeNode->setArg(1, imm(token));
invokeNode->setArg(2, imm(kTokenSize));
invokeNode->setRet(0, p1);
- cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl));
+ cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConvId::kCDecl));
invokeNode->setArg(0, p2);
invokeNode->setArg(1, imm(token));
invokeNode->setArg(2, imm(kTokenSize));
invokeNode->setRet(0, p2);
- cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdCDecl));
+ cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConvId::kCDecl));
invokeNode->setArg(0, p1);
invokeNode->setArg(1, p2);
invokeNode->setArg(2, imm(kTokenSize));
@@ -2477,9 +2389,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallStd]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallStd
+// ===================================
class X86Test_FuncCallStd : public X86TestCase {
public:
@@ -2494,15 +2405,15 @@ public:
x86::Gp y = cc.newInt32("y");
x86::Gp z = cc.newInt32("z");
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.setArg(2, z);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
+ funcNode->setArg(2, z);
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int>(CallConv::kIdStdCall));
+ FuncSignatureT<int, int, int, int>(CallConvId::kStdCall));
invokeNode->setArg(0, x);
invokeNode->setArg(1, y);
invokeNode->setArg(2, z);
@@ -2531,9 +2442,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallFast]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallFast
+// ====================================
class X86Test_FuncCallFast : public X86TestCase {
public:
@@ -2546,16 +2456,16 @@ public:
virtual void compile(x86::Compiler& cc) {
x86::Gp var = cc.newInt32("var");
- cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
- cc.setArg(0, var);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int>(CallConvId::kHost));
+ funcNode->setArg(0, var);
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConvId::kFastCall));
invokeNode->setArg(0, var);
invokeNode->setRet(0, var);
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConvId::kFastCall));
invokeNode->setArg(0, var);
invokeNode->setRet(0, var);
@@ -2582,9 +2492,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallSIMD]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallSIMD
+// ====================================
class X86Test_FuncCallSIMD : public X86TestCase {
public:
@@ -2604,7 +2513,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<void, void*, const void*, const void*>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, const void*, const void*>(CallConvId::kHost));
x86::Gp resultPtr = cc.newIntPtr("resultPtr");
x86::Gp aPtr = cc.newIntPtr("aPtr");
@@ -2614,16 +2523,16 @@ public:
x86::Xmm aXmm = cc.newXmm("aXmm");
x86::Xmm bXmm = cc.newXmm("bXmm");
- cc.setArg(0, resultPtr);
- cc.setArg(1, aPtr);
- cc.setArg(2, bPtr);
+ funcNode->setArg(0, resultPtr);
+ funcNode->setArg(1, aPtr);
+ funcNode->setArg(2, bPtr);
- uint32_t ccId = CallConv::kIdCDecl;
+ CallConvId ccId = CallConvId::kCDecl;
Imm pFnImm = imm((void*)calledFunc_cdecl);
#ifdef _MSC_VER
if (_useVectorCall) {
- ccId = CallConv::kIdVectorCall;
+ ccId = CallConvId::kVectorCall;
pFnImm = imm((void*)calledFunc_vcall);
}
#endif
@@ -2673,9 +2582,8 @@ public:
#endif
};
-// ============================================================================
-// [X86Test_FuncCallLight]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallLight
+// =====================================
class X86Test_FuncCallLight : public X86TestCase {
public:
@@ -2686,11 +2594,11 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdCDecl);
- FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdLightCall2);
+ FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> f1Sig(CallConvId::kCDecl);
+ FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> f2Sig(CallConvId::kLightCall2);
- FuncNode* func = cc.newFunc(funcSig);
- FuncNode* fast = cc.newFunc(fastSig);
+ FuncNode* f1Node = cc.newFunc(f1Sig);
+ FuncNode* f2Node = cc.newFunc(f2Sig);
{
x86::Gp aPtr = cc.newIntPtr("aPtr");
@@ -2704,13 +2612,12 @@ public:
x86::Xmm cXmm = cc.newXmm("cXmm");
x86::Xmm dXmm = cc.newXmm("dXmm");
- cc.addFunc(func);
-
- cc.setArg(0, aPtr);
- cc.setArg(1, bPtr);
- cc.setArg(2, cPtr);
- cc.setArg(3, dPtr);
- cc.setArg(4, pOut);
+ cc.addFunc(f1Node);
+ f1Node->setArg(0, aPtr);
+ f1Node->setArg(1, bPtr);
+ f1Node->setArg(2, cPtr);
+ f1Node->setArg(3, dPtr);
+ f1Node->setArg(4, pOut);
cc.movups(aXmm, x86::ptr(aPtr));
cc.movups(bXmm, x86::ptr(bPtr));
@@ -2722,12 +2629,12 @@ public:
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, fast->label(), fastSig);
+ cc.invoke(&invokeNode, f2Node->label(), f2Sig);
invokeNode->setArg(0, aXmm);
invokeNode->setArg(1, bXmm);
invokeNode->setRet(0, xXmm);
- cc.invoke(&invokeNode, fast->label(), fastSig);
+ cc.invoke(&invokeNode, f2Node->label(), f2Sig);
invokeNode->setArg(0, cXmm);
invokeNode->setArg(1, dXmm);
invokeNode->setRet(0, yXmm);
@@ -2742,9 +2649,9 @@ public:
x86::Xmm aXmm = cc.newXmm("aXmm");
x86::Xmm bXmm = cc.newXmm("bXmm");
- cc.addFunc(fast);
- cc.setArg(0, aXmm);
- cc.setArg(1, bXmm);
+ cc.addFunc(f2Node);
+ f2Node->setArg(0, aXmm);
+ f2Node->setArg(1, bXmm);
cc.paddw(aXmm, bXmm);
cc.ret(aXmm);
cc.endFunc();
@@ -2773,9 +2680,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallManyArgs]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallManyArgs
+// ========================================
class X86Test_FuncCallManyArgs : public X86TestCase {
public:
@@ -2790,7 +2696,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
// Prepare.
x86::Gp va = cc.newInt32("va");
@@ -2819,7 +2725,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
+ FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, va);
invokeNode->setArg(1, vb);
invokeNode->setArg(2, vc);
@@ -2850,9 +2756,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallDuplicateArgs]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallDuplicateArgs
+// =============================================
class X86Test_FuncCallDuplicateArgs : public X86TestCase {
public:
@@ -2867,7 +2772,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
// Prepare.
x86::Gp a = cc.newInt32("a");
@@ -2877,7 +2782,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
+ FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, a);
invokeNode->setArg(1, a);
invokeNode->setArg(2, a);
@@ -2908,9 +2813,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallImmArgs]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallImmArgs
+// =======================================
class X86Test_FuncCallImmArgs : public X86TestCase {
public:
@@ -2921,7 +2825,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
// Prepare.
x86::Gp rv = cc.newInt32("rv");
@@ -2930,7 +2834,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)X86Test_FuncCallManyArgs::calledFunc),
- FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
+ FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, imm(0x03));
invokeNode->setArg(1, imm(0x12));
@@ -2962,9 +2866,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallPtrArgs]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallPtrArgs
+// =======================================
class X86Test_FuncCallPtrArgs : public X86TestCase {
public:
@@ -2988,7 +2891,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
// Prepare.
x86::Gp rv = cc.newInt32("rv");
@@ -2997,7 +2900,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
+ FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConvId::kHost));
invokeNode->setArg(0, imm(0x01));
invokeNode->setArg(1, imm(0x02));
@@ -3029,9 +2932,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallRefArgs]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallRefArgs
+// =======================================
class X86Test_FuncCallRefArgs : public X86TestCase {
public:
@@ -3050,7 +2952,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int&, int&, int&, int&>(CallConvId::kHost));
// Prepare.
x86::Gp arg1 = cc.newInt32();
@@ -3059,16 +2961,16 @@ public:
x86::Gp arg4 = cc.newInt32();
x86::Gp rv = cc.newInt32("rv");
- cc.setArg(0, arg1);
- cc.setArg(1, arg2);
- cc.setArg(2, arg3);
- cc.setArg(3, arg4);
+ funcNode->setArg(0, arg1);
+ funcNode->setArg(1, arg2);
+ funcNode->setArg(2, arg3);
+ funcNode->setArg(3, arg4);
// Call function.
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
+ FuncSignatureT<int, int&, int&, int&, int&>(CallConvId::kHost));
invokeNode->setArg(0, arg1);
invokeNode->setArg(1, arg2);
@@ -3096,9 +2998,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallFloatAsXmmRet]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallFloatAsXmmRet
+// =============================================
class X86Test_FuncCallFloatAsXmmRet : public X86TestCase {
public:
@@ -3113,18 +3014,18 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<float, float, float>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<float, float, float>(CallConvId::kHost));
x86::Xmm a = cc.newXmmSs("a");
x86::Xmm b = cc.newXmmSs("b");
x86::Xmm ret = cc.newXmmSs("ret");
- cc.setArg(0, a);
- cc.setArg(1, b);
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
// Call function.
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<float, float, float>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<float, float, float>(CallConvId::kHost));
invokeNode->setArg(0, a);
invokeNode->setArg(1, b);
invokeNode->setRet(0, ret);
@@ -3147,9 +3048,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallDoubleAsXmmRet]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallDoubleAsXmmRet
+// ==============================================
class X86Test_FuncCallDoubleAsXmmRet : public X86TestCase {
public:
@@ -3164,17 +3064,17 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double>(CallConvId::kHost));
x86::Xmm a = cc.newXmmSd("a");
x86::Xmm b = cc.newXmmSd("b");
x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, a);
- cc.setArg(1, b);
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<double, double, double>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<double, double, double>(CallConvId::kHost));
invokeNode->setArg(0, a);
invokeNode->setArg(1, b);
invokeNode->setRet(0, ret);
@@ -3197,9 +3097,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallConditional]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallConditional
+// ===========================================
class X86Test_FuncCallConditional : public X86TestCase {
public:
@@ -3217,10 +3116,10 @@ public:
InvokeNode* invokeNode;
x86::Gp result;
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- cc.setArg(0, x);
- cc.setArg(1, y);
- cc.setArg(2, op);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
+ funcNode->setArg(0, x);
+ funcNode->setArg(1, y);
+ funcNode->setArg(2, op);
Label opAdd = cc.newLabel();
Label opMul = cc.newLabel();
@@ -3237,7 +3136,7 @@ public:
cc.bind(opAdd);
result = cc.newInt32("result_1");
- cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, x);
invokeNode->setArg(1, y);
invokeNode->setRet(0, result);
@@ -3246,7 +3145,7 @@ public:
cc.bind(opMul);
result = cc.newInt32("result_2");
- cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, x);
invokeNode->setArg(1, y);
invokeNode->setRet(0, result);
@@ -3278,9 +3177,8 @@ public:
static int calledFuncMul(int x, int y) { return x * y; }
};
-// ============================================================================
-// [X86Test_FuncCallMultiple]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMultiple
+// ========================================
class X86Test_FuncCallMultiple : public X86TestCase {
public:
@@ -3301,8 +3199,8 @@ public:
x86::Gp acc0 = cc.newInt32("acc0");
x86::Gp acc1 = cc.newInt32("acc1");
- cc.addFunc(FuncSignatureT<int, int*>(CallConv::kIdHost));
- cc.setArg(0, buf);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int*>(CallConvId::kHost));
+ funcNode->setArg(0, buf);
cc.mov(acc0, 0);
cc.mov(acc1, 0);
@@ -3316,7 +3214,7 @@ public:
cc.mov(ptr, buf);
cc.mov(idx, int(i));
- cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall));
+ cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConvId::kFastCall));
invokeNode->setArg(0, ptr);
invokeNode->setArg(1, idx);
invokeNode->setRet(0, ret);
@@ -3326,7 +3224,7 @@ public:
cc.mov(ptr, buf);
cc.mov(idx, int(i));
- cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall));
+ cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConvId::kFastCall));
invokeNode->setArg(0, ptr);
invokeNode->setArg(1, idx);
invokeNode->setRet(0, ret);
@@ -3355,9 +3253,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallRecursive]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallRecursive
+// =========================================
class X86Test_FuncCallRecursive : public X86TestCase {
public:
@@ -3371,8 +3268,8 @@ public:
x86::Gp val = cc.newInt32("val");
Label skip = cc.newLabel();
- FuncNode* func = cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
- cc.setArg(0, val);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int>(CallConvId::kHost));
+ funcNode->setArg(0, val);
cc.cmp(val, 1);
cc.jle(skip);
@@ -3383,7 +3280,7 @@ public:
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, func->label(), FuncSignatureT<int, int>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, funcNode->label(), FuncSignatureT<int, int>(CallConvId::kHost));
invokeNode->setArg(0, tmp);
invokeNode->setRet(0, tmp);
cc.mul(cc.newInt32(), val, tmp);
@@ -3407,9 +3304,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallVarArg1]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallVarArg1
+// =======================================
class X86Test_FuncCallVarArg1 : public X86TestCase {
public:
@@ -3420,17 +3316,17 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int, int>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int, int>(CallConvId::kHost));
x86::Gp a0 = cc.newInt32("a0");
x86::Gp a1 = cc.newInt32("a1");
x86::Gp a2 = cc.newInt32("a2");
x86::Gp a3 = cc.newInt32("a3");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
- cc.setArg(2, a2);
- cc.setArg(3, a3);
+ funcNode->setArg(0, a0);
+ funcNode->setArg(1, a1);
+ funcNode->setArg(2, a2);
+ funcNode->setArg(3, a3);
// We call `int func(size_t, ...)`
// - The `vaIndex` must be 1 (first argument after size_t).
@@ -3438,7 +3334,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, size_t, int, int, int, int>(CallConv::kIdHost, 1));
+ FuncSignatureT<int, size_t, int, int, int, int>(CallConvId::kHost, 1));
invokeNode->setArg(0, imm(4));
invokeNode->setArg(1, a0);
invokeNode->setArg(2, a1);
@@ -3476,9 +3372,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallVarArg2]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallVarArg2
+// =======================================
class X86Test_FuncCallVarArg2 : public X86TestCase {
public:
@@ -3489,17 +3384,17 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, double, double, double, double>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, double, double, double, double>(CallConvId::kHost));
x86::Xmm a0 = cc.newXmmSd("a0");
x86::Xmm a1 = cc.newXmmSd("a1");
x86::Xmm a2 = cc.newXmmSd("a2");
x86::Xmm a3 = cc.newXmmSd("a3");
- cc.setArg(0, a0);
- cc.setArg(1, a1);
- cc.setArg(2, a2);
- cc.setArg(3, a3);
+ funcNode->setArg(0, a0);
+ funcNode->setArg(1, a1);
+ funcNode->setArg(2, a2);
+ funcNode->setArg(3, a3);
// We call `double func(size_t, ...)`
// - The `vaIndex` must be 1 (first argument after size_t).
@@ -3507,7 +3402,7 @@ public:
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<double, size_t, double, double, double, double>(CallConv::kIdHost, 1));
+ FuncSignatureT<double, size_t, double, double, double, double>(CallConvId::kHost, 1));
invokeNode->setArg(0, imm(4));
invokeNode->setArg(1, a0);
invokeNode->setArg(2, a1);
@@ -3545,9 +3440,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallInt64Arg]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallInt64Arg
+// ========================================
class X86Test_FuncCallInt64Arg : public X86TestCase {
public:
@@ -3558,11 +3452,11 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint64_t, uint64_t>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<uint64_t, uint64_t>(CallConvId::kHost));
if (cc.is64Bit()) {
x86::Gp reg = cc.newUInt64();
- cc.setArg(0, reg);
+ funcNode->setArg(0, reg);
cc.add(reg, 1);
cc.ret(reg);
}
@@ -3570,8 +3464,8 @@ public:
x86::Gp hi = cc.newUInt32("hi");
x86::Gp lo = cc.newUInt32("lo");
- cc.setArg(0, 0, lo);
- cc.setArg(0, 1, hi);
+ funcNode->setArg(0, 0, lo);
+ funcNode->setArg(0, 1, hi);
cc.add(lo, 1);
cc.adc(hi, 0);
@@ -3607,9 +3501,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallMisc1]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc1
+// =====================================
class X86Test_FuncCallMisc1 : public X86TestCase {
public:
@@ -3622,19 +3515,19 @@ public:
static void dummy(int, int) {}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b");
x86::Gp r = cc.newInt32("r");
- cc.setArg(0, a);
- cc.setArg(1, b);
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)dummy),
- FuncSignatureT<void, int, int>(CallConv::kIdHost));
+ FuncSignatureT<void, int, int>(CallConvId::kHost));
invokeNode->setArg(0, a);
invokeNode->setArg(1, b);
@@ -3658,9 +3551,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_FuncCallMisc2]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc2
+// =====================================
class X86Test_FuncCallMisc2 : public X86TestCase {
public:
@@ -3671,19 +3563,19 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, const double*>(CallConvId::kHost));
x86::Gp p = cc.newIntPtr("p");
x86::Xmm arg = cc.newXmmSd("arg");
x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, p);
+ funcNode->setArg(0, p);
cc.movsd(arg, x86::ptr(p));
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)op),
- FuncSignatureT<double, double>(CallConv::kIdHost));
+ FuncSignatureT<double, double>(CallConvId::kHost));
invokeNode->setArg(0, arg);
invokeNode->setRet(0, ret);
@@ -3709,9 +3601,8 @@ public:
static double op(double a) { return a * a; }
};
-// ============================================================================
-// [X86Test_FuncCallMisc3]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc3
+// =====================================
class X86Test_FuncCallMisc3 : public X86TestCase {
public:
@@ -3722,19 +3613,19 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<double, const double*>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<double, const double*>(CallConvId::kHost));
x86::Gp p = cc.newIntPtr("p");
x86::Xmm arg = cc.newXmmSd("arg");
x86::Xmm ret = cc.newXmmSd("ret");
- cc.setArg(0, p);
+ funcNode->setArg(0, p);
cc.movsd(arg, x86::ptr(p));
InvokeNode* invokeNode;
cc.invoke(&invokeNode,
imm((void*)op),
- FuncSignatureT<double, double>(CallConv::kIdHost));
+ FuncSignatureT<double, double>(CallConvId::kHost));
invokeNode->setArg(0, arg);
invokeNode->setRet(0, ret);
@@ -3763,9 +3654,8 @@ public:
static double op(double a) { return a * a; }
};
-// ============================================================================
-// [X86Test_FuncCallMisc4]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc4
+// =====================================
class X86Test_FuncCallMisc4 : public X86TestCase {
public:
@@ -3779,13 +3669,13 @@ public:
InvokeNode* invokeNode;
FuncSignatureBuilder funcSignature;
- funcSignature.setCallConv(CallConv::kIdHost);
- funcSignature.setRet(Type::kIdF64);
+ funcSignature.setCallConvId(CallConvId::kHost);
+ funcSignature.setRet(TypeId::kFloat64);
cc.addFunc(funcSignature);
FuncSignatureBuilder invokeSignature;
- invokeSignature.setCallConv(CallConv::kIdHost);
- invokeSignature.setRet(Type::kIdF64);
+ invokeSignature.setCallConvId(CallConvId::kHost);
+ invokeSignature.setRet(TypeId::kFloat64);
cc.invoke(&invokeNode, imm((void*)calledFunc), invokeSignature);
x86::Xmm ret = cc.newXmmSd("ret");
@@ -3811,9 +3701,8 @@ public:
static double calledFunc() { return 3.14; }
};
-// ============================================================================
-// [X86Test_FuncCallMisc5]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc5
+// =====================================
// The register allocator should clobber the register used by the `call` itself.
class X86Test_FuncCallMisc5 : public X86TestCase {
@@ -3825,12 +3714,12 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
x86::Gp pFn = cc.newIntPtr("pFn");
x86::Gp vars[16];
- uint32_t i, regCount = cc.arch() == Environment::kArchX86 ? 8 : 16;
+ uint32_t i, regCount = cc.arch() == Arch::kX86 ? 8 : 16;
ASMJIT_ASSERT(regCount <= ASMJIT_ARRAY_SIZE(vars));
cc.mov(pFn, imm((void*)calledFunc));
@@ -3844,7 +3733,7 @@ public:
}
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, pFn, FuncSignatureT<void>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, pFn, FuncSignatureT<void>(CallConvId::kHost));
for (i = 1; i < regCount; i++)
if (vars[i].isValid())
@@ -3870,9 +3759,8 @@ public:
static void calledFunc() {}
};
-// ============================================================================
-// [X86Test_FuncCallMisc6]
-// ============================================================================
+// x86::Compiler - X86Test_FuncCallMisc6
+// =====================================
class X86Test_FuncCallMisc6 : public X86TestCase {
public:
@@ -3883,7 +3771,7 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<uint32_t, uint32_t>(CallConvId::kHost));
constexpr uint32_t kCount = 16;
@@ -3892,14 +3780,14 @@ public:
x86::Gp retVal = cc.newUInt32("retVal");
uint32_t i;
- cc.setArg(0, argVal);
+ funcNode->setArg(0, argVal);
cc.add(argVal, 1);
for (i = 0; i < kCount; i++)
v[i] = cc.newUInt32("v%u", i);
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<uint32_t, uint32_t>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<uint32_t, uint32_t>(CallConvId::kHost));
invokeNode->setArg(0, argVal);
invokeNode->setRet(0, retVal);
@@ -3931,9 +3819,8 @@ public:
static uint32_t calledFunc(uint32_t x) { return x + 1; }
};
-// ============================================================================
-// [X86Test_MiscLocalConstPool]
-// ============================================================================
+// x86::Compiler - X86Test_MiscLocalConstPool
+// ==========================================
class X86Test_MiscLocalConstPool : public X86TestCase {
public:
@@ -3944,13 +3831,13 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1");
- x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeLocal, 200);
- x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeLocal, 33);
+ x86::Mem c0 = cc.newInt32Const(ConstPoolScope::kLocal, 200);
+ x86::Mem c1 = cc.newInt32Const(ConstPoolScope::kLocal, 33);
cc.mov(v0, c0);
cc.mov(v1, c1);
@@ -3974,9 +3861,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_MiscGlobalConstPool]
-// ============================================================================
+// x86::Compiler - X86Test_MiscGlobalConstPool
+// ===========================================
class X86Test_MiscGlobalConstPool : public X86TestCase {
public:
@@ -3987,13 +3873,13 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
x86::Gp v0 = cc.newInt32("v0");
x86::Gp v1 = cc.newInt32("v1");
- x86::Mem c0 = cc.newInt32Const(ConstPool::kScopeGlobal, 200);
- x86::Mem c1 = cc.newInt32Const(ConstPool::kScopeGlobal, 33);
+ x86::Mem c0 = cc.newInt32Const(ConstPoolScope::kGlobal, 200);
+ x86::Mem c1 = cc.newInt32Const(ConstPoolScope::kGlobal, 33);
cc.mov(v0, c0);
cc.mov(v1, c1);
@@ -4017,9 +3903,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_MiscMultiRet]
-// ============================================================================
+// x86::Compiler - X86Test_MiscMultiRet
+// ====================================
struct X86Test_MiscMultiRet : public X86TestCase {
X86Test_MiscMultiRet() : X86TestCase("MiscMultiRet") {}
@@ -4029,7 +3914,7 @@ struct X86Test_MiscMultiRet : public X86TestCase {
}
virtual void compile(x86::Compiler& cc) {
- cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, int, int>(CallConvId::kHost));
x86::Gp op = cc.newInt32("op");
x86::Gp a = cc.newInt32("a");
@@ -4041,9 +3926,9 @@ struct X86Test_MiscMultiRet : public X86TestCase {
Label L_Mul = cc.newLabel();
Label L_Div = cc.newLabel();
- cc.setArg(0, op);
- cc.setArg(1, a);
- cc.setArg(2, b);
+ funcNode->setArg(0, op);
+ funcNode->setArg(1, a);
+ funcNode->setArg(2, b);
cc.cmp(op, 0);
cc.jz(L_Add);
@@ -4109,9 +3994,8 @@ struct X86Test_MiscMultiRet : public X86TestCase {
}
};
-// ============================================================================
-// [X86Test_MiscMultiFunc]
-// ============================================================================
+// x86::Compiler - X86Test_MiscMultiFunc
+// =====================================
class X86Test_MiscMultiFunc : public X86TestCase {
public:
@@ -4122,19 +4006,19 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- FuncNode* f1 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
- FuncNode* f2 = cc.newFunc(FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ FuncNode* f1Node = cc.newFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
+ FuncNode* f2Node = cc.newFunc(FuncSignatureT<int, int, int>(CallConvId::kHost));
{
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b");
- cc.addFunc(f1);
- cc.setArg(0, a);
- cc.setArg(1, b);
+ cc.addFunc(f1Node);
+ f1Node->setArg(0, a);
+ f1Node->setArg(1, b);
InvokeNode* invokeNode;
- cc.invoke(&invokeNode, f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ cc.invoke(&invokeNode, f2Node->label(), FuncSignatureT<int, int, int>(CallConvId::kHost));
invokeNode->setArg(0, a);
invokeNode->setArg(1, b);
invokeNode->setRet(0, a);
@@ -4147,9 +4031,9 @@ public:
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newInt32("b");
- cc.addFunc(f2);
- cc.setArg(0, a);
- cc.setArg(1, b);
+ cc.addFunc(f2Node);
+ f2Node->setArg(0, a);
+ f2Node->setArg(1, b);
cc.add(a, b);
cc.ret(a);
@@ -4172,9 +4056,8 @@ public:
}
};
-// ============================================================================
-// [X86Test_MiscUnfollow]
-// ============================================================================
+// x86::Compiler - X86Test_MiscUnfollow
+// ====================================
// Global (I didn't find a better way to test this).
static jmp_buf globalJmpBuf;
@@ -4188,27 +4071,21 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- // NOTE: Fastcall calling convention is the most appropriate here, as all
- // arguments will be passed by registers and there won't be any stack
- // misalignment when we call the `handler()`. This was failing on OSX
- // when targeting 32-bit.
- cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdFastCall));
-
+ // NOTE: Fastcall calling convention is the most appropriate here as all arguments are passed via registers and
+ // there won't be any stack misalignment in the `handler()`. This was failing on MacOS when targeting 32-bit mode.
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newIntPtr("b");
Label tramp = cc.newLabel();
- cc.setArg(0, a);
- cc.setArg(1, b);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<int, int, void*>(CallConvId::kFastCall));
+ funcNode->setArg(0, a);
+ funcNode->setArg(1, b);
cc.cmp(a, 0);
cc.jz(tramp);
-
cc.ret(a);
-
cc.bind(tramp);
cc.unfollow().jmp(b);
-
cc.endFunc();
}
@@ -4234,9 +4111,8 @@ public:
static void ASMJIT_FASTCALL handler() { longjmp(globalJmpBuf, 1); }
};
-// ============================================================================
-// [Export]
-// ============================================================================
+// x86::Compiler - Tests
+// =====================
void compiler_add_x86_tests(TestApp& app) {
// Base tests.
diff --git a/test/asmjit_test_emitters.cpp b/test/asmjit_test_emitters.cpp
index 9ca80e8..63c14a6 100644
--- a/test/asmjit_test_emitters.cpp
+++ b/test/asmjit_test_emitters.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
@@ -52,7 +34,7 @@ static void makeRawFunc(x86::Emitter* emitter) noexcept {
// Create and initialize `FuncDetail` and `FuncFrame`.
FuncDetail func;
- func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost), emitter->environment());
+ func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost), emitter->environment());
FuncFrame frame;
frame.init(func);
@@ -82,17 +64,16 @@ static void makeRawFunc(x86::Emitter* emitter) noexcept {
#ifndef ASMJIT_NO_COMPILER
// This function works with x86::Compiler, provided for comparison.
static void makeCompiledFunc(x86::Compiler* cc) noexcept {
- x86::Gp dst = cc->newIntPtr();
- x86::Gp src_a = cc->newIntPtr();
- x86::Gp src_b = cc->newIntPtr();
+ x86::Gp dst = cc->newIntPtr("dst");
+ x86::Gp src_a = cc->newIntPtr("src_a");
+ x86::Gp src_b = cc->newIntPtr("src_b");
+ x86::Xmm vec0 = cc->newXmm("vec0");
+ x86::Xmm vec1 = cc->newXmm("vec1");
- x86::Xmm vec0 = cc->newXmm();
- x86::Xmm vec1 = cc->newXmm();
-
- cc->addFunc(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
- cc->setArg(0, dst);
- cc->setArg(1, src_a);
- cc->setArg(2, src_b);
+ FuncNode* funcNode = cc->addFunc(FuncSignatureT<void, int*, const int*, const int*>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src_a);
+ funcNode->setArg(2, src_b);
cc->movdqu(vec0, x86::ptr(src_a));
cc->movdqu(vec1, x86::ptr(src_b));
@@ -102,10 +83,10 @@ static void makeCompiledFunc(x86::Compiler* cc) noexcept {
}
#endif
-static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
+static uint32_t testFunc(JitRuntime& rt, EmitterType emitterType) noexcept {
#ifndef ASMJIT_NO_LOGGING
FileLogger logger(stdout);
- logger.setIndentation(FormatOptions::kIndentationCode, 2);
+ logger.setIndentation(FormatIndentationGroup::kCode, 2);
#endif
CodeHolder code;
@@ -117,7 +98,11 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
Error err = kErrorOk;
switch (emitterType) {
- case BaseEmitter::kTypeAssembler: {
+ case EmitterType::kNone: {
+ break;
+ }
+
+ case EmitterType::kAssembler: {
printf("Using x86::Assembler:\n");
x86::Assembler a(&code);
makeRawFunc(a.as<x86::Emitter>());
@@ -125,7 +110,7 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
}
#ifndef ASMJIT_NO_BUILDER
- case BaseEmitter::kTypeBuilder: {
+ case EmitterType::kBuilder: {
printf("Using x86::Builder:\n");
x86::Builder cb(&code);
makeRawFunc(cb.as<x86::Emitter>());
@@ -140,7 +125,7 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
#endif
#ifndef ASMJIT_NO_COMPILER
- case BaseEmitter::kTypeCompiler: {
+ case EmitterType::kCompiler: {
printf("Using x86::Compiler:\n");
x86::Compiler cc(&code);
makeCompiledFunc(&cc);
@@ -187,14 +172,14 @@ int main() {
JitRuntime rt;
unsigned nFailed = 0;
- nFailed += testFunc(rt, BaseEmitter::kTypeAssembler);
+ nFailed += testFunc(rt, EmitterType::kAssembler);
#ifndef ASMJIT_NO_BUILDER
- nFailed += testFunc(rt, BaseEmitter::kTypeBuilder);
+ nFailed += testFunc(rt, EmitterType::kBuilder);
#endif
#ifndef ASMJIT_NO_COMPILER
- nFailed += testFunc(rt, BaseEmitter::kTypeCompiler);
+ nFailed += testFunc(rt, EmitterType::kCompiler);
#endif
if (!nFailed)
diff --git a/test/asmjit_test_instinfo.cpp b/test/asmjit_test_instinfo.cpp
index 2de8897..3d51edc 100644
--- a/test/asmjit_test_instinfo.cpp
+++ b/test/asmjit_test_instinfo.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
@@ -35,7 +17,7 @@ static char accessLetter(bool r, bool w) noexcept {
return r && w ? 'X' : r ? 'R' : w ? 'W' : '_';
}
-static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount) {
+static void printInfo(Arch arch, const BaseInst& inst, const Operand_* operands, size_t opCount) {
StringTmp<512> sb;
// Read & Write Information
@@ -45,7 +27,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
InstAPI::queryRWInfo(arch, inst, operands, opCount, &rw);
#ifndef ASMJIT_NO_LOGGING
- Formatter::formatInstruction(sb, 0, nullptr, arch, inst, operands, opCount);
+ Formatter::formatInstruction(sb, FormatFlags::kNone, nullptr, arch, inst, operands, opCount);
#else
sb.append("<Logging-Not-Available>");
#endif
@@ -77,34 +59,37 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
sb.append("\n");
}
- if (rw.readFlags() | rw.writeFlags()) {
+ // CPU Flags (Read/Write)
+ // ----------------------
+
+ if ((rw.readFlags() | rw.writeFlags()) != CpuRWFlags::kNone) {
sb.append(" Flags: \n");
struct FlagMap {
- uint32_t flag;
+ CpuRWFlags flag;
char name[4];
};
static const FlagMap flagMap[] = {
- { x86::Status::kCF, "CF" },
- { x86::Status::kOF, "OF" },
- { x86::Status::kSF, "SF" },
- { x86::Status::kZF, "ZF" },
- { x86::Status::kAF, "AF" },
- { x86::Status::kPF, "PF" },
- { x86::Status::kDF, "DF" },
- { x86::Status::kIF, "IF" },
- { x86::Status::kAC, "AC" },
- { x86::Status::kC0, "C0" },
- { x86::Status::kC1, "C1" },
- { x86::Status::kC2, "C2" },
- { x86::Status::kC3, "C3" }
+ { CpuRWFlags::kX86_CF, "CF" },
+ { CpuRWFlags::kX86_OF, "OF" },
+ { CpuRWFlags::kX86_SF, "SF" },
+ { CpuRWFlags::kX86_ZF, "ZF" },
+ { CpuRWFlags::kX86_AF, "AF" },
+ { CpuRWFlags::kX86_PF, "PF" },
+ { CpuRWFlags::kX86_DF, "DF" },
+ { CpuRWFlags::kX86_IF, "IF" },
+ { CpuRWFlags::kX86_AC, "AC" },
+ { CpuRWFlags::kX86_C0, "C0" },
+ { CpuRWFlags::kX86_C1, "C1" },
+ { CpuRWFlags::kX86_C2, "C2" },
+ { CpuRWFlags::kX86_C3, "C3" }
};
sb.append(" ");
for (uint32_t f = 0; f < 13; f++) {
- char c = accessLetter((rw.readFlags() & flagMap[f].flag) != 0,
- (rw.writeFlags() & flagMap[f].flag) != 0);
+ char c = accessLetter((rw.readFlags() & flagMap[f].flag) != CpuRWFlags::kNone,
+ (rw.writeFlags() & flagMap[f].flag) != CpuRWFlags::kNone);
if (c != '_')
sb.appendFormat("%s=%c ", flagMap[f].name, c);
}
@@ -115,7 +100,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
// CPU Features
// ------------
- BaseFeatures features;
+ CpuFeatures features;
InstAPI::queryFeatures(arch, inst, operands, opCount, &features);
#ifndef ASMJIT_NO_LOGGING
@@ -124,7 +109,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
sb.append(" ");
bool first = true;
- BaseFeatures::Iterator it(features.iterator());
+ CpuFeatures::Iterator it(features.iterator());
while (it.hasNext()) {
uint32_t featureId = uint32_t(it.next());
if (!first)
@@ -140,7 +125,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
}
template<typename... Args>
-static void printInfoSimple(uint32_t arch, uint32_t instId, uint32_t options, Args&&... args) {
+static void printInfoSimple(Arch arch,InstId instId, InstOptions options, Args&&... args) {
BaseInst inst(instId);
inst.addOptions(options);
Operand_ opArray[] = { std::forward<Args>(args)... };
@@ -148,7 +133,7 @@ static void printInfoSimple(uint32_t arch, uint32_t instId, uint32_t options, Ar
}
template<typename... Args>
-static void printInfoExtra(uint32_t arch, uint32_t instId, uint32_t options, const BaseReg& extraReg, Args&&... args) {
+static void printInfoExtra(Arch arch, InstId instId, InstOptions options, const BaseReg& extraReg, Args&&... args) {
BaseInst inst(instId);
inst.addOptions(options);
inst.setExtraReg(extraReg);
@@ -159,27 +144,27 @@ static void printInfoExtra(uint32_t arch, uint32_t instId, uint32_t options, con
static void testX86Arch() {
#if !defined(ASMJIT_NO_X86)
using namespace x86;
- uint32_t arch = Environment::kArchX64;
+ Arch arch = Arch::kX64;
- printInfoSimple(arch, Inst::kIdAdd, 0, eax, ebx);
- printInfoSimple(arch, Inst::kIdLods, 0, eax, dword_ptr(rsi));
+ printInfoSimple(arch, Inst::kIdAdd, InstOptions::kNone, eax, ebx);
+ printInfoSimple(arch, Inst::kIdLods, InstOptions::kNone, eax, dword_ptr(rsi));
- printInfoSimple(arch, Inst::kIdPshufd, 0, xmm0, xmm1, imm(0));
- printInfoSimple(arch, Inst::kIdPabsb, 0, mm1, mm2);
- printInfoSimple(arch, Inst::kIdPabsb, 0, xmm1, xmm2);
- printInfoSimple(arch, Inst::kIdPextrw, 0, eax, mm1, imm(0));
- printInfoSimple(arch, Inst::kIdPextrw, 0, eax, xmm1, imm(0));
- printInfoSimple(arch, Inst::kIdPextrw, 0, ptr(rax), xmm1, imm(0));
+ printInfoSimple(arch, Inst::kIdPshufd, InstOptions::kNone, xmm0, xmm1, imm(0));
+ printInfoSimple(arch, Inst::kIdPabsb, InstOptions::kNone, mm1, mm2);
+ printInfoSimple(arch, Inst::kIdPabsb, InstOptions::kNone, xmm1, xmm2);
+ printInfoSimple(arch, Inst::kIdPextrw, InstOptions::kNone, eax, mm1, imm(0));
+ printInfoSimple(arch, Inst::kIdPextrw, InstOptions::kNone, eax, xmm1, imm(0));
+ printInfoSimple(arch, Inst::kIdPextrw, InstOptions::kNone, ptr(rax), xmm1, imm(0));
- printInfoSimple(arch, Inst::kIdVpdpbusd, 0, xmm0, xmm1, xmm2);
- printInfoSimple(arch, Inst::kIdVpdpbusd, Inst::kOptionVex, xmm0, xmm1, xmm2);
+ printInfoSimple(arch, Inst::kIdVpdpbusd, InstOptions::kNone, xmm0, xmm1, xmm2);
+ printInfoSimple(arch, Inst::kIdVpdpbusd, InstOptions::kX86_Vex, xmm0, xmm1, xmm2);
- printInfoSimple(arch, Inst::kIdVaddpd, 0, ymm0, ymm1, ymm2);
- printInfoSimple(arch, Inst::kIdVaddpd, 0, ymm0, ymm30, ymm31);
- printInfoSimple(arch, Inst::kIdVaddpd, 0, zmm0, zmm1, zmm2);
+ printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, ymm0, ymm1, ymm2);
+ printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, ymm0, ymm30, ymm31);
+ printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, zmm0, zmm1, zmm2);
- printInfoExtra(arch, Inst::kIdVaddpd, 0, k1, zmm0, zmm1, zmm2);
- printInfoExtra(arch, Inst::kIdVaddpd, Inst::kOptionZMask, k1, zmm0, zmm1, zmm2);
+ printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kNone, k1, zmm0, zmm1, zmm2);
+ printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kX86_ZMask, k1, zmm0, zmm1, zmm2);
#endif
}
diff --git a/test/asmjit_test_misc.h b/test/asmjit_test_misc.h
index f0d156f..0839d30 100644
--- a/test/asmjit_test_misc.h
+++ b/test/asmjit_test_misc.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_TEST_MISC_H_INCLUDED
#define ASMJIT_TEST_MISC_H_INCLUDED
@@ -60,8 +42,8 @@ static void generateSseAlphaBlendInternal(
cc.movd(v0080, gp0.r32());
cc.mov(gp0.r32(), 0x01010101);
cc.movd(v0101, gp0.r32());
- cc.pshufd(v0080, v0080, x86::Predicate::shuf(0, 0, 0, 0));
- cc.pshufd(v0101, v0101, x86::Predicate::shuf(0, 0, 0, 0));
+ cc.pshufd(v0080, v0080, x86::shuffleImm(0, 0, 0, 0));
+ cc.pshufd(v0101, v0101, x86::shuffleImm(0, 0, 0, 0));
// How many pixels have to be processed to make the loop aligned.
cc.xor_(j, j);
@@ -89,7 +71,7 @@ static void generateSseAlphaBlendInternal(
cc.psrlw(a0, 8);
cc.punpcklbw(x0, vzero);
- cc.pshuflw(a0, a0, x86::Predicate::shuf(1, 1, 1, 1));
+ cc.pshuflw(a0, a0, x86::shuffleImm(1, 1, 1, 1));
cc.punpcklbw(y0, vzero);
cc.pmullw(x0, a0);
@@ -144,8 +126,8 @@ static void generateSseAlphaBlendInternal(
cc.punpckhbw(x1, vzero);
cc.punpckhwd(a1, a1);
- cc.pshufd(a0, a0, x86::Predicate::shuf(3, 3, 1, 1));
- cc.pshufd(a1, a1, x86::Predicate::shuf(3, 3, 1, 1));
+ cc.pshufd(a0, a0, x86::shuffleImm(3, 3, 1, 1));
+ cc.pshufd(a1, a1, x86::shuffleImm(3, 3, 1, 1));
cc.pmullw(x0, a0);
cc.pmullw(x1, a1);
@@ -188,7 +170,7 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -220,7 +202,7 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -260,10 +242,10 @@ static void generateSseAlphaBlend(asmjit::BaseEmitter& emitter, bool emitPrologE
Xmm v6 = cc.newXmm("v6");
Xmm v7 = cc.newXmm("v7");
- cc.addFunc(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost));
- cc.setArg(0, dst);
- cc.setArg(1, src);
- cc.setArg(2, i);
+ FuncNode* funcNode = cc.addFunc(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost));
+ funcNode->setArg(0, dst);
+ funcNode->setArg(1, src);
+ funcNode->setArg(2, i);
generateSseAlphaBlendInternal(cc, dst, src, i, j, v0, v1, v2, v3, v4, v5, v6, v7);
cc.endFunc();
}
diff --git a/test/asmjit_test_perf.cpp b/test/asmjit_test_perf.cpp
index 6340129..2ade96c 100644
--- a/test/asmjit_test_perf.cpp
+++ b/test/asmjit_test_perf.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
#include <stdio.h>
diff --git a/test/asmjit_test_perf.h b/test/asmjit_test_perf.h
index 565c18a..2ab0038 100644
--- a/test/asmjit_test_perf.h
+++ b/test/asmjit_test_perf.h
@@ -1,30 +1,13 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_TEST_PERF_H_INCLUDED
#define ASMJIT_TEST_PERF_H_INCLUDED
#include <asmjit/core.h>
+#include "asmjitutils.h"
#include "performancetimer.h"
class MyErrorHandler : public asmjit::ErrorHandler {
@@ -37,14 +20,11 @@ class MyErrorHandler : public asmjit::ErrorHandler {
};
template<typename EmitterT, typename FuncT>
-static void bench(asmjit::CodeHolder& code, uint32_t arch, uint32_t numIterations, const char* testName, const FuncT& func) noexcept {
+static void bench(asmjit::CodeHolder& code, asmjit::Arch arch, uint32_t numIterations, const char* testName, const FuncT& func) noexcept {
EmitterT emitter;
MyErrorHandler eh;
- const char* archName =
- arch == asmjit::Environment::kArchX86 ? "X86" :
- arch == asmjit::Environment::kArchX64 ? "X64" : "???";
-
+ const char* archName = asmjitArchAsString(arch);
const char* emitterName =
emitter.isAssembler() ? "Assembler" :
emitter.isCompiler() ? "Compiler" :
diff --git a/test/asmjit_test_perf_x86.cpp b/test/asmjit_test_perf_x86.cpp
index 679e2c0..e2720b7 100644
--- a/test/asmjit_test_perf_x86.cpp
+++ b/test/asmjit_test_perf_x86.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include <asmjit/core.h>
@@ -353,7 +335,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -379,7 +361,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -404,7 +386,7 @@ static void generateGpSequence(BaseEmitter& emitter, InstForm form, bool emitPro
Gp c = cc.newIntPtr("c");
Gp d = cc.newIntPtr("d");
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
generateGpSequenceInternal(cc, form, a, b, c, d);
cc.endFunc();
}
@@ -945,7 +927,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -966,7 +948,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -992,7 +974,7 @@ static void generateSseSequence(BaseEmitter& emitter, InstForm form, bool emitPr
Xmm c = cc.newXmm("c");
Xmm d = cc.newXmm("d");
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
generateSseSequenceInternal(cc, form, gp, a, b, c, d);
cc.endFunc();
}
@@ -2115,7 +2097,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -2136,7 +2118,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -2162,7 +2144,7 @@ static void generateAvxSequence(BaseEmitter& emitter, InstForm form, bool emitPr
Ymm c = cc.newYmm("c");
Ymm d = cc.newYmm("d");
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
generateAvxSequenceInternal(cc, form, gp, a, b, c, d);
cc.endFunc();
}
@@ -4867,7 +4849,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -4888,7 +4870,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
if (emitPrologEpilog) {
FuncDetail func;
- func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost), cc.environment());
+ func.init(FuncSignatureT<void, void*, const void*, size_t>(CallConvId::kHost), cc.environment());
FuncFrame frame;
frame.init(func);
@@ -4918,7 +4900,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
KReg kB = cc.newKq("kB");
KReg kC = cc.newKq("kC");
- cc.addFunc(FuncSignatureT<void>(CallConv::kIdHost));
+ cc.addFunc(FuncSignatureT<void>(CallConvId::kHost));
generateAvx512SequenceInternal(cc, form, gp, kA, kB, kC, vecA, vecB, vecC, vecD);
cc.endFunc();
}
@@ -4926,7 +4908,7 @@ static void generateAvx512Sequence(BaseEmitter& emitter, InstForm form, bool emi
}
template<typename EmitterFn>
-static void benchmarkX86Function(uint32_t arch, uint32_t numIterations, const char* description, const EmitterFn& emitterFn) noexcept {
+static void benchmarkX86Function(Arch arch, uint32_t numIterations, const char* description, const EmitterFn& emitterFn) noexcept {
CodeHolder code;
printf("%s:\n", description);
@@ -4935,12 +4917,12 @@ static void benchmarkX86Function(uint32_t arch, uint32_t numIterations, const ch
});
bench<x86::Assembler>(code, arch, numIterations, "[validated]", [&](x86::Assembler& cc) {
- cc.addValidationOptions(BaseEmitter::kValidationOptionAssembler);
+ cc.addDiagnosticOptions(DiagnosticOptions::kValidateAssembler);
emitterFn(cc, false);
});
bench<x86::Assembler>(code, arch, numIterations, "[prolog/epilog]", [&](x86::Assembler& cc) {
- cc.addValidationOptions(BaseEmitter::kValidationOptionAssembler);
+ cc.addDiagnosticOptions(DiagnosticOptions::kValidateAssembler);
emitterFn(cc, true);
});
@@ -4978,10 +4960,10 @@ void benchmarkX86Emitters(uint32_t numIterations, bool testX86, bool testX64) {
uint32_t i = 0;
uint32_t n = 0;
- uint32_t archs[2] {};
+ Arch archs[2] {};
- if (testX86) archs[n++] = Environment::kArchX86;
- if (testX64) archs[n++] = Environment::kArchX64;
+ if (testX86) archs[n++] = Arch::kX86;
+ if (testX64) archs[n++] = Arch::kX64;
for (i = 0; i < n; i++) {
static const char description[] = "GpSequence<Reg> (Sequence of GP instructions - reg-only)";
diff --git a/test/asmjit_test_unit.cpp b/test/asmjit_test_unit.cpp
index 34931b2..5658ebc 100644
--- a/test/asmjit_test_unit.cpp
+++ b/test/asmjit_test_unit.cpp
@@ -1,61 +1,26 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
-#include <asmjit/asmjit.h>
-#include "./broken.h"
+#include <asmjit/core.h>
-using namespace asmjit;
+#if !defined(ASMJIT_NO_X86)
+#include <asmjit/x86.h>
+#endif
-// ============================================================================
-// [DumpCpu]
-// ============================================================================
-
-struct DumpCpuFeature {
- uint32_t feature;
- const char* name;
-};
-
-static const char* archToString(uint32_t arch) noexcept {
- switch (arch & ~Environment::kArchBigEndianMask) {
- case Environment::kArchX86 : return "X86";
- case Environment::kArchX64 : return "X64";
- case Environment::kArchARM : return "ARM";
- case Environment::kArchThumb : return "Thumb";
- case Environment::kArchAArch64 : return "AArch64";
- case Environment::kArchMIPS32_LE: return "MIPS";
- case Environment::kArchMIPS64_LE: return "MIPS64";
- default: return "Unknown";
- }
-}
+#include "asmjitutils.h"
+#include "broken.h"
+
+using namespace asmjit;
static void dumpCpu(void) noexcept {
const CpuInfo& cpu = CpuInfo::host();
- // --------------------------------------------------------------------------
- // [CPU Information]
- // --------------------------------------------------------------------------
+ // CPU Information
+ // ---------------
- INFO("Host CPU:");
+ INFO("CPU Info:");
INFO(" Vendor : %s", cpu.vendor());
INFO(" Brand : %s", cpu.brand());
INFO(" Model ID : %u", cpu.modelId());
@@ -68,13 +33,12 @@ static void dumpCpu(void) noexcept {
INFO(" HW-Thread Count : %u", cpu.hwThreadCount());
INFO("");
- // --------------------------------------------------------------------------
- // [CPU Features]
- // --------------------------------------------------------------------------
+ // CPU Features
+ // ------------
#ifndef ASMJIT_NO_LOGGING
INFO("CPU Features:");
- BaseFeatures::Iterator it(cpu.features().iterator());
+ CpuFeatures::Iterator it(cpu.features().iterator());
while (it.hasNext()) {
uint32_t featureId = uint32_t(it.next());
StringTmp<64> featureString;
@@ -85,10 +49,6 @@ static void dumpCpu(void) noexcept {
#endif // !ASMJIT_NO_LOGGING
}
-// ============================================================================
-// [DumpSizeOf]
-// ============================================================================
-
#define DUMP_TYPE(...) \
INFO(" %-26s: %u", #__VA_ARGS__, uint32_t(sizeof(__VA_ARGS__)))
@@ -188,10 +148,6 @@ static void dumpSizeOf(void) noexcept {
#undef DUMP_TYPE
-// ============================================================================
-// [Main]
-// ============================================================================
-
static void onBeforeRun(void) noexcept {
dumpCpu();
dumpSizeOf();
@@ -208,7 +164,7 @@ int main(int argc, const char* argv[]) {
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
- archToString(Environment::kArchHost),
+ asmjitArchAsString(Arch::kHost),
buildType
);
diff --git a/test/asmjit_test_x86_sections.cpp b/test/asmjit_test_x86_sections.cpp
index 582811e..afd5807 100644
--- a/test/asmjit_test_x86_sections.cpp
+++ b/test/asmjit_test_x86_sections.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
// ----------------------------------------------------------------------------
// This is a working example that demonstrates how multiple sections can be
@@ -58,12 +40,12 @@ static void fail(const char* message, Error err) {
int main() {
printf("AsmJit X86 Sections Test\n\n");
- Environment env = hostEnvironment();
+ Environment env = Environment::host();
JitAllocator allocator;
#ifndef ASMJIT_NO_LOGGING
FileLogger logger(stdout);
- logger.setIndentation(FormatOptions::kIndentationCode, 2);
+ logger.setIndentation(FormatIndentationGroup::kCode, 2);
#endif
CodeHolder code;
@@ -74,7 +56,7 @@ int main() {
#endif
Section* dataSection;
- Error err = code.newSection(&dataSection, ".data", SIZE_MAX, 0, 8);
+ Error err = code.newSection(&dataSection, ".data", SIZE_MAX, SectionFlags::kNone, 8);
if (err) {
fail("Failed to create a .data section", err);
@@ -88,7 +70,7 @@ int main() {
Label data = a.newLabel();
FuncDetail func;
- func.init(FuncSignatureT<size_t, size_t>(CallConv::kIdHost), code.environment());
+ func.init(FuncSignatureT<size_t, size_t>(CallConvId::kHost), code.environment());
FuncFrame frame;
frame.init(func);
@@ -145,14 +127,14 @@ int main() {
}
// Allocate memory for the function and relocate it there.
- void* roPtr;
+ void* rxPtr;
void* rwPtr;
- err = allocator.alloc(&roPtr, &rwPtr, codeSize);
+ err = allocator.alloc(&rxPtr, &rwPtr, codeSize);
if (err)
fail("Failed to allocate executable memory", err);
// Relocate to the base-address of the allocated memory.
- code.relocateToBase(uint64_t(uintptr_t(roPtr)));
+ code.relocateToBase(uint64_t(uintptr_t(rxPtr)));
// Copy the flattened code into `mem.rw`. There are two ways. You can either copy
// everything manually by iterating over all sections or use `copyFlattenedData`.
@@ -162,7 +144,7 @@ int main() {
// Execute the function and test whether it works.
typedef size_t (*Func)(size_t idx);
- Func fn = (Func)roPtr;
+ Func fn = (Func)rxPtr;
printf("\n");
if (fn(0) != dataArray[0] ||
diff --git a/test/asmjitutils.h b/test/asmjitutils.h
new file mode 100644
index 0000000..d84d3d4
--- /dev/null
+++ b/test/asmjitutils.h
@@ -0,0 +1,38 @@
+// This file is part of AsmJit project <https://asmjit.com>
+//
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
+
+#ifndef ASMJITUTILS_H_INCLUDED
+#define ASMJITUTILS_H_INCLUDED
+
+#include <asmjit/core.h>
+
+static const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
+ switch (arch) {
+ case asmjit::Arch::kX86 : return "X86";
+ case asmjit::Arch::kX64 : return "X64";
+
+ case asmjit::Arch::kRISCV32 : return "RISCV32";
+ case asmjit::Arch::kRISCV64 : return "RISCV64";
+
+ case asmjit::Arch::kARM : return "ARM";
+ case asmjit::Arch::kAArch64 : return "AArch64";
+ case asmjit::Arch::kThumb : return "Thumb";
+
+ case asmjit::Arch::kMIPS32_LE : return "MIPS_LE";
+ case asmjit::Arch::kMIPS64_LE : return "MIPS64_LE";
+
+ case asmjit::Arch::kARM_BE : return "ARM_BE";
+ case asmjit::Arch::kThumb_BE : return "Thumb_BE";
+ case asmjit::Arch::kAArch64_BE: return "AArch64_BE";
+
+ case asmjit::Arch::kMIPS32_BE : return "MIPS_BE";
+ case asmjit::Arch::kMIPS64_BE : return "MIPS64_BE";
+
+ default:
+ return "<Unknown>";
+ }
+}
+
+#endif // ASMJITUTILS_H_INCLUDED
diff --git a/test/cmdline.h b/test/cmdline.h
index effedd1..4da0d2e 100644
--- a/test/cmdline.h
+++ b/test/cmdline.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef CMDLINE_H_INCLUDED
#define CMDLINE_H_INCLUDED
@@ -28,10 +10,6 @@
#include <stdlib.h>
#include <string.h>
-// ============================================================================
-// [CmdLine]
-// ============================================================================
-
class CmdLine {
public:
int _argc;
diff --git a/test/performancetimer.h b/test/performancetimer.h
index ebbaca3..baa0479 100644
--- a/test/performancetimer.h
+++ b/test/performancetimer.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef PERFORMANCETIMER_H_INCLUDED
#define PERFORMANCETIMER_H_INCLUDED
diff --git a/tools/configure-makefiles.sh b/tools/configure-makefiles.sh
index 00d2f2f..69503dc 100755
--- a/tools/configure-makefiles.sh
+++ b/tools/configure-makefiles.sh
@@ -5,11 +5,9 @@ BUILD_DIR="${CURRENT_DIR}/../build"
BUILD_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DASMJIT_TEST=1"
echo "== [Configuring Build - Debug] =="
-mkdir -p "${BUILD_DIR}/Debug"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Debug" -DCMAKE_BUILD_TYPE=Debug ${BUILD_OPTIONS}
echo ""
echo "== [Configuring Build - Release] =="
-mkdir -p "${BUILD_DIR}/Release"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release" -DCMAKE_BUILD_TYPE=Release ${BUILD_OPTIONS}
echo ""
diff --git a/tools/configure-ninja.sh b/tools/configure-ninja.sh
index f7db4d8..84808d2 100755
--- a/tools/configure-ninja.sh
+++ b/tools/configure-ninja.sh
@@ -5,11 +5,9 @@ BUILD_DIR="${CURRENT_DIR}/../build"
BUILD_OPTIONS="-G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DASMJIT_TEST=1"
echo "== [Configuring Build - Debug] =="
-mkdir -p "${BUILD_DIR}/Debug"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Debug" -DCMAKE_BUILD_TYPE=Debug ${BUILD_OPTIONS}
echo ""
echo "== [Configuring Build - Release] =="
-mkdir -p "${BUILD_DIR}/Release"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release" -DCMAKE_BUILD_TYPE=Release ${BUILD_OPTIONS}
echo ""
diff --git a/tools/configure-sanitizers.sh b/tools/configure-sanitizers.sh
index d7cc48a..a9f6496 100755
--- a/tools/configure-sanitizers.sh
+++ b/tools/configure-sanitizers.sh
@@ -2,14 +2,12 @@
CURRENT_DIR="`pwd`"
BUILD_DIR="${CURRENT_DIR}/../build"
-BUILD_OPTIONS="-G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DASMJIT_TEST=1"
+BUILD_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DASMJIT_TEST=1"
echo "== [Configuring Build - Release_ASAN] =="
-mkdir -p "${BUILD_DIR}/Release_ASAN"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release_ASAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DASMJIT_SANITIZE=address
echo ""
echo "== [Configuring Build - Release_UBSAN] =="
-mkdir -p "${BUILD_DIR}/Release_UBSAN"
eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release_UBSAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DASMJIT_SANITIZE=undefined
echo ""
diff --git a/tools/configure-vs-x64.bat b/tools/configure-vs-x64.bat
deleted file mode 100644
index db4012a..0000000
--- a/tools/configure-vs-x64.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-
-set CURRENT_DIR=%CD%
-set BUILD_DIR="build_vs_x64"
-
-mkdir ..\%BUILD_DIR%
-cd ..\%BUILD_DIR%
-cmake .. -G"Visual Studio 16" -A x64 -DASMJIT_TEST=1
-cd %CURRENT_DIR%
diff --git a/tools/configure-vs-x86.bat b/tools/configure-vs-x86.bat
deleted file mode 100644
index 7bc7b9d..0000000
--- a/tools/configure-vs-x86.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-
-set CURRENT_DIR=%CD%
-set BUILD_DIR="build_vs_x86"
-
-mkdir ..\%BUILD_DIR%
-cd ..\%BUILD_DIR%
-cmake .. -G"Visual Studio 16" -A Win32 -DASMJIT_TEST=1
-cd %CURRENT_DIR%
diff --git a/tools/configure-vs2019-x64.bat b/tools/configure-vs2019-x64.bat
new file mode 100644
index 0000000..05bc31e
--- /dev/null
+++ b/tools/configure-vs2019-x64.bat
@@ -0,0 +1,2 @@
+@echo off
+cmake .. -B "..\build_vs2019_x64" -G"Visual Studio 16" -A x64 -DASMJIT_TEST=1
diff --git a/tools/configure-vs2019-x86.bat b/tools/configure-vs2019-x86.bat
new file mode 100644
index 0000000..a0e2663
--- /dev/null
+++ b/tools/configure-vs2019-x86.bat
@@ -0,0 +1,2 @@
+@echo off
+cmake .. -B "..\build_vs2019_x86" -G"Visual Studio 16" -A Win32 -DASMJIT_TEST=1
diff --git a/tools/configure-vs2022-x64.bat b/tools/configure-vs2022-x64.bat
new file mode 100644
index 0000000..b33f541
--- /dev/null
+++ b/tools/configure-vs2022-x64.bat
@@ -0,0 +1,2 @@
+@echo off
+cmake .. -B "..\build_vs2022_x64" -G"Visual Studio 17" -A x64 -DASMJIT_TEST=1
diff --git a/tools/configure-vs2022-x86.bat b/tools/configure-vs2022-x86.bat
new file mode 100644
index 0000000..0ba3505
--- /dev/null
+++ b/tools/configure-vs2022-x86.bat
@@ -0,0 +1,2 @@
+@echo off
+cmake .. -B "..\build_vs2022_x86" -G"Visual Studio 17" -A Win32 -DASMJIT_TEST=1
diff --git a/tools/tablegen-x86.js b/tools/tablegen-x86.js
index 2ddaa3a..6b2110b 100644
--- a/tools/tablegen-x86.js
+++ b/tools/tablegen-x86.js
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
// ============================================================================
// tablegen-x86.js
@@ -161,7 +143,11 @@ const VexToEvexMap = {
"vpand": "vpandd",
"vpandn": "vpandnd",
"vpor": "vpord",
- "vpxor": "vpxord"
+ "vpxor": "vpxord",
+ "vroundpd": "vrndscalepd",
+ "vroundps": "vrndscaleps",
+ "vroundsd": "vrndscalesd",
+ "vroundss": "vrndscaless"
};
class GenUtils {
@@ -242,7 +228,8 @@ class GenUtils {
var i, j;
var mib = dbInsts.length > 0 && /^(?:bndldx|bndstx)$/.test(dbInsts[0].name);
- if (mib) f.Mib = true;
+ if (mib)
+ f.Mib = true;
var mmx = false;
var vec = false;
@@ -274,13 +261,14 @@ class GenUtils {
const dbInst = dbInsts[i];
const operands = dbInst.operands;
- if (dbInst.attributes.Lock ) f.Lock = true;
- if (dbInst.attributes.XAcquire ) f.XAcquire = true;
- if (dbInst.attributes.XRelease ) f.XRelease = true;
- if (dbInst.attributes.BND ) f.Rep = true;
- if (dbInst.attributes.REP ) f.Rep = true;
- if (dbInst.attributes.REPNE ) f.Rep = true;
- if (dbInst.attributes.RepIgnored) f.RepIgnored = true;
+ if (dbInst.attributes.Lock ) f.Lock = true;
+ if (dbInst.attributes.XAcquire ) f.XAcquire = true;
+ if (dbInst.attributes.XRelease ) f.XRelease = true;
+ if (dbInst.attributes.BND ) f.Rep = true;
+ if (dbInst.attributes.REP ) f.Rep = true;
+ if (dbInst.attributes.REPNE ) f.Rep = true;
+ if (dbInst.attributes.RepIgnored ) f.RepIgnored = true;
+ if (dbInst.attributes.ImplicitZeroing) f.Avx512ImplicitZ = true;
if (dbInst.fpu) {
for (var j = 0; j < operands.length; j++) {
@@ -325,7 +313,9 @@ class GenUtils {
GenUtils.assignVexEvexCompatibilityFlags(f, dbInsts)
}
- return Object.getOwnPropertyNames(f);
+ const result = Object.getOwnPropertyNames(f);
+ result.sort();
+ return result;
}
static eqOps(aOps, aFrom, bOps, bFrom) {
@@ -457,12 +447,12 @@ class GenUtils {
}
}
- static controlType(dbInsts) {
+ static controlFlow(dbInsts) {
if (dbInsts.checkAttribute("Control", "Jump")) return "Jump";
if (dbInsts.checkAttribute("Control", "Call")) return "Call";
if (dbInsts.checkAttribute("Control", "Branch")) return "Branch";
if (dbInsts.checkAttribute("Control", "Return")) return "Return";
- return "None";
+ return "Regular";
}
}
@@ -473,6 +463,8 @@ class GenUtils {
class X86TableGen extends core.TableGen {
constructor() {
super("X86");
+
+ this.emitMissingString = "";
}
// --------------------------------------------------------------------------
@@ -526,31 +518,31 @@ class X86TableGen extends core.TableGen {
FAIL(`Instruction '${name}' not found in asmdb`);
const flags = GenUtils.flagsOf(dbInsts);
- const controlType = GenUtils.controlType(dbInsts);
+ const controlFlow = GenUtils.controlFlow(dbInsts);
const singleRegCase = GenUtils.singleRegCase(name);
this.addInst({
- id : 0, // Instruction id (numeric value).
- name : name, // Instruction name.
- enum : enum_, // Instruction enum without `kId` prefix.
- dbInsts : dbInsts, // All dbInsts returned from asmdb query.
- encoding : encoding, // Instruction encoding.
- opcode0 : opcode0, // Primary opcode.
- opcode1 : opcode1, // Secondary opcode.
- flags : flags,
- signatures : null, // Instruction signatures.
- controlType : controlType,
- singleRegCase : singleRegCase,
-
- mainOpcodeValue : -1, // Main opcode value (0.255 hex).
- mainOpcodeIndex : -1, // Index to InstDB::_mainOpcodeTable.
- altOpcodeIndex : -1, // Index to InstDB::_altOpcodeTable.
- nameIndex : -1, // Index to InstDB::_nameData.
- commonInfoIndexA : -1,
- commomInfoIndexB : -1,
-
- signatureIndex : -1,
- signatureCount : -1
+ id : 0, // Instruction id (numeric value).
+ name : name, // Instruction name.
+ enum : enum_, // Instruction enum without `kId` prefix.
+ dbInsts : dbInsts, // All dbInsts returned from asmdb query.
+ encoding : encoding, // Instruction encoding.
+ opcode0 : opcode0, // Primary opcode.
+ opcode1 : opcode1, // Secondary opcode.
+ flags : flags,
+ signatures : null, // Instruction signatures.
+ controlFlow : controlFlow,
+ singleRegCase : singleRegCase,
+
+ mainOpcodeValue : -1, // Main opcode value (0.255 hex).
+ mainOpcodeIndex : -1, // Index to InstDB::_mainOpcodeTable.
+ altOpcodeIndex : -1, // Index to InstDB::_altOpcodeTable.
+ nameIndex : -1, // Index to InstDB::_nameData.
+ commonInfoIndex : -1,
+ additionalInfoIndex: -1,
+
+ signatureIndex : -1,
+ signatureCount : -1
});
}
@@ -563,15 +555,15 @@ class X86TableGen extends core.TableGen {
merge() {
var s = StringUtils.format(this.insts, "", true, function(inst) {
return "INST(" +
- String(inst.enum ).padEnd(17) + ", " +
- String(inst.encoding ).padEnd(19) + ", " +
- String(inst.opcode0 ).padEnd(26) + ", " +
- String(inst.opcode1 ).padEnd(26) + ", " +
- String(inst.mainOpcodeIndex ).padEnd( 3) + ", " +
- String(inst.altOpcodeIndex ).padEnd( 3) + ", " +
- String(inst.nameIndex ).padEnd( 5) + ", " +
- String(inst.commonInfoIndexA).padEnd( 3) + ", " +
- String(inst.commomInfoIndexB).padEnd( 3) + ")";
+ String(inst.enum ).padEnd(17) + ", " +
+ String(inst.encoding ).padEnd(19) + ", " +
+ String(inst.opcode0 ).padEnd(26) + ", " +
+ String(inst.opcode1 ).padEnd(26) + ", " +
+ String(inst.mainOpcodeIndex ).padEnd( 3) + ", " +
+ String(inst.altOpcodeIndex ).padEnd( 3) + ", " +
+ String(inst.nameIndex ).padEnd( 5) + ", " +
+ String(inst.commonInfoIndex ).padEnd( 3) + ", " +
+ String(inst.additionalInfoIndex).padEnd( 3) + ")";
}) + "\n";
this.inject("InstInfo", s, this.insts.length * 8);
}
@@ -613,6 +605,7 @@ class X86TableGen extends core.TableGen {
}
}, this);
console.log(out);
+ console.log(this.emitMissingString);
}
newInstFromGroup(dbInsts) {
@@ -637,24 +630,83 @@ class X86TableGen extends core.TableGen {
return s === "VEX" || s === "EVEX" || s === "XOP";
}
+ function formatEmit(dbi) {
+ const results = [];
+ const nameUp = dbi.name[0].toUpperCase() + dbi.name.substr(1);
+
+ for (let choice = 0; choice < 2; choice++) {
+ let s = `ASMJIT_INST_${dbi.operands.length}x(${dbi.name}, ${nameUp}`;
+ for (let j = 0; j < dbi.operands.length; j++) {
+ s += ", ";
+ const op = dbi.operands[j];
+ var reg = op.reg;
+ var mem = op.mem;
+
+ if (op.isReg() && op.isMem()) {
+ if (choice == 0) mem = null;
+ if (choice == 1) reg = null;
+ }
+
+ if (reg) {
+ if (reg === "xmm" || reg === "ymm" || reg === "zmm")
+ s += "Vec";
+ else if (reg === "k")
+ s += "KReg";
+ else if (reg === "r32" || reg === "r64" || reg === "r16" || reg === "r8")
+ s += "Gp";
+ else
+ s += reg;
+ }
+ else if (mem) {
+ s += "Mem";
+ }
+ else if (op.isImm()) {
+ s += "Imm";
+ }
+ else {
+ s += "Unknown";
+ }
+ }
+ s += `)`;
+ results.push(s);
+ }
+
+ return results;
+ }
+
var dbi = dbInsts[0];
- var id = this.insts.length;
- var name = dbi.name;
- var enum_ = name[0].toUpperCase() + name.substr(1);
+ var id = this.insts.length;
+ var name = dbi.name;
+ var enum_ = name[0].toUpperCase() + name.substr(1);
- var opcode = dbi.opcodeHex;
- var modR = dbi.modR;
- var mm = dbi.mm;
- var pp = dbi.pp;
+ var opcode = dbi.opcodeHex;
+ var modR = dbi.modR;
+ var mm = dbi.mm;
+ var pp = dbi.pp;
var encoding = dbi.encoding;
- var isVec = isVecPrefix(dbi.prefix);
-
- var access = GetAccess(dbi);
+ var isVec = isVecPrefix(dbi.prefix);
+ var evexCount = 0;
+
+ var access = GetAccess(dbi);
+
+ var vexL = undefined;
+ var vexW = undefined;
+ var evexW = undefined;
+ var cdshl = "_";
+ var tupleType = "_";
+
+ const tupleTypeToCDSHL = {
+ "FVM": "4",
+ "FV": "4",
+ "HVM": "3",
+ "HV": "3",
+ "QVM": "2",
+ "QV": "2",
+ "T1S": "?"
+ }
- var vexL = undefined;
- var vexW = undefined;
- var evexW = undefined;
+ const emitMap = {};
for (var i = 0; i < dbInsts.length; i++) {
dbi = dbInsts[i];
@@ -674,47 +726,66 @@ class X86TableGen extends core.TableGen {
}
if (dbi.prefix === "EVEX") {
+ evexCount++;
var newEvexW = String(dbi.w === "W0" ? 0 : dbi.w === "W1" ? 1 : "_");
if (evexW !== undefined && evexW !== newEvexW)
evexW = "x";
else
evexW = newEvexW;
+
+ if (dbi.tupleType) {
+ if (tupleType !== "_" && tupleType !== dbi.tupleType) {
+ console.log(`${dbi.name}: WARNING: TupleType ${tupleType} != ${dbi.tupleType}`);
+ }
+
+ tupleType = dbi.tupleType;
+ }
}
- if (opcode !== dbi.opcodeHex ) { console.log(`ISSUE: Opcode ${opcode} != ${dbi.opcodeHex}`); return null; }
- if (modR !== dbi.modR ) { console.log(`ISSUE: ModR ${modR} != ${dbi.modR}`); return null; }
- if (mm !== dbi.mm ) { console.log(`ISSUE: MM ${mm} != ${dbi.mm}`); return null; }
- if (pp !== dbi.pp ) { console.log(`ISSUE: PP ${pp} != ${dbi.pp}`); return null; }
- if (encoding !== dbi.encoding ) { console.log(`ISSUE: Enc ${encoding} != ${dbi.encoding}`); return null; }
- if (access !== GetAccess(dbi)) { console.log(`ISSUE: Access ${access} != ${GetAccess(dbi)}`); return null; }
- if (isVec != isVecPrefix(dbi.prefix)) { console.log(`ISSUE: Vex/Non-Vex mismatch`); return null; }
+ if (opcode !== dbi.opcodeHex ) { console.log(`${dbi.name}: ISSUE: Opcode ${opcode} != ${dbi.opcodeHex}`); return null; }
+ if (modR !== dbi.modR ) { console.log(`${dbi.name}: ISSUE: ModR ${modR} != ${dbi.modR}`); return null; }
+ if (mm !== dbi.mm ) { console.log(`${dbi.name}: ISSUE: MM ${mm} != ${dbi.mm}`); return null; }
+ if (pp !== dbi.pp ) { console.log(`${dbi.name}: ISSUE: PP ${pp} != ${dbi.pp}`); return null; }
+ if (encoding !== dbi.encoding ) { console.log(`${dbi.name}: ISSUE: Enc ${encoding} != ${dbi.encoding}`); return null; }
+ if (access !== GetAccess(dbi)) { console.log(`${dbi.name}: ISSUE: Access ${access} != ${GetAccess(dbi)}`); return null; }
+ if (isVec != isVecPrefix(dbi.prefix)) { console.log(`${dbi.name}: ISSUE: Vex/Non-Vex mismatch`); return null; }
+
+ formatEmit(dbi).forEach((emit) => {
+ if (!emitMap[emit]) {
+ emitMap[emit] = true;
+ this.emitMissingString += emit + "\n";
+ }
+ });
}
+ if (tupleType !== "_")
+ cdshl = tupleTypeToCDSHL[tupleType] || "?";
+
var ppmm = pp.padEnd(2).replace(/ /g, "0") +
mm.padEnd(4).replace(/ /g, "0") ;
var composed = composeOpCode({
- type : isVec ? "V" : "O",
+ type : evexCount == dbInsts.length ? "E" : isVec ? "V" : "O",
prefix: ppmm,
opcode: opcode,
o : modR === "r" ? "_" : (modR ? modR : "_"),
l : vexL !== undefined ? vexL : "_",
w : vexW !== undefined ? vexW : "_",
ew : evexW !== undefined ? evexW : "_",
- en : "_",
- tt : dbi.modRM ? dbi.modRM + " " : "_ "
+ en : cdshl,
+ tt : dbi.modRM ? dbi.modRM + " " : tupleType.padEnd(3)
});
return {
- id : id,
- name : name,
- enum : enum_,
- encoding : encoding,
- opcode0 : composed,
- opcode1 : "0",
- nameIndex : -1,
- commonInfoIndexA : -1,
- commomInfoIndexB : -1
+ id : id,
+ name : name,
+ enum : enum_,
+ encoding : encoding,
+ opcode0 : composed,
+ opcode1 : "0",
+ nameIndex : -1,
+ commonInfoIndex : -1,
+ additionalInfoIndex: -1
};
}
@@ -823,39 +894,103 @@ class AltOpcodeTable extends core.Task {
const mainOpcodeTable = new IndexedArray();
const altOpcodeTable = new IndexedArray();
- mainOpcodeTable.addIndexed("O(000000,00,0,0,0,0,0,_ )");
+ const cdttSimplification = {
+ "0" : "None",
+ "_" : "None",
+ "FV" : "ByLL",
+ "HV" : "ByLL",
+ "QV" : "ByLL",
+ "FVM" : "ByLL",
+ "T1S" : "None",
+ "T1F" : "None",
+ "T1_4X": "None",
+ "T2" : "None",
+ "T4" : "None",
+ "T8" : "None",
+ "HVM" : "ByLL",
+ "QVM" : "ByLL",
+ "OVM" : "ByLL",
+ "128" : "None",
+ "T4X" : "None"
+ }
- function indexOpcode(opcode) {
- if (opcode === "0")
- return ["00", 0];
+ const noOp = "O(000000,00,0,0,0,0,0,0 )";
- // O_FPU(__,__OP,_)
- if (opcode.startsWith("O_FPU(")) {
- var value = opcode.substring(11, 13);
- var remaining = opcode.substring(0, 11) + "00" + opcode.substring(13);
+ mainOpcodeTable.addIndexed(noOp);
- return [value, mainOpcodeTable.addIndexed(remaining.padEnd(26))];
+ function splitOpcodeToComponents(opcode) {
+ const i = opcode.indexOf("(");
+ const prefix = opcode.substr(0, i);
+ return [prefix].concat(opcode.substring(i + 1, opcode.length - 1).split(","));
+ }
+
+ function normalizeOpcodeComponents(components) {
+ for (let i = 1; i < components.length; i++) {
+ components[i] = components[i].trim();
+ // These all are zeros that only have some contextual meaning in the table, but the assembler doesn't care.
+ if (components[i] === "_" || components[i] === "I" || components[i] === "x")
+ components[i] = "0";
+ }
+
+ // Simplify CDTT (compressed displacement TupleType).
+ if (components.length >= 9) {
+ if (components[0] === "V" || components[0] === "E") {
+ const cdtt = components[8];
+ if (cdttSimplification[cdtt] !== undefined)
+ components[8] = cdttSimplification[cdtt];
+ }
}
+ return components;
+ }
+
+ function joinOpcodeComponents(components) {
+ const prefix = components[0];
+ const values = components.slice(1);
+ if (values.length >= 8)
+ values[7] = values[7].padEnd(4);
+ return prefix + "(" + values.join(",") + ")";
+ }
+
+ function indexMainOpcode(opcode) {
+ if (opcode === "0")
+ return ["00", 0];
- // X(______,OP,_,_,_,_,_,_ )
- if (opcode.startsWith("O(") || opcode.startsWith("V(") || opcode.startsWith("E(")) {
- var value = opcode.substring(9, 11);
- var remaining = opcode.substring(0, 9) + "00" + opcode.substring(11);
+ var opcodeByte = "";
+ const components = normalizeOpcodeComponents(splitOpcodeToComponents(opcode));
- remaining = remaining.replace(/,[_xI],/g, ",0,");
- remaining = remaining.replace(/,[_xI],/g, ",0,");
- return [value, mainOpcodeTable.addIndexed(remaining.padEnd(26))];
+ if (components[0] === "O_FPU") {
+ // Reset opcode byte, this is stored in the instruction data itself.
+ opcodeByte = components[2].substr(2, 2);
+ components[2] = components[2].substr(0, 2) + "00";
+ }
+ else if (components[0] === "O" || components[0] === "V" || components[0] === "E") {
+ // Reset opcode byte, this is stored in the instruction data itself.
+ opcodeByte = components[2];
+ components[2] = "00";
+ }
+ else {
+ FAIL(`Failed to process opcode '${opcode}'`);
}
- FAIL(`Failed to process opcode '${opcode}'`);
+ const newOpcode = joinOpcodeComponents(components);
+ return [opcodeByte, mainOpcodeTable.addIndexed(newOpcode.padEnd(27))];
+ }
+
+ function indexAltOpcode(opcode) {
+ if (opcode === "0")
+ opcode = noOp;
+ else
+ opcode = joinOpcodeComponents(normalizeOpcodeComponents(splitOpcodeToComponents(opcode)));
+ return altOpcodeTable.addIndexed(opcode.padEnd(27));
}
insts.map((inst) => {
- const [value, index] = indexOpcode(inst.opcode0);
+ const [value, index] = indexMainOpcode(inst.opcode0);
inst.mainOpcodeValue = value;
inst.mainOpcodeIndex = index;
- inst.altOpcodeIndex = altOpcodeTable.addIndexed(inst.opcode1.padEnd(26));
+ inst.altOpcodeIndex = indexAltOpcode(inst.opcode1);
});
+
// console.log(mainOpcodeTable.length);
// console.log(StringUtils.format(mainOpcodeTable, kIndent, true));
@@ -877,84 +1012,32 @@ const RegOp = MapUtils.arrayToMap(["al", "ah", "ax", "eax", "rax", "cl", "r8lo",
const MemOp = MapUtils.arrayToMap(["m8", "m16", "m32", "m48", "m64", "m80", "m128", "m256", "m512", "m1024"]);
const cmpOp = StringUtils.makePriorityCompare([
- "r8lo", "r8hi", "r16", "r32", "r64", "xmm", "ymm", "zmm", "mm", "k", "sreg", "creg", "dreg", "st", "bnd",
- "mem", "vm", "m8", "m16", "m32", "m48", "m64", "m80", "m128", "m256", "m512", "m1024",
- "mib",
- "vm32x", "vm32y", "vm32z", "vm64x", "vm64y", "vm64z",
- "memBase", "memES", "memDS",
- "i4", "u4", "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64",
- "rel8", "rel32",
- "implicit"
+ "RegGpbLo", "RegGpbHi", "RegGpw", "RegGpd", "RegGpq", "RegXmm", "RegYmm", "RegZmm", "RegMm", "RegKReg", "RegSReg", "RegCReg", "RegDReg", "RegSt", "RegBnd", "RegTmm",
+ "MemUnspecified", "Mem8", "Mem16", "Mem32", "Mem48", "Mem64", "Mem80", "Mem128", "Mem256", "Mem512", "Mem1024",
+ "Vm32x", "Vm32y", "Vm32z", "Vm64x", "Vm64y", "Vm64z",
+ "ImmI4", "ImmU4", "ImmI8", "ImmU8", "ImmI16", "ImmU16", "ImmI32", "ImmU32", "ImmI64", "ImmU64",
+ "Rel8", "Rel32",
+ "FlagMemBase",
+ "FlagMemDs",
+ "FlagMemEs",
+ "FlagMib",
+ "FlagTMem",
+ "FlagConsecutive",
+ "FlagImplicit"
]);
-const OpToAsmJitOp = {
- "implicit": "F(Implicit)",
-
- "r8lo" : "F(GpbLo)",
- "r8hi" : "F(GpbHi)",
- "r16" : "F(Gpw)",
- "r32" : "F(Gpd)",
- "r64" : "F(Gpq)",
- "xmm" : "F(Xmm)",
- "ymm" : "F(Ymm)",
- "zmm" : "F(Zmm)",
- "mm" : "F(Mm)",
- "k" : "F(KReg)",
- "sreg" : "F(SReg)",
- "creg" : "F(CReg)",
- "dreg" : "F(DReg)",
- "st" : "F(St)",
- "bnd" : "F(Bnd)",
- "tmm" : "F(Tmm)",
-
- "mem" : "F(Mem)",
- "vm" : "F(Vm)",
-
- "i4" : "F(I4)",
- "u4" : "F(U4)",
- "i8" : "F(I8)",
- "u8" : "F(U8)",
- "i16" : "F(I16)",
- "u16" : "F(U16)",
- "i32" : "F(I32)",
- "u32" : "F(U32)",
- "i64" : "F(I64)",
- "u64" : "F(U64)",
-
- "rel8" : "F(Rel8)",
- "rel32" : "F(Rel32)",
-
- "m8" : "M(M8)",
- "m16" : "M(M16)",
- "m32" : "M(M32)",
- "m48" : "M(M48)",
- "m64" : "M(M64)",
- "m80" : "M(M80)",
- "m128" : "M(M128)",
- "m256" : "M(M256)",
- "m512" : "M(M512)",
- "m1024" : "M(M1024)",
- "mib" : "M(Mib)",
- "mAny" : "M(Any)",
- "vm32x" : "M(Vm32x)",
- "vm32y" : "M(Vm32y)",
- "vm32z" : "M(Vm32z)",
- "vm64x" : "M(Vm64x)",
- "vm64y" : "M(Vm64y)",
- "vm64z" : "M(Vm64z)",
-
- "memBase" : "M(BaseOnly)",
- "memDS" : "M(Ds)",
- "memES" : "M(Es)"
-};
-
-function StringifyArray(a, map) {
+function StringifyOpArray(a, map) {
var s = "";
for (var i = 0; i < a.length; i++) {
const op = a[i];
- if (!hasOwn.call(map, op))
+ var mapped = null;
+ if (typeof map === "function")
+ mapped = map(op);
+ else if (hasOwn.call(map, op))
+ mapped = map[op];
+ else
FAIL(`UNHANDLED OPERAND '${op}'`);
- s += (s ? " | " : "") + map[op];
+ s += (s ? " | " : "") + mapped;
}
return s ? s : "0";
}
@@ -1034,134 +1117,117 @@ class OSignature {
}
toAsmJitOpData() {
- var oFlags = this.flags;
+ var opFlags = Object.create(null);
+ var regMask = 0;
- var mFlags = Object.create(null);
- var mMemFlags = Object.create(null);
- var mExtFlags = Object.create(null);
- var sRegMask = 0;
-
- for (var k in oFlags) {
+ for (var k in this.flags) {
switch (k) {
- case "implicit":
- case "r8lo" :
- case "r8hi" :
- case "r16" :
- case "r32" :
- case "r64" :
- case "creg" :
- case "dreg" :
- case "sreg" :
- case "bnd" :
- case "st" :
- case "k" :
- case "mm" :
- case "xmm" :
- case "ymm" :
- case "zmm" :
- case "tmm" : mFlags[k] = true; break;
-
- case "m8" :
- case "m16" :
- case "m32" :
- case "m48" :
- case "m64" :
- case "m80" :
- case "m128" :
- case "m256" :
- case "m512" :
- case "m1024" : mFlags.mem = true; mMemFlags[k] = true; break;
- case "mib" : mFlags.mem = true; mMemFlags.mib = true; break;
- case "mem" : mFlags.mem = true; mMemFlags.mAny = true; break;
- case "tmem" : mFlags.mem = true; mMemFlags.mAny = true; break;
-
- case "memBase" : mFlags.mem = true; mMemFlags.memBase = true; break;
- case "memDS" : mFlags.mem = true; mMemFlags.memDS = true; break;
- case "memES" : mFlags.mem = true; mMemFlags.memES = true; break;
- case "memZAX" : mFlags.mem = true; sRegMask |= 1 << 0; break;
- case "memZSI" : mFlags.mem = true; sRegMask |= 1 << 6; break;
- case "memZDI" : mFlags.mem = true; sRegMask |= 1 << 7; break;
-
- case "vm32x" : mFlags.vm = true; mMemFlags.vm32x = true; break;
- case "vm32y" : mFlags.vm = true; mMemFlags.vm32y = true; break;
- case "vm32z" : mFlags.vm = true; mMemFlags.vm32z = true; break;
- case "vm64x" : mFlags.vm = true; mMemFlags.vm64x = true; break;
- case "vm64y" : mFlags.vm = true; mMemFlags.vm64y = true; break;
- case "vm64z" : mFlags.vm = true; mMemFlags.vm64z = true; break;
-
- case "i4" :
- case "u4" :
- case "i8" :
- case "u8" :
- case "i16" :
- case "u16" :
- case "i32" :
- case "u32" :
- case "i64" :
- case "u64" : mFlags[k] = true; break;
-
- case "rel8" :
- case "rel32" :
- mFlags.i32 = true;
- mFlags.i64 = true;
- mFlags[k] = true;
- break;
-
- case "rel16" :
- mFlags.i32 = true;
- mFlags.i64 = true;
- mFlags.rel32 = true;
- break;
-
- default: {
- switch (k) {
- case "es" : mFlags.sreg = true; sRegMask |= 1 << 1; break;
- case "cs" : mFlags.sreg = true; sRegMask |= 1 << 2; break;
- case "ss" : mFlags.sreg = true; sRegMask |= 1 << 3; break;
- case "ds" : mFlags.sreg = true; sRegMask |= 1 << 4; break;
- case "fs" : mFlags.sreg = true; sRegMask |= 1 << 5; break;
- case "gs" : mFlags.sreg = true; sRegMask |= 1 << 6; break;
- case "al" : mFlags.r8lo = true; sRegMask |= 1 << 0; break;
- case "ah" : mFlags.r8hi = true; sRegMask |= 1 << 0; break;
- case "ax" : mFlags.r16 = true; sRegMask |= 1 << 0; break;
- case "eax" : mFlags.r32 = true; sRegMask |= 1 << 0; break;
- case "rax" : mFlags.r64 = true; sRegMask |= 1 << 0; break;
- case "cl" : mFlags.r8lo = true; sRegMask |= 1 << 1; break;
- case "ch" : mFlags.r8hi = true; sRegMask |= 1 << 1; break;
- case "cx" : mFlags.r16 = true; sRegMask |= 1 << 1; break;
- case "ecx" : mFlags.r32 = true; sRegMask |= 1 << 1; break;
- case "rcx" : mFlags.r64 = true; sRegMask |= 1 << 1; break;
- case "dl" : mFlags.r8lo = true; sRegMask |= 1 << 2; break;
- case "dh" : mFlags.r8hi = true; sRegMask |= 1 << 2; break;
- case "dx" : mFlags.r16 = true; sRegMask |= 1 << 2; break;
- case "edx" : mFlags.r32 = true; sRegMask |= 1 << 2; break;
- case "rdx" : mFlags.r64 = true; sRegMask |= 1 << 2; break;
- case "bl" : mFlags.r8lo = true; sRegMask |= 1 << 3; break;
- case "bh" : mFlags.r8hi = true; sRegMask |= 1 << 3; break;
- case "bx" : mFlags.r16 = true; sRegMask |= 1 << 3; break;
- case "ebx" : mFlags.r32 = true; sRegMask |= 1 << 3; break;
- case "rbx" : mFlags.r64 = true; sRegMask |= 1 << 3; break;
- case "si" : mFlags.r16 = true; sRegMask |= 1 << 6; break;
- case "esi" : mFlags.r32 = true; sRegMask |= 1 << 6; break;
- case "rsi" : mFlags.r64 = true; sRegMask |= 1 << 6; break;
- case "di" : mFlags.r16 = true; sRegMask |= 1 << 7; break;
- case "edi" : mFlags.r32 = true; sRegMask |= 1 << 7; break;
- case "rdi" : mFlags.r64 = true; sRegMask |= 1 << 7; break;
- case "st0" : mFlags.st = true; sRegMask |= 1 << 0; break;
- case "xmm0" : mFlags.xmm = true; sRegMask |= 1 << 0; break;
- case "ymm0" : mFlags.ymm = true; sRegMask |= 1 << 0; break;
- default:
- console.log(`UNKNOWN OPERAND '${k}'`);
- }
- }
+ case "r8lo" : opFlags.RegGpbLo = true; break;
+ case "r8hi" : opFlags.RegGpbHi = true; break;
+ case "r16" : opFlags.RegGpw = true; break;
+ case "r32" : opFlags.RegGpd = true; break;
+ case "r64" : opFlags.RegGpq = true; break;
+ case "creg" : opFlags.RegCReg = true; break;
+ case "dreg" : opFlags.RegDReg = true; break;
+ case "sreg" : opFlags.RegSReg = true; break;
+ case "bnd" : opFlags.RegBnd = true; break;
+ case "st" : opFlags.RegSt = true; break;
+ case "k" : opFlags.RegKReg = true; break;
+ case "mm" : opFlags.RegMm = true; break;
+ case "xmm" : opFlags.RegXmm = true; break;
+ case "ymm" : opFlags.RegYmm = true; break;
+ case "zmm" : opFlags.RegZmm = true; break;
+ case "tmm" : opFlags.RegTmm = true; break;
+
+ case "m8" : opFlags.Mem8 = true; break;
+ case "m16" : opFlags.Mem16 = true; break;
+ case "m32" : opFlags.Mem32 = true; break;
+ case "m48" : opFlags.Mem48 = true; break;
+ case "m64" : opFlags.Mem64 = true; break;
+ case "m80" : opFlags.Mem80 = true; break;
+ case "m128" : opFlags.Mem128 = true; break;
+ case "m256" : opFlags.Mem256 = true; break;
+ case "m512" : opFlags.Mem512 = true; break;
+ case "m1024" : opFlags.Mem1024 = true; break;
+
+ case "mem" : opFlags.MemUnspecified = true; break;
+ case "mib" : opFlags.MemUnspecified = true; opFlags.FlagMib = true; break;
+ case "tmem" : opFlags.MemUnspecified = true; opFlags.FlagTMem = true; break;
+
+ case "memBase" : opFlags.FlagMemBase = true; break;
+ case "memDS" : opFlags.FlagMemDs = true; break;
+ case "memES" : opFlags.FlagMemEs = true; break;
+ case "memZAX" : regMask |= 1 << 0; break;
+ case "memZSI" : regMask |= 1 << 6; break;
+ case "memZDI" : regMask |= 1 << 7; break;
+
+ case "vm32x" : opFlags.Vm32x = true; break;
+ case "vm32y" : opFlags.Vm32y = true; break;
+ case "vm32z" : opFlags.Vm32z = true; break;
+ case "vm64x" : opFlags.Vm64x = true; break;
+ case "vm64y" : opFlags.Vm64y = true; break;
+ case "vm64z" : opFlags.Vm64z = true; break;
+
+ case "i4" : opFlags.ImmI4 = true; break;
+ case "u4" : opFlags.ImmU4 = true; break;
+ case "i8" : opFlags.ImmI8 = true; break;
+ case "u8" : opFlags.ImmU8 = true; break;
+ case "i16" : opFlags.ImmI16 = true; break;
+ case "u16" : opFlags.ImmU16 = true; break;
+ case "i32" : opFlags.ImmI32 = true; break;
+ case "u32" : opFlags.ImmU32 = true; break;
+ case "i64" : opFlags.ImmI64 = true; break;
+ case "u64" : opFlags.ImmU64 = true; break;
+
+ case "rel8" : opFlags.ImmI32 = true; opFlags.ImmI64 = true; opFlags.Rel8 = true; break;
+ case "rel16" : opFlags.ImmI32 = true; opFlags.ImmI64 = true; opFlags.Rel32 = true; break;
+ case "rel32" : opFlags.ImmI32 = true; opFlags.ImmI64 = true; opFlags.Rel32 = true; break;
+
+ case "es" : opFlags.RegSReg = true; regMask |= 1 << 1; break;
+ case "cs" : opFlags.RegSReg = true; regMask |= 1 << 2; break;
+ case "ss" : opFlags.RegSReg = true; regMask |= 1 << 3; break;
+ case "ds" : opFlags.RegSReg = true; regMask |= 1 << 4; break;
+ case "fs" : opFlags.RegSReg = true; regMask |= 1 << 5; break;
+ case "gs" : opFlags.RegSReg = true; regMask |= 1 << 6; break;
+ case "al" : opFlags.RegGpbLo = true; regMask |= 1 << 0; break;
+ case "ah" : opFlags.RegGpbHi = true; regMask |= 1 << 0; break;
+ case "ax" : opFlags.RegGpw = true; regMask |= 1 << 0; break;
+ case "eax" : opFlags.RegGpd = true; regMask |= 1 << 0; break;
+ case "rax" : opFlags.RegGpq = true; regMask |= 1 << 0; break;
+ case "cl" : opFlags.RegGpbLo = true; regMask |= 1 << 1; break;
+ case "ch" : opFlags.RegGpbHi = true; regMask |= 1 << 1; break;
+ case "cx" : opFlags.RegGpw = true; regMask |= 1 << 1; break;
+ case "ecx" : opFlags.RegGpd = true; regMask |= 1 << 1; break;
+ case "rcx" : opFlags.RegGpq = true; regMask |= 1 << 1; break;
+ case "dl" : opFlags.RegGpbLo = true; regMask |= 1 << 2; break;
+ case "dh" : opFlags.RegGpbHi = true; regMask |= 1 << 2; break;
+ case "dx" : opFlags.RegGpw = true; regMask |= 1 << 2; break;
+ case "edx" : opFlags.RegGpd = true; regMask |= 1 << 2; break;
+ case "rdx" : opFlags.RegGpq = true; regMask |= 1 << 2; break;
+ case "bl" : opFlags.RegGpbLo = true; regMask |= 1 << 3; break;
+ case "bh" : opFlags.RegGpbHi = true; regMask |= 1 << 3; break;
+ case "bx" : opFlags.RegGpw = true; regMask |= 1 << 3; break;
+ case "ebx" : opFlags.RegGpd = true; regMask |= 1 << 3; break;
+ case "rbx" : opFlags.RegGpq = true; regMask |= 1 << 3; break;
+ case "si" : opFlags.RegGpw = true; regMask |= 1 << 6; break;
+ case "esi" : opFlags.RegGpd = true; regMask |= 1 << 6; break;
+ case "rsi" : opFlags.RegGpq = true; regMask |= 1 << 6; break;
+ case "di" : opFlags.RegGpw = true; regMask |= 1 << 7; break;
+ case "edi" : opFlags.RegGpd = true; regMask |= 1 << 7; break;
+ case "rdi" : opFlags.RegGpq = true; regMask |= 1 << 7; break;
+ case "st0" : opFlags.RegSt = true; regMask |= 1 << 0; break;
+ case "xmm0" : opFlags.RegXmm = true; regMask |= 1 << 0; break;
+ case "ymm0" : opFlags.RegYmm = true; regMask |= 1 << 0; break;
+
+ case "implicit": opFlags.FlagImplicit = true; break;
+
+ default:
+ console.log(`UNKNOWN OPERAND '${k}'`);
}
}
- const sFlags = StringifyArray(ArrayUtils.sorted(mFlags , cmpOp), OpToAsmJitOp);
- const sMemFlags = StringifyArray(ArrayUtils.sorted(mMemFlags, cmpOp), OpToAsmJitOp);
- const sExtFlags = StringifyArray(ArrayUtils.sorted(mExtFlags, cmpOp), OpToAsmJitOp);
-
- return `ROW(${sFlags || 0}, ${sMemFlags || 0}, ${sExtFlags || 0}, ${decToHex(sRegMask, 2)})`;
+ const outputFlags = StringifyOpArray(ArrayUtils.sorted(opFlags, cmpOp), function(k) { return `F(${k})`; });
+ return `ROW(${outputFlags || 0}, ${decToHex(regMask, 2)})`;
}
}
@@ -1411,7 +1477,7 @@ class InstSignatureTable extends core.Task {
const oSignatureArr = [];
// Must be first to be assigned to zero.
- const oSignatureNone = "ROW(0, 0, 0, 0xFF)";
+ const oSignatureNone = "ROW(0, 0xFF)";
oSignatureMap[oSignatureNone] = [0];
oSignatureArr.push(oSignatureNone);
@@ -1508,21 +1574,19 @@ class InstSignatureTable extends core.Task {
});
}
- var s = `#define ROW(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \\\n` +
- ` { count, (x86 ? uint8_t(InstDB::kModeX86) : uint8_t(0)) | \\\n` +
- ` (x64 ? uint8_t(InstDB::kModeX64) : uint8_t(0)) , \\\n` +
- ` implicit, \\\n` +
- ` 0, \\\n` +
- ` { o0, o1, o2, o3, o4, o5 } \\\n` +
+ var s = `#define ROW(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \\\n` +
+ ` { count, uint8_t(x86 ? uint8_t(InstDB::Mode::kX86) : uint8_t(0)) | \\\n` +
+ ` (x64 ? uint8_t(InstDB::Mode::kX64) : uint8_t(0)) , \\\n` +
+ ` implicit, \\\n` +
+ ` 0, \\\n` +
+ ` { o0, o1, o2, o3, o4, o5 } \\\n` +
` }\n` +
StringUtils.makeCxxArrayWithComment(iSignatureArr, "const InstDB::InstSignature InstDB::_instSignatureTable[]") +
`#undef ROW\n` +
`\n` +
- `#define ROW(flags, mFlags, extFlags, regId) { uint32_t(flags), uint16_t(mFlags), uint8_t(extFlags), uint8_t(regId) }\n` +
- `#define F(VAL) InstDB::kOp##VAL\n` +
- `#define M(VAL) InstDB::kMemOp##VAL\n` +
+ `#define ROW(opFlags, regId) { opFlags, uint8_t(regId) }\n` +
+ `#define F(VAL) uint64_t(InstDB::OpFlags::k##VAL)\n` +
StringUtils.makeCxxArray(oSignatureArr, "const InstDB::OpSignature InstDB::_opSignatureTable[]") +
- `#undef M\n` +
`#undef F\n` +
`#undef ROW\n`;
this.inject("InstSignatureTable", disclaimer(s), oSignatureArr.length * 8 + iSignatureArr.length * 8);
@@ -1710,18 +1774,18 @@ class InstSignatureTable extends core.Task {
}
// ============================================================================
-// [tablegen.x86.InstCommonInfoTableB]
+// [tablegen.x86.AdditionalInfoTable]
// ============================================================================
-class InstCommonInfoTableB extends core.Task {
+class AdditionalInfoTable extends core.Task {
constructor() {
- super("InstCommonInfoTableB");
+ super("AdditionalInfoTable");
}
run() {
const insts = this.ctx.insts;
- const commonTableB = new IndexedArray();
const rwInfoTable = new IndexedArray();
+ const additionaInfoTable = new IndexedArray();
// If the instruction doesn't read any flags it should point to the first index.
rwInfoTable.addIndexed(`{ 0, 0 }`);
@@ -1737,17 +1801,17 @@ class InstCommonInfoTableB extends core.Task {
const wData = w.map(function(flag) { return `FLAG(${flag})`; }).join(" | ") || "0";
const rwDataIndex = rwInfoTable.addIndexed(`{ ${rData}, ${wData} }`);
- inst.commomInfoIndexB = commonTableB.addIndexed(`{ { ${features} }, ${rwDataIndex}, 0 }`);
+ inst.additionalInfoIndex = additionaInfoTable.addIndexed(`{ { ${features} }, ${rwDataIndex}, 0 }`);
});
- var s = `#define EXT(VAL) uint32_t(Features::k##VAL)\n` +
- `const InstDB::CommonInfoTableB InstDB::_commonInfoTableB[] = {\n${StringUtils.format(commonTableB, kIndent, true)}\n};\n` +
+ var s = `#define EXT(VAL) uint32_t(CpuFeatures::X86::k##VAL)\n` +
+ `const InstDB::AdditionalInfo InstDB::_additionalInfoTable[] = {\n${StringUtils.format(additionaInfoTable, kIndent, true)}\n};\n` +
`#undef EXT\n` +
`\n` +
- `#define FLAG(VAL) uint32_t(Status::k##VAL)\n` +
+ `#define FLAG(VAL) uint32_t(CpuRWFlags::kX86_##VAL)\n` +
`const InstDB::RWFlagsInfoTable InstDB::_rwFlagsInfoTable[] = {\n${StringUtils.format(rwInfoTable, kIndent, true)}\n};\n` +
`#undef FLAG\n`;
- this.inject("InstCommonInfoTableB", disclaimer(s), commonTableB.length * 8 + rwInfoTable.length * 8);
+ this.inject("AdditionalInfoTable", disclaimer(s), additionaInfoTable.length * 8 + rwInfoTable.length * 8);
}
rwFlagsOf(dbInsts) {
@@ -1852,35 +1916,35 @@ class InstRWInfoTable extends core.Task {
const _ = null;
this.rwCategoryByData = {
Vmov1_8: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 8}, {access: "R", flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 16}, {access: "R", flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 32}, {access: "R", flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 8}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 16}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 32}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
],
Vmov1_4: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 32}, {access: "R", flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width:128}, {access: "R", flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 32}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width:128}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
],
Vmov1_2: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width:128}, {access: "R", flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width:256}, {access: "R", flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 64}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width:128}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:256},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width:256}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:512},_,_,_,_]
],
Vmov2_1: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", flags: {}, fixed: -1, index: 0, width:256},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:128},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:256},_,_,_,_]
],
Vmov4_1: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", flags: {}, fixed: -1, index: 0, width: 32},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", flags: {}, fixed: -1, index: 0, width:128},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 32},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width:128},_,_,_,_]
],
Vmov8_1: [
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", flags: {}, fixed: -1, index: 0, width: 16},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", flags: {}, fixed: -1, index: 0, width: 32},_,_,_,_],
- [{access: "W", flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_]
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 128}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 16},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 256}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 32},_,_,_,_],
+ [{access: "W", clc: 0, flags: {}, fixed: -1, index: 0, width: 512}, {access: "R", clc: 0, flags: {}, fixed: -1, index: 0, width: 64},_,_,_,_]
]
};
}
@@ -1900,8 +1964,9 @@ class InstRWInfoTable extends core.Task {
"0x0000000000000000u",
"0x0000000000000000u",
"0xFF",
+ "0",
CxxUtils.struct(0),
- "0"
+ "OpRWFlags::kNone"
);
this.rmInfoTable.addIndexed(noRmInfo);
@@ -1946,12 +2011,15 @@ class InstRWInfoTable extends core.Task {
const wIndex = opAcc === "X" || opAcc === "W" ? op.index : -1;
const wWidth = opAcc === "X" || opAcc === "W" ? op.width : -1;
+ const consecutiveLeadCount = op.clc;
+
const opData = CxxUtils.struct(
this.byteMaskFromBitRanges([{ start: rIndex, end: rIndex + rWidth - 1 }]) + "u",
this.byteMaskFromBitRanges([{ start: wIndex, end: wIndex + wWidth - 1 }]) + "u",
StringUtils.decToHex(op.fixed === -1 ? 0xFF : op.fixed, 2),
+ String(consecutiveLeadCount),
CxxUtils.struct(0),
- CxxUtils.flags(flags, function(flag) { return "OpRWInfo::k" + flag; })
+ CxxUtils.flags(flags, function(flag) { return "OpRWFlags::k" + flag; }, "OpRWFlags::kNone")
);
rwOpsIndex.push(this.opInfoTable.addIndexed(opData));
@@ -1962,7 +2030,7 @@ class InstRWInfoTable extends core.Task {
StringUtils.decToHex(rmInfo.rmIndexes, 2),
String(Math.max(rmInfo.memFixed, 0)).padEnd(2),
CxxUtils.flags({ "InstDB::RWInfoRm::kFlagAmbiguous": Boolean(rmInfo.memAmbiguous) }),
- rmInfo.memExtension === "None" ? "0" : "Features::k" + rmInfo.memExtension
+ rmInfo.memExtension === "None" ? "0" : "uint32_t(CpuFeatures::X86::k" + rmInfo.memExtension + ")"
);
const rwData = CxxUtils.struct(
@@ -2045,6 +2113,7 @@ class InstRWInfoTable extends core.Task {
return {
access: op.read && op.write ? "X" : op.read ? "R" : op.write ? "W" : "?",
+ clc: 0,
flags: {},
fixed: GenUtils.fixedRegOf(op.reg),
index: op.rwxIndex,
@@ -2066,12 +2135,16 @@ class InstRWInfoTable extends core.Task {
const opSize = op.isReg() ? op.regSize : op.memSize;
var d = {
access: op.read && op.write ? "X" : op.read ? "R" : op.write ? "W" : "?",
+ clc: 0,
flags: {},
fixed: -1,
index: -1,
width: -1
};
+ if (op.consecutiveLeadCount)
+ d.clc = op.consecutiveLeadCount;
+
if (op.isReg())
d.fixed = GenUtils.fixedRegOf(op.reg);
else
@@ -2080,6 +2153,9 @@ class InstRWInfoTable extends core.Task {
if (op.zext)
d.flags.ZExt = true;
+ if (op.regIndexRel)
+ d.flags.Consecutive = true;
+
for (var k in self.rwOpFlagsForInstruction(asmInst.name, j))
d.flags[k] = true;
@@ -2436,7 +2512,7 @@ class InstCommonTable extends core.Task {
"IdEnum",
"NameTable",
"InstSignatureTable",
- "InstCommonInfoTableB",
+ "AdditionalInfoTable",
"InstRWInfoTable"
]);
}
@@ -2452,26 +2528,26 @@ class InstCommonTable extends core.Task {
const commonFlags = commonFlagsArray.map(function(flag) { return `F(${flag })`; }).join("|") || "0";
const avx512Flags = avx512FlagsArray.map(function(flag) { return `X(${flag.substr(6)})`; }).join("|") || "0";
- const singleRegCase = `SINGLE_REG(${inst.singleRegCase})`;
- const controlType = `CONTROL(${inst.controlType})`;
+ const controlFlow = `CONTROL_FLOW(${inst.controlFlow})`;
+ const singleRegCase = `SAME_REG_HINT(${inst.singleRegCase})`;
const row = "{ " +
String(commonFlags ).padEnd(50) + ", " +
String(avx512Flags ).padEnd(30) + ", " +
String(inst.signatureIndex).padEnd( 3) + ", " +
String(inst.signatureCount).padEnd( 2) + ", " +
- String(controlType ).padEnd(16) + ", " +
+ String(controlFlow ).padEnd(16) + ", " +
String(singleRegCase ).padEnd(16) + "}";
- inst.commonInfoIndexA = table.addIndexed(row);
+ inst.commonInfoIndex = table.addIndexed(row);
});
- var s = `#define F(VAL) InstDB::kFlag##VAL\n` +
- `#define X(VAL) InstDB::kAvx512Flag##VAL\n` +
- `#define CONTROL(VAL) Inst::kControl##VAL\n` +
- `#define SINGLE_REG(VAL) InstDB::kSingleReg##VAL\n` +
+ var s = `#define F(VAL) uint32_t(InstDB::InstFlags::k##VAL)\n` +
+ `#define X(VAL) uint32_t(InstDB::Avx512Flags::k##VAL)\n` +
+ `#define CONTROL_FLOW(VAL) uint8_t(InstControlFlow::k##VAL)\n` +
+ `#define SAME_REG_HINT(VAL) uint8_t(InstSameRegHint::k##VAL)\n` +
`const InstDB::CommonInfo InstDB::_commonInfoTable[] = {\n${StringUtils.format(table, kIndent, true)}\n};\n` +
- `#undef SINGLE_REG\n` +
- `#undef CONTROL\n` +
+ `#undef SAME_REG_HINT\n` +
+ `#undef CONTROL_FLOW\n` +
`#undef X\n` +
`#undef F\n`;
this.inject("InstCommonTable", disclaimer(s), table.length * 8);
@@ -2487,7 +2563,7 @@ new X86TableGen()
.addTask(new NameTable())
.addTask(new AltOpcodeTable())
.addTask(new InstSignatureTable())
- .addTask(new InstCommonInfoTableB())
+ .addTask(new AdditionalInfoTable())
.addTask(new InstRWInfoTable())
.addTask(new InstCommonTable())
.run();
diff --git a/tools/tablegen.js b/tools/tablegen.js
index c367522..75d81b1 100644
--- a/tools/tablegen.js
+++ b/tools/tablegen.js
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
// ============================================================================
// tablegen.js
@@ -426,7 +408,10 @@ exports.MapUtils = MapUtils;
// ============================================================================
class CxxUtils {
- static flags(obj, fn) {
+ static flags(obj, fn, none) {
+ if (none == null)
+ none = "0";
+
if (!fn)
fn = nop;
@@ -435,7 +420,7 @@ class CxxUtils {
if (obj[k])
out += (out ? " | " : "") + fn(k);
}
- return out ? out : "0";
+ return out ? out : none;
}
static struct(...args) {